| // Copyright 2016 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 <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/memory/ptr_util.h" |
| #include "device/bluetooth/adapter.h" |
| #include "device/bluetooth/device.h" |
| #include "device/bluetooth/discovery_session.h" |
| #include "device/bluetooth/public/mojom/connect_result_type_converter.h" |
| #include "mojo/public/cpp/bindings/strong_binding.h" |
| |
| namespace bluetooth { |
| |
| Adapter::Adapter(scoped_refptr<device::BluetoothAdapter> adapter) |
| : adapter_(std::move(adapter)), client_(nullptr), weak_ptr_factory_(this) { |
| adapter_->AddObserver(this); |
| } |
| |
| Adapter::~Adapter() { |
| adapter_->RemoveObserver(this); |
| adapter_ = nullptr; |
| } |
| |
| void Adapter::ConnectToDevice(const std::string& address, |
| ConnectToDeviceCallback callback) { |
| device::BluetoothDevice* device = adapter_->GetDevice(address); |
| |
| if (!device) { |
| std::move(callback).Run(mojom::ConnectResult::DEVICE_NO_LONGER_IN_RANGE, |
| nullptr /* device */); |
| return; |
| } |
| |
| auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); |
| device->CreateGattConnection( |
| base::Bind(&Adapter::OnGattConnected, weak_ptr_factory_.GetWeakPtr(), |
| copyable_callback), |
| base::Bind(&Adapter::OnConnectError, weak_ptr_factory_.GetWeakPtr(), |
| copyable_callback)); |
| } |
| |
| void Adapter::GetDevices(GetDevicesCallback callback) { |
| std::vector<mojom::DeviceInfoPtr> devices; |
| |
| for (const device::BluetoothDevice* device : adapter_->GetDevices()) { |
| mojom::DeviceInfoPtr device_info = |
| Device::ConstructDeviceInfoStruct(device); |
| devices.push_back(std::move(device_info)); |
| } |
| |
| std::move(callback).Run(std::move(devices)); |
| } |
| |
| void Adapter::GetInfo(GetInfoCallback callback) { |
| mojom::AdapterInfoPtr adapter_info = mojom::AdapterInfo::New(); |
| adapter_info->address = adapter_->GetAddress(); |
| adapter_info->name = adapter_->GetName(); |
| adapter_info->initialized = adapter_->IsInitialized(); |
| adapter_info->present = adapter_->IsPresent(); |
| adapter_info->powered = adapter_->IsPowered(); |
| adapter_info->discoverable = adapter_->IsDiscoverable(); |
| adapter_info->discovering = adapter_->IsDiscovering(); |
| std::move(callback).Run(std::move(adapter_info)); |
| } |
| |
| void Adapter::SetClient(mojom::AdapterClientPtr client) { |
| client_ = std::move(client); |
| } |
| |
| void Adapter::StartDiscoverySession(StartDiscoverySessionCallback callback) { |
| auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); |
| adapter_->StartDiscoverySession( |
| base::Bind(&Adapter::OnStartDiscoverySession, |
| weak_ptr_factory_.GetWeakPtr(), copyable_callback), |
| base::Bind(&Adapter::OnDiscoverySessionError, |
| weak_ptr_factory_.GetWeakPtr(), copyable_callback)); |
| } |
| |
| void Adapter::AdapterPresentChanged(device::BluetoothAdapter* adapter, |
| bool present) { |
| if (client_) |
| client_->PresentChanged(present); |
| } |
| |
| void Adapter::AdapterPoweredChanged(device::BluetoothAdapter* adapter, |
| bool powered) { |
| if (client_) |
| client_->PoweredChanged(powered); |
| } |
| |
| void Adapter::AdapterDiscoverableChanged(device::BluetoothAdapter* adapter, |
| bool discoverable) { |
| if (client_) |
| client_->DiscoverableChanged(discoverable); |
| } |
| |
| void Adapter::AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, |
| bool discovering) { |
| if (client_) |
| client_->DiscoveringChanged(discovering); |
| } |
| |
| void Adapter::DeviceAdded(device::BluetoothAdapter* adapter, |
| device::BluetoothDevice* device) { |
| if (client_) { |
| auto device_info = Device::ConstructDeviceInfoStruct(device); |
| client_->DeviceAdded(std::move(device_info)); |
| } |
| } |
| |
| void Adapter::DeviceChanged(device::BluetoothAdapter* adapter, |
| device::BluetoothDevice* device) { |
| if (client_) { |
| auto device_info = Device::ConstructDeviceInfoStruct(device); |
| client_->DeviceChanged(std::move(device_info)); |
| } |
| } |
| |
| void Adapter::DeviceRemoved(device::BluetoothAdapter* adapter, |
| device::BluetoothDevice* device) { |
| if (client_) { |
| auto device_info = Device::ConstructDeviceInfoStruct(device); |
| client_->DeviceRemoved(std::move(device_info)); |
| } |
| } |
| |
| void Adapter::OnGattConnected( |
| ConnectToDeviceCallback callback, |
| std::unique_ptr<device::BluetoothGattConnection> connection) { |
| mojom::DevicePtr device_ptr; |
| Device::Create(adapter_, std::move(connection), |
| mojo::MakeRequest(&device_ptr)); |
| std::move(callback).Run(mojom::ConnectResult::SUCCESS, std::move(device_ptr)); |
| } |
| |
| void Adapter::OnConnectError( |
| ConnectToDeviceCallback callback, |
| device::BluetoothDevice::ConnectErrorCode error_code) { |
| std::move(callback).Run(mojo::ConvertTo<mojom::ConnectResult>(error_code), |
| nullptr /* Device */); |
| } |
| |
| void Adapter::OnStartDiscoverySession( |
| StartDiscoverySessionCallback callback, |
| std::unique_ptr<device::BluetoothDiscoverySession> session) { |
| mojom::DiscoverySessionPtr session_ptr; |
| mojo::MakeStrongBinding( |
| std::make_unique<DiscoverySession>(std::move(session)), |
| mojo::MakeRequest(&session_ptr)); |
| std::move(callback).Run(std::move(session_ptr)); |
| } |
| |
| void Adapter::OnDiscoverySessionError(StartDiscoverySessionCallback callback) { |
| std::move(callback).Run(nullptr /* session */); |
| } |
| |
| } // namespace bluetooth |