#ifndef DEVICE_BLUETOOTH_FLOSS_FLOSS_ADAPTER_CLIENT_H_
#define DEVICE_BLUETOOTH_FLOSS_FLOSS_ADAPTER_CLIENT_H_
#include <memory>
#include <string>
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "dbus/exported_object.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
#include "device/bluetooth/floss/floss_sdp_types.h"
namespace dbus {
class ErrorResponse;
class ObjectPath;
class Response;
}
namespace floss {
class DEVICE_BLUETOOTH_EXPORT FlossAdapterClient : public FlossDBusClient {
public:
enum class BluetoothDeviceType {
kUnknown = 0,
kBredr = 1,
kBle = 2,
kDual = 3,
};
enum class BluetoothSspVariant {
kPasskeyConfirmation = 0,
kPasskeyEntry = 1,
kConsent = 2,
kPasskeyNotification = 3,
};
enum class BondState {
kNotBonded = 0,
kBondingInProgress = 1,
kBonded = 2,
};
enum class ConnectionState {
kDisconnected = 0,
kConnectedOnly = 1,
kPairedBREDROnly = 3,
kPairedLEOnly = 5,
kPairedBoth = 7,
};
enum class BtPropertyType {
kBdName = 0x1,
kBdAddr,
kUuids,
kClassOfDevice,
kTypeOfDevice,
kServiceRecord,
kAdapterScanMode,
kAdapterBondedDevices,
kAdapterDiscoverableTimeout,
kRemoteFriendlyName,
kRemoteRssi,
kRemoteVersionInfo,
kLocalLeFeatures,
kLocalIoCaps,
kLocalIoCapsBle,
kDynamicAudioBuffer,
kRemoteIsCoordinatedSetMember,
kAppearance,
kVendorProductInfo,
kRemoteAddrType = 0x18,
kUnknown = 0xFE,
kRemoteDeviceTimestamp = 0xFF,
};
enum class BtDiscoverableMode : uint32_t {
kNonDiscoverable = 0,
kLimitedDiscoverable = 1,
kGeneralDiscoverable = 2,
};
enum class BtAddressType {
kPublic = 0,
kRandom,
kPublicId,
kRandomId,
kUnknown = 0xfe,
kAnonymous = 0xff,
};
enum class BtAdapterRole {
kCentral = 0,
kPeripheral,
kCentralPeripheral,
};
struct VendorProductInfo {
uint8_t vendorIdSrc;
uint16_t vendorId;
uint16_t productId;
uint16_t version;
VendorProductInfo()
: vendorIdSrc(
device::BluetoothDevice::VendorIDSource::VENDOR_ID_UNKNOWN),
vendorId(),
productId(),
version() {}
};
class Observer : public base::CheckedObserver {
public:
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
Observer() = default;
~Observer() override = default;
virtual void AdapterAddressChanged(const std::string& address) {}
virtual void DiscoverableChanged(bool discoverable) {}
virtual void AdapterDiscoveringChanged(bool state) {}
virtual void AdapterFoundDevice(const FlossDeviceId& device_found) {}
virtual void AdapterClearedDevice(const FlossDeviceId& device_cleared) {}
virtual void AdapterKeyMissingDevice(const FlossDeviceId& device) {}
virtual void AdapterDevicePropertyChanged(BtPropertyType prop_type,
const FlossDeviceId& device) {}
virtual void AdapterSspRequest(const FlossDeviceId& remote_device,
uint32_t cod,
BluetoothSspVariant variant,
uint32_t passkey) {}
virtual void AdapterPinDisplay(const FlossDeviceId& remote_device,
std::string pincode) {}
virtual void AdapterPinRequest(const FlossDeviceId& remote_device,
uint32_t cod,
bool min_16_digit) {}
virtual void DeviceBondStateChanged(const FlossDeviceId& remote_device,
uint32_t status,
BondState bond_state) {}
virtual void AdapterDeviceConnected(const FlossDeviceId& device) {}
virtual void AdapterDeviceDisconnected(const FlossDeviceId& device) {}
virtual void AdapterDeviceConnectionFailed(const FlossDeviceId& device,
uint32_t status) {}
virtual void SdpSearchComplete(const FlossDeviceId device,
const device::BluetoothUUID uuid,
const std::vector<BtSdpRecord>& records) {}
virtual void SdpRecordCreated(const BtSdpRecord record,
const int32_t handle) {}
};
static const char kErrorUnknownAdapter[];
static std::unique_ptr<FlossAdapterClient> Create();
static bool IsConnectionPaired(uint32_t connection_state);
FlossAdapterClient(const FlossAdapterClient&) = delete;
FlossAdapterClient& operator=(const FlossAdapterClient&) = delete;
FlossAdapterClient();
~FlossAdapterClient() override;
void AddObserver(Observer* observer);
bool HasObserver(Observer* observer);
void RemoveObserver(Observer* observer);
const std::string& GetAddress() const { return property_address_.Get(); }
const std::string& GetName() const { return property_name_.Get(); }
virtual void SetName(ResponseCallback<Void> callback,
const std::string& name);
bool GetDiscoverable() const { return property_discoverable_.Get(); }
virtual void SetDiscoverable(ResponseCallback<Void> callback,
bool discoverable);
virtual void SetDiscoverable(ResponseCallback<Void> callback,
BtDiscoverableMode mode,
uint32_t duration);
uint32_t GetDiscoverableTimeout() const { return discoverable_timeout_; }
bool IsExtAdvSupported() const { return property_ext_adv_supported_.Get(); }
virtual void StartDiscovery(ResponseCallback<Void> callback);
virtual void CancelDiscovery(ResponseCallback<Void> callback);
virtual void CreateBond(ResponseCallback<bool> callback,
FlossDeviceId device,
BluetoothTransport transport);
virtual void CreateBond(
ResponseCallback<FlossDBusClient::BtifStatus> callback,
FlossDeviceId device,
BluetoothTransport transport);
virtual void CancelBondProcess(ResponseCallback<bool> callback,
FlossDeviceId device);
virtual void RemoveBond(ResponseCallback<bool> callback,
FlossDeviceId device);
virtual void GetRemoteType(ResponseCallback<BluetoothDeviceType> callback,
FlossDeviceId device);
virtual void GetRemoteClass(ResponseCallback<uint32_t> callback,
FlossDeviceId device);
virtual void GetRemoteAppearance(ResponseCallback<uint16_t> callback,
FlossDeviceId device);
virtual void GetConnectionState(ResponseCallback<uint32_t> callback,
const FlossDeviceId& device);
virtual void GetRemoteUuids(
ResponseCallback<device::BluetoothDevice::UUIDList> callback,
FlossDeviceId device);
virtual void FetchRemoteUuids(ResponseCallback<bool> callback,
FlossDeviceId device);
virtual void GetRemoteVendorProductInfo(
ResponseCallback<VendorProductInfo> callback,
FlossDeviceId device);
virtual void GetRemoteAddressType(ResponseCallback<BtAddressType> callback,
FlossDeviceId device);
virtual void GetBondState(ResponseCallback<uint32_t> callback,
const FlossDeviceId& device);
virtual void ConnectAllEnabledProfiles(ResponseCallback<Void> callback,
const FlossDeviceId& device);
virtual void ConnectAllEnabledProfiles(
ResponseCallback<FlossDBusClient::BtifStatus> callback,
const FlossDeviceId& device);
virtual void DisconnectAllEnabledProfiles(ResponseCallback<Void> callback,
const FlossDeviceId& device);
virtual void SetPairingConfirmation(ResponseCallback<Void> callback,
const FlossDeviceId& device,
bool accept);
virtual void SetPin(ResponseCallback<Void> callback,
const FlossDeviceId& device,
bool accept,
const std::vector<uint8_t>& pin);
virtual void SetPasskey(ResponseCallback<Void> callback,
const FlossDeviceId& device,
bool accept,
const std::vector<uint8_t>& passkey);
virtual void GetBondedDevices();
virtual void GetConnectedDevices();
virtual void SdpSearch(ResponseCallback<bool> callback,
const FlossDeviceId& device,
device::BluetoothUUID uuid);
virtual void CreateSdpRecord(ResponseCallback<bool> callback,
const BtSdpRecord& record);
virtual void RemoveSdpRecord(ResponseCallback<bool> callback,
const int32_t& handle);
std::vector<BtAdapterRole> GetSupportedRoles() {
return property_roles_.Get();
}
const dbus::ObjectPath* GetObjectPath() const { return &adapter_path_; }
void Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
base::Version version,
base::OnceClosure on_ready) override;
protected:
friend class FlossAdapterClientTest;
void OnAdapterPropertyChanged(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnAddressChanged(const std::string& address);
void OnNameChanged(const std::string& name);
void OnDiscoverableChanged(const bool& discoverable);
void OnDiscoveringChanged(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceFound(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceCleared(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceKeyMissing(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDevicePropertiesChanged(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnSspRequest(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnPinDisplay(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnPinRequest(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnBondStateChanged(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnSdpSearchComplete(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnSdpRecordCreated(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceConnected(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceDisconnected(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnDeviceConnectionFailed(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
void OnGetBondedDevices(DBusResult<std::vector<FlossDeviceId>> ret);
void OnGetConnectedDevices(DBusResult<std::vector<FlossDeviceId>> ret);
void UpdateDiscoverableTimeout();
void OnDiscoverableTimeout(DBusResult<uint32_t> ret);
void OnRegisterCallback(DBusResult<uint32_t> ret);
void OnRegisterConnectionCallback(DBusResult<uint32_t> ret);
void OnUnregisterCallbacks(DBusResult<bool> ret);
base::ObserverList<Observer> observers_;
raw_ptr<dbus::Bus> bus_ = nullptr;
dbus::ObjectPath adapter_path_;
std::string service_name_;
std::string exported_callback_path_;
uint32_t discoverable_timeout_ = 0;
private:
FRIEND_TEST_ALL_PREFIXES(FlossAdapterClientTest, CallAdapterMethods);
template <typename R, typename... Args>
void CallAdapterMethod(ResponseCallback<R> callback,
const char* member,
Args... args) {
CallMethod(std::move(callback), bus_, service_name_, kAdapterInterface,
adapter_path_, member, args...);
}
FlossProperty<std::string> property_address_{
kAdapterInterface, adapter::kCallbackInterface, adapter::kGetAddress,
adapter::kOnAddressChanged};
FlossProperty<std::string> property_name_{
kAdapterInterface, adapter::kCallbackInterface, adapter::kGetName,
adapter::kOnNameChanged};
FlossProperty<bool> property_discoverable_{
kAdapterInterface, adapter::kCallbackInterface, adapter::kGetDiscoverable,
adapter::kOnDiscoverableChanged};
FlossProperty<bool> property_ext_adv_supported_{
kAdapterInterface, adapter::kCallbackInterface,
adapter::kIsLeExtendedAdvertisingSupported, nullptr};
FlossProperty<std::vector<BtAdapterRole>> property_roles_{
kAdapterInterface, adapter::kCallbackInterface,
adapter::kGetSupportedRoles, nullptr};
static const char kExportedCallbacksPath[];
base::OnceClosure on_ready_;
int pending_register_calls_ = 0;
std::optional<uint32_t> callback_id_;
std::optional<uint32_t> connection_callback_id_;
base::WeakPtrFactory<FlossAdapterClient> weak_ptr_factory_{this};
};
}
#endif