Chromium Code Reviews| 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 |