| Index: device/bluetooth/bluetooth_adapter_mac.mm | 
| diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm | 
| index ae557d0314b3395ce6d8ff4790fa15a19be63056..bf6cf4bd40e8625b17a65775aa137f6fdfdccc3e 100644 | 
| --- a/device/bluetooth/bluetooth_adapter_mac.mm | 
| +++ b/device/bluetooth/bluetooth_adapter_mac.mm | 
| @@ -22,6 +22,7 @@ | 
| #include "base/thread_task_runner_handle.h" | 
| #include "base/time/time.h" | 
| #include "device/bluetooth/bluetooth_device_mac.h" | 
| +#include "device/bluetooth/bluetooth_discovery_session.h" | 
| #include "device/bluetooth/bluetooth_socket_mac.h" | 
| #include "device/bluetooth/bluetooth_uuid.h" | 
|  | 
| @@ -57,6 +58,8 @@ BluetoothAdapterMac::BluetoothAdapterMac() | 
| num_discovery_sessions_(0), | 
| classic_discovery_manager_( | 
| BluetoothDiscoveryManagerMac::CreateClassic(this)), | 
| +      low_energy_discovery_manager_( | 
| +          BluetoothLowEnergyDiscoveryManagerMac::Create(this)), | 
| weak_ptr_factory_(this) { | 
| DCHECK(classic_discovery_manager_.get()); | 
| } | 
| @@ -109,7 +112,8 @@ void BluetoothAdapterMac::SetDiscoverable( | 
| } | 
|  | 
| bool BluetoothAdapterMac::IsDiscovering() const { | 
| -  return classic_discovery_manager_->IsDiscovering(); | 
| +  return (classic_discovery_manager_->IsDiscovering() || | 
| +          low_energy_discovery_manager_->IsDiscovering()); | 
| } | 
|  | 
| void BluetoothAdapterMac::CreateRfcommService( | 
| @@ -148,11 +152,11 @@ void BluetoothAdapterMac::RegisterAdvertisement( | 
| error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM); | 
| } | 
|  | 
| -void BluetoothAdapterMac::DeviceFound(IOBluetoothDevice* device) { | 
| -  DeviceAdded(device); | 
| +void BluetoothAdapterMac::ClassicDeviceFound(IOBluetoothDevice* device) { | 
| +  ClassicDeviceAdded(device); | 
| } | 
|  | 
| -void BluetoothAdapterMac::DiscoveryStopped(bool unexpected) { | 
| +void BluetoothAdapterMac::ClassicDiscoveryStopped(bool unexpected) { | 
| if (unexpected) { | 
| DVLOG(1) << "Discovery stopped unexpectedly"; | 
| num_discovery_sessions_ = 0; | 
| @@ -168,7 +172,11 @@ void BluetoothAdapterMac::DeviceConnected(IOBluetoothDevice* device) { | 
| // to +registerForConnectNotifications:selector:. | 
| DVLOG(1) << "Adapter registered a new connection from device with address: " | 
| << BluetoothDeviceMac::GetDeviceAddress(device); | 
| -  DeviceAdded(device); | 
| +  ClassicDeviceAdded(device); | 
| +} | 
| + | 
| +void BluetoothAdapterMac::RemovePairingDelegateInternal( | 
| +    BluetoothDevice::PairingDelegate* pairing_delegate) { | 
| } | 
|  | 
| void BluetoothAdapterMac::AddDiscoverySession( | 
| @@ -179,14 +187,19 @@ void BluetoothAdapterMac::AddDiscoverySession( | 
| if (num_discovery_sessions_ > 0) { | 
| DCHECK(IsDiscovering()); | 
| num_discovery_sessions_++; | 
| +    // We are already running a discovery session, notify the system if the | 
| +    // filter has changed. | 
| +    if (!StartDiscovery(discovery_filter)) { | 
| +      error_callback.Run(); | 
| +      return; | 
| +    } | 
| callback.Run(); | 
| return; | 
| } | 
|  | 
| DCHECK_EQ(0, num_discovery_sessions_); | 
|  | 
| -  if (!classic_discovery_manager_->StartDiscovery()) { | 
| -    DVLOG(1) << "Failed to add a discovery session"; | 
| +  if (!StartDiscovery(discovery_filter)) { | 
| error_callback.Run(); | 
| return; | 
| } | 
| @@ -219,10 +232,21 @@ void BluetoothAdapterMac::RemoveDiscoverySession( | 
| return; | 
| } | 
|  | 
| -  if (!classic_discovery_manager_->StopDiscovery()) { | 
| -    DVLOG(1) << "Failed to stop discovery"; | 
| -    error_callback.Run(); | 
| -    return; | 
| +  // Default to dual discovery if |discovery_filter| is NULL. | 
| +  BluetoothDiscoveryFilter::TransportMask transport = | 
| +      BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL; | 
| +  if (discovery_filter) | 
| +    transport = discovery_filter->GetTransport(); | 
| + | 
| +  if (transport & BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC) { | 
| +    if (!classic_discovery_manager_->StopDiscovery()) { | 
| +      DVLOG(1) << "Failed to stop classic discovery"; | 
| +      error_callback.Run(); | 
| +      return; | 
| +    } | 
| +  } | 
| +  if (transport & BluetoothDiscoveryFilter::Transport::TRANSPORT_LE) { | 
| +    low_energy_discovery_manager_->StopDiscovery(); | 
| } | 
|  | 
| DVLOG(1) << "Discovery stopped"; | 
| @@ -238,8 +262,30 @@ void BluetoothAdapterMac::SetDiscoveryFilter( | 
| error_callback.Run(); | 
| } | 
|  | 
| -void BluetoothAdapterMac::RemovePairingDelegateInternal( | 
| -    BluetoothDevice::PairingDelegate* pairing_delegate) { | 
| +bool BluetoothAdapterMac::StartDiscovery( | 
| +    BluetoothDiscoveryFilter* discovery_filter) { | 
| +  // Default to dual discovery if |discovery_filter| is NULL.  IOBluetooth seems | 
| +  // allow starting low energy and classic discovery at once. | 
| +  BluetoothDiscoveryFilter::TransportMask transport = | 
| +      BluetoothDiscoveryFilter::Transport::TRANSPORT_DUAL; | 
| +  if (discovery_filter) | 
| +    transport = discovery_filter->GetTransport(); | 
| + | 
| +  if ((transport & BluetoothDiscoveryFilter::Transport::TRANSPORT_CLASSIC) && | 
| +      !classic_discovery_manager_->IsDiscovering()) { | 
| +    // TODO(krstnmnlsn): If a classic discovery session is already running then | 
| +    // we should update its filter. crbug.com/498056 | 
| +    if (!classic_discovery_manager_->StartDiscovery()) { | 
| +      DVLOG(1) << "Failed to add a classic discovery session"; | 
| +      return false; | 
| +    } | 
| +  } | 
| +  if (transport & BluetoothDiscoveryFilter::Transport::TRANSPORT_LE) { | 
| +    // Begin a low energy discovery session or update it if one is already | 
| +    // running. | 
| +    low_energy_discovery_manager_->StartDiscovery(BluetoothDevice::UUIDList()); | 
| +  } | 
| +  return true; | 
| } | 
|  | 
| void BluetoothAdapterMac::Init() { | 
| @@ -323,7 +369,7 @@ void BluetoothAdapterMac::PollAdapter() { | 
| base::TimeDelta::FromMilliseconds(kPollIntervalMs)); | 
| } | 
|  | 
| -void BluetoothAdapterMac::DeviceAdded(IOBluetoothDevice* device) { | 
| +void BluetoothAdapterMac::ClassicDeviceAdded(IOBluetoothDevice* device) { | 
| std::string device_address = BluetoothDeviceMac::GetDeviceAddress(device); | 
|  | 
| // Only notify observers once per device. | 
| @@ -336,6 +382,17 @@ void BluetoothAdapterMac::DeviceAdded(IOBluetoothDevice* device) { | 
| DeviceAdded(this, devices_[device_address])); | 
| } | 
|  | 
| +// TODO(krstnmnlsn): This method to be implemented as soon as UpdateDevices can | 
| +// handle instances of LowEnergyBluetoothDevice in |devices_|. crbug.com/498009 | 
| +void BluetoothAdapterMac::LowEnergyDeviceUpdated( | 
| +    CBPeripheral* peripheral, | 
| +    NSDictionary* advertisementData, | 
| +    int rssi) { | 
| +} | 
| + | 
| +// TODO(krstnmnlsn): This method assumes all BluetoothDevices in devices_ are | 
| +// instances of BluetoothDeviceMac.  Add support for low energy devices. | 
| +// crbug.com/498009 | 
| void BluetoothAdapterMac::UpdateDevices() { | 
| // Notify observers if any previously seen devices are no longer available, | 
| // i.e. if they are no longer paired, connected, nor recently discovered via | 
| @@ -365,7 +422,7 @@ void BluetoothAdapterMac::UpdateDevices() { | 
|  | 
| // Add any new paired devices. | 
| for (IOBluetoothDevice* device in [IOBluetoothDevice pairedDevices]) { | 
| -    DeviceAdded(device); | 
| +    ClassicDeviceAdded(device); | 
| } | 
| } | 
|  | 
|  |