123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "device/bluetooth/bluetooth_adapter_win.h"
- #include <memory>
- #include <string>
- #include <utility>
- #include "base/bind.h"
- #include "base/check.h"
- #include "base/feature_list.h"
- #include "base/location.h"
- #include "base/memory/ptr_util.h"
- #include "base/notreached.h"
- #include "base/stl_util.h"
- #include "base/task/sequenced_task_runner.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/win/windows_version.h"
- #include "device/base/features.h"
- #include "device/bluetooth/bluetooth_adapter_winrt.h"
- #include "device/bluetooth/bluetooth_classic_win.h"
- #include "device/bluetooth/bluetooth_device_win.h"
- #include "device/bluetooth/bluetooth_discovery_session_outcome.h"
- #include "device/bluetooth/bluetooth_socket_thread.h"
- #include "device/bluetooth/bluetooth_socket_win.h"
- #include "device/bluetooth/bluetooth_task_manager_win.h"
- #include "device/bluetooth/public/cpp/bluetooth_address.h"
- #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
- namespace device {
- // static
- scoped_refptr<BluetoothAdapter> BluetoothAdapter::CreateAdapter() {
- return BluetoothAdapterWin::CreateAdapter();
- }
- // static
- scoped_refptr<BluetoothAdapter> BluetoothAdapterWin::CreateAdapter() {
- if (UseNewBLEWinImplementation())
- return base::WrapRefCounted(new BluetoothAdapterWinrt());
- return BluetoothAdapterWin::CreateClassicAdapter();
- }
- // static
- scoped_refptr<BluetoothAdapter> BluetoothAdapterWin::CreateClassicAdapter() {
- return base::WrapRefCounted(new BluetoothAdapterWin());
- }
- // static
- bool BluetoothAdapterWin::UseNewBLEWinImplementation() {
- return base::FeatureList::IsEnabled(kNewBLEWinImplementation) &&
- base::win::GetVersion() >= base::win::Version::WIN10;
- }
- BluetoothAdapterWin::BluetoothAdapterWin()
- : BluetoothAdapter(),
- initialized_(false),
- powered_(false),
- discovery_status_(NOT_DISCOVERING),
- force_update_device_for_test_(false) {}
- BluetoothAdapterWin::~BluetoothAdapterWin() {
- if (task_manager_.get())
- task_manager_->RemoveObserver(this);
- }
- std::string BluetoothAdapterWin::GetAddress() const {
- return address_;
- }
- std::string BluetoothAdapterWin::GetName() const {
- return name_;
- }
- void BluetoothAdapterWin::SetName(const std::string& name,
- base::OnceClosure callback,
- ErrorCallback error_callback) {
- NOTIMPLEMENTED();
- }
- // TODO(youngki): Return true when |task_manager_| initializes the adapter
- // state.
- bool BluetoothAdapterWin::IsInitialized() const {
- return initialized_;
- }
- bool BluetoothAdapterWin::IsPresent() const {
- return !address_.empty();
- }
- bool BluetoothAdapterWin::IsPowered() const {
- return powered_;
- }
- void BluetoothAdapterWin::SetPowered(bool powered,
- base::OnceClosure callback,
- ErrorCallback error_callback) {
- task_manager_->PostSetPoweredBluetoothTask(powered, std::move(callback),
- std::move(error_callback));
- }
- bool BluetoothAdapterWin::IsDiscoverable() const {
- NOTIMPLEMENTED();
- return false;
- }
- void BluetoothAdapterWin::SetDiscoverable(bool discoverable,
- base::OnceClosure callback,
- ErrorCallback error_callback) {
- NOTIMPLEMENTED();
- }
- bool BluetoothAdapterWin::IsDiscovering() const {
- return discovery_status_ == DISCOVERING ||
- discovery_status_ == DISCOVERY_STOPPING;
- }
- void BluetoothAdapterWin::DiscoveryStarted(bool success) {
- discovery_status_ = success ? DISCOVERING : NOT_DISCOVERING;
- std::move(discovery_changed_callback_)
- .Run(/*is_error=*/!success, UMABluetoothDiscoverySessionOutcome::UNKNOWN);
- if (success) {
- for (auto& observer : observers_)
- observer.AdapterDiscoveringChanged(this, true);
- }
- }
- void BluetoothAdapterWin::DiscoveryStopped() {
- discovered_devices_.clear();
- bool was_discovering = IsDiscovering();
- discovery_status_ = NOT_DISCOVERING;
- std::move(discovery_changed_callback_)
- .Run(/*is_error=*/false, UMABluetoothDiscoverySessionOutcome::SUCCESS);
- if (was_discovering)
- for (auto& observer : observers_)
- observer.AdapterDiscoveringChanged(this, false);
- }
- BluetoothAdapter::UUIDList BluetoothAdapterWin::GetUUIDs() const {
- NOTIMPLEMENTED();
- return UUIDList();
- }
- void BluetoothAdapterWin::CreateRfcommService(
- const BluetoothUUID& uuid,
- const ServiceOptions& options,
- CreateServiceCallback callback,
- CreateServiceErrorCallback error_callback) {
- scoped_refptr<BluetoothSocketWin> socket =
- BluetoothSocketWin::CreateBluetoothSocket(
- ui_task_runner_, socket_thread_);
- socket->Listen(this, uuid, options,
- base::BindOnce(std::move(callback), socket),
- std::move(error_callback));
- }
- void BluetoothAdapterWin::CreateL2capService(
- const BluetoothUUID& uuid,
- const ServiceOptions& options,
- CreateServiceCallback callback,
- CreateServiceErrorCallback error_callback) {
- // TODO(keybuk): implement.
- NOTIMPLEMENTED();
- }
- void BluetoothAdapterWin::RegisterAdvertisement(
- std::unique_ptr<BluetoothAdvertisement::Data> advertisement_data,
- CreateAdvertisementCallback callback,
- AdvertisementErrorCallback error_callback) {
- NOTIMPLEMENTED();
- std::move(error_callback)
- .Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
- }
- BluetoothLocalGattService* BluetoothAdapterWin::GetGattService(
- const std::string& identifier) const {
- return nullptr;
- }
- void BluetoothAdapterWin::RemovePairingDelegateInternal(
- BluetoothDevice::PairingDelegate* pairing_delegate) {
- }
- void BluetoothAdapterWin::AdapterStateChanged(
- const BluetoothTaskManagerWin::AdapterState& state) {
- DCHECK(thread_checker_.CalledOnValidThread());
- name_ = state.name;
- bool was_present = IsPresent();
- bool is_present = !state.address.empty();
- address_ = CanonicalizeBluetoothAddress(state.address);
- if (was_present != is_present) {
- for (auto& observer : observers_)
- observer.AdapterPresentChanged(this, is_present);
- }
- if (powered_ != state.powered) {
- powered_ = state.powered;
- for (auto& observer : observers_)
- observer.AdapterPoweredChanged(this, powered_);
- }
- if (!initialized_) {
- initialized_ = true;
- std::move(init_callback_).Run();
- }
- }
- void BluetoothAdapterWin::DevicesPolled(
- const std::vector<std::unique_ptr<BluetoothTaskManagerWin::DeviceState>>&
- devices) {
- DCHECK(thread_checker_.CalledOnValidThread());
- // We are receiving a new list of all devices known to the system. Merge this
- // new list with the list we know of (|devices_|) and raise corresponding
- // DeviceAdded, DeviceRemoved and DeviceChanged events.
- using DeviceAddressSet = std::set<std::string>;
- DeviceAddressSet known_devices;
- for (const auto& device : devices_)
- known_devices.insert(device.first);
- DeviceAddressSet new_devices;
- for (const auto& device_state : devices)
- new_devices.insert(device_state->address);
- // Process device removal first.
- DeviceAddressSet removed_devices =
- base::STLSetDifference<DeviceAddressSet>(known_devices, new_devices);
- for (const auto& device : removed_devices) {
- auto it = devices_.find(device);
- std::unique_ptr<BluetoothDevice> device_win = std::move(it->second);
- devices_.erase(it);
- for (auto& observer : observers_)
- observer.DeviceRemoved(this, device_win.get());
- }
- // Process added and (maybe) changed devices in one pass.
- DeviceAddressSet added_devices =
- base::STLSetDifference<DeviceAddressSet>(new_devices, known_devices);
- DeviceAddressSet changed_devices =
- base::STLSetIntersection<DeviceAddressSet>(known_devices, new_devices);
- for (const auto& device_state : devices) {
- if (added_devices.find(device_state->address) != added_devices.end()) {
- auto device_win = std::make_unique<BluetoothDeviceWin>(
- this, *device_state, ui_task_runner_, socket_thread_);
- BluetoothDeviceWin* device_win_raw = device_win.get();
- devices_[device_state->address] = std::move(device_win);
- for (auto& observer : observers_)
- observer.DeviceAdded(this, device_win_raw);
- } else if (changed_devices.find(device_state->address) !=
- changed_devices.end()) {
- auto iter = devices_.find(device_state->address);
- DCHECK(iter != devices_.end());
- BluetoothDeviceWin* device_win =
- static_cast<BluetoothDeviceWin*>(iter->second.get());
- if (!device_win->IsEqual(*device_state)) {
- device_win->Update(*device_state);
- for (auto& observer : observers_)
- observer.DeviceChanged(this, device_win);
- }
- // Above IsEqual returns true if device name, address, status and services
- // (primary services of BLE device) are the same. However, in BLE tests,
- // we may simulate characteristic, descriptor and secondary GATT service
- // after device has been initialized.
- if (force_update_device_for_test_) {
- device_win->Update(*device_state);
- }
- }
- }
- }
- base::WeakPtr<BluetoothAdapter> BluetoothAdapterWin::GetWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
- }
- // BluetoothAdapterWin should override SetPowered() instead.
- bool BluetoothAdapterWin::SetPoweredImpl(bool powered) {
- NOTREACHED();
- return false;
- }
- void BluetoothAdapterWin::UpdateFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- DiscoverySessionResultCallback callback) {
- DCHECK(discovery_status_ == DISCOVERING ||
- discovery_status_ == DISCOVERY_STARTING);
- if (discovery_status_ == DISCOVERING) {
- std::move(callback).Run(false,
- UMABluetoothDiscoverySessionOutcome::SUCCESS);
- return;
- }
- }
- void BluetoothAdapterWin::StartScanWithFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- DiscoverySessionResultCallback callback) {
- discovery_changed_callback_ = std::move(callback);
- MaybePostStartDiscoveryTask();
- }
- void BluetoothAdapterWin::StopScan(DiscoverySessionResultCallback callback) {
- if (discovery_status_ == NOT_DISCOVERING) {
- std::move(callback).Run(/*is_error=*/true,
- UMABluetoothDiscoverySessionOutcome::NOT_ACTIVE);
- return;
- }
- discovery_changed_callback_ = std::move(callback);
- MaybePostStopDiscoveryTask();
- }
- void BluetoothAdapterWin::Initialize(base::OnceClosure init_callback) {
- init_callback_ = std::move(init_callback);
- ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
- socket_thread_ = BluetoothSocketThread::Get();
- task_manager_ =
- base::MakeRefCounted<BluetoothTaskManagerWin>(ui_task_runner_);
- task_manager_->AddObserver(this);
- task_manager_->Initialize();
- }
- void BluetoothAdapterWin::InitForTest(
- base::OnceClosure init_callback,
- std::unique_ptr<win::BluetoothClassicWrapper> classic_wrapper,
- std::unique_ptr<win::BluetoothLowEnergyWrapper> le_wrapper,
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- scoped_refptr<base::SequencedTaskRunner> bluetooth_task_runner) {
- init_callback_ = std::move(init_callback);
- ui_task_runner_ = ui_task_runner;
- if (!ui_task_runner_)
- ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
- task_manager_ = BluetoothTaskManagerWin::CreateForTesting(
- std::move(classic_wrapper), std::move(le_wrapper), ui_task_runner_);
- task_manager_->AddObserver(this);
- task_manager_->InitializeWithBluetoothTaskRunner(bluetooth_task_runner);
- }
- void BluetoothAdapterWin::MaybePostStartDiscoveryTask() {
- if (discovery_status_ == NOT_DISCOVERING) {
- discovery_status_ = DISCOVERY_STARTING;
- task_manager_->PostStartDiscoveryTask();
- }
- }
- void BluetoothAdapterWin::MaybePostStopDiscoveryTask() {
- if (discovery_status_ != DISCOVERING)
- return;
- discovery_status_ = DISCOVERY_STOPPING;
- task_manager_->PostStopDiscoveryTask();
- }
- } // namespace device
|