1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ 6 #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ 7 8 #include <list> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <utility> 13 14 #include "base/callback.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/weak_ptr.h" 17 #include "device/bluetooth/bluetooth_device.h" 18 19 namespace device { 20 21 class BluetoothDiscoverySession; 22 class BluetoothGattCharacteristic; 23 class BluetoothGattDescriptor; 24 class BluetoothGattService; 25 class BluetoothSocket; 26 class BluetoothUUID; 27 28 // BluetoothAdapter represents a local Bluetooth adapter which may be used to 29 // interact with remote Bluetooth devices. As well as providing support for 30 // determining whether an adapter is present and whether the radio is powered, 31 // this class also provides support for obtaining the list of remote devices 32 // known to the adapter, discovering new devices, and providing notification of 33 // updates to device information. 34 class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { 35 public: 36 // Interface for observing changes from bluetooth adapters. 37 class Observer { 38 public: ~Observer()39 virtual ~Observer() {} 40 41 // Called when the presence of the adapter |adapter| changes. When |present| 42 // is true the adapter is now present, false means the adapter has been 43 // removed from the system. AdapterPresentChanged(BluetoothAdapter * adapter,bool present)44 virtual void AdapterPresentChanged(BluetoothAdapter* adapter, 45 bool present) {} 46 47 // Called when the radio power state of the adapter |adapter| changes. When 48 // |powered| is true the adapter radio is powered, false means the adapter 49 // radio is off. AdapterPoweredChanged(BluetoothAdapter * adapter,bool powered)50 virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, 51 bool powered) {} 52 53 // Called when the discoverability state of the adapter |adapter| changes. 54 // When |discoverable| is true the adapter is discoverable by other devices, 55 // false means the adapter is not discoverable. AdapterDiscoverableChanged(BluetoothAdapter * adapter,bool discoverable)56 virtual void AdapterDiscoverableChanged(BluetoothAdapter* adapter, 57 bool discoverable) {} 58 59 // Called when the discovering state of the adapter |adapter| changes. When 60 // |discovering| is true the adapter is seeking new devices, false means it 61 // is not. AdapterDiscoveringChanged(BluetoothAdapter * adapter,bool discovering)62 virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, 63 bool discovering) {} 64 65 // Called when a new device |device| is added to the adapter |adapter|, 66 // either because it has been discovered or a connection made. |device| 67 // should not be cached. Instead, copy its Bluetooth address. DeviceAdded(BluetoothAdapter * adapter,BluetoothDevice * device)68 virtual void DeviceAdded(BluetoothAdapter* adapter, 69 BluetoothDevice* device) {} 70 71 // Called when properties of the device |device| known to the adapter 72 // |adapter| change. |device| should not be cached. Instead, copy its 73 // Bluetooth address. DeviceChanged(BluetoothAdapter * adapter,BluetoothDevice * device)74 virtual void DeviceChanged(BluetoothAdapter* adapter, 75 BluetoothDevice* device) {} 76 77 // Called when the device |device| is removed from the adapter |adapter|, 78 // either as a result of a discovered device being lost between discovering 79 // phases or pairing information deleted. |device| should not be 80 // cached. Instead, copy its Bluetooth address. DeviceRemoved(BluetoothAdapter * adapter,BluetoothDevice * device)81 virtual void DeviceRemoved(BluetoothAdapter* adapter, 82 BluetoothDevice* device) {} 83 84 // Called when a new GATT service |service| is added to the device |device|, 85 // as the service is received from the device. Don't cache |service|. Store 86 // its identifier instead (i.e. BluetoothGattService::GetIdentifier). GattServiceAdded(BluetoothAdapter * adapter,BluetoothDevice * device,BluetoothGattService * service)87 virtual void GattServiceAdded(BluetoothAdapter* adapter, 88 BluetoothDevice* device, 89 BluetoothGattService* service) {} 90 91 // Called when the GATT service |service| is removed from the device 92 // |device|. This can happen if the attribute database of the remote device 93 // changes or when |device| gets removed. GattServiceRemoved(BluetoothAdapter * adapter,BluetoothDevice * device,BluetoothGattService * service)94 virtual void GattServiceRemoved(BluetoothAdapter* adapter, 95 BluetoothDevice* device, 96 BluetoothGattService* service) {} 97 98 // Called when all characteristic and descriptor discovery procedures are 99 // known to be completed for the GATT service |service|. This method will be 100 // called after the initial discovery of a GATT service and will usually be 101 // preceded by calls to GattCharacteristicAdded and GattDescriptorAdded. GattDiscoveryCompleteForService(BluetoothAdapter * adapter,BluetoothGattService * service)102 virtual void GattDiscoveryCompleteForService( 103 BluetoothAdapter* adapter, 104 BluetoothGattService* service) {} 105 106 // Called when properties of the remote GATT service |service| have changed. 107 // This will get called for properties such as UUID, as well as for changes 108 // to the list of known characteristics and included services. Observers 109 // should read all GATT characteristic and descriptors objects and do any 110 // necessary set up required for a changed service. GattServiceChanged(BluetoothAdapter * adapter,BluetoothGattService * service)111 virtual void GattServiceChanged(BluetoothAdapter* adapter, 112 BluetoothGattService* service) {} 113 114 // Called when the remote GATT characteristic |characteristic| has been 115 // discovered. Use this to issue any initial read/write requests to the 116 // characteristic but don't cache the pointer as it may become invalid. 117 // Instead, use the specially assigned identifier to obtain a characteristic 118 // and cache that identifier as necessary, as it can be used to retrieve the 119 // characteristic from its GATT service. The number of characteristics with 120 // the same UUID belonging to a service depends on the particular profile 121 // the remote device implements, hence the client of a GATT based profile 122 // will usually operate on the whole set of characteristics and not just 123 // one. GattCharacteristicAdded(BluetoothAdapter * adapter,BluetoothGattCharacteristic * characteristic)124 virtual void GattCharacteristicAdded( 125 BluetoothAdapter* adapter, 126 BluetoothGattCharacteristic* characteristic) {} 127 128 // Called when a GATT characteristic |characteristic| has been removed from 129 // the system. GattCharacteristicRemoved(BluetoothAdapter * adapter,BluetoothGattCharacteristic * characteristic)130 virtual void GattCharacteristicRemoved( 131 BluetoothAdapter* adapter, 132 BluetoothGattCharacteristic* characteristic) {} 133 134 // Called when the remote GATT characteristic descriptor |descriptor| has 135 // been discovered. Don't cache the arguments as the pointers may become 136 // invalid. Instead, use the specially assigned identifier to obtain a 137 // descriptor and cache that identifier as necessary. GattDescriptorAdded(BluetoothAdapter * adapter,BluetoothGattDescriptor * descriptor)138 virtual void GattDescriptorAdded(BluetoothAdapter* adapter, 139 BluetoothGattDescriptor* descriptor) {} 140 141 // Called when a GATT characteristic descriptor |descriptor| has been 142 // removed from the system. GattDescriptorRemoved(BluetoothAdapter * adapter,BluetoothGattDescriptor * descriptor)143 virtual void GattDescriptorRemoved(BluetoothAdapter* adapter, 144 BluetoothGattDescriptor* descriptor) {} 145 146 // Called when the value of a characteristic has changed. This might be a 147 // result of a read/write request to, or a notification/indication from, a 148 // remote GATT characteristic. GattCharacteristicValueChanged(BluetoothAdapter * adapter,BluetoothGattCharacteristic * characteristic,const std::vector<uint8> & value)149 virtual void GattCharacteristicValueChanged( 150 BluetoothAdapter* adapter, 151 BluetoothGattCharacteristic* characteristic, 152 const std::vector<uint8>& value) {} 153 154 // Called when the value of a characteristic descriptor has been updated. GattDescriptorValueChanged(BluetoothAdapter * adapter,BluetoothGattDescriptor * descriptor,const std::vector<uint8> & value)155 virtual void GattDescriptorValueChanged(BluetoothAdapter* adapter, 156 BluetoothGattDescriptor* descriptor, 157 const std::vector<uint8>& value) {} 158 }; 159 160 // Used to configure a listening servie. 161 struct ServiceOptions { 162 ServiceOptions(); 163 ~ServiceOptions(); 164 165 scoped_ptr<int> channel; 166 scoped_ptr<int> psm; 167 scoped_ptr<std::string> name; 168 }; 169 170 // The ErrorCallback is used for methods that can fail in which case it is 171 // called, in the success case the callback is simply not called. 172 typedef base::Closure ErrorCallback; 173 174 // The InitCallback is used to trigger a callback after asynchronous 175 // initialization, if initialization is asynchronous on the platform. 176 typedef base::Callback<void()> InitCallback; 177 178 // Returns a weak pointer to a new adapter. For platforms with asynchronous 179 // initialization, the returned adapter will run the |init_callback| once 180 // asynchronous initialization is complete. 181 // Caution: The returned pointer also transfers ownership of the adapter. The 182 // caller is expected to call |AddRef()| on the returned pointer, typically by 183 // storing it into a |scoped_refptr|. 184 static base::WeakPtr<BluetoothAdapter> CreateAdapter( 185 const InitCallback& init_callback); 186 187 // Returns a weak pointer to an existing adapter for testing purposes only. 188 base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting(); 189 190 // Adds and removes observers for events on this bluetooth adapter. If 191 // monitoring multiple adapters, check the |adapter| parameter of observer 192 // methods to determine which adapter is issuing the event. 193 virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0; 194 virtual void RemoveObserver( 195 BluetoothAdapter::Observer* observer) = 0; 196 197 // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX", 198 // where each XX is a hexadecimal number. 199 virtual std::string GetAddress() const = 0; 200 201 // The name of the adapter. 202 virtual std::string GetName() const = 0; 203 204 // Set the human-readable name of the adapter to |name|. On success, 205 // |callback| will be called. On failure, |error_callback| will be called. 206 virtual void SetName(const std::string& name, 207 const base::Closure& callback, 208 const ErrorCallback& error_callback) = 0; 209 210 // Indicates whether the adapter is initialized and ready to use. 211 virtual bool IsInitialized() const = 0; 212 213 // Indicates whether the adapter is actually present on the system. For the 214 // default adapter, this indicates whether any adapter is present. An adapter 215 // is only considered present if the address has been obtained. 216 virtual bool IsPresent() const = 0; 217 218 // Indicates whether the adapter radio is powered. 219 virtual bool IsPowered() const = 0; 220 221 // Requests a change to the adapter radio power. Setting |powered| to true 222 // will turn on the radio and false will turn it off. On success, |callback| 223 // will be called. On failure, |error_callback| will be called. 224 virtual void SetPowered(bool powered, 225 const base::Closure& callback, 226 const ErrorCallback& error_callback) = 0; 227 228 // Indicates whether the adapter radio is discoverable. 229 virtual bool IsDiscoverable() const = 0; 230 231 // Requests that the adapter change its discoverability state. If 232 // |discoverable| is true, then it will be discoverable by other Bluetooth 233 // devices. On successly changing the adapter's discoverability, |callback| 234 // will be called. On failure, |error_callback| will be called. 235 virtual void SetDiscoverable(bool discoverable, 236 const base::Closure& callback, 237 const ErrorCallback& error_callback) = 0; 238 239 // Indicates whether the adapter is currently discovering new devices. 240 virtual bool IsDiscovering() const = 0; 241 242 // Requests the adapter to start a new discovery session. On success, a new 243 // instance of BluetoothDiscoverySession will be returned to the caller via 244 // |callback| and the adapter will be discovering nearby Bluetooth devices. 245 // The returned BluetoothDiscoverySession is owned by the caller and it's the 246 // owner's responsibility to properly clean it up and stop the session when 247 // device discovery is no longer needed. 248 // 249 // If clients desire device discovery to run, they should always call this 250 // method and never make it conditional on the value of IsDiscovering(), as 251 // another client might cause discovery to stop unexpectedly. Hence, clients 252 // should always obtain a BluetoothDiscoverySession and call 253 // BluetoothDiscoverySession::Stop when done. When this method gets called, 254 // device discovery may actually be in progress. Clients can call GetDevices() 255 // and check for those with IsPaired() as false to obtain the list of devices 256 // that have been discovered so far. Otherwise, clients can be notified of all 257 // new and lost devices by implementing the Observer methods "DeviceAdded" and 258 // "DeviceRemoved". 259 typedef base::Callback<void(scoped_ptr<BluetoothDiscoverySession>)> 260 DiscoverySessionCallback; 261 virtual void StartDiscoverySession(const DiscoverySessionCallback& callback, 262 const ErrorCallback& error_callback); 263 264 // Requests the list of devices from the adapter. All devices are returned, 265 // including those currently connected and those paired. Use the returned 266 // device pointers to determine which they are. 267 typedef std::vector<BluetoothDevice*> DeviceList; 268 virtual DeviceList GetDevices(); 269 typedef std::vector<const BluetoothDevice*> ConstDeviceList; 270 virtual ConstDeviceList GetDevices() const; 271 272 // Returns a pointer to the device with the given address |address| or NULL if 273 // no such device is known. 274 virtual BluetoothDevice* GetDevice(const std::string& address); 275 virtual const BluetoothDevice* GetDevice(const std::string& address) const; 276 277 // Possible priorities for AddPairingDelegate(), low is intended for 278 // permanent UI and high is intended for interactive UI or applications. 279 enum PairingDelegatePriority { 280 PAIRING_DELEGATE_PRIORITY_LOW, 281 PAIRING_DELEGATE_PRIORITY_HIGH 282 }; 283 284 // Adds a default pairing delegate with priority |priority|. Method calls 285 // will be made on |pairing_delegate| for incoming pairing requests if the 286 // priority is higher than any other registered; or for those of the same 287 // priority, the first registered. 288 // 289 // |pairing_delegate| must not be freed without first calling 290 // RemovePairingDelegate(). 291 virtual void AddPairingDelegate( 292 BluetoothDevice::PairingDelegate* pairing_delegate, 293 PairingDelegatePriority priority); 294 295 // Removes a previously added pairing delegate. 296 virtual void RemovePairingDelegate( 297 BluetoothDevice::PairingDelegate* pairing_delegate); 298 299 // Returns the first registered pairing delegate with the highest priority, 300 // or NULL if no delegate is registered. Used to select the delegate for 301 // incoming pairing requests. 302 virtual BluetoothDevice::PairingDelegate* DefaultPairingDelegate(); 303 304 // Creates an RFCOMM service on this adapter advertised with UUID |uuid|, 305 // listening on channel |options.channel|, which may be left null to 306 // automatically allocate one. The service will be advertised with 307 // |options.name| as the English name of the service. |callback| will be 308 // called on success with a BluetoothSocket instance that is to be owned by 309 // the received. |error_callback| will be called on failure with a message 310 // indicating the cause. 311 typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> 312 CreateServiceCallback; 313 typedef base::Callback<void(const std::string& message)> 314 CreateServiceErrorCallback; 315 virtual void CreateRfcommService( 316 const BluetoothUUID& uuid, 317 const ServiceOptions& options, 318 const CreateServiceCallback& callback, 319 const CreateServiceErrorCallback& error_callback) = 0; 320 321 // Creates an L2CAP service on this adapter advertised with UUID |uuid|, 322 // listening on PSM |options.psm|, which may be left null to automatically 323 // allocate one. The service will be advertised with |options.name| as the 324 // English name of the service. |callback| will be called on success with a 325 // BluetoothSocket instance that is to be owned by the received. 326 // |error_callback| will be called on failure with a message indicating the 327 // cause. 328 virtual void CreateL2capService( 329 const BluetoothUUID& uuid, 330 const ServiceOptions& options, 331 const CreateServiceCallback& callback, 332 const CreateServiceErrorCallback& error_callback) = 0; 333 334 protected: 335 friend class base::RefCounted<BluetoothAdapter>; 336 friend class BluetoothDiscoverySession; 337 BluetoothAdapter(); 338 virtual ~BluetoothAdapter(); 339 340 // Internal methods for initiating and terminating device discovery sessions. 341 // An implementation of BluetoothAdapter keeps an internal reference count to 342 // make sure that the underlying controller is constantly searching for nearby 343 // devices and retrieving information from them as long as there are clients 344 // who have requested discovery. These methods behave in the following way: 345 // 346 // On a call to AddDiscoverySession: 347 // - If there is a pending request to the subsystem, queue this request to 348 // execute once the pending requests are done. 349 // - If the count is 0, issue a request to the subsystem to start 350 // device discovery. On success, increment the count to 1. 351 // - If the count is greater than 0, increment the count and return 352 // success. 353 // As long as the count is non-zero, the underlying controller will be 354 // discovering for devices. This means that Chrome will restart device 355 // scan and inquiry sessions if they ever end, unless these sessions 356 // terminate due to an unexpected reason. 357 // 358 // On a call to RemoveDiscoverySession: 359 // - If there is a pending request to the subsystem, queue this request to 360 // execute once the pending requests are done. 361 // - If the count is 0, return failure, as there is no active discovery 362 // session. 363 // - If the count is 1, issue a request to the subsystem to stop device 364 // discovery and decrement the count to 0 on success. 365 // - If the count is greater than 1, decrement the count and return 366 // success. 367 // 368 // These methods invoke |callback| for success and |error_callback| for 369 // failures. 370 virtual void AddDiscoverySession(const base::Closure& callback, 371 const ErrorCallback& error_callback) = 0; 372 virtual void RemoveDiscoverySession(const base::Closure& callback, 373 const ErrorCallback& error_callback) = 0; 374 375 // Called by RemovePairingDelegate() in order to perform any class-specific 376 // internal functionality necessary to remove the pairing delegate, such as 377 // cleaning up ongoing pairings using it. 378 virtual void RemovePairingDelegateInternal( 379 BluetoothDevice::PairingDelegate* pairing_delegate) = 0; 380 381 // Success callback passed to AddDiscoverySession by StartDiscoverySession. 382 void OnStartDiscoverySession(const DiscoverySessionCallback& callback); 383 384 // Marks all known DiscoverySession instances as inactive. Called by 385 // BluetoothAdapter in the event that the adapter unexpectedly stops 386 // discovering. This should be called by all platform implementations. 387 void MarkDiscoverySessionsAsInactive(); 388 389 // Removes |discovery_session| from |discovery_sessions_|, if its in there. 390 // Called by DiscoverySession when an instance is destroyed or becomes 391 // inactive. 392 void DiscoverySessionBecameInactive( 393 BluetoothDiscoverySession* discovery_session); 394 395 // Devices paired with, connected to, discovered by, or visible to the 396 // adapter. The key is the Bluetooth address of the device and the value is 397 // the BluetoothDevice object whose lifetime is managed by the adapter 398 // instance. 399 typedef std::map<const std::string, BluetoothDevice*> DevicesMap; 400 DevicesMap devices_; 401 402 // Default pairing delegates registered with the adapter. 403 typedef std::pair<BluetoothDevice::PairingDelegate*, 404 PairingDelegatePriority> PairingDelegatePair; 405 std::list<PairingDelegatePair> pairing_delegates_; 406 407 private: 408 // List of active DiscoverySession objects. This is used to notify sessions to 409 // become inactive in case of an unexpected change to the adapter discovery 410 // state. We keep raw pointers, with the invariant that a DiscoverySession 411 // will remove itself from this list when it gets destroyed or becomes 412 // inactive by calling DiscoverySessionBecameInactive(), hence no pointers to 413 // deallocated sessions are kept. 414 std::set<BluetoothDiscoverySession*> discovery_sessions_; 415 416 // Note: This should remain the last member so it'll be destroyed and 417 // invalidate its weak pointers before any other members are destroyed. 418 base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_; 419 }; 420 421 } // namespace device 422 423 #endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ 424