Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / extensions / browser / api / bluetooth_low_energy / bluetooth_low_energy_event_router.h
blob696dd9cae4774ef0c1bfc48876a1b5f3cbdd3f35
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.
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_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
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"
22 namespace base {
24 class ListValue;
26 } // namespace base
28 namespace content {
30 class BrowserContext;
32 } // namespace content
34 namespace device {
36 class BluetoothGattNotifySession;
38 } // namespace device
40 namespace extensions {
42 class BluetoothLowEnergyConnection;
43 class BluetoothLowEnergyNotifySession;
44 class Extension;
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;
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,
75 // Error callback is used by asynchronous methods to report failures.
76 typedef base::Callback<void(Status)> ErrorCallback;
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;
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);
89 // Returns true, if the BluetoothAdapter was initialized.
90 bool HasAdapter() const;
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);
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);
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;
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;
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;
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;
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;
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;
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;
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);
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);
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);
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);
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);
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);
235 // Initializes the adapter for testing. Used by unit tests only.
236 void SetAdapterForTesting(device::BluetoothAdapter* adapter);
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;
270 private:
271 // Called by BluetoothAdapterFactory.
272 void OnGetAdapter(const base::Closure& callback,
273 scoped_refptr<device::BluetoothAdapter> adapter);
275 // Initializes the identifier for all existing GATT objects and devices.
276 // Called by OnGetAdapter and SetAdapterForTesting.
277 void InitializeIdentifierMappings();
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);
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;
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;
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;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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.
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_;
401 // Pointer to the current BluetoothAdapter instance. This represents a local
402 // Bluetooth adapter of the system.
403 scoped_refptr<device::BluetoothAdapter> adapter_;
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_;
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_;
414 // BrowserContext passed during initialization.
415 content::BrowserContext* browser_context_;
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_;
421 DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyEventRouter);
424 } // namespace extensions
426 #endif // EXTENSIONS_BROWSER_API_BLUETOOTH_LOW_ENERGY_BLUETOOTH_LOW_ENERGY_EVENT_ROUTER_H_