• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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