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 BluetoothSocket; 23 class BluetoothUUID; 24 25 // BluetoothAdapter represents a local Bluetooth adapter which may be used to 26 // interact with remote Bluetooth devices. As well as providing support for 27 // determining whether an adapter is present and whether the radio is powered, 28 // this class also provides support for obtaining the list of remote devices 29 // known to the adapter, discovering new devices, and providing notification of 30 // updates to device information. 31 class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> { 32 public: 33 // Interface for observing changes from bluetooth adapters. 34 class Observer { 35 public: 36 virtual ~Observer() {} 37 38 // Called when the presence of the adapter |adapter| changes. When |present| 39 // is true the adapter is now present, false means the adapter has been 40 // removed from the system. 41 virtual void AdapterPresentChanged(BluetoothAdapter* adapter, 42 bool present) {} 43 44 // Called when the radio power state of the adapter |adapter| changes. When 45 // |powered| is true the adapter radio is powered, false means the adapter 46 // radio is off. 47 virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, 48 bool powered) {} 49 50 // Called when the discoverability state of the adapter |adapter| changes. 51 // When |discoverable| is true the adapter is discoverable by other devices, 52 // false means the adapter is not discoverable. 53 virtual void AdapterDiscoverableChanged(BluetoothAdapter* adapter, 54 bool discoverable) {} 55 56 // Called when the discovering state of the adapter |adapter| changes. When 57 // |discovering| is true the adapter is seeking new devices, false means it 58 // is not. 59 virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, 60 bool discovering) {} 61 62 // Called when a new device |device| is added to the adapter |adapter|, 63 // either because it has been discovered or a connection made. |device| 64 // should not be cached. Instead, copy its Bluetooth address. 65 virtual void DeviceAdded(BluetoothAdapter* adapter, 66 BluetoothDevice* device) {} 67 68 // Called when properties of the device |device| known to the adapter 69 // |adapter| change. |device| should not be cached. Instead, copy its 70 // Bluetooth address. 71 virtual void DeviceChanged(BluetoothAdapter* adapter, 72 BluetoothDevice* device) {} 73 74 // Called when the device |device| is removed from the adapter |adapter|, 75 // either as a result of a discovered device being lost between discovering 76 // phases or pairing information deleted. |device| should not be 77 // cached. Instead, copy its Bluetooth address. 78 virtual void DeviceRemoved(BluetoothAdapter* adapter, 79 BluetoothDevice* device) {} 80 }; 81 82 // The ErrorCallback is used for methods that can fail in which case it is 83 // called, in the success case the callback is simply not called. 84 typedef base::Closure ErrorCallback; 85 86 // The InitCallback is used to trigger a callback after asynchronous 87 // initialization, if initialization is asynchronous on the platform. 88 typedef base::Callback<void()> InitCallback; 89 90 // Returns a weak pointer to a new adapter. For platforms with asynchronous 91 // initialization, the returned adapter will run the |init_callback| once 92 // asynchronous initialization is complete. 93 // Caution: The returned pointer also transfers ownership of the adapter. The 94 // caller is expected to call |AddRef()| on the returned pointer, typically by 95 // storing it into a |scoped_refptr|. 96 static base::WeakPtr<BluetoothAdapter> CreateAdapter( 97 const InitCallback& init_callback); 98 99 // Returns a weak pointer to an existing adapter for testing purposes only. 100 base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting(); 101 102 // Adds and removes observers for events on this bluetooth adapter. If 103 // monitoring multiple adapters, check the |adapter| parameter of observer 104 // methods to determine which adapter is issuing the event. 105 virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0; 106 virtual void RemoveObserver( 107 BluetoothAdapter::Observer* observer) = 0; 108 109 // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX", 110 // where each XX is a hexadecimal number. 111 virtual std::string GetAddress() const = 0; 112 113 // The name of the adapter. 114 virtual std::string GetName() const = 0; 115 116 // Set the human-readable name of the adapter to |name|. On success, 117 // |callback| will be called. On failure, |error_callback| will be called. 118 virtual void SetName(const std::string& name, 119 const base::Closure& callback, 120 const ErrorCallback& error_callback) = 0; 121 122 // Indicates whether the adapter is initialized and ready to use. 123 virtual bool IsInitialized() const = 0; 124 125 // Indicates whether the adapter is actually present on the system. For the 126 // default adapter, this indicates whether any adapter is present. An adapter 127 // is only considered present if the address has been obtained. 128 virtual bool IsPresent() const = 0; 129 130 // Indicates whether the adapter radio is powered. 131 virtual bool IsPowered() const = 0; 132 133 // Requests a change to the adapter radio power. Setting |powered| to true 134 // will turn on the radio and false will turn it off. On success, |callback| 135 // will be called. On failure, |error_callback| will be called. 136 virtual void SetPowered(bool powered, 137 const base::Closure& callback, 138 const ErrorCallback& error_callback) = 0; 139 140 // Indicates whether the adapter radio is discoverable. 141 virtual bool IsDiscoverable() const = 0; 142 143 // Requests that the adapter change its discoverability state. If 144 // |discoverable| is true, then it will be discoverable by other Bluetooth 145 // devices. On successly changing the adapter's discoverability, |callback| 146 // will be called. On failure, |error_callback| will be called. 147 virtual void SetDiscoverable(bool discoverable, 148 const base::Closure& callback, 149 const ErrorCallback& error_callback) = 0; 150 151 // Indicates whether the adapter is currently discovering new devices. 152 virtual bool IsDiscovering() const = 0; 153 154 // Requests the adapter to start a new discovery session. On success, a new 155 // instance of BluetoothDiscoverySession will be returned to the caller via 156 // |callback| and the adapter will be discovering nearby Bluetooth devices. 157 // The returned BluetoothDiscoverySession is owned by the caller and it's the 158 // owner's responsibility to properly clean it up and stop the session when 159 // device discovery is no longer needed. 160 // 161 // If clients desire device discovery to run, they should always call this 162 // method and never make it conditional on the value of IsDiscovering(), as 163 // another client might cause discovery to stop unexpectedly. Hence, clients 164 // should always obtain a BluetoothDiscoverySession and call 165 // BluetoothDiscoverySession::Stop when done. When this method gets called, 166 // device discovery may actually be in progress. Clients can call GetDevices() 167 // and check for those with IsPaired() as false to obtain the list of devices 168 // that have been discovered so far. Otherwise, clients can be notified of all 169 // new and lost devices by implementing the Observer methods "DeviceAdded" and 170 // "DeviceRemoved". 171 typedef base::Callback<void(scoped_ptr<BluetoothDiscoverySession>)> 172 DiscoverySessionCallback; 173 virtual void StartDiscoverySession(const DiscoverySessionCallback& callback, 174 const ErrorCallback& error_callback); 175 176 // Requests the list of devices from the adapter. All devices are returned, 177 // including those currently connected and those paired. Use the returned 178 // device pointers to determine which they are. 179 typedef std::vector<BluetoothDevice*> DeviceList; 180 virtual DeviceList GetDevices(); 181 typedef std::vector<const BluetoothDevice*> ConstDeviceList; 182 virtual ConstDeviceList GetDevices() const; 183 184 // Returns a pointer to the device with the given address |address| or NULL if 185 // no such device is known. 186 virtual BluetoothDevice* GetDevice(const std::string& address); 187 virtual const BluetoothDevice* GetDevice(const std::string& address) const; 188 189 // Possible priorities for AddPairingDelegate(), low is intended for 190 // permanent UI and high is intended for interactive UI or applications. 191 enum PairingDelegatePriority { 192 PAIRING_DELEGATE_PRIORITY_LOW, 193 PAIRING_DELEGATE_PRIORITY_HIGH 194 }; 195 196 // Adds a default pairing delegate with priority |priority|. Method calls 197 // will be made on |pairing_delegate| for incoming pairing requests if the 198 // priority is higher than any other registered; or for those of the same 199 // priority, the first registered. 200 // 201 // |pairing_delegate| must not be freed without first calling 202 // RemovePairingDelegate(). 203 virtual void AddPairingDelegate( 204 BluetoothDevice::PairingDelegate* pairing_delegate, 205 PairingDelegatePriority priority); 206 207 // Removes a previously added pairing delegate. 208 virtual void RemovePairingDelegate( 209 BluetoothDevice::PairingDelegate* pairing_delegate); 210 211 // Returns the first registered pairing delegate with the highest priority, 212 // or NULL if no delegate is registered. Used to select the delegate for 213 // incoming pairing requests. 214 virtual BluetoothDevice::PairingDelegate* DefaultPairingDelegate(); 215 216 // Creates an RFCOMM service on this adapter advertised with UUID |uuid|, 217 // listening on channel |channel|, which may be the constant |kChannelAuto| 218 // to automatically allocate one. |callback| will be called on success with a 219 // BluetoothSocket instance that is to be owned by the received. 220 // |error_callback| will be called on failure with a message indicating the 221 // cause. 222 typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> 223 CreateServiceCallback; 224 typedef base::Callback<void(const std::string& message)> 225 CreateServiceErrorCallback; 226 static const int kChannelAuto; 227 virtual void CreateRfcommService( 228 const BluetoothUUID& uuid, 229 int channel, 230 const CreateServiceCallback& callback, 231 const CreateServiceErrorCallback& error_callback) = 0; 232 233 // Creates an L2CAP service on this adapter advertised with UUID |uuid|, 234 // listening on PSM |psm|, which may be the constant |kPsmAuto| to 235 // automatically allocate one. |callback| will be called on success with a 236 // BluetoothSocket instance that is to be owned by the received. 237 // |error_callback| will be called on failure with a message indicating the 238 // cause. 239 static const int kPsmAuto; 240 virtual void CreateL2capService( 241 const BluetoothUUID& uuid, 242 int psm, 243 const CreateServiceCallback& callback, 244 const CreateServiceErrorCallback& error_callback) = 0; 245 246 protected: 247 friend class base::RefCounted<BluetoothAdapter>; 248 friend class BluetoothDiscoverySession; 249 BluetoothAdapter(); 250 virtual ~BluetoothAdapter(); 251 252 // Internal methods for initiating and terminating device discovery sessions. 253 // An implementation of BluetoothAdapter keeps an internal reference count to 254 // make sure that the underlying controller is constantly searching for nearby 255 // devices and retrieving information from them as long as there are clients 256 // who have requested discovery. These methods behave in the following way: 257 // 258 // On a call to AddDiscoverySession: 259 // - If there is a pending request to the subsystem, queue this request to 260 // execute once the pending requests are done. 261 // - If the count is 0, issue a request to the subsystem to start 262 // device discovery. On success, increment the count to 1. 263 // - If the count is greater than 0, increment the count and return 264 // success. 265 // As long as the count is non-zero, the underlying controller will be 266 // discovering for devices. This means that Chrome will restart device 267 // scan and inquiry sessions if they ever end, unless these sessions 268 // terminate due to an unexpected reason. 269 // 270 // On a call to RemoveDiscoverySession: 271 // - If there is a pending request to the subsystem, queue this request to 272 // execute once the pending requests are done. 273 // - If the count is 0, return failure, as there is no active discovery 274 // session. 275 // - If the count is 1, issue a request to the subsystem to stop device 276 // discovery and decrement the count to 0 on success. 277 // - If the count is greater than 1, decrement the count and return 278 // success. 279 // 280 // These methods invoke |callback| for success and |error_callback| for 281 // failures. 282 virtual void AddDiscoverySession(const base::Closure& callback, 283 const ErrorCallback& error_callback) = 0; 284 virtual void RemoveDiscoverySession(const base::Closure& callback, 285 const ErrorCallback& error_callback) = 0; 286 287 // Called by RemovePairingDelegate() in order to perform any class-specific 288 // internal functionality necessary to remove the pairing delegate, such as 289 // cleaning up ongoing pairings using it. 290 virtual void RemovePairingDelegateInternal( 291 BluetoothDevice::PairingDelegate* pairing_delegate) = 0; 292 293 // Success callback passed to AddDiscoverySession by StartDiscoverySession. 294 void OnStartDiscoverySession(const DiscoverySessionCallback& callback); 295 296 // Marks all known DiscoverySession instances as inactive. Called by 297 // BluetoothAdapter in the event that the adapter unexpectedly stops 298 // discovering. This should be called by all platform implementations. 299 void MarkDiscoverySessionsAsInactive(); 300 301 // Removes |discovery_session| from |discovery_sessions_|, if its in there. 302 // Called by DiscoverySession when an instance is destroyed or becomes 303 // inactive. 304 void DiscoverySessionBecameInactive( 305 BluetoothDiscoverySession* discovery_session); 306 307 // Devices paired with, connected to, discovered by, or visible to the 308 // adapter. The key is the Bluetooth address of the device and the value is 309 // the BluetoothDevice object whose lifetime is managed by the adapter 310 // instance. 311 typedef std::map<const std::string, BluetoothDevice*> DevicesMap; 312 DevicesMap devices_; 313 314 // Default pairing delegates registered with the adapter. 315 typedef std::pair<BluetoothDevice::PairingDelegate*, 316 PairingDelegatePriority> PairingDelegatePair; 317 std::list<PairingDelegatePair> pairing_delegates_; 318 319 private: 320 // List of active DiscoverySession objects. This is used to notify sessions to 321 // become inactive in case of an unexpected change to the adapter discovery 322 // state. We keep raw pointers, with the invariant that a DiscoverySession 323 // will remove itself from this list when it gets destroyed or becomes 324 // inactive by calling DiscoverySessionBecameInactive(), hence no pointers to 325 // deallocated sessions are kept. 326 std::set<BluetoothDiscoverySession*> discovery_sessions_; 327 328 // Note: This should remain the last member so it'll be destroyed and 329 // invalidate its weak pointers before any other members are destroyed. 330 base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_; 331 }; 332 333 } // namespace device 334 335 #endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ 336