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
19namespace device {
20
21class BluetoothDiscoverySession;
22class BluetoothGattCharacteristic;
23class BluetoothGattDescriptor;
24class BluetoothGattService;
25class BluetoothSocket;
26class 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.
34class BluetoothAdapter : public base::RefCounted<BluetoothAdapter> {
35 public:
36  // Interface for observing changes from bluetooth adapters.
37  class Observer {
38   public:
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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