bluetooth_event_router.h revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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 CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_EVENT_ROUTER_H_
6#define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_EVENT_ROUTER_H_
7
8#include <map>
9
10#include "base/callback_forward.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_vector.h"
13#include "base/memory/weak_ptr.h"
14#include "chrome/common/extensions/api/bluetooth.h"
15#include "chrome/common/extensions/api/bluetooth_private.h"
16#include "content/public/browser/notification_observer.h"
17#include "content/public/browser/notification_registrar.h"
18#include "device/bluetooth/bluetooth_adapter.h"
19#include "device/bluetooth/bluetooth_adapter_factory.h"
20#include "device/bluetooth/bluetooth_socket.h"
21
22namespace content {
23class BrowserContext;
24}
25
26namespace device {
27
28class BluetoothDevice;
29class BluetoothDiscoverySession;
30class BluetoothProfile;
31
32}  // namespace device
33
34namespace extensions {
35
36class BluetoothApiPairingDelegate;
37
38class BluetoothEventRouter : public device::BluetoothAdapter::Observer,
39                             public content::NotificationObserver {
40 public:
41  explicit BluetoothEventRouter(content::BrowserContext* context);
42  virtual ~BluetoothEventRouter();
43
44  // Returns true if adapter_ has been initialized for testing or bluetooth
45  // adapter is available for the current platform.
46  bool IsBluetoothSupported() const;
47
48  void GetAdapter(
49      const device::BluetoothAdapterFactory::AdapterCallback& callback);
50
51  // Register the BluetoothSocket |socket| for use by the extensions system.
52  // This class will hold onto the socket for its lifetime until
53  // ReleaseSocket is called for the socket, or until the extension associated
54  // with the socket is disabled/ reloaded. Returns an id for the socket.
55  int RegisterSocket(const std::string& extension_id,
56                     scoped_refptr<device::BluetoothSocket> socket);
57
58  // Release the BluetoothSocket corresponding to |id|.  Returns true if
59  // the socket was found and released, false otherwise.
60  bool ReleaseSocket(int id);
61
62  // Add the BluetoothProfile |bluetooth_profile| for use by the extension
63  // system. This class will hold onto the profile until RemoveProfile is
64  // called for the profile, or until the extension that added the profile
65  // is disabled/reloaded.
66  void AddProfile(const std::string& uuid,
67                  const std::string& extension_id,
68                  device::BluetoothProfile* bluetooth_profile);
69
70  // Unregister the BluetoothProfile corersponding to |uuid| and release the
71  // object from this class.
72  void RemoveProfile(const std::string& uuid);
73
74  // Returns true if the BluetoothProfile corresponding to |uuid| is already
75  // registered.
76  bool HasProfile(const std::string& uuid) const;
77
78  // Requests that a new device discovery session be initiated for extension
79  // with id |extension_id|. |callback| is called, if a session has been
80  // initiated. |error_callback| is called, if the adapter failed to initiate
81  // the session or if an active session already exists for the extension.
82  void StartDiscoverySession(device::BluetoothAdapter* adapter,
83                             const std::string& extension_id,
84                             const base::Closure& callback,
85                             const base::Closure& error_callback);
86
87  // Requests that the active discovery session that belongs to the extension
88  // with id |extension_id| be terminated. |callback| is called, if the session
89  // successfully ended. |error_callback| is called, if the adapter failed to
90  // terminate the session or if no active discovery session exists for the
91  // extension.
92  void StopDiscoverySession(device::BluetoothAdapter* adapter,
93                            const std::string& extension_id,
94                            const base::Closure& callback,
95                            const base::Closure& error_callback);
96
97  // Returns the BluetoothProfile that corresponds to |uuid|. It returns NULL
98  // if the BluetoothProfile with |uuid| does not exist.
99  device::BluetoothProfile* GetProfile(const std::string& uuid) const;
100
101  // Get the BluetoothSocket corresponding to |id|.
102  scoped_refptr<device::BluetoothSocket> GetSocket(int id);
103
104  // Dispatch an event that takes a connection socket as a parameter to the
105  // extension that registered the profile that the socket has connected to.
106  void DispatchConnectionEvent(const std::string& extension_id,
107                               const std::string& uuid,
108                               const device::BluetoothDevice* device,
109                               scoped_refptr<device::BluetoothSocket> socket);
110
111  // Called when a bluetooth event listener is added.
112  void OnListenerAdded();
113
114  // Called when a bluetooth event listener is removed.
115  void OnListenerRemoved();
116
117  // Adds a pairing delegate for an extension.
118  void AddPairingDelegate(const std::string& extension_id);
119
120  // Removes the pairing delegate for an extension.
121  void RemovePairingDelegate(const std::string& extension_id);
122
123  // Returns the pairing delegate for an extension or NULL if it doesn't have a
124  // pairing delegate.
125  BluetoothApiPairingDelegate* GetPairingDelegate(
126      const std::string& extension_id);
127
128  // Exposed for testing.
129  void SetAdapterForTest(device::BluetoothAdapter* adapter) {
130    adapter_ = adapter;
131  }
132
133  // Override from device::BluetoothAdapter::Observer.
134  virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
135                                     bool present) OVERRIDE;
136  virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
137                                     bool has_power) OVERRIDE;
138  virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter,
139                                         bool discovering) OVERRIDE;
140  virtual void DeviceAdded(device::BluetoothAdapter* adapter,
141                           device::BluetoothDevice* device) OVERRIDE;
142  virtual void DeviceChanged(device::BluetoothAdapter* adapter,
143                             device::BluetoothDevice* device) OVERRIDE;
144  virtual void DeviceRemoved(device::BluetoothAdapter* adapter,
145                             device::BluetoothDevice* device) OVERRIDE;
146
147  // Overridden from content::NotificationObserver.
148  virtual void Observe(int type,
149                       const content::NotificationSource& source,
150                       const content::NotificationDetails& details) OVERRIDE;
151
152  // BrowserContextKeyedAPI implementation.
153  static const char* service_name() { return "BluetoothEventRouter"; }
154  static const bool kServiceRedirectedInIncognito = true;
155  static const bool kServiceIsNULLWhileTesting = true;
156
157 private:
158  // Forward declarations of internal structs.
159  struct ExtensionBluetoothSocketRecord;
160  struct ExtensionBluetoothProfileRecord;
161
162  void OnAdapterInitialized(const base::Closure& callback,
163                            scoped_refptr<device::BluetoothAdapter> adapter);
164  void MaybeReleaseAdapter();
165  void DispatchAdapterStateEvent();
166  void DispatchDeviceEvent(const std::string& event_name,
167                           device::BluetoothDevice* device);
168  void CleanUpForExtension(const std::string& extension_id);
169  void CleanUpAllExtensions();
170  void OnStartDiscoverySession(
171      const std::string& extension_id,
172      const base::Closure& callback,
173      scoped_ptr<device::BluetoothDiscoverySession> discovery_session);
174
175  content::BrowserContext* browser_context_;
176  scoped_refptr<device::BluetoothAdapter> adapter_;
177
178  int num_event_listeners_;
179
180  // The next id to use for referring to a BluetoothSocket.  We avoid using
181  // the fd of the socket because we don't want to leak that information to
182  // the extension javascript.
183  int next_socket_id_;
184
185  typedef std::map<int, ExtensionBluetoothSocketRecord> SocketMap;
186  SocketMap socket_map_;
187
188  // Maps uuids to a struct containing a Bluetooth profile and its
189  // associated extension id.
190  typedef std::map<std::string, ExtensionBluetoothProfileRecord>
191      BluetoothProfileMap;
192  BluetoothProfileMap bluetooth_profile_map_;
193
194  // A map that maps extension ids to BluetoothDiscoverySession pointers.
195  typedef std::map<std::string, device::BluetoothDiscoverySession*>
196      DiscoverySessionMap;
197  DiscoverySessionMap discovery_session_map_;
198
199  // Maps an extension id to its pairing delegate.
200  typedef std::map<std::string, BluetoothApiPairingDelegate*>
201      PairingDelegateMap;
202  PairingDelegateMap pairing_delegate_map_;
203
204  content::NotificationRegistrar registrar_;
205
206  base::WeakPtrFactory<BluetoothEventRouter> weak_ptr_factory_;
207
208  DISALLOW_COPY_AND_ASSIGN(BluetoothEventRouter);
209};
210
211}  // namespace extensions
212
213#endif  // CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_EVENT_ROUTER_H_
214