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/api/profile_keyed_api_factory.h"
11 #include "chrome/browser/extensions/chrome_extension_function.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/extensions/api/webrtc_audio_private.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "media/audio/audio_device_name.h"
19 class SingleThreadTaskRunner;
22 namespace extensions {
24 // Listens for device changes and forwards as an extension event.
25 class WebrtcAudioPrivateEventService
26 : public ProfileKeyedAPI,
27 public base::SystemMonitor::DevicesChangedObserver {
29 explicit WebrtcAudioPrivateEventService(Profile* profile);
30 virtual ~WebrtcAudioPrivateEventService();
32 // ProfileKeyedAPI implementation.
33 virtual void Shutdown() OVERRIDE;
34 static ProfileKeyedAPIFactory<WebrtcAudioPrivateEventService>*
36 static const char* service_name();
38 // base::SystemMonitor::DevicesChangedObserver implementation.
39 virtual void OnDevicesChanged(
40 base::SystemMonitor::DeviceType device_type) OVERRIDE;
43 friend class ProfileKeyedAPIFactory<WebrtcAudioPrivateEventService>;
50 class WebrtcAudioPrivateGetSinksFunction : public ChromeAsyncExtensionFunction {
52 virtual ~WebrtcAudioPrivateGetSinksFunction() {}
55 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getSinks",
56 WEBRTC_AUDIO_PRIVATE_GET_SINKS);
58 virtual bool RunImpl() OVERRIDE;
60 void DoneOnUIThread();
63 // Common base for functions that start by retrieving the list of
64 // controllers for the specified tab.
65 class WebrtcAudioPrivateTabIdFunction : public ChromeAsyncExtensionFunction {
67 virtual ~WebrtcAudioPrivateTabIdFunction() {}
70 bool DoRunImpl(int tab_id);
71 virtual void OnControllerList(
72 const content::RenderViewHost::AudioOutputControllerList& list) = 0;
75 class WebrtcAudioPrivateGetActiveSinkFunction
76 : public WebrtcAudioPrivateTabIdFunction {
78 virtual ~WebrtcAudioPrivateGetActiveSinkFunction() {}
81 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
82 WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
84 virtual bool RunImpl() OVERRIDE;
85 virtual void OnControllerList(
86 const content::RenderViewHost::AudioOutputControllerList&
87 controllers) OVERRIDE;
88 void OnSinkId(const std::string&);
91 class WebrtcAudioPrivateSetActiveSinkFunction
92 : public WebrtcAudioPrivateTabIdFunction {
94 WebrtcAudioPrivateSetActiveSinkFunction();
97 virtual ~WebrtcAudioPrivateSetActiveSinkFunction();
100 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
101 WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
103 virtual bool RunImpl() OVERRIDE;
104 virtual void OnControllerList(
105 const content::RenderViewHost::AudioOutputControllerList&
106 controllers) OVERRIDE;
108 void DoneOnUIThread();
110 // Task runner of the thread this class is constructed on.
111 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
114 std::string sink_id_;
116 // Number of sink IDs we are still waiting for. Can become greater
117 // than 0 in OnControllerList, decreases on every OnSinkId call.
118 size_t num_remaining_sink_ids_;
121 class WebrtcAudioPrivateGetAssociatedSinkFunction
122 : public ChromeAsyncExtensionFunction {
124 WebrtcAudioPrivateGetAssociatedSinkFunction();
127 virtual ~WebrtcAudioPrivateGetAssociatedSinkFunction();
130 DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
131 WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
133 virtual bool RunImpl() OVERRIDE;
135 // This implementation is slightly complicated because of different
136 // thread requirements for the various functions we need to invoke.
138 // All OnXyzDone callbacks occur on the UI thread, and they trigger
139 // the next step (or send the response in case of the last step).
141 // The sequence of events is:
142 // 1. Get the list of source devices on the device thread.
143 // 2. Given a source ID for an origin and that security origin, find
144 // the raw source ID. This needs to happen on the IO thread since
145 // we will be using the ResourceContext.
146 // 3. Given a raw source ID, get the associated sink ID on the
149 // Fills in |source_devices_|. OnGetDevicesDone will be invoked on
150 // the UI thread once done.
151 void GetDevicesOnDeviceThread();
152 void OnGetDevicesDone();
154 // Takes the parameters of the function, returns the raw source
155 // device ID, or the empty string if none.
156 std::string GetRawSourceIDOnIOThread(content::ResourceContext* context,
157 GURL security_origin,
158 const std::string& source_id_in_origin);
159 void OnGetRawSourceIDDone(const std::string& raw_source_id);
161 // Given a raw source ID, get its associated sink, which needs to
162 // happen on the device thread.
163 std::string GetAssociatedSinkOnDeviceThread(const std::string& raw_source_id);
164 void OnGetAssociatedSinkDone(const std::string& associated_sink_id);
166 // Accessed from UI thread and device thread, but only on one at a
167 // time, no locking needed.
168 scoped_ptr<api::webrtc_audio_private::GetAssociatedSink::Params> params_;
170 // Filled in by DoWorkOnDeviceThread.
171 media::AudioDeviceNames source_devices_;
174 } // namespace extensions
176 #endif // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_