1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
|
// 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 DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_ADAPTER_APPLE_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_ADAPTER_APPLE_H_
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/task/single_thread_task_runner.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_export.h"
#include "device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h"
#include "device/bluetooth/bluetooth_low_energy_device_mac.h"
#include "device/bluetooth/bluetooth_low_energy_device_watcher_mac.h"
#include "device/bluetooth/bluetooth_low_energy_discovery_manager_mac.h"
#include "device/bluetooth/public/cpp/bluetooth_uuid.h"
@class CBUUID;
@class BluetoothLowEnergyCentralManagerDelegate;
@class BluetoothLowEnergyPeripheralManagerDelegate;
namespace device {
// BluetoothLowEnergyAdapterApple implements BluetoothAdapter supported with
// CoreBluetooth on Apple devices.
class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyAdapterApple
: public BluetoothAdapter,
public BluetoothLowEnergyDiscoveryManagerMac::Observer {
public:
using DevicesInfo = std::map<std::string, std::string>;
using GetDevicePairedStatusCallback =
base::RepeatingCallback<bool(const std::string& address)>;
BluetoothLowEnergyAdapterApple(const BluetoothLowEnergyAdapterApple&) =
delete;
BluetoothLowEnergyAdapterApple& operator=(
const BluetoothLowEnergyAdapterApple&) = delete;
// Converts CBUUID into BluetoothUUID
static BluetoothUUID BluetoothUUIDWithCBUUID(CBUUID* UUID);
// Converts NSError to string for logging.
static std::string String(NSError* error);
// BluetoothAdapter overrides:
std::string GetAddress() const override;
std::string GetName() 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;
PermissionStatus GetOsPermissionStatus() const override;
void RequestSystemPermission(RequestSystemPermissionCallback) override;
bool IsDiscoverable() const override;
void SetDiscoverable(bool discoverable,
base::OnceClosure callback,
ErrorCallback error_callback) override;
bool IsDiscovering() const override;
void CreateRfcommService(const BluetoothUUID& uuid,
const ServiceOptions& options,
CreateServiceCallback callback,
CreateServiceErrorCallback error_callback) override;
void CreateL2capService(const BluetoothUUID& uuid,
const ServiceOptions& options,
CreateServiceCallback callback,
CreateServiceErrorCallback error_callback) override;
std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
RetrieveGattConnectedDevicesWithDiscoveryFilter(
const BluetoothDiscoveryFilter& discovery_filter) override;
UUIDList GetUUIDs() const override;
void RegisterAdvertisement(
std::unique_ptr<BluetoothAdvertisement::Data> advertisement_data,
CreateAdvertisementCallback callback,
AdvertisementErrorCallback error_callback) override;
DeviceList GetDevices() override;
ConstDeviceList GetDevices() const override;
BluetoothLocalGattService* GetGattService(
const std::string& identifier) const override;
// Creates a GATT connection by calling CoreBluetooth APIs.
void CreateGattConnection(BluetoothLowEnergyDeviceMac* device_mac);
// Closes the GATT connection by calling CoreBluetooth APIs.
void DisconnectGatt(BluetoothLowEnergyDeviceMac* device_mac);
// Methods called from CBCentralManager delegate.
void DidConnectPeripheral(CBPeripheral* peripheral);
void DidFailToConnectPeripheral(CBPeripheral* peripheral, NSError* error);
void DidDisconnectPeripheral(CBPeripheral* peripheral, NSError* error);
void UpdateKnownLowEnergyDevices(DevicesInfo updated_low_energy_device_info);
// Returns true when `device_identifier` is found in
// `low_energy_devices_info_`. If the framework supports the paired status, it
// calls GetDevicePairedStatusCallback to check the status of the device.
bool IsBluetoothLowEnergyDeviceSystemPaired(
std::string_view device_identifier) const;
protected:
BluetoothLowEnergyAdapterApple();
~BluetoothLowEnergyAdapterApple() override;
virtual void LazyInitialize();
virtual void InitForTest(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
virtual GetDevicePairedStatusCallback GetDevicePairedStatus() const;
virtual base::WeakPtr<BluetoothLowEnergyAdapterApple>
GetLowEnergyWeakPtr() = 0;
virtual void TriggerSystemPermissionPrompt() = 0;
// BluetoothAdapter override:
bool SetPoweredImpl(bool powered) override;
void RemovePairingDelegateInternal(
device::BluetoothDevice::PairingDelegate* pairing_delegate) override;
// Returns the CBCentralManager instance.
CBCentralManager* GetCentralManager();
// Returns the CBPeripheralManager instance.
CBPeripheralManager* GetPeripheralManager();
// Checks if the low energy central manager is powered on. Returns false if
// BLE is not available.
bool IsLowEnergyPowered() const;
// Starts a low energy discovery session or update it if one is already
// running.
void StartScanLowEnergy();
// Stops discovery and clears all advertisement data.
void StopScanLowEnergy();
// The Initialize() method intentionally does not initialize
// |low_energy_central_manager_| or |low_energy_peripheral_manager_| because
// Chromium might not have permission to access the Bluetooth adapter.
// Methods which require these to be initialized must call LazyInitialize()
// first.
bool lazy_initialized_ = false;
private:
friend class BluetoothTestMac;
friend class BluetoothLowEnergyAdapterAppleTest;
friend class BluetoothLowEnergyCentralManagerBridge;
friend class BluetoothLowEnergyPeripheralManagerBridge;
// BluetoothAdapter overrides:
void StartScanWithFilter(
std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
DiscoverySessionResultCallback callback) override;
void UpdateFilter(
std::unique_ptr<device::BluetoothDiscoveryFilter> discovery_filter,
DiscoverySessionResultCallback callback) override;
void StopScan(DiscoverySessionResultCallback callback) override;
void Initialize(base::OnceClosure callback) override;
// BluetoothLowEnergyDiscoveryManagerMac::Observer override:
void LowEnergyDeviceUpdated(CBPeripheral* peripheral,
NSDictionary* advertisement_data,
int rssi) override;
// Updates |devices_| when there is a change to the CBCentralManager's state.
void LowEnergyCentralManagerUpdatedState();
// Resets |low_energy_central_manager_| to |central_manager| and sets
// |low_energy_central_manager_delegate_| as the manager's delegate. Should
// be called only when |IsLowEnergyAvailable()|.
void SetCentralManagerForTesting(CBCentralManager* central_manager);
// Allow the mocking out of BluetoothLowEnergyDeviceWatcher for testing.
void SetLowEnergyDeviceWatcherForTesting(
scoped_refptr<BluetoothLowEnergyDeviceWatcherMac> watcher);
// Returns the list of devices that are connected by other applications than
// Chromium, based on a service UUID. If no uuid is given, generic access
// service (1800) is used (since CoreBluetooth requires to use a service).
std::vector<BluetoothDevice*> RetrieveGattConnectedDevicesWithService(
const BluetoothUUID* uuid);
// Returns the BLE device associated with the CoreBluetooth peripheral.
BluetoothLowEnergyDeviceMac* GetBluetoothLowEnergyDeviceMac(
CBPeripheral* peripheral);
// Returns true if a new device collides with an existing device.
bool DoesCollideWithKnownDevice(CBPeripheral* peripheral,
BluetoothLowEnergyDeviceMac* device_mac);
void FlushRequestSystemPermissionCallbacks();
// Discovery manager for Bluetooth Low Energy.
std::unique_ptr<BluetoothLowEnergyDiscoveryManagerMac>
low_energy_discovery_manager_;
// Advertisement manager for Bluetooth Low Energy.
std::unique_ptr<BluetoothLowEnergyAdvertisementManagerMac>
low_energy_advertisement_manager_;
// Underlying CoreBluetooth CBCentralManager and its delegate.
CBCentralManager* __strong low_energy_central_manager_;
BluetoothLowEnergyCentralManagerDelegate* __strong
low_energy_central_manager_delegate_;
// Underlying CoreBluetooth CBPeripheralManager and its delegate.
CBPeripheralManager* __strong low_energy_peripheral_manager_;
BluetoothLowEnergyPeripheralManagerDelegate* __strong
low_energy_peripheral_manager_delegate_;
// Watches system file /Library/Preferences/com.apple.Bluetooth.plist to
// obtain information about system paired bluetooth devices.
scoped_refptr<BluetoothLowEnergyDeviceWatcherMac>
bluetooth_low_energy_device_watcher_;
// Map of UUID formatted device identifiers of paired Bluetooth devices and
// corresponding device address.
DevicesInfo low_energy_devices_info_;
// Callbacks from `RequestSystemPermission` will be called once the Bluetooth
// system permission has settled.
std::vector<BluetoothAdapter::RequestSystemPermissionCallback>
request_system_permission_callbacks_;
};
} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_LOW_ENERGY_ADAPTER_APPLE_H_
|