14fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//
24fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  Copyright (C) 2015 Google, Inc.
34fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//
44fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
54fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  you may not use this file except in compliance with the License.
64fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  You may obtain a copy of the License at:
74fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//
84fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
94fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//
104fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  Unless required by applicable law or agreed to in writing, software
114fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
124fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  See the License for the specific language governing permissions and
144fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//  limitations under the License.
154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray//
164fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
174fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include "service/adapter.h"
184fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <atomic>
200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <mutex>
210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <string>
220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <unordered_set>
230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
244fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include <base/logging.h>
250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include <base/observer_list.h>
264fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/common/bluetooth/util/atomic_string.h"
280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/gatt_client.h"
290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/gatt_server.h"
300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/hal/bluetooth_interface.h"
314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray#include "service/logging_helpers.h"
320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray#include "service/low_energy_client.h"
334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
346791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::lock_guard;
356791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayusing std::mutex;
366791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
374fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguraynamespace bluetooth {
384fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
3903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static
4003b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
4103b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray// static
4203b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Ugurayconst char Adapter::kDefaultName[] = "not-initialized";
4303b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
446791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// TODO(armansito): The following constants come straight from
456791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
466791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// nice to know if there were a way to obtain these values from the stack
476791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// instead of hardcoding them here.
486791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
4910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// The minimum number of advertising instances required for multi-advertisement
5010b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray// support.
516791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinAdvInstancesForMultiAdv = 5;
526791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
536791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan filtering is supported.
546791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedFilters = 10;
556791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
566791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray// Used when determining if offloaded scan batching is supported.
576791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Ugurayconst int kMinOffloadedScanStorageBytes = 1024;
5810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray
594cebc7e190f29acb56ef8658a9ad02137e82e967Arman Ugurayvoid Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
604cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                                              AdapterState prev_state,
614cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray                                              AdapterState new_state) {
624cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray  // Default implementation does nothing
634cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
644cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
650f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Ugurayvoid Adapter::Observer::OnDeviceConnectionStateChanged(
660f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray    Adapter* adapter, const std::string& device_address, bool connected) {
670f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  // Default implementation does nothing
680f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray}
690f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray// The real Adapter implementation used in production.
710a0d3932136995a722cc125ef920679113d8ce0fArman Ugurayclass AdapterImpl : public Adapter,
720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                    public hal::BluetoothInterface::Observer {
730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray public:
740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  AdapterImpl()
7503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray    : state_(ADAPTER_STATE_OFF),
7603b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      address_(kDefaultAddress),
7703b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray      name_(kDefaultName) {
780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    memset(&local_le_features_, 0, sizeof(local_le_features_));
790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    hal::BluetoothInterface::Get()->AddObserver(this);
8060b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski    ble_client_factory_.reset(new LowEnergyClientFactory(*this));
810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    gatt_client_factory_.reset(new GattClientFactory());
820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    gatt_server_factory_.reset(new GattServerFactory());
830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
854cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  ~AdapterImpl() override {
870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    hal::BluetoothInterface::Get()->RemoveObserver(this);
880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
894cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void AddObserver(Adapter::Observer* observer) override {
910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(observers_lock_);
920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    observers_.AddObserver(observer);
930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
942117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void RemoveObserver(Adapter::Observer* observer) override {
960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(observers_lock_);
970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    observers_.RemoveObserver(observer);
980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  AdapterState GetState() const override {
1010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return state_.load();
1024fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1034fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1040a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool IsEnabled() const override {
1050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return state_.load() == ADAPTER_STATE_ON;
1064fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1074fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
108c7087d2466a291185853a6b2a16f789233e3420fAjay Panicker  bool Enable(bool start_restricted) override {
1090a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    AdapterState current_state = GetState();
1100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (current_state != ADAPTER_STATE_OFF) {
1110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(INFO) << "Adapter not disabled - state: "
1120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                << AdapterStateToString(current_state);
1130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1154fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // Set the state before calling enable() as there might be a race between
1170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // here and the AdapterStateChangedCallback.
1180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    state_ = ADAPTER_STATE_TURNING_ON;
1190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    NotifyAdapterStateChanged(current_state, state_);
1200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
121c7087d2466a291185853a6b2a16f789233e3420fAjay Panicker    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(start_restricted);
1220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (status != BT_STATUS_SUCCESS) {
1230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "Failed to enable Bluetooth - status: "
1240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                 << BtStatusText((const bt_status_t)status);
1250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      state_ = ADAPTER_STATE_OFF;
1260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
1270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
1300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return true;
1314fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1324fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1330a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool Disable() override {
1340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (!IsEnabled()) {
1350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(INFO) << "Adapter is not enabled";
1360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1380a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
1390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    AdapterState current_state = GetState();
1400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
1410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // Set the state before calling enable() as there might be a race between
1420a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // here and the AdapterStateChangedCallback.
1430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    state_ = ADAPTER_STATE_TURNING_OFF;
1440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    NotifyAdapterStateChanged(current_state, state_);
1452117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1460a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
1470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (status != BT_STATUS_SUCCESS) {
1480a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "Failed to disable Bluetooth - status: "
1490a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                 << BtStatusText((const bt_status_t)status);
1500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      state_ = current_state;
1510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
1520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1542117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
1550a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return true;
1564fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1574fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::string GetName() const override {
1590a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return name_.Get();
1600a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
1614fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool SetName(const std::string& name) override {
1630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    bt_bdname_t hal_name;
1640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    size_t max_name_len = sizeof(hal_name.name);
16503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
1660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // Include the \0 byte in size measurement.
1670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (name.length() >= max_name_len) {
1680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum"
1690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                 << " allowed size: " << max_name_len;
1700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1724fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
1740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray            name.length() + 1);
1754fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    VLOG(1) << "Setting adapter name: " << name;
1774fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
1790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "Failed to set adapter name: " << name;
1800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
1810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
1824fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return true;
1844fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
1854fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::string GetAddress() const override {
1870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return address_.Get();
1880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
1894fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
1900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool IsMultiAdvertisementSupported() override {
1910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(local_le_features_lock_);
1920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
1930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
19403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
1950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool IsDeviceConnected(const std::string& device_address) override {
1960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(connected_devices_lock_);
1970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return connected_devices_.find(device_address) != connected_devices_.end();
1980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
19910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray
2000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  int GetTotalNumberOfTrackableAdvertisements() override {
2010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(local_le_features_lock_);
2020a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return local_le_features_.total_trackable_advertisers;
2030a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
2040f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
2050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool IsOffloadedFilteringSupported() override {
2060a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(local_le_features_lock_);
2070a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters;
2080a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
2096791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
2100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool IsOffloadedScanBatchingSupported() override {
2110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(local_le_features_lock_);
2120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return local_le_features_.scan_result_storage_size >=
2130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        kMinOffloadedScanStorageBytes;
2140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
2156791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
2160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
2170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return ble_client_factory_.get();
2180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
2196791e9ab3892cbe61cf088eb1ebd7c4bfb2e603eArman Uguray
2200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  GattClientFactory* GetGattClientFactory() const override {
2210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return gatt_client_factory_.get();
2220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
223c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray
2240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  GattServerFactory* GetGattServerFactory() const override {
2250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return gatt_server_factory_.get();
2260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  }
22750a31545d2d20d92d161c51195b653eafd164025Arman Uguray
2280a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // hal::BluetoothInterface::Observer overrides.
2290a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void AdapterStateChangedCallback(bt_state_t state) override {
2300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    LOG(INFO) << "Adapter state changed: " << BtStateText(state);
2310f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray
2320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    AdapterState prev_state = GetState();
2334fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    switch (state) {
2350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    case BT_STATE_OFF:
2360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      state_ = ADAPTER_STATE_OFF;
2370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      break;
2384cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
2390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    case BT_STATE_ON:
2400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      state_ = ADAPTER_STATE_ON;
2410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      break;
2424fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    default:
2440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      NOTREACHED();
2450a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
2464fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
2470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    NotifyAdapterStateChanged(prev_state, GetState());
2484fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
2492117e520c9f5b105ade7e92c4ab4928ea905f176Arman Uguray
2500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void AdapterPropertiesCallback(bt_status_t status,
2510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                                 int num_properties,
2520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                                 bt_property_t* properties) override {
2530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    LOG(INFO) << "Adapter properties changed";
25403b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
2550a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (status != BT_STATUS_SUCCESS) {
2560a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "status: " << BtStatusText(status);
2570a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return;
2580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
25903b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
2600a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    for (int i = 0; i < num_properties; i++) {
2610a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      bt_property_t* property = properties + i;
2620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      switch (property->type) {
2630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        case BT_PROPERTY_BDADDR: {
2640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>(
2650a0d3932136995a722cc125ef920679113d8ce0fArman Uguray              property->val));
2660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          LOG(INFO) << "Adapter address changed: " << address;
2670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          address_.Set(address);
2680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          break;
2690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        }
2700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        case BT_PROPERTY_BDNAME: {
2710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
2720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          std::string name = reinterpret_cast<char*>(hal_name->name);
2730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          LOG(INFO) << "Adapter name changed: " << name;
2740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          name_.Set(name);
2750a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          break;
2760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        }
2770a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        case BT_PROPERTY_LOCAL_LE_FEATURES: {
2780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          lock_guard<mutex> lock(local_le_features_lock_);
2790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          if (property->len != sizeof(bt_local_le_features_t)) {
2800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray            LOG(WARNING) << "Malformed value received for property: "
2810a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                         << "BT_PROPERTY_LOCAL_LE_FEATURES";
2820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray            break;
2830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          }
2840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          bt_local_le_features_t* features =
2850a0d3932136995a722cc125ef920679113d8ce0fArman Uguray              reinterpret_cast<bt_local_le_features_t*>(property->val);
2860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          memcpy(&local_le_features_, features, sizeof(*features));
2870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          LOG(INFO) << "Supported LE features updated";
28810b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray          break;
28910b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray        }
2900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        default:
2910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          VLOG(1) << "Unhandled adapter property: "
2920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                  << BtPropertyText(property->type);
2930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray          break;
29410b54c4b7f1a863a27eca4158f256062ec9c3770Arman Uguray      }
29503b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray
2960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      // TODO(armansito): notify others of the updated properties
2970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
29803b1f0fb7247ddc1c8496bf3b1bdc056110d12faArman Uguray  }
2994fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
3000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void AclStateChangedCallback(bt_status_t status,
3010a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                               const bt_bdaddr_t& remote_bdaddr,
3020a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                               bt_acl_state_t state) override {
3030a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    std::string device_address = BtAddrString(&remote_bdaddr);
3040a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    bool connected = (state == BT_ACL_STATE_CONNECTED);
3050a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    LOG(INFO) << "ACL state changed: " << device_address << " - connected: "
3060a0d3932136995a722cc125ef920679113d8ce0fArman Uguray              << (connected ? "true" : "false");
3070a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3080a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // If this is reported with an error status, I suppose the best thing we can
3090a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // do is to log it and ignore the event.
3100a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (status != BT_STATUS_SUCCESS) {
3110a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      LOG(ERROR) << "status: " << BtStatusText(status);
3120a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return;
3130a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
3140a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3150a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    // Introduce a scope to manage |connected_devices_lock_| with RAII.
3160a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    {
3170a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      lock_guard<mutex> lock(connected_devices_lock_);
3180a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      if (connected)
3190a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        connected_devices_.insert(device_address);
3200a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      else
3210a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        connected_devices_.erase(device_address);
3220a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
3230a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3240a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(observers_lock_);
3250a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    FOR_EACH_OBSERVER(
3260a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        Adapter::Observer, observers_,
3270a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        OnDeviceConnectionStateChanged(this, device_address, connected));
3280f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  }
3290f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
3300a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // Sends a request to set the given HAL adapter property type and value.
3310a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bool SetAdapterProperty(bt_property_type_t type, void* value, int length) {
3320a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    CHECK(length > 0);
3330a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    CHECK(value);
3340a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3350a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    bt_property_t property;
3360a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    property.len = length;
3370a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    property.val = value;
3380a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    property.type = type;
3390a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3400a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    int status = hal::BluetoothInterface::Get()->GetHALInterface()->
3410a0d3932136995a722cc125ef920679113d8ce0fArman Uguray        set_adapter_property(&property);
3420a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (status != BT_STATUS_SUCCESS) {
3430a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      VLOG(1) << "Failed to set property";
3440a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return false;
3450a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    }
3460a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3470a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    return true;
3480f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray  }
3490f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
3500a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // Helper for invoking the AdapterStateChanged observer method.
3510a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  void NotifyAdapterStateChanged(AdapterState prev_state,
3520a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                                 AdapterState new_state) {
3530a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    if (prev_state == new_state)
3540a0d3932136995a722cc125ef920679113d8ce0fArman Uguray      return;
3550f29c005ee0a1a5c68c9b8e33f099fffefb5bab8Arman Uguray
3560a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    lock_guard<mutex> lock(observers_lock_);
3570a0d3932136995a722cc125ef920679113d8ce0fArman Uguray    FOR_EACH_OBSERVER(Adapter::Observer, observers_,
3580a0d3932136995a722cc125ef920679113d8ce0fArman Uguray                      OnAdapterStateChanged(this, prev_state, new_state));
3594fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray  }
3604fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
3610a0d3932136995a722cc125ef920679113d8ce0fArman Uguray private:
3620a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // The current adapter state.
3630a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::atomic<AdapterState> state_;
3640a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3650a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // The Bluetooth device address of the local adapter in string from
3660a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // (i.e.. XX:XX:XX:XX:XX:XX)
3670a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  util::AtomicString address_;
3680a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3690a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // The current local adapter name.
3700a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  util::AtomicString name_;
3710a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3720a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // The current set of supported LE features as obtained from the stack. The
3730a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // values here are all initially set to 0 and updated when the corresponding
3740a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // adapter property has been received from the stack.
3750a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::mutex local_le_features_lock_;
3760a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  bt_local_le_features_t local_le_features_;
3770a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3780a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // List of observers that are interested in notifications from us.
3790a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::mutex observers_lock_;
3800a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  base::ObserverList<Adapter::Observer> observers_;
3814fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray
3820a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // List of devices addresses that are currently connected.
3830a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::mutex connected_devices_lock_;
3840a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::unordered_set<std::string> connected_devices_;
3854cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
3860a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // Factory used to create per-app LowEnergyClient instances.
3870a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;
3880a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3890a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // Factory used to create per-app GattClient instances.
3900a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::unique_ptr<GattClientFactory> gatt_client_factory_;
3910a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3920a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  // Factory used to create per-app GattServer instances.
3930a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  std::unique_ptr<GattServerFactory> gatt_server_factory_;
3940a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3950a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
3960a0d3932136995a722cc125ef920679113d8ce0fArman Uguray};
3970a0d3932136995a722cc125ef920679113d8ce0fArman Uguray
3980a0d3932136995a722cc125ef920679113d8ce0fArman Uguray// static
3990a0d3932136995a722cc125ef920679113d8ce0fArman Uguraystd::unique_ptr<Adapter> Adapter::Create() {
4000a0d3932136995a722cc125ef920679113d8ce0fArman Uguray  return std::unique_ptr<Adapter>(new AdapterImpl());
4014cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray}
4024cebc7e190f29acb56ef8658a9ad02137e82e967Arman Uguray
4034fdadb6c834ec5299f47fc4e1c59c00410e07a45Arman Uguray}  // namespace bluetooth
404