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

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

Issue 2339253002: bluetooth: mac: add connected LE devices to chooser (Closed)
Patch Set: More tests, and fixing ortuno's comments Created 4 years, 1 month 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_adapter_mac.h" 5 #include "device/bluetooth/bluetooth_adapter_mac.h"
6 6
7 #import <IOBluetooth/objc/IOBluetoothDevice.h> 7 #import <IOBluetooth/objc/IOBluetoothDevice.h>
8 #import <IOBluetooth/objc/IOBluetoothHostController.h> 8 #import <IOBluetooth/objc/IOBluetoothHostController.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 10
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 179 }
180 180
181 bool BluetoothAdapterMac::IsDiscovering() const { 181 bool BluetoothAdapterMac::IsDiscovering() const {
182 bool is_discovering = classic_discovery_manager_->IsDiscovering(); 182 bool is_discovering = classic_discovery_manager_->IsDiscovering();
183 if (IsLowEnergyAvailable()) 183 if (IsLowEnergyAvailable())
184 is_discovering = 184 is_discovering =
185 is_discovering || low_energy_discovery_manager_->IsDiscovering(); 185 is_discovering || low_energy_discovery_manager_->IsDiscovering();
186 return is_discovering; 186 return is_discovering;
187 } 187 }
188 188
189 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
190 BluetoothAdapterMac::RetrieveGattConnectedDevicesWithDiscoveryFilter(
191 const BluetoothDiscoveryFilter& discovery_filter) {
192 std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
193 connected_devices;
194 std::set<device::BluetoothUUID> uuids;
195 discovery_filter.GetUUIDs(uuids);
196 if (uuids.empty()) {
197 for (BluetoothDevice* device :
198 RetrieveGattConnectedDevicesWithService(nullptr)) {
199 connected_devices[device] = BluetoothDevice::UUIDSet();
200 }
201 return connected_devices;
202 }
203 for (const BluetoothUUID& uuid : uuids) {
204 for (BluetoothDevice* device :
205 RetrieveGattConnectedDevicesWithService(&uuid)) {
206 connected_devices[device].insert(uuid);
207 }
208 }
209 return connected_devices;
210 }
211
189 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const { 212 BluetoothAdapter::UUIDList BluetoothAdapterMac::GetUUIDs() const {
190 NOTIMPLEMENTED(); 213 NOTIMPLEMENTED();
191 return UUIDList(); 214 return UUIDList();
192 } 215 }
193 216
194 void BluetoothAdapterMac::CreateRfcommService( 217 void BluetoothAdapterMac::CreateRfcommService(
195 const BluetoothUUID& uuid, 218 const BluetoothUUID& uuid,
196 const ServiceOptions& options, 219 const ServiceOptions& options,
197 const CreateServiceCallback& callback, 220 const CreateServiceCallback& callback,
198 const CreateServiceErrorCallback& error_callback) { 221 const CreateServiceErrorCallback& error_callback) {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 int rssi) { 515 int rssi) {
493 BluetoothLowEnergyDeviceMac* device_mac = 516 BluetoothLowEnergyDeviceMac* device_mac =
494 GetBluetoothLowEnergyDeviceMac(peripheral); 517 GetBluetoothLowEnergyDeviceMac(peripheral);
495 // If has no entry in the map, create new device and insert into |devices_|, 518 // If has no entry in the map, create new device and insert into |devices_|,
496 // otherwise update the existing device. 519 // otherwise update the existing device.
497 const bool is_new_device = device_mac == nullptr; 520 const bool is_new_device = device_mac == nullptr;
498 if (is_new_device) { 521 if (is_new_device) {
499 VLOG(1) << "LowEnergyDeviceUpdated new device"; 522 VLOG(1) << "LowEnergyDeviceUpdated new device";
500 // A new device has been found. 523 // A new device has been found.
501 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral); 524 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
502 } else { 525 } else if (DoesCollideWithKnownDevice(peripheral, device_mac)) {
503 // Check that there are no collisions. 526 return;
504 std::string stored_device_id = device_mac->GetIdentifier();
505 std::string updated_device_id =
506 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
507 if (stored_device_id != updated_device_id) {
508 VLOG(1)
509 << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
510 << std::endl
511 << " " << stored_device_id << std::endl
512 << " " << updated_device_id;
513 // Collision, two identifiers map to the same hash address. With a 48 bit
514 // hash the probability of this occuring with 10,000 devices
515 // simultaneously present is 1e-6 (see
516 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
517 // ignore the second device by returning.
518 return;
519 }
520 } 527 }
521 528
522 DCHECK(device_mac); 529 DCHECK(device_mac);
523 530
524 // Get Advertised UUIDs 531 // Get Advertised UUIDs
525 BluetoothDevice::UUIDList advertised_uuids; 532 BluetoothDevice::UUIDList advertised_uuids;
526 NSArray* service_uuids = 533 NSArray* service_uuids =
527 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; 534 [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey];
528 for (CBUUID* uuid in service_uuids) { 535 for (CBUUID* uuid in service_uuids) {
529 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String])); 536 advertised_uuids.push_back(BluetoothUUID([[uuid UUIDString] UTF8String]));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 // Add any new paired devices. 582 // Add any new paired devices.
576 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { 583 for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) {
577 // pairedDevices sometimes includes unknown devices that are not paired. 584 // pairedDevices sometimes includes unknown devices that are not paired.
578 // Radar issue with id 2282763004 has been filed about it. 585 // Radar issue with id 2282763004 has been filed about it.
579 if ([device isPaired]) { 586 if ([device isPaired]) {
580 ClassicDeviceAdded(device); 587 ClassicDeviceAdded(device);
581 } 588 }
582 } 589 }
583 } 590 }
584 591
592 std::vector<BluetoothDevice*>
593 BluetoothAdapterMac::RetrieveGattConnectedDevicesWithService(
594 const BluetoothUUID* uuid) {
595 NSArray* cbUUIDs = nil;
596 if (!uuid) {
597 // It is not possible to ask for all connected peripherals with
598 // -[CBCentralManager retrieveConnectedPeripheralsWithServices:] by passing
599 // nil. To try to get most of the peripherals, the search is done with
600 // Generic Access service.
601 CBUUID* genericAccessServiceUUID = [CBUUID UUIDWithString:@"1800"];
602 cbUUIDs = @[ genericAccessServiceUUID ];
603 } else {
604 NSString* uuidString =
605 base::SysUTF8ToNSString(uuid->canonical_value().c_str());
606 cbUUIDs = @[ [CBUUID UUIDWithString:uuidString] ];
607 }
608 #pragma clang diagnostic push
609 #pragma clang diagnostic ignored "-Wpartial-availability"
ortuno 2016/11/07 03:12:33 nit: I think we can remove this now.
jlebel 2016/11/07 05:56:39 Ah yes!
610 // Can remove ignore -Wpartial-availability when 10.8 will not be supported
611 // anymore.
612 // TODO(crbug.com/653056)
613 NSArray* peripherals = [low_energy_central_manager_
614 retrieveConnectedPeripheralsWithServices:cbUUIDs];
615 #pragma clang diagnostic pop
616 std::vector<BluetoothDevice*> connected_devices;
617 for (CBPeripheral* peripheral in peripherals) {
618 BluetoothLowEnergyDeviceMac* device_mac =
619 GetBluetoothLowEnergyDeviceMac(peripheral);
620 const bool is_new_device = device_mac == nullptr;
621
622 if (!is_new_device && DoesCollideWithKnownDevice(peripheral, device_mac)) {
623 continue;
624 }
625 if (is_new_device) {
626 device_mac = new BluetoothLowEnergyDeviceMac(this, peripheral);
627 std::string device_address =
628 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
629 devices_.add(device_address,
630 std::unique_ptr<BluetoothDevice>(device_mac));
631 for (auto& observer : observers_) {
632 observer.DeviceAdded(this, device_mac);
633 }
634 }
635 connected_devices.push_back(device_mac);
636 }
637 return connected_devices;
638 }
639
585 void BluetoothAdapterMac::CreateGattConnection( 640 void BluetoothAdapterMac::CreateGattConnection(
586 BluetoothLowEnergyDeviceMac* device_mac) { 641 BluetoothLowEnergyDeviceMac* device_mac) {
587 [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_ 642 [low_energy_central_manager_ connectPeripheral:device_mac->peripheral_
588 options:nil]; 643 options:nil];
589 } 644 }
590 645
591 void BluetoothAdapterMac::DisconnectGatt( 646 void BluetoothAdapterMac::DisconnectGatt(
592 BluetoothLowEnergyDeviceMac* device_mac) { 647 BluetoothLowEnergyDeviceMac* device_mac) {
593 [low_energy_central_manager_ 648 [low_energy_central_manager_
594 cancelPeripheralConnection:device_mac->peripheral_]; 649 cancelPeripheralConnection:device_mac->peripheral_];
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) { 700 BluetoothAdapterMac::GetBluetoothLowEnergyDeviceMac(CBPeripheral* peripheral) {
646 std::string device_address = 701 std::string device_address =
647 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral); 702 BluetoothLowEnergyDeviceMac::GetPeripheralHashAddress(peripheral);
648 DevicesMap::const_iterator iter = devices_.find(device_address); 703 DevicesMap::const_iterator iter = devices_.find(device_address);
649 if (iter == devices_.end()) { 704 if (iter == devices_.end()) {
650 return nil; 705 return nil;
651 } 706 }
652 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second); 707 return static_cast<BluetoothLowEnergyDeviceMac*>(iter->second);
653 } 708 }
654 709
710 bool BluetoothAdapterMac::DoesCollideWithKnownDevice(
711 CBPeripheral* peripheral,
712 BluetoothLowEnergyDeviceMac* device_mac) {
713 // Check that there are no collisions.
714 std::string stored_device_id = device_mac->GetIdentifier();
715 std::string updated_device_id =
716 BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(peripheral);
717 if (stored_device_id != updated_device_id) {
718 VLOG(1) << "LowEnergyDeviceUpdated stored_device_id != updated_device_id: "
719 << std::endl
720 << " " << stored_device_id << std::endl
721 << " " << updated_device_id;
722 // Collision, two identifiers map to the same hash address. With a 48 bit
723 // hash the probability of this occuring with 10,000 devices
724 // simultaneously present is 1e-6 (see
725 // https://en.wikipedia.org/wiki/Birthday_problem#Probability_table). We
726 // ignore the second device by returning.
727 return true;
728 }
729 return false;
730 }
731
655 } // namespace device 732 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698