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