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.
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_
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"
18 class ResourceContext;
21 namespace extensions {
23 // Listens for device changes and forwards as an extension event.
24 class WebrtcAudioPrivateEventService
25 : public BrowserContextKeyedAPI,
26 public base::SystemMonitor::DevicesChangedObserver {
28 explicit WebrtcAudioPrivateEventService(content::BrowserContext* context);
29 virtual ~WebrtcAudioPrivateEventService();
31 // BrowserContextKeyedAPI implementation.
32 virtual void Shutdown() OVERRIDE;
33 static BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>*
35 static const char* service_name();
37 // base::SystemMonitor::DevicesChangedObserver implementation.
38 virtual void OnDevicesChanged(
39 base::SystemMonitor::DeviceType device_type) OVERRIDE;
42 friend class BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>;
46 content::BrowserContext* browser_context_;
49 // Common base for WebrtcAudioPrivate functions, that provides a
50 // couple of optionally-used common implementations.
51 class WebrtcAudioPrivateFunction : public ChromeAsyncExtensionFunction {
53 WebrtcAudioPrivateFunction();
54 virtual ~WebrtcAudioPrivateFunction();
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();
61 // Must override this if you call GetOutputDeviceNames. Called on IO thread.
62 virtual void OnOutputDeviceNames(
63 scoped_ptr<media::AudioDeviceNames> device_names);
65 // Retrieve the list of AudioOutputController objects. Calls back
66 // via OnControllerList.
68 // Returns false on error, in which case it has set |error_| and the
69 // entire function should fail.
71 // Call from any thread. Callback will occur on originating thread.
72 bool GetControllerList(int tab_id);
74 // Must override this if you call GetControllerList.
75 virtual void OnControllerList(
76 const content::RenderViewHost::AudioOutputControllerList& list);
78 // Calculates a single HMAC. Call from any thread. Calls back via
79 // OnHMACCalculated on UI thread.
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);
87 // Must override this if you call CalculateHMAC.
88 virtual void OnHMACCalculated(const std::string& hmac);
90 // Calculates a single HMAC, using the extension ID as the security origin.
92 // Call only on IO thread.
93 std::string CalculateHMACImpl(const std::string& raw_id);
95 // Initializes |resource_context_|. Must be called on the UI thread,
96 // before any calls to |resource_context()|.
97 void InitResourceContext();
99 // Callable from any thread. Must previously have called
100 // |InitResourceContext()|.
101 content::ResourceContext* resource_context() const;
104 content::ResourceContext* resource_context_;
106 DISALLOW_COPY_AND_ASSIGN(WebrtcAudioPrivateFunction);
109 class WebrtcAudioPrivateGetSinksFunction : public WebrtcAudioPrivateFunction {
111 virtual ~WebrtcAudioPrivateGetSinksFunction() {}
114 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getSinks",
115 WEBRTC_AUDIO_PRIVATE_GET_SINKS);
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;
122 virtual void OnOutputDeviceNames(
123 scoped_ptr<media::AudioDeviceNames> raw_ids) OVERRIDE;
124 void DoneOnUIThread();
127 class WebrtcAudioPrivateGetActiveSinkFunction
128 : public WebrtcAudioPrivateFunction {
130 virtual ~WebrtcAudioPrivateGetActiveSinkFunction() {}
133 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
134 WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
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;
143 class WebrtcAudioPrivateSetActiveSinkFunction
144 : public WebrtcAudioPrivateFunction {
146 WebrtcAudioPrivateSetActiveSinkFunction();
149 virtual ~WebrtcAudioPrivateSetActiveSinkFunction();
152 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
153 WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
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;
162 void DoneOnUIThread();
165 std::string sink_id_;
167 // Filled in by OnControllerList.
168 content::RenderViewHost::AudioOutputControllerList controllers_;
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_;
175 class WebrtcAudioPrivateGetAssociatedSinkFunction
176 : public WebrtcAudioPrivateFunction {
178 WebrtcAudioPrivateGetAssociatedSinkFunction();
181 virtual ~WebrtcAudioPrivateGetAssociatedSinkFunction();
184 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
185 WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
187 virtual bool RunAsync() OVERRIDE;
189 // This implementation is slightly complicated because of different
190 // thread requirements for the various functions we need to invoke.
192 // Each worker function will post a task to the appropriate thread
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
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.
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();
210 // Takes the parameters of the function, retrieves the raw source
211 // device ID, or the empty string if none.
212 void GetRawSourceIDOnIOThread();
214 // Gets the raw sink ID for a raw source ID. Sends it to |CalculateHMAC|.
215 void GetAssociatedSinkOnDeviceThread(const std::string& raw_source_id);
217 // Receives the associated sink ID after its HMAC is calculated.
218 virtual void OnHMACCalculated(const std::string& hmac) OVERRIDE;
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_;
224 // Audio sources (input devices). Filled in by DoWorkOnDeviceThread.
225 media::AudioDeviceNames source_devices_;
228 } // namespace extensions
230 #endif // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_