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

Side by Side Diff: device/bluetooth/bluetooth_low_energy_device_mac.mm

Issue 2641133003: Bluetooth: macOS: Adding counter for service discovery callbacks. (Closed)
Patch Set: Better test Created 3 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" 5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h"
6 6
7 #import <CoreFoundation/CoreFoundation.h> 7 #import <CoreFoundation/CoreFoundation.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/sdk_forward_declarations.h" 12 #include "base/mac/sdk_forward_declarations.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/sys_string_conversions.h" 15 #include "base/strings/sys_string_conversions.h"
16 #include "device/bluetooth/bluetooth_adapter_mac.h" 16 #include "device/bluetooth/bluetooth_adapter_mac.h"
17 #include "device/bluetooth/bluetooth_device.h" 17 #include "device/bluetooth/bluetooth_device.h"
18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h" 18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h"
19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" 19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
20 20
21 using device::BluetoothDevice; 21 using device::BluetoothDevice;
22 using device::BluetoothLowEnergyDeviceMac; 22 using device::BluetoothLowEnergyDeviceMac;
23 23
24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( 24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
25 BluetoothAdapterMac* adapter, 25 BluetoothAdapterMac* adapter,
26 CBPeripheral* peripheral) 26 CBPeripheral* peripheral)
27 : BluetoothDeviceMac(adapter), 27 : BluetoothDeviceMac(adapter),
28 peripheral_(peripheral, base::scoped_policy::RETAIN) { 28 peripheral_(peripheral, base::scoped_policy::RETAIN),
29 discovery_pending_count_(0) {
29 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); 30 DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable());
30 DCHECK(peripheral_.get()); 31 DCHECK(peripheral_.get());
31 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] 32 peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc]
32 initWithBluetoothLowEnergyDeviceMac:this]); 33 initWithBluetoothLowEnergyDeviceMac:this]);
33 [peripheral_ setDelegate:peripheral_delegate_]; 34 [peripheral_ setDelegate:peripheral_delegate_];
34 identifier_ = GetPeripheralIdentifier(peripheral); 35 identifier_ = GetPeripheralIdentifier(peripheral);
35 hash_address_ = GetPeripheralHashAddress(peripheral); 36 hash_address_ = GetPeripheralHashAddress(peripheral);
36 UpdateTimestamp(); 37 UpdateTimestamp();
37 } 38 }
38 39
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 void BluetoothLowEnergyDeviceMac::DidDiscoverPrimaryServices(NSError* error) { 187 void BluetoothLowEnergyDeviceMac::DidDiscoverPrimaryServices(NSError* error) {
187 if (error) { 188 if (error) {
188 // TODO(http://crbug.com/609320): Need to pass the error. 189 // TODO(http://crbug.com/609320): Need to pass the error.
189 // TODO(http://crbug.com/609844): Decide what to do if discover failed 190 // TODO(http://crbug.com/609844): Decide what to do if discover failed
190 // a device services. 191 // a device services.
191 VLOG(1) << "Can't discover primary services: " 192 VLOG(1) << "Can't discover primary services: "
192 << error.localizedDescription.UTF8String << " (" << error.domain 193 << error.localizedDescription.UTF8String << " (" << error.domain
193 << ": " << error.code << ")"; 194 << ": " << error.code << ")";
194 return; 195 return;
195 } 196 }
196 VLOG(1) << "DidDiscoverPrimaryServices."; 197 VLOG(1) << "DidDiscoverPrimaryServices, pending count: "
198 << discovery_pending_count_;
197 199
198 if (!IsGattConnected()) { 200 if (!IsGattConnected()) {
199 // Don't create services if the device disconnected. 201 // Don't create services if the device disconnected.
200 return; 202 return;
201 } 203 }
202 204
203 for (CBService* cb_service in GetPeripheral().services) { 205 for (CBService* cb_service in GetPeripheral().services) {
204 BluetoothRemoteGattServiceMac* gatt_service = 206 BluetoothRemoteGattServiceMac* gatt_service =
205 GetBluetoothRemoteGattService(cb_service); 207 GetBluetoothRemoteGattService(cb_service);
206 if (!gatt_service) { 208 if (!gatt_service) {
207 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service, 209 gatt_service = new BluetoothRemoteGattServiceMac(this, cb_service,
208 true /* is_primary */); 210 true /* is_primary */);
209 auto result_iter = gatt_services_.insert(std::make_pair( 211 auto result_iter = gatt_services_.insert(std::make_pair(
210 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service))); 212 gatt_service->GetIdentifier(), base::WrapUnique(gatt_service)));
211 DCHECK(result_iter.second); 213 DCHECK(result_iter.second);
212 adapter_->NotifyGattServiceAdded(gatt_service); 214 adapter_->NotifyGattServiceAdded(gatt_service);
213 } 215 }
214 } 216 }
215 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) { 217 --discovery_pending_count_;
216 device::BluetoothRemoteGattService* gatt_service = it->second.get(); 218 DCHECK(discovery_pending_count_ >= 0);
217 device::BluetoothRemoteGattServiceMac* gatt_service_mac = 219 if (discovery_pending_count_ == 0) {
218 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service); 220 for (auto it = gatt_services_.begin(); it != gatt_services_.end(); ++it) {
219 gatt_service_mac->DiscoverCharacteristics(); 221 device::BluetoothRemoteGattService* gatt_service = it->second.get();
222 device::BluetoothRemoteGattServiceMac* gatt_service_mac =
223 static_cast<BluetoothRemoteGattServiceMac*>(gatt_service);
224 gatt_service_mac->DiscoverCharacteristics();
225 }
226 SendNotificationIfDiscoveryComplete();
220 } 227 }
221 } 228 }
222 229
223 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics( 230 void BluetoothLowEnergyDeviceMac::DidDiscoverCharacteristics(
224 CBService* cb_service, 231 CBService* cb_service,
225 NSError* error) { 232 NSError* error) {
226 if (error) { 233 if (error) {
227 // TODO(http://crbug.com/609320): Need to pass the error. 234 // TODO(http://crbug.com/609320): Need to pass the error.
228 // TODO(http://crbug.com/609844): Decide what to do if discover failed 235 // TODO(http://crbug.com/609844): Decide what to do if discover failed
229 VLOG(1) << "Can't discover characteristics: " 236 VLOG(1) << "Can't discover characteristics: "
(...skipping 24 matching lines...) Expand all
254 DCHECK(gatt_service); 261 DCHECK(gatt_service);
255 VLOG(1) << gatt_service->GetUUID().canonical_value(); 262 VLOG(1) << gatt_service->GetUUID().canonical_value();
256 std::unique_ptr<BluetoothRemoteGattService> scoped_service = 263 std::unique_ptr<BluetoothRemoteGattService> scoped_service =
257 std::move(gatt_services_[gatt_service->GetIdentifier()]); 264 std::move(gatt_services_[gatt_service->GetIdentifier()]);
258 gatt_services_.erase(gatt_service->GetIdentifier()); 265 gatt_services_.erase(gatt_service->GetIdentifier());
259 adapter_->NotifyGattServiceRemoved(scoped_service.get()); 266 adapter_->NotifyGattServiceRemoved(scoped_service.get());
260 } 267 }
261 device_uuids_.ClearServiceUUIDs(); 268 device_uuids_.ClearServiceUUIDs();
262 SetGattServicesDiscoveryComplete(false); 269 SetGattServicesDiscoveryComplete(false);
263 adapter_->NotifyDeviceChanged(this); 270 adapter_->NotifyDeviceChanged(this);
264 [GetPeripheral() discoverServices:nil]; 271 DiscoverPrimaryServices();
265 } 272 }
266 273
267 void BluetoothLowEnergyDeviceMac::DidUpdateValue( 274 void BluetoothLowEnergyDeviceMac::DidUpdateValue(
268 CBCharacteristic* characteristic, 275 CBCharacteristic* characteristic,
269 NSError* error) { 276 NSError* error) {
270 VLOG(1) << "DidUpdateValue."; 277 VLOG(1) << "DidUpdateValue.";
271 BluetoothRemoteGattServiceMac* gatt_service = 278 BluetoothRemoteGattServiceMac* gatt_service =
272 GetBluetoothRemoteGattService(characteristic.service); 279 GetBluetoothRemoteGattService(characteristic.service);
273 DCHECK(gatt_service); 280 DCHECK(gatt_service);
274 gatt_service->DidUpdateValue(characteristic, error); 281 gatt_service->DidUpdateValue(characteristic, error);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress( 337 std::string BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(
331 CBPeripheral* peripheral) { 338 CBPeripheral* peripheral) {
332 const size_t kCanonicalAddressNumberOfBytes = 6; 339 const size_t kCanonicalAddressNumberOfBytes = 6;
333 char raw[kCanonicalAddressNumberOfBytes]; 340 char raw[kCanonicalAddressNumberOfBytes];
334 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw, 341 crypto::SHA256HashString(GetPeripheralIdentifier(peripheral), raw,
335 sizeof(raw)); 342 sizeof(raw));
336 std::string hash = base::HexEncode(raw, sizeof(raw)); 343 std::string hash = base::HexEncode(raw, sizeof(raw));
337 return BluetoothDevice::CanonicalizeAddress(hash); 344 return BluetoothDevice::CanonicalizeAddress(hash);
338 } 345 }
339 346
347 void BluetoothLowEnergyDeviceMac::DiscoverPrimaryServices() {
348 [GetPeripheral() discoverServices:nil];
ortuno 2017/01/23 20:44:02 nit: Move this to the end of the function.
jlebel 2017/01/26 00:36:54 Done.
349 VLOG(1) << "DidDiscoverDescriptors pending count" << discovery_pending_count_;
350 ++discovery_pending_count_;
351 }
352
340 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() { 353 void BluetoothLowEnergyDeviceMac::SendNotificationIfDiscoveryComplete() {
341 // Notify when all services have been discovered. 354 // Notify when all services have been discovered.
342 bool discovery_complete = 355 bool discovery_complete =
356 discovery_pending_count_ == 0 &&
343 std::find_if_not( 357 std::find_if_not(
344 gatt_services_.begin(), gatt_services_.end(), 358 gatt_services_.begin(), gatt_services_.end(),
345 [](GattServiceMap::value_type& pair) { 359 [](GattServiceMap::value_type& pair) {
346 BluetoothRemoteGattService* gatt_service = pair.second.get(); 360 BluetoothRemoteGattService* gatt_service = pair.second.get();
347 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service) 361 return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service)
348 ->IsDiscoveryComplete(); 362 ->IsDiscoveryComplete();
349 }) == gatt_services_.end(); 363 }) == gatt_services_.end();
350 if (discovery_complete) { 364 if (discovery_complete) {
351 device_uuids_.ReplaceServiceUUIDs(gatt_services_); 365 device_uuids_.ReplaceServiceUUIDs(gatt_services_);
352 SetGattServicesDiscoveryComplete(true); 366 SetGattServicesDiscoveryComplete(true);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 // 2. When we cancel a pending connection request. 404 // 2. When we cancel a pending connection request.
391 if (create_gatt_connection_error_callbacks_.empty()) { 405 if (create_gatt_connection_error_callbacks_.empty()) {
392 // If there are no pending callbacks then the connection broke (#1). 406 // If there are no pending callbacks then the connection broke (#1).
393 DidDisconnectGatt(true /* notifyDeviceChanged */); 407 DidDisconnectGatt(true /* notifyDeviceChanged */);
394 return; 408 return;
395 } 409 }
396 // Else we canceled the connection request (#2). 410 // Else we canceled the connection request (#2).
397 // TODO(http://crbug.com/585897): Need to pass the error. 411 // TODO(http://crbug.com/585897): Need to pass the error.
398 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED); 412 DidFailToConnectGatt(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
399 } 413 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698