Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: content/browser/renderer_host/media/media_stream_ui_proxy.cc

Issue 562263002: Check media permissions through RenderFrameHostDelegate. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@render_frame_get_sources
Patch Set: Rebase Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698