blob: 76866abc3aa053167f7cbb42705286f95b06b32f [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_ASH_ARC_BLUETOOTH_ARC_BLUETOOTH_BRIDGE_H_
#define CHROME_BROWSER_ASH_ARC_BLUETOOTH_ARC_BLUETOOTH_BRIDGE_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "base/callback_forward.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/files/file.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/arc/bluetooth/arc_bluetooth_task_queue.h"
#include "components/arc/mojom/bluetooth.mojom.h"
#include "components/arc/mojom/intent_helper.mojom-forward.h"
#include "components/arc/session/connection_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_advertisement.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_local_gatt_service.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_remote_gatt_descriptor.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
#include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace content {
class BrowserContext;
} // namespace content
namespace arc {
namespace mojom {
class AppInstance;
class IntentHelperInstance;
} // namespace mojom
class ArcBridgeService;
class ArcBluetoothBridge
: public KeyedService,
public device::BluetoothAdapter::Observer,
public device::BluetoothAdapterFactory::AdapterCallback,
public device::BluetoothLocalGattService::Delegate,
public ConnectionObserver<mojom::AppInstance>,
public ConnectionObserver<mojom::IntentHelperInstance>,
public mojom::BluetoothHost {
public:
using GattStatusCallback =
base::OnceCallback<void(mojom::BluetoothGattStatus)>;
using AdapterStateCallback =
base::OnceCallback<void(mojom::BluetoothAdapterState)>;
// Returns singleton instance for the given BrowserContext,
// or nullptr if the browser |context| is not allowed to use ARC.
static ArcBluetoothBridge* GetForBrowserContext(
content::BrowserContext* context);
ArcBluetoothBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service);
~ArcBluetoothBridge() override;
void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter);
// Overridden from device::BluetoothAdapter::Observer
void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) override;
void DeviceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
void DeviceChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
void DeviceAddressChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
const std::string& old_address) override;
void DevicePairedChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
bool new_paired_status) override;
void DeviceMTUChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
uint16_t mtu) override;
void DeviceAdvertisementReceived(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
int16_t rssi,
const std::vector<uint8_t>& eir) override;
void DeviceConnectedStateChanged(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
bool is_now_connected) override;
void DeviceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
void GattServiceAdded(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
device::BluetoothRemoteGattService* service) override;
void GattServiceRemoved(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device,
device::BluetoothRemoteGattService* service) override;
void GattServicesDiscovered(device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) override;
void GattDiscoveryCompleteForService(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattService* service) override;
void GattServiceChanged(device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattService* service) override;
void GattCharacteristicAdded(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattCharacteristic* characteristic) override;
void GattCharacteristicRemoved(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattCharacteristic* characteristic) override;
void GattDescriptorAdded(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattDescriptor* descriptor) override;
void GattDescriptorRemoved(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattDescriptor* descriptor) override;
void GattCharacteristicValueChanged(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattCharacteristic* characteristic,
const std::vector<uint8_t>& value) override;
void GattDescriptorValueChanged(
device::BluetoothAdapter* adapter,
device::BluetoothRemoteGattDescriptor* descriptor,
const std::vector<uint8_t>& value) override;
// Overridden from device::BluetoothLocalGattService::Delegate
void OnCharacteristicReadRequest(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattCharacteristic* characteristic,
int offset,
ValueCallback callback) override;
void OnCharacteristicWriteRequest(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattCharacteristic* characteristic,
const std::vector<uint8_t>& value,
int offset,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void OnCharacteristicPrepareWriteRequest(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattCharacteristic* characteristic,
const std::vector<uint8_t>& value,
int offset,
bool has_subsequent_write,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void OnDescriptorReadRequest(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattDescriptor* descriptor,
int offset,
ValueCallback callback) override;
void OnDescriptorWriteRequest(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattDescriptor* descriptor,
const std::vector<uint8_t>& value,
int offset,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void OnNotificationsStart(
const device::BluetoothDevice* device,
device::BluetoothGattCharacteristic::NotificationType notification_type,
const device::BluetoothLocalGattCharacteristic* characteristic) override;
void OnNotificationsStop(
const device::BluetoothDevice* device,
const device::BluetoothLocalGattCharacteristic* characteristic) override;
// Bluetooth Mojo host interface
void EnableAdapter(EnableAdapterCallback callback) override;
void DisableAdapter(DisableAdapterCallback callback) override;
void GetAdapterProperty(mojom::BluetoothPropertyType type) override;
void SetAdapterProperty(mojom::BluetoothPropertyPtr property) override;
void StartDiscovery() override;
void CancelDiscovery() override;
void CreateBond(mojom::BluetoothAddressPtr addr, int32_t transport) override;
void RemoveBond(mojom::BluetoothAddressPtr addr) override;
void CancelBond(mojom::BluetoothAddressPtr addr) override;
void GetConnectionState(mojom::BluetoothAddressPtr addr,
GetConnectionStateCallback callback) override;
// Bluetooth Mojo host interface - Bluetooth Gatt Client functions
void StartLEScan() override;
void StopLEScan() override;
void ConnectLEDevice(mojom::BluetoothAddressPtr remote_addr) override;
void DisconnectLEDevice(mojom::BluetoothAddressPtr remote_addr) override;
void SearchService(mojom::BluetoothAddressPtr remote_addr) override;
void GetGattDB(mojom::BluetoothAddressPtr remote_addr) override;
void ReadGattCharacteristic(mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
ReadGattCharacteristicCallback callback) override;
void WriteGattCharacteristic(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
mojom::BluetoothGattValuePtr value,
bool prepare,
WriteGattCharacteristicCallback callback) override;
void ReadGattDescriptor(mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
mojom::BluetoothGattIDPtr desc_id,
ReadGattDescriptorCallback callback) override;
void WriteGattDescriptor(mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
mojom::BluetoothGattIDPtr desc_id,
mojom::BluetoothGattValuePtr value,
WriteGattDescriptorCallback callback) override;
void ExecuteWrite(mojom::BluetoothAddressPtr remote_addr,
bool execute,
ExecuteWriteCallback callback) override;
void RegisterForGattNotification(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
RegisterForGattNotificationCallback callback) override;
void DeregisterForGattNotification(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
DeregisterForGattNotificationCallback callback) override;
void ReadRemoteRssi(mojom::BluetoothAddressPtr remote_addr,
ReadRemoteRssiCallback callback) override;
void OpenBluetoothSocketDeprecated(
OpenBluetoothSocketDeprecatedCallback callback) override;
// Bluetooth Mojo host interface - Bluetooth Gatt Server functions
// Android counterpart link:
// https://source.android.com/devices/halref/bt__gatt__server_8h.html
// Create a new service. Chrome will create an integer service handle based on
// that BlueZ identifier that will pass back to Android in the callback.
// num_handles: number of handle for characteristic / descriptor that will be
// created in this service
void AddService(mojom::BluetoothGattServiceIDPtr service_id,
int32_t num_handles,
AddServiceCallback callback) override;
// Add a characteristic to a service and pass the characteristic handle back.
void AddCharacteristic(int32_t service_handle,
const device::BluetoothUUID& uuid,
int32_t properties,
int32_t permissions,
AddCharacteristicCallback callback) override;
// Add a descriptor to the last characteristic added to the given service
// and pass the descriptor handle back.
void AddDescriptor(int32_t service_handle,
const device::BluetoothUUID& uuid,
int32_t permissions,
AddDescriptorCallback callback) override;
// Start a local service.
void StartService(int32_t service_handle,
StartServiceCallback callback) override;
// Stop a local service.
void StopService(int32_t service_handle,
StopServiceCallback callback) override;
// Delete a local service.
void DeleteService(int32_t service_handle,
DeleteServiceCallback callback) override;
// Send value indication to a remote device.
void SendIndication(int32_t attribute_handle,
mojom::BluetoothAddressPtr address,
bool confirm,
const std::vector<uint8_t>& value,
SendIndicationCallback callback) override;
// Bluetooth Mojo host interface - Bluetooth SDP functions
void GetSdpRecords(mojom::BluetoothAddressPtr remote_addr,
const device::BluetoothUUID& target_uuid) override;
void CreateSdpRecord(mojom::BluetoothSdpRecordPtr record_mojo,
CreateSdpRecordCallback callback) override;
void RemoveSdpRecord(uint32_t service_handle,
RemoveSdpRecordCallback callback) override;
// Bluetooth Mojo host interface - Bluetooth RFCOMM functions
void RfcommListenDeprecated(int32_t channel,
int32_t optval,
RfcommListenDeprecatedCallback callback) override;
void RfcommConnectDeprecated(
mojom::BluetoothAddressPtr remote_addr,
int32_t channel,
int32_t optval,
RfcommConnectDeprecatedCallback callback) override;
// Bluetooth Mojo host interface - Bluetooth socket functions
void BluetoothSocketListen(mojom::BluetoothSocketType sock_type,
mojom::BluetoothSocketFlagsPtr sock_flags,
int32_t port,
BluetoothSocketListenCallback callback) override;
void BluetoothSocketConnect(mojom::BluetoothSocketType sock_type,
mojom::BluetoothSocketFlagsPtr sock_flags,
mojom::BluetoothAddressPtr remote_addr,
int32_t port,
BluetoothSocketConnectCallback callback) override;
// Set up or disable multiple advertising.
void ReserveAdvertisementHandle(
ReserveAdvertisementHandleCallback callback) override;
void EnableAdvertisement(
int32_t adv_handle,
std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement,
EnableAdvertisementCallback callback) override;
void DisableAdvertisement(int32_t adv_handle,
DisableAdvertisementCallback callback) override;
void ReleaseAdvertisementHandle(
int32_t adv_handle,
ReleaseAdvertisementHandleCallback callback) override;
private:
void ReserveAdvertisementHandleImpl(
ReserveAdvertisementHandleCallback callback);
void EnableAdvertisementImpl(
int32_t adv_handle,
std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement,
EnableAdvertisementCallback callback);
void DisableAdvertisementImpl(int32_t adv_handle,
DisableAdvertisementCallback callback);
void ReleaseAdvertisementHandleImpl(
int32_t adv_handle,
ReleaseAdvertisementHandleCallback callback);
// StartDiscovery() is used for scanning both BR/EDR and LE devices, while
// StartLEScan() is only for LE devices.
void StartDiscoveryImpl();
void CancelDiscoveryImpl();
void StartLEScanImpl();
void StopLEScanImpl();
// The callback function triggered by le_scan_off_timer_.
void StopLEScanByTimer();
// Power state change on Bluetooth adapter.
enum class AdapterPowerState { TURN_OFF, TURN_ON };
// Chrome observer callbacks
void OnPoweredOn(AdapterStateCallback callback, bool save_user_pref) const;
void OnPoweredOff(AdapterStateCallback callback, bool save_user_pref) const;
void OnPoweredError(AdapterStateCallback callback) const;
void OnDiscoveryStarted(
std::unique_ptr<device::BluetoothDiscoverySession> session);
void OnDiscoveryError();
void OnLEScanStarted(
std::unique_ptr<device::BluetoothDiscoverySession> session);
void OnLEScanError();
void OnPairing(mojom::BluetoothAddressPtr addr) const;
void OnPairedDone(mojom::BluetoothAddressPtr addr) const;
void OnPairedError(
mojom::BluetoothAddressPtr addr,
device::BluetoothDevice::ConnectErrorCode error_code) const;
void OnForgetDone(mojom::BluetoothAddressPtr addr);
void OnForgetError(mojom::BluetoothAddressPtr addr) const;
void OnGattConnectStateChanged(mojom::BluetoothAddressPtr addr,
bool connected) const;
void OnGattConnect(
mojom::BluetoothAddressPtr addr,
std::unique_ptr<device::BluetoothGattConnection> connection,
absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code);
void OnGattDisconnected(mojom::BluetoothAddressPtr addr);
void OnGattNotifyStartDone(
GattStatusCallback callback,
const std::string char_string_id,
std::unique_ptr<device::BluetoothGattNotifySession> notify_session);
// Indicates if a power change is initiated by Chrome / Android.
bool IsPowerChangeInitiatedByRemote(
ArcBluetoothBridge::AdapterPowerState powered) const;
bool IsPowerChangeInitiatedByLocal(
ArcBluetoothBridge::AdapterPowerState powered) const;
// ConnectionObserver<mojom::AppInstance>:
// ConnectionObserver<mojom::IntentHelperInstance>:
void OnConnectionReady() override;
// Manages the powered change intents sent to Android.
void EnqueueLocalPowerChange(AdapterPowerState powered);
void DequeueLocalPowerChange(AdapterPowerState powered);
// Manages the powered change requests received from Android.
void EnqueueRemotePowerChange(AdapterPowerState powered,
AdapterStateCallback callback);
void DequeueRemotePowerChange(AdapterPowerState powered);
// Sends properties of cached devices to Android. The list of cached devices
// is got by BluetoothAdapter::GetDevices(), which includes all devices have
// been discovered (not necessarily paired or connected) but not yet expired.
// This function should be called when Bluetooth service in Android is ready.
void SendCachedDevices() const;
std::vector<mojom::BluetoothPropertyPtr> GetDeviceProperties(
mojom::BluetoothPropertyType type,
const device::BluetoothDevice* device) const;
std::vector<mojom::BluetoothPropertyPtr> GetAdapterProperties(
mojom::BluetoothPropertyType type) const;
std::vector<mojom::BluetoothAdvertisingDataPtr> GetAdvertisingData(
const device::BluetoothDevice* device) const;
device::BluetoothRemoteGattCharacteristic* FindGattCharacteristic(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id) const;
device::BluetoothRemoteGattDescriptor* FindGattDescriptor(
mojom::BluetoothAddressPtr remote_addr,
mojom::BluetoothGattServiceIDPtr service_id,
mojom::BluetoothGattIDPtr char_id,
mojom::BluetoothGattIDPtr desc_id) const;
// Send the power status change to Android via an intent.
void SendBluetoothPoweredStateBroadcast(AdapterPowerState powered) const;
bool IsGattServerAttributeHandleAvailable(int need);
int32_t GetNextGattServerAttributeHandle();
template <class LocalGattAttribute>
int32_t CreateGattAttributeHandle(LocalGattAttribute* attribute);
// Common code for OnCharacteristicReadRequest and OnDescriptorReadRequest
template <class LocalGattAttribute>
void OnGattAttributeReadRequest(
const device::BluetoothDevice* device,
const LocalGattAttribute* attribute,
int offset,
mojom::BluetoothGattDBAttributeType attribute_type,
ValueCallback callback);
// Common code for OnCharacteristicWriteRequest and OnDescriptorWriteRequest
// |is_prepare| is only set when a local characteristic receives a prepare
// write request, and |has_subsequent_write| indicates whether there are
// subsequent prepare write requests following the current one.
template <class LocalGattAttribute>
void OnGattAttributeWriteRequest(
const device::BluetoothDevice* device,
const LocalGattAttribute* attribute,
const std::vector<uint8_t>& value,
int offset,
mojom::BluetoothGattDBAttributeType attribute_type,
bool is_prepare,
bool has_subsequent_write,
base::OnceClosure success_callback,
ErrorCallback error_callback);
void OnSetDiscoverable(bool discoverable, bool success, uint32_t timeout);
void SetDiscoverable(bool discoverable, uint32_t timeout);
void OnGetServiceRecordsDone(
mojom::BluetoothAddressPtr remote_addr,
const device::BluetoothUUID& target_uuid,
const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez);
void OnGetServiceRecordsError(
mojom::BluetoothAddressPtr remote_addr,
const device::BluetoothUUID& target_uuid,
bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code);
void OnSetAdapterProperty(mojom::BluetoothStatus success,
mojom::BluetoothPropertyPtr property);
// Convenience function to set primary user's bluetooth pref.
void SetPrimaryUserBluetoothPowerSetting(bool enabled) const;
// Callbacks for managing advertisements registered from the instance.
// Called when we have an open slot in the advertisement map and want to
// register the advertisement given by |data| for handle |adv_handle|.
void OnReadyToRegisterAdvertisement(
GattStatusCallback callback,
int32_t adv_handle,
std::unique_ptr<device::BluetoothAdvertisement::Data> data);
// Called when we've successfully registered a new advertisement for
// handle |adv_handle|.
void OnRegisterAdvertisementDone(
GattStatusCallback callback,
int32_t adv_handle,
scoped_refptr<device::BluetoothAdvertisement> advertisement);
// Called when the attempt to register an advertisement for handle
// |adv_handle| has failed. |adv_handle| remains reserved, but no
// advertisement is associated with it.
void OnRegisterAdvertisementError(
GattStatusCallback callback,
int32_t adv_handle,
device::BluetoothAdvertisement::ErrorCode error_code);
void OnUnregisterAdvertisementDone(GattStatusCallback callback,
int32_t adv_handle);
void OnUnregisterAdvertisementError(
GattStatusCallback callback,
int32_t adv_handle,
device::BluetoothAdvertisement::ErrorCode error_code);
// Both of the following are called after we've tried to release |adv_handle|.
// Either way, we will no longer be broadcasting this advertisement, so in
// either case, the handle can be released.
void OnReleaseAdvertisementHandleDone(GattStatusCallback callback,
int32_t adv_handle);
void OnReleaseAdvertisementHandleError(
GattStatusCallback callback,
int32_t adv_handle,
device::BluetoothAdvertisement::ErrorCode error_code);
// Find the next free advertisement handle and put it in *adv_handle,
// or return false if the advertisement map is full.
bool GetAdvertisementHandle(int32_t* adv_handle);
void OnGattServerPrepareWrite(mojom::BluetoothAddressPtr addr,
bool has_subsequent_write,
base::OnceClosure success_callback,
ErrorCallback error_callback,
mojom::BluetoothGattStatus status);
void SendDevice(const device::BluetoothDevice* device) const;
// Detects the pairing state change from DeviceChanged(). Two actions will be
// taken in this function:
// - Updates |devices_pairing_| to reflect the set of ongoing pairing requests
// initiated by ARC;
// - Notifies Android of the pairing failure.
// Note that notifying Android of the pairing success is handled in
// DevicePairedChange() but not in this function.
void TrackPairingState(const device::BluetoothDevice* device);
// Data structures for Bluetooth listening/connecting sockets that live in
// Chrome.
struct BluetoothListeningSocket {
mojom::BluetoothSocketType sock_type;
// TODO(b/163099156): Remove the following two fields when
// RfcommListenDeprecated()/RfcommConnectDeprecated() are removed.
bool created_by_deprecated_method = false;
mojo::Remote<mojom::RfcommListeningSocketClient> deprecated_remote;
mojo::Remote<mojom::BluetoothListenSocketClient> remote;
base::ScopedFD file;
std::unique_ptr<base::FileDescriptorWatcher::Controller> controller;
BluetoothListeningSocket();
~BluetoothListeningSocket();
};
struct BluetoothConnectingSocket {
mojom::BluetoothSocketType sock_type;
// TODO(b/163099156): Remove the following two fields when
// RfcommListenDeprecated()/RfcommConnectDeprecated() are removed.
bool created_by_deprecated_method = false;
mojo::Remote<mojom::RfcommConnectingSocketClient> deprecated_remote;
mojo::Remote<mojom::BluetoothConnectSocketClient> remote;
base::ScopedFD file;
std::unique_ptr<base::FileDescriptorWatcher::Controller> controller;
BluetoothConnectingSocket();
~BluetoothConnectingSocket();
};
// Creates a Bluetooth socket with socket option |optval|, and then bind() and
// listen() with requested |port| number. The actual port number will be
// filled in |port| as the return value. Returns a BluetoothListeningSocket
// that holds the socket.
std::unique_ptr<BluetoothListeningSocket> CreateBluetoothListenSocket(
mojom::BluetoothSocketType type,
int32_t optval,
uint16_t* port);
// Creates a Bluetooth socket with socket option |optval|, and then calls
// connect() to (|addr|, |port|). This connect() call is non-blocking.
// Returns a BluetoothConnectingSocket that holds the socket.
std::unique_ptr<BluetoothConnectingSocket> CreateBluetoothConnectSocket(
mojom::BluetoothSocketType type,
int32_t optval,
mojom::BluetoothAddressPtr addr,
uint16_t port);
// Closes Bluetooth sockets. Releases the corresponding resources.
void CloseBluetoothListeningSocket(BluetoothListeningSocket* socket);
void CloseBluetoothConnectingSocket(BluetoothConnectingSocket* socket);
// Called when the listening socket is ready to accept().
void OnBluetoothListeningSocketReady(
ArcBluetoothBridge::BluetoothListeningSocket* socket);
// Called when the connecting socket is ready.
void OnBluetoothConnectingSocketReady(
ArcBluetoothBridge::BluetoothConnectingSocket* socket);
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
scoped_refptr<bluez::BluetoothAdapterBlueZ> bluetooth_adapter_;
scoped_refptr<device::BluetoothAdvertisement> advertisment_;
// Discovery session created by StartDiscovery().
std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_;
// Discovery session created by StartLEScan().
std::unique_ptr<device::BluetoothDiscoverySession> le_scan_session_;
// Discovered devices in the current discovery session started by
// StartDiscovery(). We don't need to keep track of this for StartLEScan()
// since Android don't have a callback for new found devices in LE scan. When
// a new advertisement of an LE device comes, DeviceAdertismentReceived() will
// be called and we pass the result to Android via OnLEDeviceFound(), and then
// it will notify the LE scanner in Android.
std::set<std::string> discovered_devices_;
std::unordered_map<std::string,
std::unique_ptr<device::BluetoothGattNotifySession>>
notification_session_;
// Map from Android int handle to Chrome (BlueZ) string identifier.
std::unordered_map<int32_t, std::string> gatt_identifier_;
// Map from Chrome (BlueZ) string identifier to android int handle.
std::unordered_map<std::string, int32_t> gatt_handle_;
// Store last GattCharacteristic added to each GattService for GattServer.
std::unordered_map<int32_t, int32_t> last_characteristic_;
// Monotonically increasing value to use as handle to give to Android side.
int32_t gatt_server_attribute_next_handle_ = 0;
// The devices that ARC has tried to pair by CreateBond() (including the
// devices that the pair request is ongoing) but there is no
// BluetoothGattConnection object associated to, during the lifetime of
// Android BT service. The main reason we need to maintain this set is that we
// need to manually close the links created by pair but not used by any GATT
// connection when Android BT service goes down, otherwise these links will be
// lingering.
std::set<std::string> devices_paired_by_arc_;
// The devices that ARC has tried to pair by CreateBond() and is in pairing
// state. This should be a subset of |devices_paired_by_arc_|. We maintain
// this set to detect the pairing failure signal. Please refer to
// TrackPairingState() for more details.
std::set<std::string> devices_pairing_;
// {state, connection}
// - For established connection from remote device, this is {CONNECTED, null}.
// - For ongoing connection to remote device, this is {CONNECTING, null}.
// - For established connection to remote device, this is {CONNECTED, ptr}.
struct GattConnection {
enum class ConnectionState { CONNECTING, CONNECTED } state;
std::unique_ptr<device::BluetoothGattConnection> connection;
// Indicates whether we should call BluetoothDevice::Disconnect() when
// |connection| is closed. This field is true when the connection is
// initiated by ARC, i.e, when ConnectLEDevice is called, either 1) the link
// is down or 2) the remote device is paired by ARC firstly.
// TODO(b/151573141): Remove this field when Chrome can perform hard
// disconnect on a paired device correctly.
bool need_hard_disconnect;
GattConnection(ConnectionState state,
std::unique_ptr<device::BluetoothGattConnection> connection,
bool need_hard_disconnect);
GattConnection();
~GattConnection();
GattConnection(GattConnection&&);
GattConnection& operator=(GattConnection&&);
private:
DISALLOW_COPY_AND_ASSIGN(GattConnection);
};
std::unordered_map<std::string, GattConnection> gatt_connections_;
// Timer to turn off discovery_session_.
base::OneShotTimer discovery_off_timer_;
// Timer to turn off le_scan_session_.
// TODO(b/152463320): Remove this timer after the platform side supports
// setting scan parameters and filters.
base::OneShotTimer le_scan_off_timer_;
// Timer to turn adapter discoverable off.
base::OneShotTimer discoverable_off_timer_;
// Adapter discoverable timeout value.
uint32_t discoverable_off_timeout_ = 0;
// Queue to track the powered state changes initiated by Android.
base::queue<AdapterPowerState> remote_power_changes_;
// Queue to track the powered state changes initiated by Chrome.
base::queue<AdapterPowerState> local_power_changes_;
// Timer to track the completion of power-changed intent sent to Android.
base::OneShotTimer power_intent_timer_;
// Holds advertising data registered by the instance.
//
// When a handle is reserved, an entry is placed into the advertisements_
// map. This entry is not yet associated with a device::BluetoothAdvertisement
// because the instance hasn't sent us any advertising data yet, so its
// mapped value is nullptr until that happens. Thus we have three states for a
// handle:
// * unmapped -> free
// * mapped to nullptr -> reserved, awaiting data
// * mapped to a device::BluetoothAdvertisement -> in use, and the mapped
// BluetoothAdvertisement is currently registered with the adapter.
// TODO(crbug.com/658385) Change back to 5 when we support setting signal
// strength per each advertisement slot.
enum { kMaxAdvertisements = 1 };
std::map<int32_t, scoped_refptr<device::BluetoothAdvertisement>>
advertisements_;
ArcBluetoothTaskQueue advertisement_queue_;
// This queue will hold requests from both Start/CancelDiscovery() and
// Start/StopLEScan().
ArcBluetoothTaskQueue discovery_queue_;
// Bluetooth sockets that live in Chrome.
std::set<std::unique_ptr<BluetoothListeningSocket>, base::UniquePtrComparator>
listening_sockets_;
std::set<std::unique_ptr<BluetoothConnectingSocket>,
base::UniquePtrComparator>
connecting_sockets_;
// Observes the ARC connection to Bluetooth service in Android. We need to do
// some cleanup when it is down.
class BluetoothArcConnectionObserver
: public ConnectionObserver<mojom::BluetoothInstance> {
public:
explicit BluetoothArcConnectionObserver(
ArcBluetoothBridge* arc_bluetooth_bridge);
BluetoothArcConnectionObserver(const BluetoothArcConnectionObserver&) =
delete;
BluetoothArcConnectionObserver& operator=(
const BluetoothArcConnectionObserver&) = delete;
~BluetoothArcConnectionObserver() override;
// ConnectionObserver<mojom::BluetoothInstance> override.
void OnConnectionClosed() override;
private:
ArcBluetoothBridge* arc_bluetooth_bridge_;
};
BluetoothArcConnectionObserver bluetooth_arc_connection_observer_;
THREAD_CHECKER(thread_checker_);
// WeakPtrFactory to use for callbacks.
base::WeakPtrFactory<ArcBluetoothBridge> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ArcBluetoothBridge);
};
} // namespace arc
#endif // CHROME_BROWSER_ASH_ARC_BLUETOOTH_ARC_BLUETOOTH_BRIDGE_H_