Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_ui_proxy.cc
blobb6c7f1f49cbcd81f8611b363bea8d93b70b69564
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 "content/browser/renderer_host/render_view_host_delegate.h"
8 #include "content/browser/renderer_host/render_view_host_impl.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "media/video/capture/fake_video_capture_device.h"
12 namespace content {
14 class MediaStreamUIProxy::Core {
15 public:
16 explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
17 RenderViewHostDelegate* test_render_delegate);
18 ~Core();
20 void RequestAccess(const MediaStreamRequest& request);
21 void OnStarted(gfx::NativeViewId* window_id);
23 private:
24 void ProcessAccessRequestResponse(const MediaStreamDevices& devices,
25 content::MediaStreamRequestResult result,
26 scoped_ptr<MediaStreamUI> stream_ui);
27 void ProcessStopRequestFromUI();
29 base::WeakPtr<MediaStreamUIProxy> proxy_;
30 scoped_ptr<MediaStreamUI> ui_;
32 RenderViewHostDelegate* const test_render_delegate_;
34 // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way
35 // cancel media requests.
36 base::WeakPtrFactory<Core> weak_factory_;
38 DISALLOW_COPY_AND_ASSIGN(Core);
41 MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
42 RenderViewHostDelegate* test_render_delegate)
43 : proxy_(proxy),
44 test_render_delegate_(test_render_delegate),
45 weak_factory_(this) {
48 MediaStreamUIProxy::Core::~Core() {
49 DCHECK_CURRENTLY_ON(BrowserThread::UI);
52 void MediaStreamUIProxy::Core::RequestAccess(
53 const MediaStreamRequest& request) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI);
56 RenderViewHostDelegate* render_delegate;
58 if (test_render_delegate_) {
59 render_delegate = test_render_delegate_;
60 } else {
61 RenderViewHostImpl* host = RenderViewHostImpl::FromID(
62 request.render_process_id, request.render_view_id);
64 // Tab may have gone away.
65 if (!host || !host->GetDelegate()) {
66 ProcessAccessRequestResponse(
67 MediaStreamDevices(),
68 MEDIA_DEVICE_INVALID_STATE,
69 scoped_ptr<MediaStreamUI>());
70 return;
73 render_delegate = host->GetDelegate();
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 RenderViewHostDelegate* render_delegate) {
118 return scoped_ptr<MediaStreamUIProxy>(
119 new MediaStreamUIProxy(render_delegate));
122 MediaStreamUIProxy::MediaStreamUIProxy(
123 RenderViewHostDelegate* 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);
131 BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, core_.release());
134 void MediaStreamUIProxy::RequestAccess(
135 const MediaStreamRequest& request,
136 const ResponseCallback& response_callback) {
137 DCHECK_CURRENTLY_ON(BrowserThread::IO);
139 response_callback_ = response_callback;
140 BrowserThread::PostTask(
141 BrowserThread::UI, FROM_HERE,
142 base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request));
145 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback,
146 const WindowIdCallback& window_id_callback) {
147 DCHECK_CURRENTLY_ON(BrowserThread::IO);
149 stop_callback_ = stop_callback;
151 // Owned by the PostTaskAndReply callback.
152 gfx::NativeViewId* window_id = new gfx::NativeViewId(0);
154 BrowserThread::PostTaskAndReply(
155 BrowserThread::UI,
156 FROM_HERE,
157 base::Bind(&Core::OnStarted, base::Unretained(core_.get()), window_id),
158 base::Bind(&MediaStreamUIProxy::OnWindowId,
159 weak_factory_.GetWeakPtr(),
160 window_id_callback,
161 base::Owned(window_id)));
164 void MediaStreamUIProxy::OnWindowId(const WindowIdCallback& window_id_callback,
165 gfx::NativeViewId* window_id) {
166 DCHECK_CURRENTLY_ON(BrowserThread::IO);
167 if (!window_id_callback.is_null())
168 window_id_callback.Run(*window_id);
171 void MediaStreamUIProxy::ProcessAccessRequestResponse(
172 const MediaStreamDevices& devices,
173 content::MediaStreamRequestResult result) {
174 DCHECK_CURRENTLY_ON(BrowserThread::IO);
175 DCHECK(!response_callback_.is_null());
177 ResponseCallback cb = response_callback_;
178 response_callback_.Reset();
179 cb.Run(devices, result);
182 void MediaStreamUIProxy::ProcessStopRequestFromUI() {
183 DCHECK_CURRENTLY_ON(BrowserThread::IO);
184 DCHECK(!stop_callback_.is_null());
186 base::Closure cb = stop_callback_;
187 stop_callback_.Reset();
188 cb.Run();
191 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
192 : MediaStreamUIProxy(NULL) {
195 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {}
197 void FakeMediaStreamUIProxy::SetAvailableDevices(
198 const MediaStreamDevices& devices) {
199 devices_ = devices;
202 void FakeMediaStreamUIProxy::RequestAccess(
203 const MediaStreamRequest& request,
204 const ResponseCallback& response_callback) {
205 DCHECK_CURRENTLY_ON(BrowserThread::IO);
207 response_callback_ = response_callback;
209 MediaStreamDevices devices_to_use;
210 bool accepted_audio = false;
211 bool accepted_video = false;
213 // Use the first capture device of the same media type in the list for the
214 // fake UI.
215 for (MediaStreamDevices::const_iterator it = devices_.begin();
216 it != devices_.end(); ++it) {
217 if (!accepted_audio &&
218 IsAudioMediaType(request.audio_type) &&
219 IsAudioMediaType(it->type) &&
220 (request.requested_audio_device_id.empty() ||
221 request.requested_audio_device_id == it->id)) {
222 devices_to_use.push_back(*it);
223 accepted_audio = true;
224 } else if (!accepted_video &&
225 IsVideoMediaType(request.video_type) &&
226 IsVideoMediaType(it->type) &&
227 (request.requested_video_device_id.empty() ||
228 request.requested_video_device_id == it->id)) {
229 devices_to_use.push_back(*it);
230 accepted_video = true;
234 // Fail the request if a device exist for the requested type.
235 if ((request.audio_type != MEDIA_NO_SERVICE && !accepted_audio) ||
236 (request.video_type != MEDIA_NO_SERVICE && !accepted_video)) {
237 devices_to_use.clear();
240 BrowserThread::PostTask(
241 BrowserThread::IO, FROM_HERE,
242 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
243 weak_factory_.GetWeakPtr(),
244 devices_to_use,
245 devices_to_use.empty() ?
246 MEDIA_DEVICE_NO_HARDWARE :
247 MEDIA_DEVICE_OK));
250 void FakeMediaStreamUIProxy::OnStarted(
251 const base::Closure& stop_callback,
252 const WindowIdCallback& window_id_callback) {}
254 } // namespace content