Index: device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm |
diff --git a/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm b/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..930dc1e9190b5eb1960a6c5c5415e059c727fbea |
--- /dev/null |
+++ b/device/bluetooth/bluetooth_low_energy_discovery_manager_mac.mm |
@@ -0,0 +1,174 @@ |
+#include "device/bluetooth/bluetooth_low_energy_discovery_manager_mac.h" |
armansito
2015/01/24 17:59:38
Is this file missing the copyright header?
dvh
2015/01/27 00:14:55
Done.
|
+ |
+#include "base/mac/mac_util.h" |
+ |
+#include "device/bluetooth/bluetooth_low_energy_device_mac.h" |
+ |
+using namespace device; |
+ |
+namespace device { |
+ |
+// This class is a helper to call some protected methods in |
+// BluetoothLowEnergyDiscoverManagerMac. |
+class BluetoothLowEnergyDiscoverManagerMacDelegate { |
+ public: |
+ BluetoothLowEnergyDiscoverManagerMacDelegate( |
+ BluetoothLowEnergyDiscoverManagerMac *manager) |
+ : manager_(manager) {} |
+ |
+ virtual ~BluetoothLowEnergyDiscoverManagerMacDelegate() {} |
+ |
+ virtual void DiscoveredPeripheral(CBPeripheral *peripheral, |
armansito
2015/01/24 17:59:38
nit: This should read "CBPeripheral* peripheral" (
dvh
2015/01/27 00:14:56
Done.
|
+ NSDictionary *advertisementData, int rssi) { |
+ manager_->DiscoveredPeripheral(peripheral, advertisementData, rssi); |
+ } |
+ |
+ virtual void TryStartDiscovery() { manager_->TryStartDiscovery(); } |
+ |
+ private: |
+ BluetoothLowEnergyDiscoverManagerMac *manager_; |
+}; |
+ |
+} // namespace device |
+ |
+// This class will serve as the Objective-C delegate of CBCentralManager. |
+@interface BluetoothLowEnergyDiscoverManagerMacBridge |
+ : NSObject<CBCentralManagerDelegate> |
+ |
+- (id)initWithManager:(BluetoothLowEnergyDiscoverManagerMac *)manager; |
+ |
+@end |
+ |
+@implementation BluetoothLowEnergyDiscoverManagerMacBridge { |
+ BluetoothLowEnergyDiscoverManagerMac *manager_; |
+ BluetoothLowEnergyDiscoverManagerMacDelegate *delegate_; |
+} |
+ |
+- (id)initWithManager:(BluetoothLowEnergyDiscoverManagerMac *)manager { |
+ self = [super init]; |
armansito
2015/01/24 17:59:38
nit: check if init worked here (i.e. set the membe
dvh
2015/01/27 00:14:56
Done.
|
+ manager_ = manager; |
+ delegate_ = new BluetoothLowEnergyDiscoverManagerMacDelegate(manager_); |
+ return self; |
+} |
+ |
+- (void)dealloc { |
+ delete delegate_; |
+ [super dealloc]; |
+} |
+ |
+- (void)centralManager:(CBCentralManager *)central |
+ didDiscoverPeripheral:(CBPeripheral *)peripheral |
+ advertisementData:(NSDictionary *)advertisementData |
+ RSSI:(NSNumber *)RSSI { |
+ // Notifies the discovery of a device. |
+ delegate_->DiscoveredPeripheral(peripheral, advertisementData, |
+ [RSSI intValue]); |
+} |
+ |
+- (void)centralManagerDidUpdateState:(CBCentralManager *)central { |
+ // Notifies when the powered state of the central manager changed. |
+ delegate_->TryStartDiscovery(); |
+} |
+ |
+@end |
+ |
+BluetoothLowEnergyDiscoverManagerMac::~BluetoothLowEnergyDiscoverManagerMac() { |
+ ClearDevices(); |
+} |
+ |
+bool BluetoothLowEnergyDiscoverManagerMac::IsDiscovering() const { |
+ return discovering_; |
+} |
+ |
+void BluetoothLowEnergyDiscoverManagerMac::StartDiscovery( |
+ BluetoothDevice::UUIDList services_uuids) { |
+ ClearDevices(); |
+ discovering_ = true; |
+ pending_ = true; |
+ services_uuids_ = services_uuids; |
+ TryStartDiscovery(); |
+} |
+ |
+void BluetoothLowEnergyDiscoverManagerMac::TryStartDiscovery() { |
+ if (!discovering_) { |
+ return; |
+ } |
+ if (!pending_) { |
+ return; |
+ } |
+ // Can only start if the bluetooth power is turned on. |
+ if ([manager_ state] != CBCentralManagerStatePoweredOn) { |
+ return; |
+ } |
armansito
2015/01/24 17:59:38
Please add new lines where you can to make the cod
dvh
2015/01/27 00:14:56
Done.
|
+ // Converts the services UUIDs to a CoreBluetooth data structure. |
+ NSMutableArray *services = nil; |
+ if (services_uuids_.size() > 0) { |
armansito
2015/01/24 17:59:38
nit: if (!services_uuids_.empty()) {
dvh
2015/01/27 00:14:55
Done.
|
+ services = [NSMutableArray array]; |
+ for (unsigned int i = 0; i < services_uuids_.size(); i++) { |
+ NSString *uuidString = [NSString |
+ stringWithUTF8String:services_uuids_[i].canonical_value().c_str()]; |
+ CBUUID *uuid = [CBUUID UUIDWithString:uuidString]; |
+ [services addObject:uuid]; |
+ } |
+ } |
+ [manager_ scanForPeripheralsWithServices:services options:nil]; |
+ pending_ = false; |
+} |
+ |
+void BluetoothLowEnergyDiscoverManagerMac::StopDiscovery() { |
+ if (!pending_) { |
+ [manager_ stopScan]; |
armansito
2015/01/24 17:59:38
Don't call this if |discovering_| is true?
dvh
2015/01/27 00:14:55
Done.
|
+ } |
+ discovering_ = false; |
+} |
+ |
+void BluetoothLowEnergyDiscoverManagerMac::DiscoveredPeripheral( |
+ CBPeripheral *peripheral, NSDictionary *advertisementData, int rssi) { |
+ BluetoothLowEnergyDeviceMac *device = |
armansito
2015/01/24 17:59:38
It seems like this is being unnecessarily created
dvh
2015/01/27 00:14:55
The main goal here is to be able to lookup any exi
armansito
2015/01/29 04:37:18
It seems strange to me to construct a whole object
|
+ new BluetoothLowEnergyDeviceMac(peripheral, advertisementData, rssi); |
+ // Look for existing device. |
+ std::map<const std::string, BluetoothLowEnergyDeviceMac *>::iterator iter = |
+ devices_.find(device->GetIdentifier()); |
+ if (iter != devices_.end()) { |
armansito
2015/01/24 17:59:38
Do an early return and get rid of the else. I'd ac
dvh
2015/01/27 00:14:55
Done.
|
+ // A device has an update. |
+ delete device; |
+ BluetoothLowEnergyDeviceMac *old_device = iter->second; |
+ old_device->Update(peripheral, advertisementData, rssi); |
+ observer_->DeviceUpdated(old_device); |
+ } else { |
+ // A device has been added. |
+ devices_.insert(devices_.begin(), |
+ std::pair<const std::string, BluetoothLowEnergyDeviceMac *>( |
+ device->GetIdentifier(), device)); |
+ observer_->DeviceFound(device); |
+ } |
+} |
+ |
+BluetoothLowEnergyDiscoverManagerMac * |
+BluetoothLowEnergyDiscoverManagerMac::Create(Observer *observer) { |
+ return new BluetoothLowEnergyDiscoverManagerMac(observer); |
+} |
+ |
+BluetoothLowEnergyDiscoverManagerMac::BluetoothLowEnergyDiscoverManagerMac( |
+ Observer *observer) |
+ : observer_(observer) { |
+ bridge_.reset([[BluetoothLowEnergyDiscoverManagerMacBridge alloc] |
+ initWithManager:this]); |
+ // Since CoreBluetooth is only available on OS X 10.7 or later, we |
+ // instantiate CBCentralManager only for OS X >= 10.7. |
+ if (base::mac::IsOSLionOrLater()) { |
+ manager_.reset( |
+ [[CBCentralManager alloc] initWithDelegate:bridge_ |
armansito
2015/01/24 17:59:38
Will this code compile at all in older versions? W
dvh
2015/01/27 00:14:56
The build system of Chromium will build using a re
armansito
2015/01/29 04:37:18
I don't directly work on Chrome for Mac, so as lon
groby-ooo-7-16
2015/01/30 15:10:32
Unless I'm completely misinformed, we're currently
|
+ queue:dispatch_get_main_queue()]); |
+ } |
+ discovering_ = false; |
+} |
+ |
+void BluetoothLowEnergyDiscoverManagerMac::ClearDevices() { |
+ for (std::map<const std::string, BluetoothLowEnergyDeviceMac *>::iterator |
+ iter = devices_.begin(); |
+ iter != devices_.end(); ++iter) { |
+ delete iter->second; |
+ } |
+ devices_.clear(); |
+} |