OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" | 5 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "content/browser/frame_host/render_frame_host_delegate.h" | 8 #include "content/browser/frame_host/render_frame_host_delegate.h" |
9 #include "content/browser/frame_host/render_frame_host_impl.h" | 9 #include "content/browser/frame_host/render_frame_host_impl.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
11 #include "content/public/common/content_switches.h" | 11 #include "content/public/common/content_switches.h" |
12 #include "media/video/capture/fake_video_capture_device.h" | 12 #include "media/video/capture/fake_video_capture_device.h" |
13 | 13 |
14 namespace content { | 14 namespace content { |
15 | 15 |
16 class MediaStreamUIProxy::Core { | 16 class MediaStreamUIProxy::Core { |
17 public: | 17 public: |
18 explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy, | 18 explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy, |
19 RenderFrameHostDelegate* test_render_delegate); | 19 RenderFrameHostDelegate* test_render_delegate); |
20 ~Core(); | 20 ~Core(); |
21 | 21 |
22 void RequestAccess(const MediaStreamRequest& request); | 22 void RequestAccess(const MediaStreamRequest& request); |
| 23 bool CheckAccess(const GURL& security_origin, |
| 24 MediaStreamType type, |
| 25 int process_id, |
| 26 int frame_id); |
23 void OnStarted(gfx::NativeViewId* window_id); | 27 void OnStarted(gfx::NativeViewId* window_id); |
24 | 28 |
25 private: | 29 private: |
26 void ProcessAccessRequestResponse(const MediaStreamDevices& devices, | 30 void ProcessAccessRequestResponse(const MediaStreamDevices& devices, |
27 content::MediaStreamRequestResult result, | 31 content::MediaStreamRequestResult result, |
28 scoped_ptr<MediaStreamUI> stream_ui); | 32 scoped_ptr<MediaStreamUI> stream_ui); |
29 void ProcessStopRequestFromUI(); | 33 void ProcessStopRequestFromUI(); |
| 34 RenderFrameHostDelegate* GetRenderFrameHostDelegate(int render_process_id, |
| 35 int render_frame_id); |
30 | 36 |
31 base::WeakPtr<MediaStreamUIProxy> proxy_; | 37 base::WeakPtr<MediaStreamUIProxy> proxy_; |
32 scoped_ptr<MediaStreamUI> ui_; | 38 scoped_ptr<MediaStreamUI> ui_; |
33 | 39 |
34 RenderFrameHostDelegate* const test_render_delegate_; | 40 RenderFrameHostDelegate* const test_render_delegate_; |
35 | 41 |
36 // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way | 42 // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way |
37 // cancel media requests. | 43 // cancel media requests. |
38 base::WeakPtrFactory<Core> weak_factory_; | 44 base::WeakPtrFactory<Core> weak_factory_; |
39 | 45 |
40 DISALLOW_COPY_AND_ASSIGN(Core); | 46 DISALLOW_COPY_AND_ASSIGN(Core); |
41 }; | 47 }; |
42 | 48 |
43 MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy, | 49 MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy, |
44 RenderFrameHostDelegate* test_render_delegate) | 50 RenderFrameHostDelegate* test_render_delegate) |
45 : proxy_(proxy), | 51 : proxy_(proxy), |
46 test_render_delegate_(test_render_delegate), | 52 test_render_delegate_(test_render_delegate), |
47 weak_factory_(this) { | 53 weak_factory_(this) { |
48 } | 54 } |
49 | 55 |
50 MediaStreamUIProxy::Core::~Core() { | 56 MediaStreamUIProxy::Core::~Core() { |
51 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 57 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
52 } | 58 } |
53 | 59 |
54 void MediaStreamUIProxy::Core::RequestAccess( | 60 void MediaStreamUIProxy::Core::RequestAccess( |
55 const MediaStreamRequest& request) { | 61 const MediaStreamRequest& request) { |
56 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 62 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
57 | 63 |
58 RenderFrameHostDelegate* render_delegate; | 64 RenderFrameHostDelegate* render_delegate = GetRenderFrameHostDelegate( |
59 if (test_render_delegate_) { | 65 request.render_process_id, request.render_frame_id); |
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; | |
65 } | |
66 | 66 |
67 // Tab may have gone away, or has no delegate from which to request access. | 67 // Tab may have gone away, or has no delegate from which to request access. |
68 if (!render_delegate) { | 68 if (!render_delegate) { |
69 ProcessAccessRequestResponse( | 69 ProcessAccessRequestResponse( |
70 MediaStreamDevices(), | 70 MediaStreamDevices(), |
71 MEDIA_DEVICE_INVALID_STATE, | 71 MEDIA_DEVICE_INVALID_STATE, |
72 scoped_ptr<MediaStreamUI>()); | 72 scoped_ptr<MediaStreamUI>()); |
73 return; | 73 return; |
74 } | 74 } |
75 | 75 |
76 render_delegate->RequestMediaAccessPermission( | 76 render_delegate->RequestMediaAccessPermission( |
77 request, base::Bind(&Core::ProcessAccessRequestResponse, | 77 request, base::Bind(&Core::ProcessAccessRequestResponse, |
78 weak_factory_.GetWeakPtr())); | 78 weak_factory_.GetWeakPtr())); |
79 } | 79 } |
80 | 80 |
| 81 bool MediaStreamUIProxy::Core::CheckAccess(const GURL& security_origin, |
| 82 MediaStreamType type, |
| 83 int render_process_id, |
| 84 int render_frame_id) { |
| 85 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 86 |
| 87 RenderFrameHostDelegate* render_delegate = |
| 88 GetRenderFrameHostDelegate(render_process_id, render_frame_id); |
| 89 if (!render_delegate) |
| 90 return false; |
| 91 |
| 92 return render_delegate->CheckMediaAccessPermission(security_origin, type); |
| 93 } |
| 94 |
81 void MediaStreamUIProxy::Core::OnStarted(gfx::NativeViewId* window_id) { | 95 void MediaStreamUIProxy::Core::OnStarted(gfx::NativeViewId* window_id) { |
82 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 96 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
83 if (ui_) { | 97 if (ui_) { |
84 *window_id = ui_->OnStarted( | 98 *window_id = ui_->OnStarted( |
85 base::Bind(&Core::ProcessStopRequestFromUI, base::Unretained(this))); | 99 base::Bind(&Core::ProcessStopRequestFromUI, base::Unretained(this))); |
86 } | 100 } |
87 } | 101 } |
88 | 102 |
89 void MediaStreamUIProxy::Core::ProcessAccessRequestResponse( | 103 void MediaStreamUIProxy::Core::ProcessAccessRequestResponse( |
90 const MediaStreamDevices& devices, | 104 const MediaStreamDevices& devices, |
91 content::MediaStreamRequestResult result, | 105 content::MediaStreamRequestResult result, |
92 scoped_ptr<MediaStreamUI> stream_ui) { | 106 scoped_ptr<MediaStreamUI> stream_ui) { |
93 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 107 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
94 | 108 |
95 ui_ = stream_ui.Pass(); | 109 ui_ = stream_ui.Pass(); |
96 BrowserThread::PostTask( | 110 BrowserThread::PostTask( |
97 BrowserThread::IO, FROM_HERE, | 111 BrowserThread::IO, FROM_HERE, |
98 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, | 112 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, |
99 proxy_, devices, result)); | 113 proxy_, devices, result)); |
100 } | 114 } |
101 | 115 |
102 void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() { | 116 void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() { |
103 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 117 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
104 | 118 |
105 BrowserThread::PostTask( | 119 BrowserThread::PostTask( |
106 BrowserThread::IO, FROM_HERE, | 120 BrowserThread::IO, FROM_HERE, |
107 base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_)); | 121 base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_)); |
108 } | 122 } |
109 | 123 |
| 124 RenderFrameHostDelegate* MediaStreamUIProxy::Core::GetRenderFrameHostDelegate( |
| 125 int render_process_id, |
| 126 int render_frame_id) { |
| 127 if (test_render_delegate_) |
| 128 return test_render_delegate_; |
| 129 RenderFrameHostImpl* host = |
| 130 RenderFrameHostImpl::FromID(render_process_id, render_frame_id); |
| 131 return host ? host->delegate() : NULL; |
| 132 } |
| 133 |
110 // static | 134 // static |
111 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() { | 135 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() { |
112 return scoped_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL)); | 136 return scoped_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL)); |
113 } | 137 } |
114 | 138 |
115 // static | 139 // static |
116 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::CreateForTests( | 140 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::CreateForTests( |
117 RenderFrameHostDelegate* render_delegate) { | 141 RenderFrameHostDelegate* render_delegate) { |
118 return scoped_ptr<MediaStreamUIProxy>( | 142 return scoped_ptr<MediaStreamUIProxy>( |
119 new MediaStreamUIProxy(render_delegate)); | 143 new MediaStreamUIProxy(render_delegate)); |
(...skipping 14 matching lines...) Expand all Loading... |
134 const MediaStreamRequest& request, | 158 const MediaStreamRequest& request, |
135 const ResponseCallback& response_callback) { | 159 const ResponseCallback& response_callback) { |
136 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 160 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
137 | 161 |
138 response_callback_ = response_callback; | 162 response_callback_ = response_callback; |
139 BrowserThread::PostTask( | 163 BrowserThread::PostTask( |
140 BrowserThread::UI, FROM_HERE, | 164 BrowserThread::UI, FROM_HERE, |
141 base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request)); | 165 base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request)); |
142 } | 166 } |
143 | 167 |
| 168 void MediaStreamUIProxy::CheckAccess( |
| 169 const GURL& security_origin, |
| 170 MediaStreamType type, |
| 171 int render_process_id, |
| 172 int render_frame_id, |
| 173 const base::Callback<void(bool)>& callback) { |
| 174 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 175 |
| 176 BrowserThread::PostTaskAndReplyWithResult( |
| 177 BrowserThread::UI, |
| 178 FROM_HERE, |
| 179 base::Bind(&Core::CheckAccess, |
| 180 base::Unretained(core_.get()), |
| 181 security_origin, |
| 182 type, |
| 183 render_process_id, |
| 184 render_frame_id), |
| 185 base::Bind(&MediaStreamUIProxy::OnCheckedAccess, |
| 186 weak_factory_.GetWeakPtr(), |
| 187 callback)); |
| 188 } |
| 189 |
144 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback, | 190 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback, |
145 const WindowIdCallback& window_id_callback) { | 191 const WindowIdCallback& window_id_callback) { |
146 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 192 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
147 | 193 |
148 stop_callback_ = stop_callback; | 194 stop_callback_ = stop_callback; |
149 | 195 |
150 // Owned by the PostTaskAndReply callback. | 196 // Owned by the PostTaskAndReply callback. |
151 gfx::NativeViewId* window_id = new gfx::NativeViewId(0); | 197 gfx::NativeViewId* window_id = new gfx::NativeViewId(0); |
152 | 198 |
153 BrowserThread::PostTaskAndReply( | 199 BrowserThread::PostTaskAndReply( |
154 BrowserThread::UI, | 200 BrowserThread::UI, |
155 FROM_HERE, | 201 FROM_HERE, |
156 base::Bind(&Core::OnStarted, base::Unretained(core_.get()), window_id), | 202 base::Bind(&Core::OnStarted, base::Unretained(core_.get()), window_id), |
157 base::Bind(&MediaStreamUIProxy::OnWindowId, | 203 base::Bind(&MediaStreamUIProxy::OnWindowId, |
158 weak_factory_.GetWeakPtr(), | 204 weak_factory_.GetWeakPtr(), |
159 window_id_callback, | 205 window_id_callback, |
160 base::Owned(window_id))); | 206 base::Owned(window_id))); |
161 } | 207 } |
162 | 208 |
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); | |
168 } | |
169 | |
170 void MediaStreamUIProxy::ProcessAccessRequestResponse( | 209 void MediaStreamUIProxy::ProcessAccessRequestResponse( |
171 const MediaStreamDevices& devices, | 210 const MediaStreamDevices& devices, |
172 content::MediaStreamRequestResult result) { | 211 content::MediaStreamRequestResult result) { |
173 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 212 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
174 DCHECK(!response_callback_.is_null()); | 213 DCHECK(!response_callback_.is_null()); |
175 | 214 |
176 ResponseCallback cb = response_callback_; | 215 ResponseCallback cb = response_callback_; |
177 response_callback_.Reset(); | 216 response_callback_.Reset(); |
178 cb.Run(devices, result); | 217 cb.Run(devices, result); |
179 } | 218 } |
180 | 219 |
181 void MediaStreamUIProxy::ProcessStopRequestFromUI() { | 220 void MediaStreamUIProxy::ProcessStopRequestFromUI() { |
182 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 221 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
183 DCHECK(!stop_callback_.is_null()); | 222 DCHECK(!stop_callback_.is_null()); |
184 | 223 |
185 base::Closure cb = stop_callback_; | 224 base::Closure cb = stop_callback_; |
186 stop_callback_.Reset(); | 225 stop_callback_.Reset(); |
187 cb.Run(); | 226 cb.Run(); |
188 } | 227 } |
189 | 228 |
| 229 void MediaStreamUIProxy::OnWindowId(const WindowIdCallback& window_id_callback, |
| 230 gfx::NativeViewId* window_id) { |
| 231 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 232 if (!window_id_callback.is_null()) |
| 233 window_id_callback.Run(*window_id); |
| 234 } |
| 235 |
| 236 void MediaStreamUIProxy::OnCheckedAccess( |
| 237 const base::Callback<void(bool)>& callback, |
| 238 bool have_access) { |
| 239 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 240 if (!callback.is_null()) |
| 241 callback.Run(have_access); |
| 242 } |
| 243 |
190 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy() | 244 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy() |
191 : MediaStreamUIProxy(NULL) { | 245 : MediaStreamUIProxy(NULL), |
| 246 mic_access_(true), |
| 247 camera_access_(true) { |
192 } | 248 } |
193 | 249 |
194 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {} | 250 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {} |
195 | 251 |
196 void FakeMediaStreamUIProxy::SetAvailableDevices( | 252 void FakeMediaStreamUIProxy::SetAvailableDevices( |
197 const MediaStreamDevices& devices) { | 253 const MediaStreamDevices& devices) { |
198 devices_ = devices; | 254 devices_ = devices; |
199 } | 255 } |
200 | 256 |
| 257 void FakeMediaStreamUIProxy::SetMicAccess(bool access) { |
| 258 mic_access_ = access; |
| 259 } |
| 260 |
| 261 void FakeMediaStreamUIProxy::SetCameraAccess(bool access) { |
| 262 camera_access_ = access; |
| 263 } |
| 264 |
201 void FakeMediaStreamUIProxy::RequestAccess( | 265 void FakeMediaStreamUIProxy::RequestAccess( |
202 const MediaStreamRequest& request, | 266 const MediaStreamRequest& request, |
203 const ResponseCallback& response_callback) { | 267 const ResponseCallback& response_callback) { |
204 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 268 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
205 | 269 |
206 response_callback_ = response_callback; | 270 response_callback_ = response_callback; |
207 | 271 |
208 if (CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 272 if (CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
209 switches::kUseFakeUIForMediaStream) == "deny") { | 273 switches::kUseFakeUIForMediaStream) == "deny") { |
210 // Immediately deny the request. | 274 // Immediately deny the request. |
(...skipping 24 matching lines...) Expand all Loading... |
235 } else if (!accepted_video && | 299 } else if (!accepted_video && |
236 IsVideoMediaType(request.video_type) && | 300 IsVideoMediaType(request.video_type) && |
237 IsVideoMediaType(it->type) && | 301 IsVideoMediaType(it->type) && |
238 (request.requested_video_device_id.empty() || | 302 (request.requested_video_device_id.empty() || |
239 request.requested_video_device_id == it->id)) { | 303 request.requested_video_device_id == it->id)) { |
240 devices_to_use.push_back(*it); | 304 devices_to_use.push_back(*it); |
241 accepted_video = true; | 305 accepted_video = true; |
242 } | 306 } |
243 } | 307 } |
244 | 308 |
245 // Fail the request if a device exist for the requested type. | 309 // Fail the request if a device doesn't exist for the requested type. |
246 if ((request.audio_type != MEDIA_NO_SERVICE && !accepted_audio) || | 310 if ((request.audio_type != MEDIA_NO_SERVICE && !accepted_audio) || |
247 (request.video_type != MEDIA_NO_SERVICE && !accepted_video)) { | 311 (request.video_type != MEDIA_NO_SERVICE && !accepted_video)) { |
248 devices_to_use.clear(); | 312 devices_to_use.clear(); |
249 } | 313 } |
250 | 314 |
251 BrowserThread::PostTask( | 315 BrowserThread::PostTask( |
252 BrowserThread::IO, FROM_HERE, | 316 BrowserThread::IO, FROM_HERE, |
253 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, | 317 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, |
254 weak_factory_.GetWeakPtr(), | 318 weak_factory_.GetWeakPtr(), |
255 devices_to_use, | 319 devices_to_use, |
256 devices_to_use.empty() ? | 320 devices_to_use.empty() ? |
257 MEDIA_DEVICE_NO_HARDWARE : | 321 MEDIA_DEVICE_NO_HARDWARE : |
258 MEDIA_DEVICE_OK)); | 322 MEDIA_DEVICE_OK)); |
259 } | 323 } |
260 | 324 |
| 325 void FakeMediaStreamUIProxy::CheckAccess( |
| 326 const GURL& security_origin, |
| 327 MediaStreamType type, |
| 328 int render_process_id, |
| 329 int render_frame_id, |
| 330 const base::Callback<void(bool)>& callback) { |
| 331 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 332 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 333 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 334 |
| 335 bool have_access = false; |
| 336 if (CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 337 switches::kUseFakeUIForMediaStream) != "deny") { |
| 338 have_access = |
| 339 type == MEDIA_DEVICE_AUDIO_CAPTURE ? mic_access_ : camera_access_; |
| 340 } |
| 341 |
| 342 BrowserThread::PostTask( |
| 343 BrowserThread::IO, |
| 344 FROM_HERE, |
| 345 base::Bind(&MediaStreamUIProxy::OnCheckedAccess, |
| 346 weak_factory_.GetWeakPtr(), |
| 347 callback, |
| 348 have_access)); |
| 349 return; |
| 350 } |
| 351 |
261 void FakeMediaStreamUIProxy::OnStarted( | 352 void FakeMediaStreamUIProxy::OnStarted( |
262 const base::Closure& stop_callback, | 353 const base::Closure& stop_callback, |
263 const WindowIdCallback& window_id_callback) {} | 354 const WindowIdCallback& window_id_callback) {} |
264 | 355 |
265 } // namespace content | 356 } // namespace content |
OLD | NEW |