blob: ca1e6149dbf2370efbbb3caea1dd7d202d18fb56 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include <vector>
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "device/bluetooth/device.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
namespace bluetooth {
Device::~Device() {
adapter_->RemoveObserver(this);
}
// static
void Device::Create(scoped_refptr<device::BluetoothAdapter> adapter,
std::unique_ptr<device::BluetoothGattConnection> connection,
mojom::DeviceRequest request) {
auto device_impl =
base::WrapUnique(new Device(adapter, std::move(connection)));
auto* device_ptr = device_impl.get();
device_ptr->binding_ =
mojo::MakeStrongBinding(std::move(device_impl), std::move(request));
}
// static
mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct(
const device::BluetoothDevice* device) {
mojom::DeviceInfoPtr device_info = mojom::DeviceInfo::New();
device_info->name = device->GetName();
device_info->name_for_display =
base::UTF16ToUTF8(device->GetNameForDisplay());
device_info->address = device->GetAddress();
device_info->is_gatt_connected = device->IsGattConnected();
if (device->GetInquiryRSSI()) {
device_info->rssi = mojom::RSSIWrapper::New();
device_info->rssi->value = device->GetInquiryRSSI().value();
}
return device_info;
}
void Device::DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
if (device->GetAddress() != GetAddress()) {
return;
}
if (!device->IsGattConnected()) {
binding_->Close();
}
}
void Device::GattServicesDiscovered(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) {
if (device->GetAddress() != GetAddress()) {
return;
}
std::vector<base::Closure> requests;
requests.swap(pending_services_requests_);
for (const base::Closure& request : requests) {
request.Run();
}
}
void Device::Disconnect() {
binding_->Close();
}
void Device::GetInfo(const GetInfoCallback& callback) {
device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
DCHECK(device);
callback.Run(ConstructDeviceInfoStruct(device));
}
void Device::GetServices(const GetServicesCallback& callback) {
device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
DCHECK(device);
if (device->IsGattServicesDiscoveryComplete()) {
GetServicesImpl(callback);
return;
}
// pending_services_requests_ is owned by Device, so base::Unretained is
// safe.
pending_services_requests_.push_back(
base::Bind(&Device::GetServicesImpl, base::Unretained(this), callback));
}
void Device::GetCharacteristics(const std::string& service_id,
const GetCharacteristicsCallback& callback) {
device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
DCHECK(device);
if (device->IsGattServicesDiscoveryComplete()) {
GetCharacteristicsImpl(service_id, callback);
return;
}
// pending_services_requests_ is owned by Device, so base::Unretained is
// safe.
pending_services_requests_.push_back(
base::Bind(&Device::GetCharacteristicsImpl, base::Unretained(this),
service_id, callback));
}
Device::Device(scoped_refptr<device::BluetoothAdapter> adapter,
std::unique_ptr<device::BluetoothGattConnection> connection)
: adapter_(std::move(adapter)), connection_(std::move(connection)) {
adapter_->AddObserver(this);
}
void Device::GetServicesImpl(const GetServicesCallback& callback) {
device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
DCHECK(device);
std::vector<mojom::ServiceInfoPtr> services;
for (const device::BluetoothRemoteGattService* service :
device->GetGattServices()) {
services.push_back(ConstructServiceInfoStruct(*service));
}
callback.Run(std::move(services));
}
mojom::ServiceInfoPtr Device::ConstructServiceInfoStruct(
const device::BluetoothRemoteGattService& service) {
mojom::ServiceInfoPtr service_info = mojom::ServiceInfo::New();
service_info->id = service.GetIdentifier();
service_info->uuid = service.GetUUID();
service_info->is_primary = service.IsPrimary();
return service_info;
}
void Device::GetCharacteristicsImpl(
const std::string& service_id,
const GetCharacteristicsCallback& callback) {
device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
DCHECK(device);
device::BluetoothRemoteGattService* service =
device->GetGattService(service_id);
DCHECK(service);
std::vector<mojom::CharacteristicInfoPtr> characteristics;
for (const auto* characteristic : service->GetCharacteristics()) {
mojom::CharacteristicInfoPtr characteristic_info =
mojom::CharacteristicInfo::New();
characteristic_info->id = characteristic->GetIdentifier();
characteristic_info->uuid = characteristic->GetUUID();
characteristic_info->properties = characteristic->GetProperties();
characteristics.push_back(std::move(characteristic_info));
}
callback.Run(std::move(characteristics));
}
const std::string& Device::GetAddress() {
return connection_->GetDeviceAddress();
}
} // namespace bluetooth