#ifndef DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_DEVICE_FLOSS_H_
#define DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_DEVICE_FLOSS_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/floss/bluetooth_adapter_floss.h"
#include "device/bluetooth/floss/bluetooth_pairing_floss.h"
#include "device/bluetooth/floss/bluetooth_socket_floss.h"
#include "device/bluetooth/floss/floss_adapter_client.h"
#include "device/bluetooth/floss/floss_gatt_manager_client.h"
namespace floss {
class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceFloss
: public device::BluetoothDevice,
public FlossGattClientObserver {
public:
enum class ConnectingState {
kIdle = 0,
kACLConnecting,
kProfilesConnecting,
kProfilesConnected,
};
enum class GattConnectingState {
kGattDisconnected = 0,
kGattConnecting,
kGattConnected,
kGattConnectionInit,
};
enum PropertiesState : uint32_t {
kNotRead = 0,
kTriggeredByScan = 1 << 1,
kTriggeredByInquiry = 1 << 2,
kTriggeredbyBoth = (kTriggeredByScan | kTriggeredByInquiry)
};
BluetoothDeviceFloss(const BluetoothDeviceFloss&) = delete;
BluetoothDeviceFloss& operator=(const BluetoothDeviceFloss&) = delete;
BluetoothDeviceFloss(
BluetoothAdapterFloss* adapter,
const FlossDeviceId& device,
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<device::BluetoothSocketThread> socket_thread);
~BluetoothDeviceFloss() override;
uint32_t GetBluetoothClass() const override;
device::BluetoothTransport GetType() const override;
std::string GetAddress() const override;
AddressType GetAddressType() const override;
VendorIDSource GetVendorIDSource() const override;
uint16_t GetVendorID() const override;
uint16_t GetProductID() const override;
uint16_t GetDeviceID() const override;
uint16_t GetAppearance() const override;
std::optional<std::string> GetName() const override;
bool IsPaired() const override;
#if BUILDFLAG(IS_CHROMEOS)
bool IsBonded() const override;
#endif
bool IsConnected() const override;
bool IsGattConnected() const override;
bool IsConnectable() const override;
bool IsConnecting() const override;
UUIDSet GetUUIDs() const override;
std::optional<int8_t> GetInquiryTxPower() const override;
bool ExpectingPinCode() const override;
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(ConnectionInfoCallback callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
ConnectCallback callback) override;
#if BUILDFLAG(IS_CHROMEOS)
void ConnectClassic(
device::BluetoothDevice::PairingDelegate* pairing_delegate,
ConnectCallback callback) override;
#endif
void SetPinCode(const std::string& pincode) override;
void SetPasskey(uint32_t passkey) override;
void ConfirmPairing() override;
void RejectPairing() override;
void CancelPairing() override;
void Disconnect(base::OnceClosure callback,
ErrorCallback error_callback) override;
void Forget(base::OnceClosure callback,
ErrorCallback error_callback) override;
void ConnectToService(const device::BluetoothUUID& uuid,
ConnectToServiceCallback callback,
ConnectToServiceErrorCallback error_callback) override;
void ConnectToServiceInsecurely(
const device::BluetoothUUID& uuid,
ConnectToServiceCallback callback,
ConnectToServiceErrorCallback error_callback) override;
std::unique_ptr<device::BluetoothGattConnection>
CreateBluetoothGattConnectionObject() override;
void SetGattServicesDiscoveryComplete(bool complete) override;
bool IsGattServicesDiscoveryComplete() const override;
void Pair(device::BluetoothDevice::PairingDelegate* pairing_delegate,
ConnectCallback callback) override;
BluetoothPairingFloss* BeginPairing(
BluetoothDevice::PairingDelegate* pairing_delegate);
#if BUILDFLAG(IS_CHROMEOS)
bool UsingReliableWrite() const { return using_reliable_write_; }
void BeginReliableWrite();
void ExecuteWrite(base::OnceClosure callback,
ExecuteWriteErrorCallback error_callback) override;
void AbortWrite(base::OnceClosure callback,
AbortWriteErrorCallback error_callback) override;
#endif
FlossDeviceId AsFlossDeviceId() const;
bool IsBondedImpl() const;
void SetName(const std::string& name);
FlossAdapterClient::BondState GetBondState() { return bond_state_; }
void SetBondState(
FlossAdapterClient::BondState bond_state,
std::optional<BluetoothDevice::ConnectErrorCode> error_code);
void SetIsConnected(bool is_connected);
void SetConnectionState(uint32_t state);
void ResetPairing();
BluetoothPairingFloss* pairing() const { return pairing_.get(); }
void InitializeDeviceProperties(PropertiesState state,
base::OnceClosure callback);
bool IsReadingProperties() const {
return property_reads_triggered_ != PropertiesState::kNotRead;
}
bool HasReadProperties() const {
return property_reads_completed_ != PropertiesState::kNotRead;
}
PropertiesState GetPropertiesState() const {
return property_reads_completed_;
}
void GattClientConnectionState(GattStatus status,
int32_t client_id,
bool connected,
std::string address) override;
void GattSearchComplete(std::string address,
const std::vector<GattService>& services,
GattStatus status) override;
void GattConnectionUpdated(std::string address,
int32_t interval,
int32_t latency,
int32_t timeout,
GattStatus status) override;
void GattConfigureMtu(std::string address,
int32_t mtu,
GattStatus status) override;
#if BUILDFLAG(IS_CHROMEOS)
void GattServiceChanged(std::string address) override;
void GattExecuteWrite(std::string address, GattStatus status) override;
#endif
BluetoothAdapterFloss* adapter() const {
return static_cast<BluetoothAdapterFloss*>(adapter_);
}
void FetchRemoteType(base::OnceClosure callback);
void FetchRemoteClass(base::OnceClosure callback);
void FetchRemoteAppearance(base::OnceClosure callback);
void FetchRemoteUuids(base::OnceClosure callback);
void FetchRemoteVendorProductInfo(base::OnceClosure callback);
void FetchRemoteAddressType(base::OnceClosure callback);
void FetchRemoteBondState(base::OnceClosure callback);
void FetchRemoteConnectionState(base::OnceClosure callback);
void OnDeviceConnectionFailed(FlossDBusClient::BtifStatus status);
protected:
void CreateGattConnectionImpl(
std::optional<device::BluetoothUUID> service_uuid) override;
void UpgradeToFullDiscovery() override;
void DisconnectGatt() override;
private:
void ConnectionIncomplete();
void ConnectWithTransport(
device::BluetoothDevice::PairingDelegate* pairing_delegate,
ConnectCallback callback,
FlossAdapterClient::BluetoothTransport transport);
void ConnectAllEnabledProfiles();
void UpdateConnectingState(
ConnectingState state,
std::optional<BluetoothDevice::ConnectErrorCode> error);
void UpdateGattConnectingState(GattConnectingState state);
void TriggerConnectCallback(
std::optional<BluetoothDevice::ConnectErrorCode> error_code);
void OnGetRemoteType(base::OnceClosure callback,
DBusResult<FlossAdapterClient::BluetoothDeviceType> ret);
void OnGetRemoteClass(base::OnceClosure callback, DBusResult<uint32_t> ret);
void OnGetRemoteAppearance(base::OnceClosure callback,
DBusResult<uint16_t> ret);
void OnGetRemoteVendorProductInfo(
base::OnceClosure callback,
DBusResult<FlossAdapterClient::VendorProductInfo> ret);
void OnGetRemoteUuids(base::OnceClosure callback, DBusResult<UUIDList> ret);
void OnGetRemoteAddressType(
base::OnceClosure callback,
DBusResult<FlossAdapterClient::BtAddressType> ret);
void OnGetRemoteBondState(base::OnceClosure callback,
DBusResult<uint32_t> ret);
void OnGetRemoteConnectionState(base::OnceClosure callback,
DBusResult<uint32_t> ret);
void OnConnectAllEnabledProfiles(DBusResult<Void> ret);
void OnConnectAllEnabledProfiles(DBusResult<FlossDBusClient::BtifStatus> ret);
void OnDisconnectAllEnabledProfiles(base::OnceClosure callback,
ErrorCallback error_callback,
DBusResult<Void> ret);
void OnConnectToServiceError(scoped_refptr<BluetoothSocketFloss> socket,
ConnectToServiceErrorCallback error_callback,
const std::string& error_message);
void TriggerInitDevicePropertiesCallback();
void OnConnectGatt(DBusResult<Void> ret);
void OnSetConnectionLatency(base::OnceClosure callback,
ErrorCallback error_callback,
DBusResult<Void> ret);
void OnCreateBond(DBusResult<bool> ret);
void OnCreateBond(DBusResult<FlossDBusClient::BtifStatus> ret);
#if BUILDFLAG(IS_CHROMEOS)
void OnExecuteWrite(base::OnceClosure callback,
ExecuteWriteErrorCallback error_callback,
DBusResult<Void> ret);
#endif
std::optional<ConnectCallback> pending_callback_on_connect_profiles_ =
std::nullopt;
base::OneShotTimer connection_incomplete_timer_;
std::optional<base::OnceClosure> pending_callback_on_init_props_ =
std::nullopt;
std::optional<std::pair<base::OnceClosure, ErrorCallback>>
pending_set_connection_latency_ = std::nullopt;
#if BUILDFLAG(IS_CHROMEOS)
std::optional<std::pair<base::OnceClosure, ExecuteWriteErrorCallback>>
pending_execute_write_ = std::nullopt;
bool using_reliable_write_ = false;
#endif
int num_pending_properties_ = 0;
const std::string address_;
std::string name_;
device::BluetoothTransport transport_ =
device::BluetoothTransport::BLUETOOTH_TRANSPORT_CLASSIC;
uint32_t cod_ = 0;
uint16_t appearance_ = 0;
FlossAdapterClient::VendorProductInfo vpi_;
AddressType address_type_ = AddressType::ADDR_TYPE_UNKNOWN;
FlossAdapterClient::BondState bond_state_ =
FlossAdapterClient::BondState::kNotBonded;
bool is_acl_connected_ = false;
bool svc_resolved_ = false;
PropertiesState property_reads_triggered_ = PropertiesState::kNotRead;
PropertiesState property_reads_completed_ = PropertiesState::kNotRead;
std::optional<device::BluetoothUUID> search_uuid;
uint32_t connection_state_ = 0;
ConnectingState connecting_state_ = ConnectingState::kIdle;
GattConnectingState gatt_connecting_state_ =
GattConnectingState::kGattConnectionInit;
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
scoped_refptr<device::BluetoothSocketThread> socket_thread_;
std::unique_ptr<BluetoothPairingFloss> pairing_;
base::WeakPtrFactory<BluetoothDeviceFloss> weak_ptr_factory_{this};
};
}
#endif