//
//  Copyright 2015 Google, Inc.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#include "service/adapter.h"

#include <atomic>
#include <mutex>
#include <string>
#include <unordered_set>

#include <base/logging.h>
#include <base/observer_list.h>

#include "abstract_observer_list.h"
#include "service/a2dp_sink.h"
#include "service/a2dp_source.h"
#include "service/avrcp_control.h"
#include "service/avrcp_target.h"
#include "service/common/bluetooth/util/atomic_string.h"
#include "service/gatt_client.h"
#include "service/gatt_server.h"
#include "service/hal/bluetooth_interface.h"
#include "service/logging_helpers.h"
#include "service/low_energy_advertiser.h"
#include "service/low_energy_client.h"
#include "service/low_energy_scanner.h"

using std::lock_guard;
using std::mutex;

namespace bluetooth {

namespace {

RemoteDeviceProps ParseRemoteDeviceProps(int num_properties,
                                         bt_property_t* properties) {
  std::string name;
  std::string address;
  std::vector<Uuid> service_uuids;
  int32_t device_class = 0;
  int32_t device_type = 0;
  int32_t rssi = 0;

  for (int i = 0; i < num_properties; ++i) {
    bt_property_t* property = properties + i;
    switch (property->type) {
      case BT_PROPERTY_BDNAME: {
        if (property->len < 0) {
          NOTREACHED() << "Invalid length for BT_PROPERTY_BDNAME";
          break;
        }
        bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
        name = reinterpret_cast<char*>(hal_name->name);
        break;
      }
      case BT_PROPERTY_BDADDR: {
        if (property->len != sizeof(RawAddress)) {
          NOTREACHED() << "Invalid length for BT_PROPERTY_BDADDR";
          break;
        }
        address = BtAddrString(reinterpret_cast<RawAddress*>(property->val));
        break;
      }
      case BT_PROPERTY_UUIDS: {
        if (property->len < 0) {
          NOTREACHED() << "Negative length on BT_PROPERTY_UUIDS:";
          break;
        }
        if (property->len % sizeof(Uuid) != 0) {
          NOTREACHED() << "Trailing bytes on BT_PROPERTY_UUIDS:";
        }
        auto uuids = static_cast<const Uuid*>(property->val);

        for (size_t i = 0; i < property->len / sizeof(Uuid); ++i) {
          service_uuids.push_back(uuids[i]);
        }
        break;
      }
      case BT_PROPERTY_CLASS_OF_DEVICE: {
        if (property->len != sizeof(int32_t)) {
          NOTREACHED() << "Invalid length for BT_PROPERTY_CLASS_OF_DEVICE";
          break;
        }
        device_class = *reinterpret_cast<const int32_t*>(property->val);
        break;
      }
      case BT_PROPERTY_TYPE_OF_DEVICE: {
        if (property->len != sizeof(int32_t)) {
          NOTREACHED() << "Invalid length for BT_PROPERTY_TYPE_OF_DEVICE";
          break;
        }
        device_type = *reinterpret_cast<const int32_t*>(property->val);
        break;
      }
      case BT_PROPERTY_REMOTE_RSSI: {
        if (property->len != sizeof(int8_t)) {
          NOTREACHED() << "Invalid length for BT_PROPERTY_REMOTE_RSSI";
          break;
        }
        rssi = *reinterpret_cast<const int8_t*>(property->val);
        break;
      }
      default:
        VLOG(1) << "Unhandled adapter property: "
                << BtPropertyText(property->type);
        break;
    }
  }

  return RemoteDeviceProps(name, address, service_uuids, device_class,
                           device_type, rssi);
}

}  // namespace

// static
const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
// static
const char Adapter::kDefaultName[] = "not-initialized";

// TODO(armansito): The following constants come straight from
// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
// nice to know if there were a way to obtain these values from the stack
// instead of hardcoding them here.

// The minimum number of advertising instances required for multi-advertisement
// support.
const int kMinAdvInstancesForMultiAdv = 5;

// Used when determining if offloaded scan filtering is supported.
const int kMinOffloadedFilters = 10;

// Used when determining if offloaded scan batching is supported.
const int kMinOffloadedScanStorageBytes = 1024;

void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
                                              AdapterState prev_state,
                                              AdapterState new_state) {
  // Default implementation does nothing
}

void Adapter::Observer::OnDeviceConnectionStateChanged(
    Adapter* adapter, const std::string& device_address, bool connected) {
  // Default implementation does nothing
}

void Adapter::Observer::OnScanEnableChanged(Adapter* adapter,
                                            bool scan_enabled) {
  // Default implementation does nothing
}

void Adapter::Observer::OnSspRequest(Adapter* adapter,
                                     const std::string& device_address,
                                     const std::string& device_name, int cod,
                                     int pairing_variant, int pass_key) {
  // Default implementation does nothing
}

void Adapter::Observer::OnBondStateChanged(Adapter* adapter, int status,
                                           const std::string& device_address,
                                           int state) {
  // Default implementation does nothing
}

void Adapter::Observer::OnGetBondedDevices(
    Adapter* adapter, int status,
    const std::vector<std::string>& bonded_devices) {
  // Default implementation does nothing
}

void Adapter::Observer::OnGetRemoteDeviceProperties(
    Adapter* adapter, int status, const std::string& device_address,
    const RemoteDeviceProps& properties) {
  // Default implementation does nothing
}

void Adapter::Observer::OnDeviceFound(Adapter* adapter,
                                      const RemoteDeviceProps& properties) {
  // Default implementation does nothing
}

// The real Adapter implementation used in production.
class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
 public:
  AdapterImpl()
      : state_(ADAPTER_STATE_OFF),
        address_(kDefaultAddress),
        name_(kDefaultName) {
    memset(&local_le_features_, 0, sizeof(local_le_features_));
    hal::BluetoothInterface::Get()->AddObserver(this);
    a2dp_sink_factory_.reset(new A2dpSinkFactory);
    a2dp_source_factory_.reset(new A2dpSourceFactory);
    avrcp_control_factory_.reset(new AvrcpControlFactory);
    avrcp_target_factory_.reset(new AvrcpTargetFactory);
    ble_client_factory_.reset(new LowEnergyClientFactory(*this));
    ble_advertiser_factory_.reset(new LowEnergyAdvertiserFactory());
    ble_scanner_factory_.reset(new LowEnergyScannerFactory(*this));
    gatt_client_factory_.reset(new GattClientFactory());
    gatt_server_factory_.reset(new GattServerFactory());
    hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
  }

  ~AdapterImpl() override {
    hal::BluetoothInterface::Get()->RemoveObserver(this);
  }

  void AddObserver(Adapter::Observer* observer) override {
    lock_guard<mutex> lock(observers_lock_);
    observers_.AddObserver(observer);
  }

  void RemoveObserver(Adapter::Observer* observer) override {
    lock_guard<mutex> lock(observers_lock_);
    observers_.RemoveObserver(observer);
  }

  AdapterState GetState() const override { return state_.load(); }

  bool IsEnabled() const override { return state_.load() == ADAPTER_STATE_ON; }

  bool Enable() override {
    AdapterState current_state = GetState();
    if (current_state != ADAPTER_STATE_OFF) {
      LOG(INFO) << "Adapter not disabled - state: "
                << AdapterStateToString(current_state);
      return false;
    }

    // Set the state before calling enable() as there might be a race between
    // here and the AdapterStateChangedCallback.
    state_ = ADAPTER_STATE_TURNING_ON;
    NotifyAdapterStateChanged(current_state, state_);

    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to enable Bluetooth - status: "
                 << BtStatusText((const bt_status_t)status);
      state_ = ADAPTER_STATE_OFF;
      NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
      return false;
    }

    return true;
  }

  bool Disable() override {
    if (!IsEnabled()) {
      LOG(INFO) << "Adapter is not enabled";
      return false;
    }

    AdapterState current_state = GetState();

    // Set the state before calling enable() as there might be a race between
    // here and the AdapterStateChangedCallback.
    state_ = ADAPTER_STATE_TURNING_OFF;
    NotifyAdapterStateChanged(current_state, state_);

    int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to disable Bluetooth - status: "
                 << BtStatusText((const bt_status_t)status);
      state_ = current_state;
      NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
      return false;
    }

    return true;
  }

  std::string GetName() const override { return name_.Get(); }

  bool SetName(const std::string& name) override {
    bt_bdname_t hal_name;
    size_t max_name_len = sizeof(hal_name.name);

    // Include the \0 byte in size measurement.
    if (name.length() >= max_name_len) {
      LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum"
                 << " allowed size: " << max_name_len;
      return false;
    }

    strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
            name.length() + 1);

    VLOG(1) << "Setting adapter name: " << name;

    if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
      LOG(ERROR) << "Failed to set adapter name: " << name;
      return false;
    }

    return true;
  }

  std::string GetAddress() const override { return address_.Get(); }

  bool SetScanMode(int scan_mode) override {
    switch (scan_mode) {
      case BT_SCAN_MODE_NONE:
      case BT_SCAN_MODE_CONNECTABLE:
      case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
        break;
      default:
        LOG(ERROR) << "Unknown scan mode: " << scan_mode;
        return false;
    }

    auto bd_scanmode = static_cast<bt_scan_mode_t>(scan_mode);

    if (!SetAdapterProperty(BT_PROPERTY_ADAPTER_SCAN_MODE, &bd_scanmode,
                            sizeof(bd_scanmode))) {
      LOG(ERROR) << "Failed to set scan mode to : " << scan_mode;
      return false;
    }

    return true;
  }

  bool SetScanEnable(bool scan_enable) override {
    if (scan_enable) {
      int status =
          hal::BluetoothInterface::Get()->GetHALInterface()->start_discovery();
      if (status != BT_STATUS_SUCCESS) {
        LOG(ERROR) << "Failed to enable scanning";
        return false;
      }
    } else {
      int status =
          hal::BluetoothInterface::Get()->GetHALInterface()->cancel_discovery();
      if (status != BT_STATUS_SUCCESS) {
        LOG(ERROR) << "Failed to disable scanning";
        return false;
      }
    }
    return true;
  }

  bool SspReply(const std::string& device_address, int variant, bool accept,
                int32_t pass_key) override {
    RawAddress addr;
    if (!RawAddress::FromString(device_address, addr)) {
      LOG(ERROR) << "Invalid device address given: " << device_address;
      return false;
    }

    int status = hal::BluetoothInterface::Get()->GetHALInterface()->ssp_reply(
        &addr, static_cast<bt_ssp_variant_t>(variant), accept, pass_key);
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to send SSP response - status: "
                 << BtStatusText((const bt_status_t)status);
      return false;
    }

    return true;
  }

  bool CreateBond(const std::string& device_address, int transport) override {
    RawAddress addr;
    if (!RawAddress::FromString(device_address, addr)) {
      LOG(ERROR) << "Invalid device address given: " << device_address;
      return false;
    }

    int status = hal::BluetoothInterface::Get()->GetHALInterface()->create_bond(
        &addr, transport);
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to create bond - status: "
                 << BtStatusText((const bt_status_t)status);
      return false;
    }

    return true;
  }

  bool IsMultiAdvertisementSupported() override {
    lock_guard<mutex> lock(local_le_features_lock_);
    return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
  }

  bool IsDeviceConnected(const std::string& device_address) override {
    lock_guard<mutex> lock(connected_devices_lock_);
    return connected_devices_.find(device_address) != connected_devices_.end();
  }

  int GetTotalNumberOfTrackableAdvertisements() override {
    lock_guard<mutex> lock(local_le_features_lock_);
    return local_le_features_.total_trackable_advertisers;
  }

  bool IsOffloadedFilteringSupported() override {
    lock_guard<mutex> lock(local_le_features_lock_);
    return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters;
  }

  bool IsOffloadedScanBatchingSupported() override {
    lock_guard<mutex> lock(local_le_features_lock_);
    return local_le_features_.scan_result_storage_size >=
           kMinOffloadedScanStorageBytes;
  }

  bool GetBondedDevices() override {
    int status =
        hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_property(
            BT_PROPERTY_ADAPTER_BONDED_DEVICES);
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to get bonded devices. Status: "
                 << BtStatusText(static_cast<bt_status_t>(status));
      return false;
    }

    return true;
  }

  bool RemoveBond(const std::string& device_address) override {
    RawAddress addr;
    if (!RawAddress::FromString(device_address, addr)) {
      LOG(ERROR) << "Invalid device address given: " << device_address;
      return false;
    }

    int status =
        hal::BluetoothInterface::Get()->GetHALInterface()->remove_bond(&addr);
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to send remove bond - status: "
                 << BtStatusText(static_cast<bt_status_t>(status));
      return false;
    }

    return true;
  }

  bool GetRemoteDeviceProperties(const std::string& device_address) override {
    RawAddress addr;
    if (!RawAddress::FromString(device_address, addr)) {
      LOG(ERROR) << "Invalid device address given: " << device_address;
      return false;
    }

    int status = hal::BluetoothInterface::Get()
                     ->GetHALInterface()
                     ->get_remote_device_properties(&addr);
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to send GetRemoteDeviceProperties - status: "
                 << BtStatusText((const bt_status_t)status);
      return false;
    }

    return true;
  }

  A2dpSinkFactory* GetA2dpSinkFactory() const override {
    return a2dp_sink_factory_.get();
  }

  A2dpSourceFactory* GetA2dpSourceFactory() const override {
    return a2dp_source_factory_.get();
  }

  AvrcpControlFactory* GetAvrcpControlFactory() const override {
    return avrcp_control_factory_.get();
  }

  AvrcpTargetFactory* GetAvrcpTargetFactory() const override {
    return avrcp_target_factory_.get();
  }

  LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
    return ble_client_factory_.get();
  }

  LowEnergyAdvertiserFactory* GetLeAdvertiserFactory() const override {
    return ble_advertiser_factory_.get();
  }

  LowEnergyScannerFactory* GetLeScannerFactory() const override {
    return ble_scanner_factory_.get();
  }

  GattClientFactory* GetGattClientFactory() const override {
    return gatt_client_factory_.get();
  }

  GattServerFactory* GetGattServerFactory() const override {
    return gatt_server_factory_.get();
  }

  // hal::BluetoothInterface::Observer overrides.
  void AdapterStateChangedCallback(bt_state_t state) override {
    LOG(INFO) << "Adapter state changed: " << BtStateText(state);

    AdapterState prev_state = GetState();

    switch (state) {
      case BT_STATE_OFF:
        state_ = ADAPTER_STATE_OFF;
        break;

      case BT_STATE_ON:
        state_ = ADAPTER_STATE_ON;
        break;

      default:
        NOTREACHED();
    }

    NotifyAdapterStateChanged(prev_state, GetState());
  }

  void AdapterPropertiesCallback(bt_status_t status, int num_properties,
                                 bt_property_t* properties) override {
    LOG(INFO) << "Adapter properties changed";

    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "status: " << BtStatusText(status);

      for (int i = 0; i < num_properties; ++i) {
        bt_property_t* property = properties + i;
        if (property->type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
          lock_guard<mutex> lock(observers_lock_);
          for (auto& observer : observers_) {
            observer.OnGetBondedDevices(this, status, {});
          }
        }
      }
      return;
    }

    for (int i = 0; i < num_properties; i++) {
      bt_property_t* property = properties + i;
      switch (property->type) {
        case BT_PROPERTY_BDADDR: {
          std::string address =
              BtAddrString(reinterpret_cast<RawAddress*>(property->val));
          LOG(INFO) << "Adapter address changed: " << address;
          address_.Set(address);
          break;
        }
        case BT_PROPERTY_BDNAME: {
          bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
          if (hal_name) {
            std::string name = reinterpret_cast<char*>(hal_name->name);
            LOG(INFO) << "Adapter name changed: " << name;
            name_.Set(name);
          }
          break;
        }
        case BT_PROPERTY_LOCAL_LE_FEATURES: {
          lock_guard<mutex> lock(local_le_features_lock_);
          if (property->len != sizeof(bt_local_le_features_t)) {
            LOG(WARNING) << "Malformed value received for property: "
                         << "BT_PROPERTY_LOCAL_LE_FEATURES";
            break;
          }
          bt_local_le_features_t* features =
              reinterpret_cast<bt_local_le_features_t*>(property->val);
          memcpy(&local_le_features_, features, sizeof(*features));
          LOG(INFO) << "Supported LE features updated";
          break;
        }
        case BT_PROPERTY_ADAPTER_BONDED_DEVICES: {
          if (property->len < 0) {
            NOTREACHED() << "Negative property length";
            break;
          }
          auto addrs = reinterpret_cast<const RawAddress*>(property->val);
          if (property->len % sizeof(addrs[0]) != 0) {
            LOG(ERROR) << "Invalid property length: " << property->len;
            // TODO(bcf): Seems to be a bug where we hit this somewhat
            // frequently.
            break;
          }
          std::vector<std::string> str_addrs;

          for (size_t i = 0; i < property->len / sizeof(addrs[0]); ++i)
            str_addrs.push_back(BtAddrString(addrs + i));

          lock_guard<mutex> lock(observers_lock_);
          for (auto& observer : observers_) {
            observer.OnGetBondedDevices(this, status, str_addrs);
          }
          break;
        }
        default:
          VLOG(1) << "Unhandled adapter property: "
                  << BtPropertyText(property->type);
          break;
      }

      // TODO(armansito): notify others of the updated properties
    }
  }

  void RemoteDevicePropertiesCallback(bt_status_t status,
                                      RawAddress* remote_bdaddr,
                                      int num_properties,
                                      bt_property_t* properties) override {
    std::string device_address = BtAddrString(remote_bdaddr);
    if (status != BT_STATUS_SUCCESS) {
      lock_guard<mutex> lock(observers_lock_);
      for (auto& observer : observers_) {
        observer.OnGetRemoteDeviceProperties(this, status, device_address,
                                             RemoteDeviceProps());
      }
      return;
    }

    RemoteDeviceProps props =
        ParseRemoteDeviceProps(num_properties, properties);

    std::string address = BtAddrString(remote_bdaddr);
    props.set_address(address);

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnGetRemoteDeviceProperties(this, status, device_address, props);
    }
  }

  void DeviceFoundCallback(int num_properties,
                           bt_property_t* properties) override {
    RemoteDeviceProps props =
        ParseRemoteDeviceProps(num_properties, properties);

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnDeviceFound(this, props);
    }
  }

  void DiscoveryStateChangedCallback(bt_discovery_state_t state) override {
    bool enabled = false;
    switch (state) {
      case BT_DISCOVERY_STOPPED:
        enabled = false;
        break;
      case BT_DISCOVERY_STARTED:
        enabled = true;
        break;
      default:
        NOTREACHED();
    }

    for (auto& observer : observers_) {
      observer.OnScanEnableChanged(this, enabled);
    }
  }

  void SSPRequestCallback(RawAddress* remote_bdaddr, bt_bdname_t* bd_name,
                          uint32_t cod, bt_ssp_variant_t pairing_variant,
                          uint32_t pass_key) override {
    std::string device_address = BtAddrString(remote_bdaddr);
    std::string name = reinterpret_cast<char*>(bd_name->name);

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnSspRequest(this, device_address, name, cod, pairing_variant,
                            pass_key);
    }
  }

  void BondStateChangedCallback(bt_status_t status, RawAddress* remote_bdaddr,
                                bt_bond_state_t state) override {
    std::string device_address = BtAddrString(remote_bdaddr);

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnBondStateChanged(this, status, device_address, state);
    }
  }

  void AclStateChangedCallback(bt_status_t status,
                               const RawAddress& remote_bdaddr,
                               bt_acl_state_t state,
                               bt_hci_error_code_t hci_reason) override {
    std::string device_address = BtAddrString(&remote_bdaddr);
    bool connected = (state == BT_ACL_STATE_CONNECTED);
    LOG(INFO) << "ACL state changed: " << device_address
              << " - connected: " << (connected ? "true" : "false");

    // If this is reported with an error status, I suppose the best thing we can
    // do is to log it and ignore the event.
    if (status != BT_STATUS_SUCCESS) {
      LOG(ERROR) << "status: " << BtStatusText(status);
      return;
    }

    // Introduce a scope to manage |connected_devices_lock_| with RAII.
    {
      lock_guard<mutex> lock(connected_devices_lock_);
      if (connected)
        connected_devices_.insert(device_address);
      else
        connected_devices_.erase(device_address);
    }

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnDeviceConnectionStateChanged(this, device_address, connected);
    }
  }

  // Sends a request to set the given HAL adapter property type and value.
  bool SetAdapterProperty(bt_property_type_t type, void* value, int length) {
    CHECK(length > 0);
    CHECK(value);

    bt_property_t property;
    property.len = length;
    property.val = value;
    property.type = type;

    int status =
        hal::BluetoothInterface::Get()->GetHALInterface()->set_adapter_property(
            &property);
    if (status != BT_STATUS_SUCCESS) {
      VLOG(1) << "Failed to set property";
      return false;
    }

    return true;
  }

  // Helper for invoking the AdapterStateChanged observer method.
  void NotifyAdapterStateChanged(AdapterState prev_state,
                                 AdapterState new_state) {
    if (prev_state == new_state) return;

    lock_guard<mutex> lock(observers_lock_);
    for (auto& observer : observers_) {
      observer.OnAdapterStateChanged(this, prev_state, new_state);
    }
  }

 private:
  // The current adapter state.
  std::atomic<AdapterState> state_;

  // The Bluetooth device address of the local adapter in string from
  // (i.e.. XX:XX:XX:XX:XX:XX)
  util::AtomicString address_;

  // The current local adapter name.
  util::AtomicString name_;

  // The current set of supported LE features as obtained from the stack. The
  // values here are all initially set to 0 and updated when the corresponding
  // adapter property has been received from the stack.
  std::mutex local_le_features_lock_;
  bt_local_le_features_t local_le_features_;

  // List of observers that are interested in notifications from us.
  std::mutex observers_lock_;
  btbase::AbstractObserverList<Adapter::Observer> observers_;

  // List of devices addresses that are currently connected.
  std::mutex connected_devices_lock_;
  std::unordered_set<std::string> connected_devices_;

  // Factory used to create per-app A2dpSink instances.
  std::unique_ptr<A2dpSinkFactory> a2dp_sink_factory_;

  // Factory used to create per-app A2dpSource instances.
  std::unique_ptr<A2dpSourceFactory> a2dp_source_factory_;

  // Factory used to create per-app AvrcpControl instances.
  std::unique_ptr<AvrcpControlFactory> avrcp_control_factory_;

  // Factory used to create per-app AvrcpTarget instances.
  std::unique_ptr<AvrcpTargetFactory> avrcp_target_factory_;

  // Factory used to create per-app LowEnergyClient instances.
  std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;

  // Factory used to create per-app LeAdvertiser instances.
  std::unique_ptr<LowEnergyAdvertiserFactory> ble_advertiser_factory_;

  // Factory used to create per-app LeScanner instances.
  std::unique_ptr<LowEnergyScannerFactory> ble_scanner_factory_;

  // Factory used to create per-app GattClient instances.
  std::unique_ptr<GattClientFactory> gatt_client_factory_;

  // Factory used to create per-app GattServer instances.
  std::unique_ptr<GattServerFactory> gatt_server_factory_;

  DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
};

// static
std::unique_ptr<Adapter> Adapter::Create() {
  return std::unique_ptr<Adapter>(new AdapterImpl());
}

}  // namespace bluetooth
