blob: c7e6211718d5032376dd81cdecf19f1e9d7ca02d [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// 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_FLOSS_BRIDGE_H_
#define CHROME_BROWSER_ASH_ARC_BLUETOOTH_ARC_FLOSS_BRIDGE_H_
#include "chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.h"
#include "chromeos/ash/experiences/arc/mojom/bluetooth.mojom.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
#include "device/bluetooth/floss/bluetooth_adapter_floss.h"
#include "device/bluetooth/floss/floss_adapter_client.h"
namespace arc {
// Floss specialization for Arc Bluetooth bridge. Use this class whenever the
// common |device::BluetoothAdapter| or |device::BluetoothDevice| class apis are
// insufficient.
class ArcFlossBridge : public ArcBluetoothBridge,
public floss::FlossAdapterClient::Observer {
public:
ArcFlossBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service);
~ArcFlossBridge() override;
ArcFlossBridge(const ArcFlossBridge&) = delete;
ArcFlossBridge& operator=(const ArcFlossBridge&) = delete;
// ArcBluetoothBridge overrides
void SendCachedDevices() const override;
void StartLEScanImpl() override;
void ResetLEScanSession() override;
bool IsDiscoveringOrScanning() 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;
// Closes Bluetooth sockets. Releases the corresponding resources.
void CloseBluetoothListeningSocket(BluetoothListeningSocket* socket);
void CloseBluetoothConnectingSocket(BluetoothConnectingSocket* socket);
// floss::FlossAdapterClient::Observer overrides
void SdpSearchComplete(
const floss::FlossDeviceId device,
const device::BluetoothUUID uuid,
const std::vector<floss::BtSdpRecord>& records) override;
void SdpRecordCreated(const floss::BtSdpRecord record,
const int32_t handle) override;
protected:
floss::BluetoothAdapterFloss* GetAdapter() const;
void HandlePoweredOn() override;
void OnSdpSearchResult(mojom::BluetoothAddressPtr remote_addr,
const device::BluetoothUUID& target_uuid,
floss::DBusResult<bool> result);
void RemoveSdpRecordComplete(RemoveSdpRecordCallback callback,
floss::DBusResult<bool> result);
void CreateSdpRecordComplete(device::BluetoothUUID uuid,
floss::DBusResult<bool> result);
void CompleteCreateSdpRecord(
device::BluetoothUUID uuid,
arc::mojom::BluetoothCreateSdpRecordResultPtr result);
void CreateBluetoothListenSocket(
mojom::BluetoothSocketType type,
mojom::BluetoothSocketFlagsPtr flags,
int port,
BluetoothSocketListenCallback callback) override;
void OnCloseBluetoothListeningSocketComplete(
BluetoothListeningSocket* socket,
floss::DBusResult<floss::FlossDBusClient::BtifStatus> result);
void CreateBluetoothConnectSocket(
mojom::BluetoothSocketType type,
mojom::BluetoothSocketFlagsPtr flags,
mojom::BluetoothAddressPtr addr,
int port,
BluetoothSocketConnectCallback callback) override;
void OnCreateListenSocketCallback(
std::unique_ptr<ArcBluetoothBridge::BluetoothListeningSocket>
sock_wrapper,
int socket_ready_id,
floss::DBusResult<floss::FlossDBusClient::BtifStatus> result);
void OnCreateConnectSocketCallback(
std::unique_ptr<ArcBluetoothBridge::BluetoothConnectingSocket>
sock_wrapper,
ArcFlossBridge::BluetoothSocketConnectCallback callback,
floss::FlossDBusClient::BtifStatus status,
std::optional<floss::FlossSocketManager::FlossSocket>&& socket);
void OnBtifError(const std::string& error_message);
void OnBtifSuccess();
void OnConnectionStateChanged(
ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper,
int socket_ready_id,
floss::FlossSocketManager::ServerSocketState state,
floss::FlossSocketManager::FlossListeningSocket socket,
floss::FlossSocketManager::BtifStatus status);
void OnConnectionAccepted(
const ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper,
floss::FlossSocketManager::FlossSocket&& socket);
int GetPortOrChannel(
ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper,
floss::FlossSocketManager::FlossListeningSocket socket);
void CompleteListenSocketReady(
int socket_ready_id,
mojom::BluetoothStatus status,
int port_or_channel,
ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper);
void CompleteListenSocketReady(
int socket_ready_id,
mojom::BluetoothStatus status,
ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper);
void CompleteListenSocketReady(
int socket_ready_id,
mojom::BluetoothStatus status,
ArcBluetoothBridge::BluetoothListeningSocket* sock_wrapper,
floss::FlossSocketManager::FlossListeningSocket socket);
private:
bool AdapterReadyAndRegistered();
// Map of socket_ready_id -> listen callback
base::flat_map<int, BluetoothSocketListenCallback> socket_ready_callbacks_{};
// The next callback id to use. Starts at a non-zero number for easier
// debugging.
int next_socket_ready_callback_id_{42};
// Map of SDP record UUIDs to CreateSdpRecordCallback for SdpRecordCreated to
// use to resolve CreateSdpRecord calls.
base::flat_map<device::BluetoothUUID, CreateSdpRecordCallback>
create_sdp_record_callbacks_{};
// Lookup for mapping listening socket pointers to SocketIds so they can be
// closed with Floss.
base::flat_map<
ArcBluetoothBridge::BluetoothListeningSocket*,
std::pair<std::unique_ptr<ArcBluetoothBridge::BluetoothListeningSocket>,
floss::FlossSocketManager::SocketId>>
listening_sockets_{};
// Default SocketId until a real one is obtained.
static constexpr floss::FlossSocketManager::SocketId empty_socket_id_ = 0;
// Floss doesn't require us to close connecting sockets through it so we don't
// need to keep the SocketId.
std::set<std::unique_ptr<BluetoothConnectingSocket>,
base::UniquePtrComparator>
connecting_sockets_;
// Map of device+channel combinations to service UUIDs
base::flat_map<std::pair<std::string, int32_t>, device::BluetoothUUID>
uuid_lookups_{};
// LE scan session created by StartLEScanImpl()
std::unique_ptr<device::BluetoothLowEnergyScanSession> ble_scan_session_;
// WeakPtrFactory to use for callbacks.
base::WeakPtrFactory<ArcFlossBridge> weak_factory_{this};
};
} // namespace arc
#endif // CHROME_BROWSER_ASH_ARC_BLUETOOTH_ARC_FLOSS_BRIDGE_H_