Index: device/bluetooth/bluetooth_adapter_mac.mm |
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm |
index c4f9e39ea2a4863ce82b37a0844ed3314d407cb5..19bd893319bd4bebffd77197c043f000a6f5b4dd 100644 |
--- a/device/bluetooth/bluetooth_adapter_mac.mm |
+++ b/device/bluetooth/bluetooth_adapter_mac.mm |
@@ -138,6 +138,10 @@ void BluetoothAdapterMac::CreateL2capService( |
void BluetoothAdapterMac::DeviceFound(BluetoothDiscoveryManagerMac* manager, |
IOBluetoothDevice* device) { |
+ // TODO(isherman): The list of discovered devices is never reset. This should |
+ // probably key off of |devices_| instead. Currently, if a device is paired, |
+ // then unpaired, then paired again, the app would never hear about the second |
+ // pairing. |
armansito
2014/06/17 14:56:43
I agree with this, since to be consistent with the
Ilya Sherman
2014/06/17 21:43:38
Yeah, all of this logic is kinda wrong. It's not
keybuk
2014/06/17 21:48:50
CrOS for a device that was found by discovery, and
armansito
2014/06/17 22:07:22
Yes, let's not include the DeviceRemoved notificat
Ilya Sherman
2014/06/17 22:15:55
Done.
|
std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); |
if (discovered_devices_.find(device_address) == discovered_devices_.end()) { |
BluetoothDeviceMac device_mac(device); |
@@ -161,6 +165,22 @@ void BluetoothAdapterMac::DiscoveryStopped( |
AdapterDiscoveringChanged(this, false)); |
} |
+void BluetoothAdapterMac::DeviceConnected(IOBluetoothDevice* device) { |
+ std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); |
+ DVLOG(1) << "Adapter registered a new connection from device with address: " |
+ << device_address; |
+ |
+ // Only notify once per device. |
+ if (devices_.count(device_address)) |
+ return; |
+ |
+ scoped_ptr<BluetoothDeviceMac> device_mac(new BluetoothDeviceMac(device)); |
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
+ observers_, |
+ DeviceAdded(this, device_mac.get())); |
+ devices_[device_address] = device_mac.release(); |
+} |
+ |
void BluetoothAdapterMac::AddDiscoverySession( |
const base::Closure& callback, |
const ErrorCallback& error_callback) { |
@@ -262,6 +282,7 @@ void BluetoothAdapterMac::PollAdapter() { |
AdapterPoweredChanged(this, powered_)); |
} |
+ // TODO(isherman): This doesn't detect when a device is unpaired. |
IOBluetoothDevice* recent_device = |
[[IOBluetoothDevice recentDevices:1] lastObject]; |
NSDate* access_timestamp = [recent_device recentAccessDate]; |
@@ -269,7 +290,7 @@ void BluetoothAdapterMac::PollAdapter() { |
access_timestamp == nil || |
[recently_accessed_device_timestamp_ compare:access_timestamp] == |
NSOrderedAscending) { |
- UpdateDevices([IOBluetoothDevice pairedDevices]); |
+ UpdateDevices(); |
recently_accessed_device_timestamp_.reset([access_timestamp copy]); |
} |
@@ -280,15 +301,42 @@ void BluetoothAdapterMac::PollAdapter() { |
base::TimeDelta::FromMilliseconds(kPollIntervalMs)); |
} |
-void BluetoothAdapterMac::UpdateDevices(NSArray* devices) { |
- // TODO(armansito): This code never calls |
- // BluetoothAdapter::Observer::DeviceRemoved. It should, if a device |
- // no longer exists. |
- STLDeleteValues(&devices_); |
- for (IOBluetoothDevice* device in devices) { |
+void BluetoothAdapterMac::UpdateDevices() { |
+ // Snapshot the devices observers were previously notified of. |
+ // Note that the code below is careful to take ownership of any values that |
+ // are erased from the map, since the map owns the memory for all its mapped |
+ // devices. |
+ DevicesMap old_devices = devices_; |
+ |
+ // Add all the paired devices. |
+ devices_.clear(); |
+ for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { |
std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); |
- devices_[device_address] = new BluetoothDeviceMac(device); |
+ scoped_ptr<BluetoothDevice> device_mac(old_devices[device_address]); |
+ if (!device_mac) |
+ device_mac.reset(new BluetoothDeviceMac(device)); |
+ devices_[device_address] = device_mac.release(); |
+ old_devices.erase(device_address); |
+ } |
+ |
+ // Add any unpaired connected devices. |
+ for (const auto& old_device : old_devices) { |
armansito
2014/06/17 14:56:43
C++11 is allowed now?
Ilya Sherman
2014/06/17 21:43:38
It is in Mac-only files :D
|
+ if (!old_device.second->IsConnected()) |
+ continue; |
+ |
+ const std::string& device_address = old_device.first; |
+ DCHECK(!devices_.count(device_address)); |
+ devices_[device_address] = old_device.second; |
+ old_devices.erase(device_address); |
+ } |
+ |
+ // Notify observers of any devices that are no longer paired nor connected. |
+ for (const auto& removed_device : old_devices) { |
+ FOR_EACH_OBSERVER(BluetoothAdapter::Observer, |
+ observers_, |
+ DeviceRemoved(this, removed_device.second)); |
armansito
2014/06/17 14:56:43
Good catch on realizing that this was never called
|
} |
+ STLDeleteValues(&old_devices); |
} |
} // namespace device |