Chromium Code Reviews| Index: device/bluetooth/device.cc |
| diff --git a/device/bluetooth/device.cc b/device/bluetooth/device.cc |
| index 7e662802eabb5aed91c9859f782903049c866170..7a519efa8341843786d4b88b76d56243e44cb1e6 100644 |
| --- a/device/bluetooth/device.cc |
| +++ b/device/bluetooth/device.cc |
| @@ -3,18 +3,37 @@ |
| // found in the LICENSE file. |
| #include <utility> |
| +#include <vector> |
| +#include "base/logging.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(const std::string& address, |
| - scoped_refptr<device::BluetoothAdapter> adapter) |
| - : address_(address), adapter_(std::move(adapter)) {} |
| +Device::Device(scoped_refptr<device::BluetoothAdapter> adapter, |
| + std::unique_ptr<device::BluetoothGattConnection> connection, |
| + mojom::DeviceRequest request) |
| + : adapter_(std::move(adapter)), |
| + connection_(std::move(connection)), |
| + binding_(this, std::move(request)) { |
| + // Binding is owned by this Device, so base::Unretatined is safe. |
| + binding_.set_connection_error_handler( |
| + base::Bind(&Device::Disconnect, base::Unretained(this))); |
| -Device::~Device() {} |
| + adapter_->AddObserver(this); |
| +} |
| + |
| +Device::~Device() { |
| + // Callbacks shouldn't be deleted before the connection is closed. |
| + if (has_pending_services_) { |
|
ortuno
2016/11/02 07:56:04
Ah sorry I think I confused you. I don't think you
mbrunson
2016/11/02 21:57:08
Done.
|
| + DCHECK(!pending_services_requests_.empty()); |
| + } |
| + |
| + binding_.Close(); |
| + adapter_->RemoveObserver(this); |
| +} |
| // static |
| mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct( |
| @@ -25,6 +44,7 @@ mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct( |
| 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(); |
| @@ -34,14 +54,91 @@ mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct( |
| return device_info; |
| } |
| +size_t Device::GetPendingServiceRequestCountForTesting() { |
| + return pending_services_requests_.size(); |
| +} |
| + |
| +void Device::DeviceChanged(device::BluetoothAdapter* adapter, |
| + device::BluetoothDevice* device) { |
| + if (device->GetAddress() != GetAddress()) { |
| + return; |
| + } |
| + |
| + if (!device->IsGattConnected()) { |
| + delete this; |
| + } |
| +} |
| + |
| +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(); |
| + } |
| + |
| + has_pending_services_ = false; |
| +} |
| + |
| +void Device::Disconnect() { |
| + delete this; |
| +} |
| + |
| void Device::GetInfo(const GetInfoCallback& callback) { |
| - device::BluetoothDevice* device = adapter_->GetDevice(address_); |
| - if (device) { |
| - mojom::DeviceInfoPtr device_info = ConstructDeviceInfoStruct(device); |
| - callback.Run(std::move(device_info)); |
| - } else { |
| - callback.Run(nullptr); |
| + device::BluetoothDevice* device = adapter_->GetDevice(GetAddress()); |
| + DCHECK(device); |
| + |
| + mojom::DeviceInfoPtr device_info = ConstructDeviceInfoStruct(device); |
| + callback.Run(std::move(device_info)); |
| +} |
| + |
| +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::Unretatined is |
| + // safe. |
| + pending_services_requests_.push_back( |
| + base::Bind(&Device::GetServicesImpl, base::Unretained(this), callback)); |
| + has_pending_services_ = true; |
| +} |
| + |
| +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()) { |
| + mojom::ServiceInfoPtr service_info = ConstructServiceInfoStruct(*service); |
| + services.push_back(std::move(service_info)); |
| } |
| + |
| + callback.Run(std::move(services)); |
| +} |
| + |
| +mojom::ServiceInfoPtr Device::ConstructServiceInfoStruct( |
| + const device::BluetoothRemoteGattService& service) { |
| + mojom::ServiceInfoPtr service_info = mojom::ServiceInfo::New(); |
| + |
| + service_info->uuid = service.GetUUID(); |
| + service_info->is_primary = service.IsPrimary(); |
| + |
| + return service_info; |
| +} |
| + |
| +const std::string& Device::GetAddress() { |
| + return connection_->GetDeviceAddress(); |
| } |
| } // namespace bluetooth |