• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
7 
8 #include "base/memory/ref_counted.h"
9 #include "base/system_monitor/system_monitor.h"
10 #include "chrome/browser/extensions/chrome_extension_function.h"
11 #include "chrome/common/extensions/api/webrtc_audio_private.h"
12 #include "content/public/browser/render_view_host.h"
13 #include "extensions/browser/browser_context_keyed_api_factory.h"
14 #include "media/audio/audio_device_name.h"
15 #include "url/gurl.h"
16 
17 namespace content {
18 class ResourceContext;
19 }
20 
21 namespace extensions {
22 
23 // Listens for device changes and forwards as an extension event.
24 class WebrtcAudioPrivateEventService
25     : public BrowserContextKeyedAPI,
26       public base::SystemMonitor::DevicesChangedObserver {
27  public:
28   explicit WebrtcAudioPrivateEventService(content::BrowserContext* context);
29   virtual ~WebrtcAudioPrivateEventService();
30 
31   // BrowserContextKeyedAPI implementation.
32   virtual void Shutdown() OVERRIDE;
33   static BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>*
34       GetFactoryInstance();
35   static const char* service_name();
36 
37   // base::SystemMonitor::DevicesChangedObserver implementation.
38   virtual void OnDevicesChanged(
39       base::SystemMonitor::DeviceType device_type) OVERRIDE;
40 
41  private:
42   friend class BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>;
43 
44   void SignalEvent();
45 
46   content::BrowserContext* browser_context_;
47 };
48 
49 // Common base for WebrtcAudioPrivate functions, that provides a
50 // couple of optionally-used common implementations.
51 class WebrtcAudioPrivateFunction : public ChromeAsyncExtensionFunction {
52  protected:
53   WebrtcAudioPrivateFunction();
54   virtual ~WebrtcAudioPrivateFunction();
55 
56  protected:
57   // Retrieves the list of output device names on the appropriate
58   // thread. Call from UI thread, callback will occur on IO thread.
59   void GetOutputDeviceNames();
60 
61   // Must override this if you call GetOutputDeviceNames. Called on IO thread.
62   virtual void OnOutputDeviceNames(
63       scoped_ptr<media::AudioDeviceNames> device_names);
64 
65   // Retrieve the list of AudioOutputController objects. Calls back
66   // via OnControllerList.
67   //
68   // Returns false on error, in which case it has set |error_| and the
69   // entire function should fail.
70   //
71   // Call from any thread. Callback will occur on originating thread.
72   bool GetControllerList(int tab_id);
73 
74   // Must override this if you call GetControllerList.
75   virtual void OnControllerList(
76       const content::RenderViewHost::AudioOutputControllerList& list);
77 
78   // Calculates a single HMAC. Call from any thread. Calls back via
79   // OnHMACCalculated on UI thread.
80   //
81   // This function, and device ID HMACs in this API in general use the
82   // calling extension's ID as the security origin. The only exception
83   // to this rule is when calculating the input device ID HMAC in
84   // getAssociatedSink, where we use the provided |securityOrigin|.
85   void CalculateHMAC(const std::string& raw_id);
86 
87   // Must override this if you call CalculateHMAC.
88   virtual void OnHMACCalculated(const std::string& hmac);
89 
90   // Calculates a single HMAC, using the extension ID as the security origin.
91   //
92   // Call only on IO thread.
93   std::string CalculateHMACImpl(const std::string& raw_id);
94 
95   // Initializes |resource_context_|. Must be called on the UI thread,
96   // before any calls to |resource_context()|.
97   void InitResourceContext();
98 
99   // Callable from any thread. Must previously have called
100   // |InitResourceContext()|.
101   content::ResourceContext* resource_context() const;
102 
103  private:
104   content::ResourceContext* resource_context_;
105 
106   DISALLOW_COPY_AND_ASSIGN(WebrtcAudioPrivateFunction);
107 };
108 
109 class WebrtcAudioPrivateGetSinksFunction : public WebrtcAudioPrivateFunction {
110  protected:
~WebrtcAudioPrivateGetSinksFunction()111   virtual ~WebrtcAudioPrivateGetSinksFunction() {}
112 
113  private:
114   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getSinks",
115                              WEBRTC_AUDIO_PRIVATE_GET_SINKS);
116 
117   // Sequence of events is that we query the list of sinks on the
118   // AudioManager's thread, then calculate HMACs on the IO thread,
119   // then finish on the UI thread.
120   virtual bool RunAsync() OVERRIDE;
121   void DoQuery();
122   virtual void OnOutputDeviceNames(
123       scoped_ptr<media::AudioDeviceNames> raw_ids) OVERRIDE;
124   void DoneOnUIThread();
125 };
126 
127 class WebrtcAudioPrivateGetActiveSinkFunction
128     : public WebrtcAudioPrivateFunction {
129  protected:
~WebrtcAudioPrivateGetActiveSinkFunction()130   virtual ~WebrtcAudioPrivateGetActiveSinkFunction() {}
131 
132  private:
133   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
134                              WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
135 
136   virtual bool RunAsync() OVERRIDE;
137   virtual void OnControllerList(
138       const content::RenderViewHost::AudioOutputControllerList&
139       controllers) OVERRIDE;
140   virtual void OnHMACCalculated(const std::string& hmac) OVERRIDE;
141 };
142 
143 class WebrtcAudioPrivateSetActiveSinkFunction
144     : public WebrtcAudioPrivateFunction {
145  public:
146   WebrtcAudioPrivateSetActiveSinkFunction();
147 
148  protected:
149   virtual ~WebrtcAudioPrivateSetActiveSinkFunction();
150 
151  private:
152   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
153                              WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
154 
155   virtual bool RunAsync() OVERRIDE;
156   virtual void OnControllerList(
157       const content::RenderViewHost::AudioOutputControllerList&
158       controllers) OVERRIDE;
159   virtual void OnOutputDeviceNames(
160       scoped_ptr<media::AudioDeviceNames> device_names) OVERRIDE;
161   void SwitchDone();
162   void DoneOnUIThread();
163 
164   int tab_id_;
165   std::string sink_id_;
166 
167   // Filled in by OnControllerList.
168   content::RenderViewHost::AudioOutputControllerList controllers_;
169 
170   // Number of sink IDs we are still waiting for. Can become greater
171   // than 0 in OnControllerList, decreases on every OnSinkId call.
172   size_t num_remaining_sink_ids_;
173 };
174 
175 class WebrtcAudioPrivateGetAssociatedSinkFunction
176     : public WebrtcAudioPrivateFunction {
177  public:
178   WebrtcAudioPrivateGetAssociatedSinkFunction();
179 
180  protected:
181   virtual ~WebrtcAudioPrivateGetAssociatedSinkFunction();
182 
183  private:
184   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
185                              WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
186 
187   virtual bool RunAsync() OVERRIDE;
188 
189   // This implementation is slightly complicated because of different
190   // thread requirements for the various functions we need to invoke.
191   //
192   // Each worker function will post a task to the appropriate thread
193   // for the next one.
194   //
195   // The sequence of events is:
196   // 1. Get the list of source devices on the device thread.
197   // 2. Given a source ID for an origin and that security origin, find
198   //    the raw source ID. This needs to happen on the IO thread since
199   //    we will be using the ResourceContext.
200   // 3. Given a raw source ID, get the raw associated sink ID on the
201   //    device thread.
202   // 4. Given the raw associated sink ID, get its HMAC on the IO thread.
203   // 5. Respond with the HMAC of the associated sink ID on the UI thread.
204 
205   // Fills in |source_devices_|. Note that these are input devices,
206   // not output devices, so don't use
207   // |WebrtcAudioPrivateFunction::GetOutputDeviceNames|.
208   void GetDevicesOnDeviceThread();
209 
210   // Takes the parameters of the function, retrieves the raw source
211   // device ID, or the empty string if none.
212   void GetRawSourceIDOnIOThread();
213 
214   // Gets the raw sink ID for a raw source ID. Sends it to |CalculateHMAC|.
215   void GetAssociatedSinkOnDeviceThread(const std::string& raw_source_id);
216 
217   // Receives the associated sink ID after its HMAC is calculated.
218   virtual void OnHMACCalculated(const std::string& hmac) OVERRIDE;
219 
220   // Accessed from UI thread and device thread, but only on one at a
221   // time, no locking needed.
222   scoped_ptr<api::webrtc_audio_private::GetAssociatedSink::Params> params_;
223 
224   // Audio sources (input devices). Filled in by DoWorkOnDeviceThread.
225   media::AudioDeviceNames source_devices_;
226 };
227 
228 }  // namespace extensions
229 
230 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
231