Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Unified Diff: device/bluetooth/bluetooth_low_energy_device_mac.mm

Issue 1948763003: Adding support for service scan on OS X (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cleanup
Patch Set: Adding disconnect with error Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/bluetooth_low_energy_device_mac.mm
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm
index 03981d77d1f15848b9ddcfadd71be1aa41f36548..580dbbbeda762d871367b98d57d5ad2bce0550d9 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.mm
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -14,6 +14,8 @@
#include "base/strings/sys_string_conversions.h"
#include "device/bluetooth/bluetooth_adapter_mac.h"
#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h"
+#include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
using device::BluetoothDevice;
using device::BluetoothLowEnergyDeviceMac;
@@ -27,6 +29,9 @@ BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
peripheral_(peripheral, base::scoped_policy::RETAIN) {
DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
DCHECK(peripheral_.get());
+ peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc]
+ initWithBluetoothLowEnergyDeviceMac:this]);
+ [peripheral_ setDelegate:peripheral_delegate_];
identifier_ = GetPeripheralIdentifier(peripheral);
hash_address_ = GetPeripheralHashAddress(peripheral);
Update(advertisement_data, rssi);
@@ -226,10 +231,52 @@ void BluetoothLowEnergyDeviceMac::CreateGattConnectionImpl() {
}
}
+void BluetoothLowEnergyDeviceMac::DidConnectGatt() {
+ [GetPeripheral() discoverServices:nil];
ortuno 2016/05/06 16:03:33 Could this be called from BluetoothAdapterMac::Did
jlebel 2016/05/07 00:16:10 Yes, of course, it can be done there. But it doesn
ortuno 2016/05/09 19:54:00 Ah, good point. Up to you.
+ BluetoothDeviceMac::DidConnectGatt();
+}
+
void BluetoothLowEnergyDeviceMac::DisconnectGatt() {
GetMacAdapter()->DisconnectGatt(this);
}
+void BluetoothLowEnergyDeviceMac::DidDiscoverPrimaryServices(NSError* error) {
+ if (error) {
ortuno 2016/05/06 16:03:33 I think for now let's just VLOG it or UMA it to ma
jlebel 2016/05/07 00:16:10 Done.
+ // TODO(http://crbug.com/609320): Need to pass the error.
+ DisconnectGatt();
+ return;
+ }
+ for (CBService* cb_service in GetPeripheral().services) {
+ BluetoothRemoteGattServiceMac* gatt_service =
+ GetBluetoothRemoteGattService(cb_service);
+ if (!gatt_service) {
+ gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service, true);
ortuno 2016/05/06 16:03:33 To make the code easier to read, you should commen
jlebel 2016/05/07 00:16:11 Done.
+ gatt_services_.add(
ortuno 2016/05/06 16:03:33 nit: I would save the result from here and then DC
jlebel 2016/05/07 00:16:11 a DCHECK like: DCHECK(GetPeripheralIdentifier(cb_s
ortuno 2016/05/09 19:54:00 More like: auto result_iter = gatt_services_.add(
+ gatt_service->GetIdentifier(),
+ std::unique_ptr<BluetoothRemoteGattService>(gatt_service));
ortuno 2016/05/06 16:03:33 nit: maybe you can just use base::WrapUnique() ins
jlebel 2016/05/07 00:16:10 Done.
+ adapter_->NotifyGattServiceAdded(gatt_service);
ortuno 2016/05/06 16:03:33 It's a bit dangerous to be passing the raw pointer
jlebel 2016/05/07 00:16:11 It is nicer to create a service so I can track whi
+ }
+ }
+ SetGattServicesDiscoveryComplete(true);
+ adapter_->NotifyGattServicesDiscovered(this);
ortuno 2016/05/06 16:03:33 As discussed, this should be called only after all
jlebel 2016/05/07 00:16:10 Done.
+}
+
+void BluetoothLowEnergyDeviceMac::DidModifyServices(
ortuno 2016/05/06 16:03:33 Does this get called when disconnecting?
jlebel 2016/05/07 00:16:10 No. It is called when the services are modified.
+ NSArray* invalidatedServices) {
+ for (CBService* cb_service in invalidatedServices) {
+ BluetoothRemoteGattServiceMac* gatt_service =
+ GetBluetoothRemoteGattService(cb_service);
+ DCHECK(gatt_service);
+ if ([GetPeripheral().services containsObject:cb_service]) {
ortuno 2016/05/06 16:03:33 Based on [1] it seems we can no longer use the *an
jlebel 2016/05/07 00:16:10 Done.
+ adapter_->NotifyGattServiceChanged(gatt_service);
+ } else {
+ gatt_services_.take_and_erase(gatt_service->GetIdentifier());
+ }
+ }
+ SetGattServicesDiscoveryComplete(false);
+ [GetPeripheral() discoverServices:nil];
+}
+
// static
std::string BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(
CBPeripheral* peripheral) {
@@ -258,8 +305,32 @@ CBPeripheral* BluetoothLowEnergyDeviceMac::GetPeripheral() {
return peripheral_;
}
+device::BluetoothRemoteGattServiceMac*
+BluetoothLowEnergyDeviceMac::GetBluetoothRemoteGattService(
+ CBService* cb_service) const {
+ for (GattServiceMap::const_iterator it = gatt_services_.begin();
+ it != gatt_services_.end(); ++it) {
+ device::BluetoothRemoteGattService* gatt_service = it->second;
+ device::BluetoothRemoteGattServiceMac* gatt_service_mac =
+ static_cast<BluetoothRemoteGattServiceMac*>(gatt_service);
+ if (gatt_service_mac->GetService() == cb_service)
+ return gatt_service_mac;
+ }
+ return NULL;
ortuno 2016/05/06 16:03:33 nit: return nullptr;
jlebel 2016/05/07 00:16:11 Done.
+}
+
void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral(
BluetoothDevice::ConnectErrorCode error_code) {
+ SetGattServicesDiscoveryComplete(false);
+ // Explicitly take and erase GATT services one by one to ensure that calling
+ // GetGattService on removed service in GattServiceRemoved returns null.
+ std::vector<std::string> service_keys;
+ for (const auto& gatt_service : gatt_services_) {
+ service_keys.push_back(gatt_service.first);
+ }
+ for (const auto& key : service_keys) {
+ gatt_services_.take_and_erase(key);
+ }
ortuno 2016/05/06 16:03:33 You could also swap it with a local map and erase
jlebel 2016/05/07 00:16:11 I have a crash on the second service removed.
ortuno 2016/05/09 19:54:00 Hmm really? I just tried it with the tests and it
if (create_gatt_connection_error_callbacks_.empty()) {
// TODO(http://crbug.com/585897): Need to pass the error.
DidDisconnectGatt();

Powered by Google App Engine
This is Rietveld 408576698