Index: device/bluetooth/device.cc |
diff --git a/device/bluetooth/device.cc b/device/bluetooth/device.cc |
index 7e662802eabb5aed91c9859f782903049c866170..05dbcde232838761beda4ef6e9c45526fd2a9ee3 100644 |
--- a/device/bluetooth/device.cc |
+++ b/device/bluetooth/device.cc |
@@ -3,18 +3,35 @@ |
// 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_.set_connection_error_handler( |
+ base::Bind(&Device::Disconnect, base::Unretained(this))); |
ortuno
2016/11/01 06:27:39
base::Unretained always raises some alarms. It's l
mbrunson
2016/11/02 01:25:45
Hmm. Should I prefer WeakPtrFactory over base::Unr
ortuno
2016/11/02 07:56:04
We shouldn't add complexity unless it's needed. A
|
-Device::~Device() {} |
+ adapter_->AddObserver(this); |
+} |
+ |
+Device::~Device() { |
+ binding_.Close(); |
+ |
+ if (connection_->IsConnected()) |
+ connection_->Disconnect(); |
ortuno
2016/11/01 06:27:39
No need to call Disconnect. Destroying the object
mbrunson
2016/11/02 01:25:45
Removed. Done.
|
+ |
+ adapter_->RemoveObserver(this); |
+} |
// static |
mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct( |
@@ -25,6 +42,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,8 +52,36 @@ mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct( |
return device_info; |
} |
+void Device::set_connection_error_handler(const base::Closure& closure) { |
+ binding_.set_connection_error_handler(closure); |
+} |
+ |
+void Device::DeviceChanged(device::BluetoothAdapter* adapter, |
+ device::BluetoothDevice* device) { |
+ if (device->GetAddress() == GetAddress()) { |
ortuno
2016/11/01 06:27:39
nit:
if (device->GetAddress() != GetAddress()) {
mbrunson
2016/11/02 01:25:45
Done.
|
+ if (!device->IsGattConnected()) { |
+ delete this; |
+ } |
+ } |
+} |
+ |
+void Device::GattServicesDiscovered(device::BluetoothAdapter* adapter, |
+ device::BluetoothDevice* device) { |
+ if (device->GetAddress() == GetAddress()) { |
ortuno
2016/11/01 06:27:39
nit:
if (device->GetAddress() != GetAddress()) {
mbrunson
2016/11/02 01:25:45
Done.
|
+ for (const base::Closure& request : pending_services_requests_) { |
+ request.Run(); |
ortuno
2016/11/01 06:27:39
Running closures in a for loop could lead to unexp
mbrunson
2016/11/02 01:25:45
Are you saying running the requests removes them f
ortuno
2016/11/02 07:56:04
Or adds them. For example we in device/bluetooth w
|
+ } |
+ |
+ pending_services_requests_.clear(); |
+ } |
+} |
+ |
+void Device::Disconnect() { |
+ delete this; |
+} |
+ |
void Device::GetInfo(const GetInfoCallback& callback) { |
- device::BluetoothDevice* device = adapter_->GetDevice(address_); |
+ device::BluetoothDevice* device = adapter_->GetDevice(GetAddress()); |
if (device) { |
ortuno
2016/11/01 06:27:39
Now that lifetime of this class is owned by the co
mbrunson
2016/11/02 01:25:46
Done.
|
mojom::DeviceInfoPtr device_info = ConstructDeviceInfoStruct(device); |
callback.Run(std::move(device_info)); |
@@ -44,4 +90,48 @@ void Device::GetInfo(const GetInfoCallback& callback) { |
} |
} |
+void Device::GetServices(const GetServicesCallback& callback) { |
+ device::BluetoothDevice* device = adapter_->GetDevice(GetAddress()); |
+ |
+ if (device) { |
ortuno
2016/11/01 06:27:39
Same here. I don't think you need the if anymore.
mbrunson
2016/11/02 01:25:45
Done.
|
+ if (device->IsGattServicesDiscoveryComplete()) { |
+ GetServicesImpl(callback); |
+ return; |
+ } |
+ |
+ pending_services_requests_.push_back( |
+ base::Bind(&Device::GetServicesImpl, base::Unretained(this), callback)); |
ortuno
2016/11/01 06:27:39
Here it's a bit harder to see why base::Unretained
|
+ return; |
+ } |
+ |
+ callback.Run(std::vector<mojom::ServiceInfoPtr>()); |
+} |
+ |
+void Device::GetServicesImpl(const GetServicesCallback& callback) { |
+ device::BluetoothDevice* device = adapter_->GetDevice(GetAddress()); |
+ 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( |
ortuno
2016/11/01 06:27:39
Since you know service will always be there just t
mbrunson
2016/11/02 01:25:46
Done.
|
+ 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; |
+} |
+ |
+std::string Device::GetAddress() { |
+ return connection_->GetDeviceAddress(); |
+} |
+ |
} // namespace bluetooth |