Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_ui_proxy.cc
blob837577ae98713a8aaf7f4f8d6fa6f286a05e20a2
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 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
7 #include "base/command_line.h"
8 #include "content/browser/frame_host/render_frame_host_delegate.h"
9 #include "content/browser/frame_host/render_frame_host_impl.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/common/content_switches.h"
12 #include "media/video/capture/fake_video_capture_device.h"
14 namespace content {
16 class MediaStreamUIProxy::Core {
17 public:
18 explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
19 RenderFrameHostDelegate* test_render_delegate);
20 ~Core();
22 void RequestAccess(const MediaStreamRequest& request);
23 void OnStarted(gfx::NativeViewId* window_id);
25 private:
26 void ProcessAccessRequestResponse(const MediaStreamDevices& devices,
27 content::MediaStreamRequestResult result,
28 scoped_ptr<MediaStreamUI> stream_ui);
29 void ProcessStopRequestFromUI();
31 base::WeakPtr<MediaStreamUIProxy> proxy_;
32 scoped_ptr<MediaStreamUI> ui_;
34 RenderFrameHostDelegate* const test_render_delegate_;
36 // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way
37 // cancel media requests.
38 base::WeakPtrFactory<Core> weak_factory_;
40 DISALLOW_COPY_AND_ASSIGN(Core);
43 MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
44 RenderFrameHostDelegate* test_render_delegate)
45 : proxy_(proxy),
46 test_render_delegate_(test_render_delegate),
47 weak_factory_(this) {
50 MediaStreamUIProxy::Core::~Core() {
51 DCHECK_CURRENTLY_ON(BrowserThread::UI);
54 void MediaStreamUIProxy::Core::RequestAccess(
55 const MediaStreamRequest& request) {
56 DCHECK_CURRENTLY_ON(BrowserThread::UI);
58 RenderFrameHostDelegate* render_delegate;
59 if (test_render_delegate_) {
60 render_delegate = test_render_delegate_;
61 } else {
62 RenderFrameHostImpl* const host = RenderFrameHostImpl::FromID(
63 request.render_process_id, request.render_frame_id);
64 render_delegate = host ? host->delegate() : NULL;
67 // Tab may have gone away, or has no delegate from which to request access.
68 if (!render_delegate) {
69 ProcessAccessRequestResponse(
70 MediaStreamDevices(),
71 MEDIA_DEVICE_INVALID_STATE,
72 scoped_ptr<MediaStreamUI>());
73 return;
76 render_delegate->RequestMediaAccessPermission(
77 request, base::Bind(&Core::ProcessAccessRequestResponse,
78 weak_factory_.GetWeakPtr()));
81 void MediaStreamUIProxy::Core::OnStarted(gfx::NativeViewId* window_id) {
82 DCHECK_CURRENTLY_ON(BrowserThread::UI);
83 if (ui_) {
84 *window_id = ui_->OnStarted(
85 base::Bind(&Core::ProcessStopRequestFromUI, base::Unretained(this)));
89 void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
90 const MediaStreamDevices& devices,
91 content::MediaStreamRequestResult result,
92 scoped_ptr<MediaStreamUI> stream_ui) {
93 DCHECK_CURRENTLY_ON(BrowserThread::UI);
95 ui_ = stream_ui.Pass();
96 BrowserThread::PostTask(
97 BrowserThread::IO, FROM_HERE,
98 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
99 proxy_, devices, result));
102 void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() {
103 DCHECK_CURRENTLY_ON(BrowserThread::UI);
105 BrowserThread::PostTask(
106 BrowserThread::IO, FROM_HERE,
107 base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_));
110 // static
111 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() {
112 return scoped_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL));
115 // static
116 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::CreateForTests(
117 RenderFrameHostDelegate* render_delegate) {
118 return scoped_ptr<MediaStreamUIProxy>(
119 new MediaStreamUIProxy(render_delegate));
122 MediaStreamUIProxy::MediaStreamUIProxy(
123 RenderFrameHostDelegate* test_render_delegate)
124 : weak_factory_(this) {
125 DCHECK_CURRENTLY_ON(BrowserThread::IO);
126 core_.reset(new Core(weak_factory_.GetWeakPtr(), test_render_delegate));
129 MediaStreamUIProxy::~MediaStreamUIProxy() {
130 DCHECK_CURRENTLY_ON(BrowserThread::IO);
133 void MediaStreamUIProxy::RequestAccess(
134 const MediaStreamRequest& request,
135 const ResponseCallback& response_callback) {
136 DCHECK_CURRENTLY_ON(BrowserThread::IO);
138 response_callback_ = response_callback;
139 BrowserThread::PostTask(
140 BrowserThread::UI, FROM_HERE,
141 base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request));
144 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback,
145 const WindowIdCallback& window_id_callback) {
146 DCHECK_CURRENTLY_ON(BrowserThread::IO);
148 stop_callback_ = stop_callback;
150 // Owned by the PostTaskAndReply callback.
151 gfx::NativeViewId* window_id = new gfx::NativeViewId(0);
153 BrowserThread::PostTaskAndReply(
154 BrowserThread::UI,
155 FROM_HERE,
156 base::Bind(&Core::OnStarted, base::Unretained(core_.get()), window_id),
157 base::Bind(&MediaStreamUIProxy::OnWindowId,
158 weak_factory_.GetWeakPtr(),
159 window_id_callback,
160 base::Owned(window_id)));
163 void MediaStreamUIProxy::OnWindowId(const WindowIdCallback& window_id_callback,
164 gfx::NativeViewId* window_id) {
165 DCHECK_CURRENTLY_ON(BrowserThread::IO);
166 if (!window_id_callback.is_null())
167 window_id_callback.Run(*window_id);
170 void MediaStreamUIProxy::ProcessAccessRequestResponse(
171 const MediaStreamDevices& devices,
172 content::MediaStreamRequestResult result) {
173 DCHECK_CURRENTLY_ON(BrowserThread::IO);
174 DCHECK(!response_callback_.is_null());
176 ResponseCallback cb = response_callback_;
177 response_callback_.Reset();
178 cb.Run(devices, result);
181 void MediaStreamUIProxy::ProcessStopRequestFromUI() {
182 DCHECK_CURRENTLY_ON(BrowserThread::IO);
183 DCHECK(!stop_callback_.is_null());
185 base::Closure cb = stop_callback_;
186 stop_callback_.Reset();
187 cb.Run();
190 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
191 : MediaStreamUIProxy(NULL) {
194 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {}
196 void FakeMediaStreamUIProxy::SetAvailableDevices(
197 const MediaStreamDevices& devices) {
198 devices_ = devices;
201 void FakeMediaStreamUIProxy::RequestAccess(
202 const MediaStreamRequest& request,
203 const ResponseCallback& response_callback) {
204 DCHECK_CURRENTLY_ON(BrowserThread::IO);
206 response_callback_ = response_callback;
208 if (CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
209 switches::kUseFakeUIForMediaStream) == "deny") {
210 // Immediately deny the request.
211 BrowserThread::PostTask(
212 BrowserThread::IO, FROM_HERE,
213 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
214 weak_factory_.GetWeakPtr(),
215 MediaStreamDevices(),
216 MEDIA_DEVICE_PERMISSION_DENIED));
217 return;
220 MediaStreamDevices devices_to_use;
221 bool accepted_audio = false;
222 bool accepted_video = false;
224 // Use the first capture device of the same media type in the list for the
225 // fake UI.
226 for (MediaStreamDevices::const_iterator it = devices_.begin();
227 it != devices_.end(); ++it) {
228 if (!accepted_audio &&
229 IsAudioInputMediaType(request.audio_type) &&
230 IsAudioInputMediaType(it->type) &&
231 (request.requested_audio_device_id.empty() ||
232 request.requested_audio_device_id == it->id)) {
233 devices_to_use.push_back(*it);
234 accepted_audio = true;
235 } else if (!accepted_video &&
236 IsVideoMediaType(request.video_type) &&
237 IsVideoMediaType(it->type) &&
238 (request.requested_video_device_id.empty() ||
239 request.requested_video_device_id == it->id)) {
240 devices_to_use.push_back(*it);
241 accepted_video = true;
245 // Fail the request if a device exist for the requested type.
246 if ((request.audio_type != MEDIA_NO_SERVICE && !accepted_audio) ||
247 (request.video_type != MEDIA_NO_SERVICE && !accepted_video)) {
248 devices_to_use.clear();
251 BrowserThread::PostTask(
252 BrowserThread::IO, FROM_HERE,
253 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
254 weak_factory_.GetWeakPtr(),
255 devices_to_use,
256 devices_to_use.empty() ?
257 MEDIA_DEVICE_NO_HARDWARE :
258 MEDIA_DEVICE_OK));
261 void FakeMediaStreamUIProxy::OnStarted(
262 const base::Closure& stop_callback,
263 const WindowIdCallback& window_id_callback) {}
265 } // namespace content