Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / bluetooth_low_energy / bluetooth_low_energy_event_router.h
1 // Copyright 2014 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 CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_BLUETOOTH_LOW_ENERGY_EVENT_ROUTER_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_BLUETOOTH_LOW_ENERGY_EVENT_ROUTER_H_
7
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/callback.h"
14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "chrome/common/extensions/api/bluetooth_low_energy.h"
17 #include "content/public/browser/notification_observer.h"
18 #include "device/bluetooth/bluetooth_adapter.h"
19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_gatt_service.h"
21
22 namespace base {
23
24 class ListValue;
25
26 }  // namespace base
27
28 namespace content {
29
30 class BrowserContext;
31
32 }  // namespace content
33
34 namespace device {
35
36 class BluetoothGattNotifySession;
37
38 }  // namespace device
39
40 namespace extensions {
41
42 class BluetoothLowEnergyConnection;
43 class BluetoothLowEnergyNotifySession;
44 class Extension;
45
46 // The BluetoothLowEnergyEventRouter is used by the bluetoothLowEnergy API to
47 // interface with the internal Bluetooth API in device/bluetooth.
48 class BluetoothLowEnergyEventRouter
49     : public device::BluetoothAdapter::Observer {
50  public:
51   explicit BluetoothLowEnergyEventRouter(content::BrowserContext* context);
52   virtual ~BluetoothLowEnergyEventRouter();
53
54   // Possible ways that an API method can fail or succeed.
55   enum Status {
56     kStatusSuccess = 0,
57     kStatusErrorPermissionDenied,
58     kStatusErrorNotFound,
59     kStatusErrorAlreadyConnected,
60     kStatusErrorAlreadyNotifying,
61     kStatusErrorNotConnected,
62     kStatusErrorNotNotifying,
63     kStatusErrorInProgress,
64     kStatusErrorFailed
65   };
66
67   // Error callback is used by asynchronous methods to report failures.
68   typedef base::Callback<void(Status)> ErrorCallback;
69
70   // Returns true if Bluetooth is supported on the current platform or if the
71   // internal |adapter_| instance has been initialized for testing.
72   bool IsBluetoothSupported() const;
73
74   // Obtains a handle on the BluetoothAdapter and invokes |callback|. Returns
75   // false, if Bluetooth is not supported. Otherwise, asynchronously initializes
76   // it and invokes |callback|. Until the first successful call to this method,
77   // none of the methods in this class will succeed and no device::Bluetooth*
78   // API events will be observed.
79   bool InitializeAdapterAndInvokeCallback(const base::Closure& callback);
80
81   // Returns true, if the BluetoothAdapter was initialized.
82   bool HasAdapter() const;
83
84   // Creates a GATT connection to the device with address |device_address| for
85   // extension |extension|. The connection is kept alive until the extension is
86   // unloaded, the device is removed, or is disconnect by the host subsystem.
87   // |error_callback| is called with an error status in case of failure. If
88   // |persistent| is true, then the allocated connection resource is persistent
89   // across unloads.
90   void Connect(bool persistent,
91                const Extension* extension,
92                const std::string& device_address,
93                const base::Closure& callback,
94                const ErrorCallback& error_callback);
95
96   // Disconnects the currently open GATT connection of extension |extension| to
97   // device with address |device_address|. |error_callback| is called with an
98   // error status in case of failure, e.g. if the device is not found or the
99   // given
100   // extension does not have an open connection to the device.
101   void Disconnect(const Extension* extension,
102                   const std::string& device_address,
103                   const base::Closure& callback,
104                   const ErrorCallback& error_callback);
105
106   // Returns the list of api::bluetooth_low_energy::Service objects associated
107   // with the Bluetooth device with address |device_address| in |out_services|.
108   // Returns false, if no device with the given address is known. If the device
109   // is found but it has no GATT services, then returns true and leaves
110   // |out_services| empty. Returns true, on success. |out_services| must not
111   // be NULL. If it is non-empty, then its contents will be cleared.
112   typedef std::vector<linked_ptr<api::bluetooth_low_energy::Service> >
113       ServiceList;
114   bool GetServices(const std::string& device_address,
115                    ServiceList* out_services) const;
116
117   // Populates |out_service| based on GATT service with instance ID
118   // |instance_id|. |out_service| must not be NULL.
119   Status GetService(const std::string& instance_id,
120                     api::bluetooth_low_energy::Service* out_service) const;
121
122   // Populates |out_services| with the list of GATT services that are included
123   // by the GATT service with instance ID |instance_id|. Returns false, if not
124   // GATT service with the given ID is known. If the given service has no
125   // included services, then |out_service| will be empty. |out_service| must not
126   // be NULL. If it is non-empty, then its contents will be cleared.
127   Status GetIncludedServices(const std::string& instance_id,
128                              ServiceList* out_services) const;
129
130   // Returns the list of api::bluetooth_low_energy::Characteristic objects
131   // associated with the GATT service with instance ID |instance_id| in
132   // |out_characteristics|. Returns false, if no service with the given instance
133   // ID is known. If the service is found but it has no characteristics, then
134   // returns true and leaves |out_characteristics| empty.
135   // |out_characteristics| must not be NULL and if it is non-empty,
136   // then its contents will be cleared. |extension| is the extension that made
137   // the call.
138   typedef std::vector<linked_ptr<api::bluetooth_low_energy::Characteristic> >
139       CharacteristicList;
140   Status GetCharacteristics(const Extension* extension,
141                             const std::string& instance_id,
142                             CharacteristicList* out_characteristics) const;
143
144   // Populates |out_characteristic| based on GATT characteristic with instance
145   // ID |instance_id|. |out_characteristic| must not be NULL. |extension| is the
146   // extension that made the call.
147   Status GetCharacteristic(
148       const Extension* extension,
149       const std::string& instance_id,
150       api::bluetooth_low_energy::Characteristic* out_characteristic) const;
151
152   // Returns the list of api::bluetooth_low_energy::Descriptor objects
153   // associated with the GATT characteristic with instance ID |instance_id| in
154   // |out_descriptors|. If the characteristic is found but it has no
155   // descriptors, then returns true and leaves |out_descriptors| empty.
156   // |out_descriptors| must not be NULL and if it is non-empty,
157   // then its contents will be cleared. |extension| is the extension that made
158   // the call.
159   typedef std::vector<linked_ptr<api::bluetooth_low_energy::Descriptor> >
160       DescriptorList;
161   Status GetDescriptors(const Extension* extension,
162                         const std::string& instance_id,
163                         DescriptorList* out_descriptors) const;
164
165   // Populates |out_descriptor| based on GATT characteristic descriptor with
166   // instance ID |instance_id|. |out_descriptor| must not be NULL.
167   // |extension| is the extension that made the call.
168   Status GetDescriptor(
169       const Extension* extension,
170       const std::string& instance_id,
171       api::bluetooth_low_energy::Descriptor* out_descriptor) const;
172
173   // Sends a request to read the value of the characteristic with intance ID
174   // |instance_id|. Invokes |callback| on success and |error_callback| on
175   // failure. |extension| is the extension that made the call.
176   void ReadCharacteristicValue(const Extension* extension,
177                                const std::string& instance_id,
178                                const base::Closure& callback,
179                                const ErrorCallback& error_callback);
180
181   // Sends a request to write the value of the characteristic with instance ID
182   // |instance_id|. Invokes |callback| on success and |error_callback| on
183   // failure. |extension| is the extension that made the call.
184   void WriteCharacteristicValue(const Extension* extension,
185                                 const std::string& instance_id,
186                                 const std::vector<uint8>& value,
187                                 const base::Closure& callback,
188                                 const ErrorCallback& error_callback);
189
190   // Sends a request to start characteristic notifications from characteristic
191   // with instance ID |instance_id|, for extension |extension|. Invokes
192   // |callback| on success and |error_callback| on failure. If |persistent| is
193   // true, then the allocated connection resource is persistent across unloads.
194   void StartCharacteristicNotifications(bool persistent,
195                                         const Extension* extension,
196                                         const std::string& instance_id,
197                                         const base::Closure& callback,
198                                         const ErrorCallback& error_callback);
199
200   // Sends a request to stop characteristic notifications from characteristic
201   // with instance ID |instance_id|, for extension |extension|. Invokes
202   // |callback| on success and |error_callback| on failure.
203   void StopCharacteristicNotifications(const Extension* extension,
204                                        const std::string& instance_id,
205                                        const base::Closure& callback,
206                                        const ErrorCallback& error_callback);
207
208   // Sends a request to read the value of the descriptor with instance ID
209   // |instance_id|. Invokes |callback| on success and |error_callback| on
210   // failure. |extension| is the extension that made the call.
211   void ReadDescriptorValue(const Extension* extension,
212                            const std::string& instance_id,
213                            const base::Closure& callback,
214                            const ErrorCallback& error_callback);
215
216   // Sends a request to write the value of the descriptor with instance ID
217   // |instance_id|. Invokes |callback| on success and |error_callback| on
218   // failure. |extension| is the extension that made the call.
219   void WriteDescriptorValue(const Extension* extension,
220                             const std::string& instance_id,
221                             const std::vector<uint8>& value,
222                             const base::Closure& callback,
223                             const ErrorCallback& error_callback);
224
225   // Initializes the adapter for testing. Used by unit tests only.
226   void SetAdapterForTesting(device::BluetoothAdapter* adapter);
227
228   // device::BluetoothAdapter::Observer overrides.
229   virtual void GattServiceAdded(device::BluetoothAdapter* adapter,
230                                 device::BluetoothDevice* device,
231                                 device::BluetoothGattService* service) OVERRIDE;
232   virtual void GattServiceRemoved(
233       device::BluetoothAdapter* adapter,
234       device::BluetoothDevice* device,
235       device::BluetoothGattService* service) OVERRIDE;
236   virtual void GattDiscoveryCompleteForService(
237       device::BluetoothAdapter* adapter,
238       device::BluetoothGattService* service) OVERRIDE;
239   virtual void GattServiceChanged(
240       device::BluetoothAdapter* adapter,
241       device::BluetoothGattService* service) OVERRIDE;
242   virtual void GattCharacteristicAdded(
243       device::BluetoothAdapter* adapter,
244       device::BluetoothGattCharacteristic* characteristic) OVERRIDE;
245   virtual void GattCharacteristicRemoved(
246       device::BluetoothAdapter* adapter,
247       device::BluetoothGattCharacteristic* characteristic) OVERRIDE;
248   virtual void GattDescriptorAdded(
249       device::BluetoothAdapter* adapter,
250       device::BluetoothGattDescriptor* descriptor) OVERRIDE;
251   virtual void GattDescriptorRemoved(
252       device::BluetoothAdapter* adapter,
253       device::BluetoothGattDescriptor* descriptor) OVERRIDE;
254   virtual void GattCharacteristicValueChanged(
255       device::BluetoothAdapter* adapter,
256       device::BluetoothGattCharacteristic* characteristic,
257       const std::vector<uint8>& value) OVERRIDE;
258   virtual void GattDescriptorValueChanged(
259       device::BluetoothAdapter* adapter,
260       device::BluetoothGattDescriptor* descriptor,
261       const std::vector<uint8>& value) OVERRIDE;
262
263  private:
264   // Called by BluetoothAdapterFactory.
265   void OnGetAdapter(const base::Closure& callback,
266                     scoped_refptr<device::BluetoothAdapter> adapter);
267
268   // Initializes the identifier for all existing GATT objects and devices.
269   // Called by OnGetAdapter and SetAdapterForTesting.
270   void InitializeIdentifierMappings();
271
272   // Sends the event named |event_name| to all listeners of that event that
273   // have the Bluetooth UUID manifest permission for UUID |uuid| and the
274   // "low_energy" manifest permission, with |args| as the argument to that
275   // event. If the event involves a characteristic, then |characteristic_id|
276   // should be the instance ID of the involved characteristic. Otherwise, an
277   // empty string should be passed.
278   void DispatchEventToExtensionsWithPermission(
279       const std::string& event_name,
280       const device::BluetoothUUID& uuid,
281       const std::string& characteristic_id,
282       scoped_ptr<base::ListValue> args);
283
284   // Returns a BluetoothGattService by its instance ID |instance_id|. Returns
285   // NULL, if the service cannot be found.
286   device::BluetoothGattService* FindServiceById(
287       const std::string& instance_id) const;
288
289   // Returns a BluetoothGattCharacteristic by its instance ID |instance_id|.
290   // Returns NULL, if the characteristic cannot be found.
291   device::BluetoothGattCharacteristic* FindCharacteristicById(
292       const std::string& instance_id) const;
293
294   // Returns a BluetoothGattDescriptor by its instance ID |instance_id|.
295   // Returns NULL, if the descriptor cannot be found.
296   device::BluetoothGattDescriptor* FindDescriptorById(
297       const std::string& instance_id) const;
298
299   // Called by BluetoothGattCharacteristic and BluetoothGattDescriptor in
300   // response to ReadRemoteCharacteristic and ReadRemoteDescriptor.
301   void OnValueSuccess(const base::Closure& callback,
302                       const std::vector<uint8>& value);
303
304   // Called by BluetoothDevice in response to a call to CreateGattConnection.
305   void OnCreateGattConnection(
306       bool persistent,
307       const std::string& extension_id,
308       const std::string& device_address,
309       const base::Closure& callback,
310       scoped_ptr<device::BluetoothGattConnection> connection);
311
312   // Called by BluetoothGattConnection in response to a call to Disconnect.
313   void OnDisconnect(const std::string& extension_id,
314                     const std::string& device_address,
315                     const base::Closure& callback);
316
317   // Called by BluetoothGattCharacteristic and BluetoothGattDescriptor in
318   // case of an error during the read/write operations.
319   void OnError(const ErrorCallback& error_callback);
320
321   // Called by BluetoothDevice in response to a call to CreateGattConnection.
322   void OnConnectError(const std::string& extension_id,
323                       const std::string& device_address,
324                       const ErrorCallback& error_callback,
325                       device::BluetoothDevice::ConnectErrorCode error_code);
326
327   // Called by BluetoothGattCharacteristic in response to a call to
328   // StartNotifySession.
329   void OnStartNotifySession(
330       bool persistent,
331       const std::string& extension_id,
332       const std::string& characteristic_id,
333       const base::Closure& callback,
334       scoped_ptr<device::BluetoothGattNotifySession> session);
335
336   // Called by BluetoothGattCharacteristic in response to a call to
337   // StartNotifySession.
338   void OnStartNotifySessionError(const std::string& extension_id,
339                                  const std::string& characteristic_id,
340                                  const ErrorCallback& error_callback);
341
342   // Called by BluetoothGattNotifySession in response to a call to Stop.
343   void OnStopNotifySession(const std::string& extension_id,
344                            const std::string& characteristic_id,
345                            const base::Closure& callback);
346
347   // Finds and returns a BluetoothLowEnergyConnection to device with address
348   // |device_address| from the managed API resources for extension with ID
349   // |extension_id|.
350   BluetoothLowEnergyConnection* FindConnection(
351       const std::string& extension_id,
352       const std::string& device_address);
353
354   // Removes the connection to device with address |device_address| from the
355   // managed API resources for extension with ID |extension_id|. Returns false,
356   // if the connection could not be found.
357   bool RemoveConnection(const std::string& extension_id,
358                         const std::string& device_address);
359
360   // Finds and returns a BluetoothLowEnergyNotifySession associated with
361   // characteristic with instance ID |characteristic_id| from the managed API
362   // API resources for extension with ID |extension_id|.
363   BluetoothLowEnergyNotifySession* FindNotifySession(
364       const std::string& extension_id,
365       const std::string& characteristic_id);
366
367   // Removes the notify session associated with characteristic with
368   // instance ID |characteristic_id| from the managed API resources for
369   // extension with ID |extension_id|. Returns false, if the session could
370   // not be found.
371   bool RemoveNotifySession(const std::string& extension_id,
372                            const std::string& characteristic_id);
373
374   // Mapping from instance ids to identifiers of owning instances. The keys are
375   // used to identify individual instances of GATT objects and are used by
376   // bluetoothLowEnergy API functions to obtain the correct GATT object to
377   // operate on. Instance IDs are string identifiers that are returned by the
378   // device/bluetooth API, by calling GetIdentifier() on the corresponding
379   // device::BluetoothGatt* instance.
380   //
381   // This mapping is necessary, as GATT object instances can only be obtained
382   // from the object that owns it, where raw pointers should not be cached. E.g.
383   // to obtain a device::BluetoothGattCharacteristic, it is necessary to obtain
384   // a pointer to the associated device::BluetoothDevice, and then to the
385   // device::BluetoothGattService that owns the characteristic.
386   typedef std::map<std::string, std::string> InstanceIdMap;
387   InstanceIdMap service_id_to_device_address_;
388   InstanceIdMap chrc_id_to_service_id_;
389   InstanceIdMap desc_id_to_chrc_id_;
390
391   // Pointer to the current BluetoothAdapter instance. This represents a local
392   // Bluetooth adapter of the system.
393   scoped_refptr<device::BluetoothAdapter> adapter_;
394
395   // Set of extension ID + device addresses to which a connect/disconnect is
396   // currently pending.
397   std::set<std::string> connecting_devices_;
398   std::set<std::string> disconnecting_devices_;
399
400   // Set of extension ID + characteristic ID to which a request to start a
401   // notify session is currently pending.
402   std::set<std::string> pending_session_calls_;
403
404   // BrowserContext passed during initialization.
405   content::BrowserContext* browser_context_;
406
407   // Note: This should remain the last member so it'll be destroyed and
408   // invalidate its weak pointers before any other members are destroyed.
409   base::WeakPtrFactory<BluetoothLowEnergyEventRouter> weak_ptr_factory_;
410
411   DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyEventRouter);
412 };
413
414 }  // namespace extensions
415
416 #endif  // CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_LOW_ENERGY_BLUETOOTH_LOW_ENERGY_EVENT_ROUTER_H_