123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
- #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
- #include <stdint.h>
- #include <list>
- #include <memory>
- #include <set>
- #include <string>
- #include <unordered_map>
- #include <utility>
- #include <vector>
- #include "base/callback.h"
- #include "base/containers/queue.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "base/time/time.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "device/bluetooth/bluetooth_advertisement.h"
- #include "device/bluetooth/bluetooth_device.h"
- #include "device/bluetooth/bluetooth_discovery_filter.h"
- #include "device/bluetooth/bluetooth_export.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #if BUILDFLAG(IS_CHROMEOS)
- #include "device/bluetooth/bluetooth_low_energy_scan_session.h"
- #endif // BUILDFLAG(IS_CHROMEOS)
- namespace base {
- class SingleThreadTaskRunner;
- } // namespace base
- namespace device {
- class BluetoothAdvertisement;
- class BluetoothDiscoveryFilter;
- class BluetoothDiscoverySession;
- class BluetoothLocalGattService;
- #if BUILDFLAG(IS_CHROMEOS)
- class BluetoothLowEnergyScanFilter;
- #endif // BUILDFLAG(IS_CHROMEOS)
- class BluetoothRemoteGattCharacteristic;
- class BluetoothRemoteGattDescriptor;
- class BluetoothRemoteGattService;
- class BluetoothSocket;
- class BluetoothUUID;
- enum class UMABluetoothDiscoverySessionOutcome;
- // BluetoothAdapter represents a local Bluetooth adapter which may be used to
- // interact with remote Bluetooth devices. As well as providing support for
- // determining whether an adapter is present and whether the radio is powered,
- // this class also provides support for obtaining the list of remote devices
- // known to the adapter, discovering new devices, and providing notification of
- // updates to device information.
- class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
- : public base::RefCounted<BluetoothAdapter> {
- public:
- #if BUILDFLAG(IS_CHROMEOS)
- enum class LowEnergyScanSessionHardwareOffloadingStatus {
- kUndetermined = 0,
- kNotSupported,
- kSupported
- };
- #endif // BUILDFLAG(IS_CHROMEOS)
- // Interface for observing changes from bluetooth adapters.
- class DEVICE_BLUETOOTH_EXPORT Observer {
- public:
- virtual ~Observer() {}
- // Called when the presence of the adapter |adapter| changes. When |present|
- // is true the adapter is now present, false means the adapter has been
- // removed from the system.
- virtual void AdapterPresentChanged(BluetoothAdapter* adapter,
- bool present) {}
- // Called when the radio power state of the adapter |adapter| changes. When
- // |powered| is true the adapter radio is powered, false means the adapter
- // radio is off.
- virtual void AdapterPoweredChanged(BluetoothAdapter* adapter,
- bool powered) {}
- // Called when the discoverability state of the adapter |adapter| changes.
- // When |discoverable| is true the adapter is discoverable by other devices,
- // false means the adapter is not discoverable.
- virtual void AdapterDiscoverableChanged(BluetoothAdapter* adapter,
- bool discoverable) {}
- // Called when the discovering state of the adapter |adapter| changes. When
- // |discovering| is true the adapter is seeking new devices, false means it
- // is not.
- virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter,
- bool discovering) {}
- // Called when a new device |device| is added to the adapter |adapter|,
- // either because it has been discovered or a connection made. |device|
- // should not be cached. Instead, copy its Bluetooth address.
- virtual void DeviceAdded(BluetoothAdapter* adapter,
- BluetoothDevice* device) {}
- // Called when the adapter |DiscoveryChangeComplete| is finished
- virtual void DiscoveryChangeCompletedForTesting() {}
- // Called when the result of one of the following methods of the device
- // |device| changes:
- // * GetAddress()
- // * GetAppearance()
- // * GetName() (Chrome OS and Windows only)
- // * GetBluetoothClass()
- // * GetInquiryRSSI()
- // * GetInquiryTxPower()
- // * GetUUIDs()
- // * GetServiceData()
- // * GetServiceDataUUIDs()
- // * GetServiceDataForUUID()
- // * GetManufacturerData()
- // * GetManufacturerDataIDs()
- // * GetManufacturerDataForID()
- // * GetAdvertisingDataFlags()
- // * IsConnectable()
- // * IsConnected()
- // * IsConnecting()
- // * IsGattConnected()
- // * IsPaired()
- //
- // On Android and MacOS this method is called for each advertisement packet
- // received. On Chrome OS and Linux, we can't guarantee that this method
- // will be called for each Adv. Packet received but, because the RSSI is
- // always changing, it's very likely this method will be called for each
- // Adv. Packet.
- // |device| should not be cached. Instead, copy its Bluetooth address.
- virtual void DeviceChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device) {}
- // Called when address property of the device |device| known to the adapter
- // |adapter| change due to pairing.
- virtual void DeviceAddressChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- const std::string& old_address) {}
- // Called when advertisement is received.
- //
- // Override this function to observe LE advertisements. This function
- // returns the raw values that have been parsed from EIR.
- virtual void DeviceAdvertisementReceived(
- const std::string& device_address,
- const absl::optional<std::string>& device_name,
- const absl::optional<std::string>& advertisement_name,
- absl::optional<int8_t> rssi,
- absl::optional<int8_t> tx_power,
- absl::optional<uint16_t> appearance,
- const BluetoothDevice::UUIDList& advertised_uuids,
- const BluetoothDevice::ServiceDataMap& service_data_map,
- const BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) {}
- #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
- // Called when paired property of the device |device| known to the adapter
- // |adapter| changed.
- virtual void DevicePairedChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- bool new_paired_status) {}
- // Called when the MTU |mtu| (Bluetooth Spec Vol 3, Part F, 3.4.2) used in
- // ATT communication with device |device| known to the adapter |adapter|
- // changed.
- virtual void DeviceMTUChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- uint16_t mtu) {}
- // Called when advertisement is received from |device|. |eir| is the
- // extended inquiry response specified in Bluetooth Core Spec, Vol 3,
- // Part C, Section 11.
- //
- // Override this function to observe LE advertisements. Whenever |rssi| of
- // |device| changes, this function is called with the latest |eir| from
- // |device|. This function is never called on classic |device|.
- virtual void DeviceAdvertisementReceived(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- int16_t rssi,
- const std::vector<uint8_t>& eir) {}
- // Called when |device|'s state has changed from connected to not connected
- // or vice versa.
- virtual void DeviceConnectedStateChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- bool is_now_connected) {}
- // Called when blocked by policy property of the |device| known to the
- // |adapter| changes.
- virtual void DeviceBlockedByPolicyChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- bool new_blocked_status) {}
- #endif
- #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
- // Called when the device battery info with |type| has been updated.
- virtual void DeviceBatteryChanged(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- BluetoothDevice::BatteryType type) {}
- #endif
- // Called when the device |device| is removed from the adapter |adapter|,
- // either as a result of a discovered device being lost between discovering
- // phases or pairing information deleted. |device| should not be
- // cached. Instead, copy its Bluetooth address.
- virtual void DeviceRemoved(BluetoothAdapter* adapter,
- BluetoothDevice* device) {}
- // Deprecated GATT Added/Removed Events NOTE:
- //
- // The series of Observer methods for Service, Characteristic, & Descriptor
- // Added/Removed events should be removed. They are rarely used and add
- // API & implementation complexity. They are not reliable for cross
- // platform use, and devices that modify their attribute table have not been
- // tested or supported.
- //
- // New code should use Observer::GattServicesDiscovered and then call
- // GetGattService(s)
- // GetCharacteristic(s)
- // GetDescriptor(s)
- //
- // TODO(710352): Remove Service, Characteristic, & Descriptor Added/Removed.
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when a new GATT service |service| is added to the device |device|,
- // as the service is received from the device. Don't cache |service|. Store
- // its identifier instead (i.e. BluetoothRemoteGattService::GetIdentifier).
- virtual void GattServiceAdded(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- BluetoothRemoteGattService* service) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when the GATT service |service| is removed from the device
- // |device|. This can happen if the attribute database of the remote device
- // changes or when |device| gets removed.
- virtual void GattServiceRemoved(BluetoothAdapter* adapter,
- BluetoothDevice* device,
- BluetoothRemoteGattService* service) {}
- // Called when the GATT discovery process has completed for all services,
- // characteristics, and descriptors in |device|.
- virtual void GattServicesDiscovered(BluetoothAdapter* adapter,
- BluetoothDevice* device) {}
- // TODO(782494): Deprecated & not functional on all platforms. Use
- // GattServicesDiscovered.
- //
- // Called when all characteristic and descriptor discovery procedures are
- // known to be completed for the GATT service |service|. This method will be
- // called after the initial discovery of a GATT service and will usually be
- // preceded by calls to GattCharacteristicAdded and GattDescriptorAdded.
- virtual void GattDiscoveryCompleteForService(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattService* service) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when properties of the remote GATT service |service| have changed.
- // This will get called for properties such as UUID, as well as for changes
- // to the list of known characteristics and included services. Observers
- // should read all GATT characteristic and descriptors objects and do any
- // necessary set up required for a changed service.
- virtual void GattServiceChanged(BluetoothAdapter* adapter,
- BluetoothRemoteGattService* service) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when the remote GATT characteristic |characteristic| has been
- // discovered. Use this to issue any initial read/write requests to the
- // characteristic but don't cache the pointer as it may become invalid.
- // Instead, use the specially assigned identifier to obtain a characteristic
- // and cache that identifier as necessary, as it can be used to retrieve the
- // characteristic from its GATT service. The number of characteristics with
- // the same UUID belonging to a service depends on the particular profile
- // the remote device implements, hence the client of a GATT based profile
- // will usually operate on the whole set of characteristics and not just
- // one.
- virtual void GattCharacteristicAdded(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattCharacteristic* characteristic) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when a GATT characteristic |characteristic| has been removed from
- // the system.
- virtual void GattCharacteristicRemoved(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattCharacteristic* characteristic) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when the remote GATT characteristic descriptor |descriptor| has
- // been discovered. Don't cache the arguments as the pointers may become
- // invalid. Instead, use the specially assigned identifier to obtain a
- // descriptor and cache that identifier as necessary.
- virtual void GattDescriptorAdded(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattDescriptor* descriptor) {}
- // See "Deprecated GATT Added/Removed Events NOTE" above.
- //
- // Called when a GATT characteristic descriptor |descriptor| has been
- // removed from the system.
- virtual void GattDescriptorRemoved(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattDescriptor* descriptor) {}
- // Called when the value of a characteristic has changed. This might be a
- // result of a read/write request to, or a notification/indication from, a
- // remote GATT characteristic.
- virtual void GattCharacteristicValueChanged(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattCharacteristic* characteristic,
- const std::vector<uint8_t>& value) {}
- // Called when the value of a characteristic descriptor has been updated.
- virtual void GattDescriptorValueChanged(
- BluetoothAdapter* adapter,
- BluetoothRemoteGattDescriptor* descriptor,
- const std::vector<uint8_t>& value) {}
- #if BUILDFLAG(IS_CHROMEOS)
- // Called when the low energy scanning hardware offloading support state
- // changes.
- virtual void LowEnergyScanSessionHardwareOffloadingStatusChanged(
- LowEnergyScanSessionHardwareOffloadingStatus status) {}
- #endif // BUILDFLAG(IS_CHROMEOS)
- };
- // Used to configure a listening service.
- struct DEVICE_BLUETOOTH_EXPORT ServiceOptions {
- ServiceOptions();
- ~ServiceOptions();
- absl::optional<int> channel;
- absl::optional<int> psm;
- absl::optional<std::string> name;
- // Clients can configure this option to choose if they want to enforce
- // bonding with remote devices that connect to this device. Options:
- // * Unset: bonding is not enforced by the local device, and the remote
- // device can choose if they want to enforce bonding.
- // * Set to false: bonding is prevented by the local device. Clients which
- // use this are responsible for securing their communication at the
- // application level.
- // * Set to true: bonding is enforced by the local device.
- absl::optional<bool> require_authentication;
- };
- // The ErrorCallback is used for methods that can fail in which case it is
- // called, in the success case the callback is simply not called.
- using ErrorCallback = base::OnceClosure;
- using DiscoverySessionCallback =
- base::OnceCallback<void(std::unique_ptr<BluetoothDiscoverySession>)>;
- using DeviceList = std::vector<BluetoothDevice*>;
- using ConstDeviceList = std::vector<const BluetoothDevice*>;
- using UUIDList = std::vector<BluetoothUUID>;
- using CreateServiceCallback =
- base::OnceCallback<void(scoped_refptr<BluetoothSocket>)>;
- using CreateServiceErrorCallback =
- base::OnceCallback<void(const std::string& message)>;
- using CreateAdvertisementCallback =
- base::OnceCallback<void(scoped_refptr<BluetoothAdvertisement>)>;
- using AdvertisementErrorCallback = BluetoothAdvertisement::ErrorCallback;
- using ConnectDeviceCallback = base::OnceCallback<void(BluetoothDevice*)>;
- using DiscoverySessionErrorCallback =
- base::OnceCallback<void(UMABluetoothDiscoverySessionOutcome)>;
- // The is_error bool is a flag to indicate if the result is an error(true)
- // or a success(false)
- // The Session Outcome is the result which could be success or some sort of
- // error. However, this variable is ignored when the bool is false
- using DiscoverySessionResultCallback =
- base::OnceCallback<void(/*is_error*/ bool,
- UMABluetoothDiscoverySessionOutcome)>;
- enum class DiscoveryState {
- kStarting = 0,
- kStopping,
- kDiscovering,
- kIdle,
- };
- enum class PermissionStatus { kUndetermined = 0, kDenied, kAllowed };
- // Creates a new adapter. Initialize() must be called before the adapter can
- // be used.
- static scoped_refptr<BluetoothAdapter> CreateAdapter();
- virtual void Initialize(base::OnceClosure callback) = 0;
- // Returns a weak pointer to an existing adapter for testing purposes only.
- base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting();
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- // Shutdown the adapter: tear down and clean up all objects owned by
- // BluetoothAdapter. After this call, the BluetoothAdapter will behave as if
- // no Bluetooth controller exists in the local system. |IsPresent| will return
- // false.
- virtual void Shutdown();
- #endif
- // Adds and removes observers for events on this bluetooth adapter. If
- // monitoring multiple adapters, check the |adapter| parameter of observer
- // methods to determine which adapter is issuing the event.
- virtual void AddObserver(BluetoothAdapter::Observer* observer);
- virtual void RemoveObserver(BluetoothAdapter::Observer* observer);
- virtual bool HasObserver(BluetoothAdapter::Observer* observer);
- // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX",
- // where each XX is a hexadecimal number.
- virtual std::string GetAddress() const = 0;
- // The name of the adapter.
- virtual std::string GetName() const = 0;
- // The Bluetooth system name. Implementations may return an informational name
- // "BlueZ 5.54" on Chrome OS.
- virtual std::string GetSystemName() const;
- // Set the human-readable name of the adapter to |name|. On success,
- // |callback| will be called. On failure, |error_callback| will be called.
- // TODO(crbug.com/1117654): Implement a mechanism to request this resource
- // before being able to use it.
- virtual void SetName(const std::string& name,
- base::OnceClosure callback,
- ErrorCallback error_callback) = 0;
- // Indicates whether the adapter is initialized and ready to use.
- virtual bool IsInitialized() const = 0;
- // Indicates whether the adapter is actually present on the system. For the
- // default adapter, this indicates whether any adapter is present. An adapter
- // is only considered present if the address has been obtained.
- virtual bool IsPresent() const = 0;
- // Indicates whether the adapter radio can be powered. Defaults to
- // IsPresent(). Currently only overridden on Windows, where the adapter can be
- // present, but we might fail to get access to the underlying radio.
- virtual bool CanPower() const;
- // Indicates whether the adapter radio is powered.
- virtual bool IsPowered() const = 0;
- // Returns the status of the browser's Bluetooth permission status.
- virtual PermissionStatus GetOsPermissionStatus() const;
- // Requests a change to the adapter radio power. Setting |powered| to true
- // will turn on the radio and false will turn it off. On success, |callback|
- // will be called. On failure, |error_callback| will be called.
- //
- // The default implementation is meant for platforms that don't have a
- // callback based API. It will store pending callbacks in
- // |set_powered_callbacks_| and invoke SetPoweredImpl(bool) which these
- // platforms need to implement. Pending callbacks are only run when
- // RunPendingPowerCallbacks() is invoked.
- //
- // Platforms that natively support a callback based API (e.g. BlueZ and Win)
- // should override this method and provide their own implementation instead.
- //
- // Due to an issue with non-native APIs on Windows 10, both IsPowered() and
- // SetPowered() don't work correctly when run from a x86 Chrome on a x64 CPU.
- // See https://github.com/Microsoft/cppwinrt/issues/47 for more details.
- virtual void SetPowered(bool powered,
- base::OnceClosure callback,
- ErrorCallback error_callback);
- // Indicates whether the adapter support the LowEnergy peripheral role.
- virtual bool IsPeripheralRoleSupported() const;
- // Indicates whether the adapter radio is discoverable.
- virtual bool IsDiscoverable() const = 0;
- // Requests that the adapter change its discoverability state. If
- // |discoverable| is true, then it will be discoverable by other Bluetooth
- // devices. On successfully changing the adapter's discoverability, |callback|
- // will be called. On failure, |error_callback| will be called.
- virtual void SetDiscoverable(bool discoverable,
- base::OnceClosure callback,
- ErrorCallback error_callback) = 0;
- // Indicates whether the adapter is currently discovering new devices.
- virtual bool IsDiscovering() const = 0;
- // Inserts all the devices that are connected by the operating system, and not
- // being connected by Chromium, into |devices_|. This method is useful since
- // a discovery session cannot find devices that are already connected to the
- // computer.
- // TODO(crbug.com/653032): Needs to be implemented for Android and Windows.
- virtual std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
- RetrieveGattConnectedDevicesWithDiscoveryFilter(
- const BluetoothDiscoveryFilter& discovery_filter);
- // Requests the adapter to start a new discovery session. On success, a new
- // instance of BluetoothDiscoverySession will be returned to the caller via
- // |callback| and the adapter will be discovering nearby Bluetooth devices.
- // The returned BluetoothDiscoverySession is owned by the caller and it's the
- // owner's responsibility to properly clean it up and stop the session when
- // device discovery is no longer needed.
- //
- // If clients desire device discovery to run, they should always call this
- // method and never make it conditional on the value of IsDiscovering(), as
- // another client might cause discovery to stop unexpectedly. Hence, clients
- // should always obtain a BluetoothDiscoverySession and call
- // BluetoothDiscoverySession::Stop when done. When this method gets called,
- // device discovery may actually be in progress. Clients can call GetDevices()
- // and check for those with IsPaired() as false to obtain the list of devices
- // that have been discovered so far. Otherwise, clients can be notified of all
- // new and lost devices by implementing the Observer methods "DeviceAdded" and
- // "DeviceRemoved".
- //
- // |client_name|: The name of the application using this scan session. This
- // field is for logging purposes and does not affect any scanning logic, so
- // the value can be freely defined by the caller.
- void StartDiscoverySession(const std::string& client_name,
- DiscoverySessionCallback callback,
- ErrorCallback error_callback);
- void StartDiscoverySessionWithFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- const std::string& client_name,
- DiscoverySessionCallback callback,
- ErrorCallback error_callback);
- // Return all discovery filters assigned to this adapter merged together.
- std::unique_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilter() const;
- // Requests the list of devices from the adapter. All devices are returned,
- // including those currently connected, those paired and all devices returned
- // by RetrieveGattConnectedDevicesWithDiscoveryFilter() (from the previous
- // call). Use the returned device pointers to determine which they are.
- virtual DeviceList GetDevices();
- virtual ConstDeviceList GetDevices() const;
- // Returns a pointer to the device with the given address |address| or NULL if
- // no such device is known.
- virtual BluetoothDevice* GetDevice(const std::string& address);
- virtual const BluetoothDevice* GetDevice(const std::string& address) const;
- // Returns a list of UUIDs for services registered on this adapter.
- // This may include UUIDs from standard profiles (e.g. A2DP) as well
- // as those created by CreateRfcommService and CreateL2capService.
- virtual UUIDList GetUUIDs() const = 0;
- // Possible priorities for AddPairingDelegate(), low is intended for
- // permanent UI and high is intended for interactive UI or applications.
- enum PairingDelegatePriority {
- PAIRING_DELEGATE_PRIORITY_LOW,
- PAIRING_DELEGATE_PRIORITY_HIGH
- };
- // Adds a default pairing delegate with priority |priority|. Method calls
- // will be made on |pairing_delegate| for incoming pairing requests if the
- // priority is higher than any other registered; or for those of the same
- // priority, the first registered.
- //
- // |pairing_delegate| must not be freed without first calling
- // RemovePairingDelegate().
- virtual void AddPairingDelegate(
- BluetoothDevice::PairingDelegate* pairing_delegate,
- PairingDelegatePriority priority);
- // Removes a previously added pairing delegate.
- virtual void RemovePairingDelegate(
- BluetoothDevice::PairingDelegate* pairing_delegate);
- // Returns the first registered pairing delegate with the highest priority,
- // or NULL if no delegate is registered. Used to select the delegate for
- // incoming pairing requests.
- virtual BluetoothDevice::PairingDelegate* DefaultPairingDelegate();
- // Creates an RFCOMM service on this adapter advertised with UUID |uuid|,
- // listening on channel |options.channel|, which may be left null to
- // automatically allocate one. The service will be advertised with
- // |options.name| as the English name of the service. |callback| will be
- // called on success with a BluetoothSocket instance that is to be owned by
- // the received. |error_callback| will be called on failure with a message
- // indicating the cause.
- virtual void CreateRfcommService(
- const BluetoothUUID& uuid,
- const ServiceOptions& options,
- CreateServiceCallback callback,
- CreateServiceErrorCallback error_callback) = 0;
- // Creates an L2CAP service on this adapter advertised with UUID |uuid|,
- // listening on PSM |options.psm|, which may be left null to automatically
- // allocate one. The service will be advertised with |options.name| as the
- // English name of the service. |callback| will be called on success with a
- // BluetoothSocket instance that is to be owned by the received.
- // |error_callback| will be called on failure with a message indicating the
- // cause.
- virtual void CreateL2capService(
- const BluetoothUUID& uuid,
- const ServiceOptions& options,
- CreateServiceCallback callback,
- CreateServiceErrorCallback error_callback) = 0;
- // Creates and registers an advertisement for broadcast over the LE channel.
- // The created advertisement will be returned via the success callback. An
- // advertisement can unregister itself at any time by calling its unregister
- // function.
- virtual void RegisterAdvertisement(
- std::unique_ptr<BluetoothAdvertisement::Data> advertisement_data,
- CreateAdvertisementCallback callback,
- AdvertisementErrorCallback error_callback) = 0;
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
- // Sets the interval between two consecutive advertisements. Valid ranges
- // for the interval are from 20ms to 10.24 seconds, with min <= max.
- // Note: This is a best effort. The actual interval may vary non-trivially
- // from the requested intervals. On some hardware, there is a minimum
- // interval of 100ms. The minimum and maximum values are specified by the
- // Core 4.2 Spec, Vol 2, Part E, Section 7.8.5.
- virtual void SetAdvertisingInterval(
- const base::TimeDelta& min,
- const base::TimeDelta& max,
- base::OnceClosure callback,
- AdvertisementErrorCallback error_callback) = 0;
- // Resets advertising on this adapter. This will unregister all existing
- // advertisements and will stop advertising them.
- virtual void ResetAdvertising(base::OnceClosure callback,
- AdvertisementErrorCallback error_callback) = 0;
- // Connect to a device with |address| that is either undiscovered or not
- // previously paired or connected. Callers are responsible for ensuring that
- // the device with |address| is available and nearby via their own out-of-band
- // mechanism, and should not call this method if GetDevice(address) returns
- // a valid reference (in which case this method will fail).
- virtual void ConnectDevice(
- const std::string& address,
- const absl::optional<BluetoothDevice::AddressType>& address_type,
- ConnectDeviceCallback callback,
- ErrorCallback error_callback) = 0;
- #endif
- // Returns the list of pending advertisements that are not registered yet.
- virtual std::vector<BluetoothAdvertisement*>
- GetPendingAdvertisementsForTesting() const;
- // Returns the local GATT services associated with this adapter with the
- // given identifier. Returns NULL if the service doesn't exist.
- virtual BluetoothLocalGattService* GetGattService(
- const std::string& identifier) const = 0;
- // The following methods are used to send various events to observers.
- void NotifyAdapterPresentChanged(bool present);
- void NotifyAdapterPoweredChanged(bool powered);
- void NotifyDeviceChanged(BluetoothDevice* device);
- void NotifyAdapterDiscoveryChangeCompletedForTesting();
- #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
- void NotifyDevicePairedChanged(BluetoothDevice* device,
- bool new_paired_status);
- void NotifyDeviceConnectedStateChanged(BluetoothDevice* device,
- bool is_connected);
- #endif
- #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
- void NotifyDeviceBatteryChanged(BluetoothDevice* device,
- BluetoothDevice::BatteryType type);
- #endif
- #if BUILDFLAG(IS_CHROMEOS)
- void NotifyDeviceIsBlockedByPolicyChanged(BluetoothDevice* device,
- bool new_blocked_status);
- #endif
- void NotifyGattServiceAdded(BluetoothRemoteGattService* service);
- void NotifyGattServiceRemoved(BluetoothRemoteGattService* service);
- void NotifyGattServiceChanged(BluetoothRemoteGattService* service);
- void NotifyGattServicesDiscovered(BluetoothDevice* device);
- void NotifyGattDiscoveryComplete(BluetoothRemoteGattService* service);
- void NotifyGattCharacteristicAdded(
- BluetoothRemoteGattCharacteristic* characteristic);
- void NotifyGattCharacteristicRemoved(
- BluetoothRemoteGattCharacteristic* characteristic);
- void NotifyGattDescriptorAdded(BluetoothRemoteGattDescriptor* descriptor);
- void NotifyGattDescriptorRemoved(BluetoothRemoteGattDescriptor* descriptor);
- void NotifyGattCharacteristicValueChanged(
- BluetoothRemoteGattCharacteristic* characteristic,
- const std::vector<uint8_t>& value);
- void NotifyGattDescriptorValueChanged(
- BluetoothRemoteGattDescriptor* descriptor,
- const std::vector<uint8_t>& value);
- #if BUILDFLAG(IS_CHROMEOS)
- void NotifyLowEnergyScanSessionHardwareOffloadingStatusChanged(
- LowEnergyScanSessionHardwareOffloadingStatus status);
- // Set a service allowlist by specifying services UUIDs. When this is called,
- // existing connections will be disconnected and services not in the allowlist
- // will be blocked. Device property |IsBlockedByPolicy| will be True if some
- // of the auto-connect services are blocked, False otherwise.
- virtual void SetServiceAllowList(const UUIDList& uuids,
- base::OnceClosure callback,
- ErrorCallback error_callback) = 0;
- // Returns |kSupported| if the device supports the offloading of filtering and
- // other scanning logic to the Bluetooth hardware. This brings the benefit of
- // reduced power consumption for BluetoothLowEnergyScanSession. Returns
- // |kNotSupported| if hardware offloading is not available, in which case
- // BluetoothLowEnergyScanSession will operate with higher power
- // consumption. |kUndetermined| indicates the status can not currently be
- // determined (such as when the adapter is not present), and the client should
- // retry.
- //
- // Consumers should check this value before
- // creating a BluetoothLowEnergyScanSession and consider ways to mitigate
- // power usage, especially if the scan session is intended to be long-running.
- virtual LowEnergyScanSessionHardwareOffloadingStatus
- GetLowEnergyScanSessionHardwareOffloadingStatus() = 0;
- // Starts a low energy scanning session that will notify the client on session
- // started, session invalidated, device found and device lost events via the
- // |delegate|.
- //
- // The client controls the lifetime of the session (except on unexpected
- // invalidation, see below). The client ends a scan session by destroying the
- // returned instance.
- //
- // A session cannot recover once the
- // BluetoothLowEnergyScanSession::Delegate::OnSessionInvalidated() callback
- // has been invoked. Invalidation can happen if the platform unexpectedly
- // cleans up the scan session due to a firmware crash, etc.. If a client wants
- // an identical scanning session, it should discard its newly invalidated
- // BluetoothLowEnergyScanSession and create a new one by calling
- // StartLowEnergyScanSession() again.
- virtual std::unique_ptr<BluetoothLowEnergyScanSession>
- StartLowEnergyScanSession(
- std::unique_ptr<BluetoothLowEnergyScanFilter> filter,
- base::WeakPtr<BluetoothLowEnergyScanSession::Delegate> delegate) = 0;
- #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.
- virtual void SetStandardChromeOSAdapterName() = 0;
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- // The timeout in seconds used by RemoveTimedOutDevices.
- static const base::TimeDelta timeoutSec;
- // This struct is meant to hold any possible callback from a discovery
- // request. The purpose of this is to consolidate all discovery request
- // callbacks into one array that can be handled all at once when the state
- // desired from all requests is achieved or an error is thrown.
- struct StartOrStopDiscoveryCallback {
- StartOrStopDiscoveryCallback(base::OnceClosure start_callback,
- ErrorCallback start_error_callback);
- StartOrStopDiscoveryCallback(
- base::OnceClosure stop_callback,
- DiscoverySessionErrorCallback stop_error_callback);
- ~StartOrStopDiscoveryCallback();
- // The success callback for a start discovery request.
- base::OnceClosure start_callback;
- // The success callback for a stop discovery request.
- base::OnceClosure stop_callback;
- // The error callback for a start discovery request.
- ErrorCallback start_error_callback;
- // The error callback for a stop discovery request.
- DiscoverySessionErrorCallback stop_error_callback;
- };
- protected:
- friend class base::RefCounted<BluetoothAdapter>;
- friend class BluetoothAdapterFactory;
- friend class BluetoothDiscoverySession;
- friend class BluetoothTestBase;
- using DevicesMap =
- std::unordered_map<std::string, std::unique_ptr<BluetoothDevice>>;
- using PairingDelegatePair =
- std::pair<BluetoothDevice::PairingDelegate*, PairingDelegatePriority>;
- using CallbackQueue =
- base::queue<std::unique_ptr<StartOrStopDiscoveryCallback>>;
- // Implementations on Android and macOS need to store pending SetPowered()
- // callbacks until an appropriate event is received, due to a lack of blocking
- // or callback supporting platform APIs. Declaring the struct here allows
- // Android and macOS to share the implementation.
- struct SetPoweredCallbacks {
- SetPoweredCallbacks();
- ~SetPoweredCallbacks();
- bool powered = false;
- base::OnceClosure callback;
- ErrorCallback error_callback;
- };
- BluetoothAdapter();
- virtual ~BluetoothAdapter();
- virtual base::WeakPtr<BluetoothAdapter> GetWeakPtr() = 0;
- // This method calls into platform specific logic on macOS and Android where
- // pending SetPowered() callbacks need to be stored explicitly.
- virtual bool SetPoweredImpl(bool powered) = 0;
- // Called by macOS, Android and WinRT once the specific powered state events
- // are received or an error occurred. Clears out pending callbacks.
- void RunPendingPowerCallbacks();
- // Internal methods for initiating and terminating device discovery sessions.
- // An implementation of BluetoothAdapter keeps an internal reference count to
- // make sure that the underlying controller is constantly searching for nearby
- // devices and retrieving information from them as long as there are clients
- // who have requested discovery. These methods behave in the following way:
- //
- // On a call to StartScanWithFilter:
- // - This should only be called when we get the first request to start the
- // scan with only the initial filter in that request.
- // - This function should do the OS specific things to get the filter
- // started.
- // - When finished it should callback with success or the appropriate
- // Output for an error.
- // On a call to UpdateFilter:
- // - The scan should already be started or at least starting.
- // - This function takes in a filter and should do all the OS specifics
- // needed to update the scan with the new filter.
- // - When finished it should call the callback with success or the
- // appropriate output for an error
- //
- // On a call to StopScan:
- // - Make a request to the physical adapter that we no longer needs to
- // be scanning
- // - When finished it should callback with success. If an error is thrown
- // we still return success to the user and update our internal state to
- // say that we are not discovering.
- virtual void StartScanWithFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- DiscoverySessionResultCallback callback) = 0;
- virtual void UpdateFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- DiscoverySessionResultCallback callback) = 0;
- virtual void StopScan(DiscoverySessionResultCallback callback) = 0;
- // Removes the |discovery_session| from |discovery_sessions_| and updates
- // accordingly
- void RemoveDiscoverySession(BluetoothDiscoverySession* discovery_session,
- base::OnceClosure callback,
- DiscoverySessionErrorCallback error_callback);
- // Helper function that short circuits a successful callback if the filter is
- // the same as the current filter.
- void MaybeUpdateFilter(
- std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
- DiscoverySessionResultCallback callback);
- // Called by RemovePairingDelegate() in order to perform any class-specific
- // internal functionality necessary to remove the pairing delegate, such as
- // cleaning up ongoing pairings using it.
- virtual void RemovePairingDelegateInternal(
- BluetoothDevice::PairingDelegate* pairing_delegate) = 0;
- // Marks all known DiscoverySession instances as inactive. Called by
- // BluetoothAdapter in the event that the adapter unexpectedly stops
- // discovering. This should be called by all platform implementations.
- void MarkDiscoverySessionsAsInactive();
- void DeleteDeviceForTesting(const std::string& address);
- // Removes from |devices_| any previously paired, connected or seen
- // devices which are no longer present. Notifies observers. Note:
- // this is only used by platforms where there is no notification of
- // lost devices.
- void RemoveTimedOutDevices();
- int NumDiscoverySessions() const;
- // Number of DiscoverySessions with the status of SCANNING.
- int NumScanningDiscoverySessions() const;
- // UI thread task runner.
- scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
- // Observers of BluetoothAdapter, notified from implementation subclasses.
- base::ObserverList<device::BluetoothAdapter::Observer>::Unchecked observers_;
- // Devices paired with, connected to, discovered by, or visible to the
- // adapter. The key is the Bluetooth address of the device and the value is
- // the BluetoothDevice object whose lifetime is managed by the adapter
- // instance.
- DevicesMap devices_;
- // Default pairing delegates registered with the adapter.
- std::list<PairingDelegatePair> pairing_delegates_;
- // SetPowered() callbacks, only relevant for macOS and Android.
- std::unique_ptr<SetPoweredCallbacks> set_powered_callbacks_;
- // List of active DiscoverySession objects. This is used to notify sessions to
- // become inactive in case of an unexpected change to the adapter discovery
- // state. We keep raw pointers, with the invariant that a DiscoverySession
- // will remove itself from this list when it gets destroyed or becomes
- // inactive by calling DiscoverySessionBecameInactive(), hence no pointers to
- // deallocated sessions are kept.
- std::set<BluetoothDiscoverySession*> discovery_sessions_;
- private:
- // This is the callback for all OS level calls to StartScanWithFilter,
- // UpdateFilter, and StopScan. It updates the state accordingly, calls all
- // appropriate callbacks, and calls ProcessDiscoveryQueue().
- void OnDiscoveryChangeComplete(bool is_error,
- UMABluetoothDiscoverySessionOutcome outcome);
- // This method processes all queued requests that have been waiting for a
- // process to finish.
- void ProcessDiscoveryQueue();
- // Utility method used to call all callbacks in the case of an error in a
- // process
- void NotifyDiscoveryError(CallbackQueue queue);
- // Utility function to update our internal state after a process has
- // completed(example: kStarting -> kDiscovering)
- void UpdateDiscoveryState(bool is_error);
- // List of callbacks for requests that have been queued up and are awaiting a
- // process to finish before they can begin the request
- CallbackQueue discovery_callback_queue_;
- // List of callbacks whose requests are currently being processed by the OS
- // level adapter
- CallbackQueue callbacks_awaiting_response_;
- // Discovery filter currently being used by the adapter
- device::BluetoothDiscoveryFilter current_discovery_filter_;
- // Discovery filter that is about to be set in the OS level adapter. After
- // the process that is implementing this feature is finished this will become
- // the |current_discovery_filter_|.
- device::BluetoothDiscoveryFilter filter_being_set_;
- // True, if there is a pending request to start or stop discovery.
- bool discovery_request_pending_ = false;
- // enum used to track our internal discovery state.
- DiscoveryState internal_discovery_state_ = DiscoveryState::kIdle;
- };
- } // namespace device
- #endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
|