blob: b1f8e2f4f086bc0993fb384e12038b6cb44918f3 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_ADAPTER_FLOSS_H_
#define DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_ADAPTER_FLOSS_H_
#include <cstdint>
#include <string>
#include <unordered_map>
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "build/chromeos_buildflags.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/floss/bluetooth_low_energy_scan_session_floss.h"
#include "device/bluetooth/floss/bluetooth_socket_floss.h"
#include "device/bluetooth/floss/floss_adapter_client.h"
#include "device/bluetooth/floss/floss_battery_manager_client.h"
#include "device/bluetooth/floss/floss_dbus_client.h"
#include "device/bluetooth/floss/floss_gatt_manager_client.h"
#include "device/bluetooth/floss/floss_lescan_client.h"
#include "device/bluetooth/floss/floss_manager_client.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
#include "device/bluetooth/floss/floss_admin_client.h"
#endif // BUILDFLAG(IS_CHROMEOS)
namespace floss {
class BluetoothDeviceFloss;
class BluetoothAdvertisementFloss;
class BluetoothLocalGattServiceFloss;
class BluetoothLocalGattCharacteristicFloss;
// The BluetoothAdapterFloss class implements BluetoothAdapter for platforms
// that use Floss, a dbus front-end for the Fluoride Bluetooth stack.
//
// Floss separates the "Powered" management of adapters in a separate manager
// interface. This class will first initialize the manager interface before
// initializing any clients that depend on a specific adapter being targeted.
class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterFloss final
: public device::BluetoothAdapter,
public floss::FlossManagerClient::Observer,
public floss::FlossAdapterClient::Observer,
public floss::FlossBatteryManagerClient::
FlossBatteryManagerClientObserver,
public floss::FlossGattManagerClient::FlossGattServerObserver,
#if BUILDFLAG(IS_CHROMEOS)
public FlossAdminClientObserver,
#endif // BUILDFLAG(IS_CHROMEOS)
public ScannerClientObserver {
public:
static scoped_refptr<BluetoothAdapterFloss> CreateAdapter();
BluetoothAdapterFloss(const BluetoothAdapterFloss&) = delete;
BluetoothAdapterFloss& operator=(const BluetoothAdapterFloss&) = delete;
// BluetoothAdapter:
void Initialize(base::OnceClosure callback) override;
void Shutdown() override;
UUIDList GetUUIDs() const override;
std::string GetAddress() const override;
std::string GetName() const override;
std::string GetSystemName() const override;
void SetName(const std::string& name,
base::OnceClosure callback,
ErrorCallback error_callback) override;
bool IsInitialized() const override;
bool IsPresent() const override;
bool IsPowered() const override;
void SetPowered(bool powered,
base::OnceClosure callback,
ErrorCallback error_callback) override;
bool IsDiscoverable() const override;
void SetDiscoverable(bool discoverable,
base::OnceClosure callback,
ErrorCallback error_callback) override;
base::TimeDelta GetDiscoverableTimeout() const override;
bool IsDiscovering() const override;
std::unordered_map<device::BluetoothDevice*, device::BluetoothDevice::UUIDSet>
RetrieveGattConnectedDevicesWithDiscoveryFilter(
const device::BluetoothDiscoveryFilter& discovery_filter) override;
void CreateRfcommService(const device::BluetoothUUID& uuid,
const ServiceOptions& options,
CreateServiceCallback callback,
CreateServiceErrorCallback error_callback) override;
void CreateL2capService(const device::BluetoothUUID& uuid,
const ServiceOptions& options,
CreateServiceCallback callback,
CreateServiceErrorCallback error_callback) override;
// Intercept errors when creating an RFCOMM or L2CAP service. This keeps
// a reference to the |socket| so that it does not go out of scope until after
// the error is completed.
void OnCreateServiceError(scoped_refptr<BluetoothSocketFloss> socket,
CreateServiceErrorCallback error_callback,
const std::string& error_message);
void RegisterAdvertisement(
std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
CreateAdvertisementCallback callback,
AdvertisementErrorCallback error_callback) override;
void SetAdvertisingInterval(
const base::TimeDelta& min,
const base::TimeDelta& max,
base::OnceClosure callback,
AdvertisementErrorCallback error_callback) override;
void ResetAdvertising(base::OnceClosure callback,
AdvertisementErrorCallback error_callback) override;
void ConnectDevice(
const std::string& address,
const absl::optional<device::BluetoothDevice::AddressType>& address_type,
ConnectDeviceCallback callback,
ConnectDeviceErrorCallback error_callback) override;
device::BluetoothLocalGattService* GetGattService(
const std::string& identifier) const override;
// Register a GATT service. The service must belong to this adapter.
void RegisterGattService(BluetoothLocalGattServiceFloss* service);
// Gatt service added dbus hook.
void OnGattServiceAdded(BluetoothLocalGattServiceFloss* service,
DBusResult<Void> ret);
// Unregister a GATT service. The service must already be registered.
void UnregisterGattService(BluetoothLocalGattServiceFloss* service);
// Gatt service removed dbus hook.
void OnGattServiceRemoved(BluetoothLocalGattServiceFloss* service,
DBusResult<Void> ret);
void AddLocalGattService(
std::unique_ptr<BluetoothLocalGattServiceFloss> service);
void RemoveLocalGattService(BluetoothLocalGattServiceFloss* service);
// Returns if a given service is currently registered.
bool IsGattServiceRegistered(BluetoothLocalGattServiceFloss* service);
// Send a notification for this characteristic that its value has been
// updated. If the service that owns that characteristic is not registered,
// this method will return false.
bool SendValueChanged(BluetoothLocalGattCharacteristicFloss* characteristic,
const std::vector<uint8_t>& value);
// FlossGattServerObserver overrides
void GattServerNotificationSent(std::string address,
GattStatus status) override;
#if BUILDFLAG(IS_CHROMEOS)
void SetServiceAllowList(const UUIDList& uuids,
base::OnceClosure callback,
ErrorCallback error_callback) override;
LowEnergyScanSessionHardwareOffloadingStatus
GetLowEnergyScanSessionHardwareOffloadingStatus() override;
std::unique_ptr<device::BluetoothLowEnergyScanSession>
StartLowEnergyScanSession(
std::unique_ptr<device::BluetoothLowEnergyScanFilter> filter,
base::WeakPtr<device::BluetoothLowEnergyScanSession::Delegate> delegate)
override;
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Set the adapter name to one chosen from the system information. Only Ash
// needs to do this.
void SetStandardChromeOSAdapterName() override;
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// ScannerClientObserver overrides
void ScannerRegistered(device::BluetoothUUID uuid,
uint8_t scanner_id,
GattStatus status) override;
void ScanResultReceived(ScanResult scan_result) override;
void AdvertisementFound(uint8_t scanner_id, ScanResult scan_result) override;
void AdvertisementLost(uint8_t scanner_id, ScanResult scan_result) override;
protected:
// BluetoothAdapter:
void RemovePairingDelegateInternal(
device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
private:
BluetoothAdapterFloss();
~BluetoothAdapterFloss() override;
// Init will get asynchronouly called once we know if Object Manager is
// supported.
void Init();
void NotifyDeviceFound(uint8_t scanner_id, const std::string& address);
BluetoothDeviceFloss* CreateOrGetDeviceForUpdate(const std::string& address,
const std::string& name);
// Helper function to create a Floss device
std::unique_ptr<BluetoothDeviceFloss> CreateBluetoothDeviceFloss(
FlossDeviceId device);
// Helper function to update device properties if necessary
void UpdateDeviceProperties(bool is_triggered_by_inquiry,
const FlossDeviceId& device_found);
// Handle responses to most method calls
void OnMethodResponse(base::OnceClosure callback,
ErrorCallback error_callback,
DBusResult<Void> ret);
// Handle when discovery is automatically repeated based on active sessions.
void OnRepeatedDiscoverySessionResult(
bool start_discovery,
bool is_error,
device::UMABluetoothDiscoverySessionOutcome outcome);
// Called on completion of start discovery and stop discovery
void OnStartDiscovery(DiscoverySessionResultCallback callback,
DBusResult<Void> ret);
void OnStopDiscovery(DiscoverySessionResultCallback callback,
DBusResult<Void> ret);
// Called when all device properties have been initialized
void OnInitializeDeviceProperties(BluetoothDeviceFloss* device_ptr);
void OnGetConnectionState(const FlossDeviceId& device_id,
DBusResult<uint32_t> ret);
void OnGetBondState(const FlossDeviceId& device_id, DBusResult<uint32_t> ret);
// Announce to observers a change in the adapter state.
void DiscoveringChanged(bool discovering);
void PresentChanged(bool present);
void NotifyAdapterPoweredChanged(bool powered);
// Announce to observers that |device| has changed its connected state.
void NotifyDeviceConnectedStateChanged(BluetoothDeviceFloss* device,
bool is_now_connected);
// Observers
// floss::FlossManagerClient::Observer override.
void AdapterPresent(int adapter, bool present) override;
void AdapterEnabledChanged(int adapter, bool enabled) override;
// Complete adapter power changes after adapter clients are ready.
void OnAdapterClientsReady(bool enabled);
// Initialize observers for adapter dependent clients. We need to add + remove
// these observers whenever we get a powered notification.
void AddAdapterObservers();
void RemoveAdapterObservers();
// Remove any active adapters.
void RemoveAdapter();
void PopulateInitialDevices();
void ClearAllDevices();
// floss::FlossAdapterClient::Observer override.
void DiscoverableChanged(bool discoverable) override;
void AdapterDiscoveringChanged(bool state) override;
void AdapterFoundDevice(const FlossDeviceId& device_found) override;
void AdapterClearedDevice(const FlossDeviceId& device_found) override;
void AdapterSspRequest(const FlossDeviceId& remote_device,
uint32_t cod,
FlossAdapterClient::BluetoothSspVariant variant,
uint32_t passkey) override;
void DeviceBondStateChanged(
const FlossDeviceId& remote_device,
uint32_t status,
FlossAdapterClient::BondState bond_state) override;
void AdapterDeviceConnected(const FlossDeviceId& device_id) override;
void AdapterDeviceDisconnected(const FlossDeviceId& device_id) override;
// floss::FlossBatteryManagerClient::FlossBatteryManagerClientObserver
// override.
void BatteryInfoUpdated(std::string remote_address,
BatterySet battery_set) override;
#if BUILDFLAG(IS_CHROMEOS)
// floss::FlossAdminClientObserver override.
void DevicePolicyEffectChanged(
const FlossDeviceId& device_id,
const absl::optional<PolicyEffect>& effect) override;
void ServiceAllowlistChanged(
const std::vector<device::BluetoothUUID>& allowlist) override;
#endif // BUILDFLAG(IS_CHROMEOS)
// BluetoothAdapter:
base::WeakPtr<BluetoothAdapter> GetWeakPtr() override;
bool SetPoweredImpl(bool powered) override;
void StartScanWithFilter(
std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
DiscoverySessionResultCallback callback) override;
void UpdateFilter(
std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
DiscoverySessionResultCallback callback) override;
void StopScan(DiscoverySessionResultCallback callback) override;
void OnRegisterScanner(
base::WeakPtr<BluetoothLowEnergyScanSessionFloss> scan_session,
DBusResult<device::BluetoothUUID> ret);
void OnStartScan(device::BluetoothUUID uuid,
uint8_t scanner_id,
DBusResult<FlossDBusClient::BtifStatus> ret);
void OnLowEnergyScanSessionDestroyed(const std::string& uuid_str);
void OnUnregisterScanner(uint8_t scanner_id, DBusResult<bool> ret);
std::map<device::BluetoothUUID,
base::WeakPtr<BluetoothLowEnergyScanSessionFloss>>
scanners_;
base::OnceClosure init_callback_;
// Keeps track of whether the adapter is fully initialized.
bool initialized_ = false;
// Keeps track of whether Shutdown is called (and dbus clients are cleaned
// up properly).
bool dbus_is_shutdown_ = false;
// Socket thread object used to create sockets. Public socket apis are run on
// the ui thread but socket operations (including connect/disconnect) will be
// run in this thread. See |BluetoothSocketNet| for more details.
scoped_refptr<device::BluetoothSocketThread> socket_thread_;
// List of advertisements registered with this adapter. This list is used
// to ensure we unregister any advertisements that were registered with
// this adapter on adapter shutdown. This is a sub-optimal solution since
// we'll keep a list of all advertisements ever created by this adapter (the
// unregistered ones will just be inactive). This will be fixed with
// crbug.com/687396.
std::vector<scoped_refptr<BluetoothAdvertisementFloss>> advertisements_;
// While we are doing discovery, we will also maintain a separate LE scan
// session to respond on the current discovery session.
std::unique_ptr<device::BluetoothLowEnergyScanSession> le_discovery_session_ =
nullptr;
// Delegate for forwarding scan session notifications.
std::unique_ptr<device::BluetoothLowEnergyScanSession::Delegate>
le_discovery_session_delegate_;
// Default BLE advertising interval.
// 100 ms is one of the recommended values on Floss AdvertisingSetParameters.
// b/253718595 will provide a 'no preference' option so that Floss can choose
// a default value for the advertising interval.
uint16_t interval_ms_ = 100;
// List of GATT services that are owned by this adapter.
base::flat_map<std::string, std::unique_ptr<BluetoothLocalGattServiceFloss>>
owned_gatt_services_;
base::WeakPtrFactory<BluetoothAdapterFloss> weak_ptr_factory_{this};
};
} // namespace floss
#endif // DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_ADAPTER_FLOSS_H_