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

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

Issue 795703003: Don't auto allow access to media devices unless a the security origin of the requester is the same … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix problem with that the ui_request_ was used for state updates. Created 5 years, 10 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 requesting_process_id(requesting_process_id), 231 requesting_process_id(requesting_process_id),
232 requesting_frame_id(requesting_frame_id), 232 requesting_frame_id(requesting_frame_id),
233 page_request_id(page_request_id), 233 page_request_id(page_request_id),
234 security_origin(security_origin), 234 security_origin(security_origin),
235 user_gesture(user_gesture), 235 user_gesture(user_gesture),
236 request_type(request_type), 236 request_type(request_type),
237 options(options), 237 options(options),
238 salt_callback(salt_callback), 238 salt_callback(salt_callback),
239 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), 239 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
240 audio_type_(MEDIA_NO_SERVICE), 240 audio_type_(MEDIA_NO_SERVICE),
241 video_type_(MEDIA_NO_SERVICE) { 241 video_type_(MEDIA_NO_SERVICE),
242 target_process_id_(-1),
243 target_frame_id_(-1) {
242 } 244 }
243 245
244 ~DeviceRequest() {} 246 ~DeviceRequest() {}
245 247
246 void SetAudioType(MediaStreamType audio_type) { 248 void SetAudioType(MediaStreamType audio_type) {
247 DCHECK(IsAudioInputMediaType(audio_type) || 249 DCHECK(IsAudioInputMediaType(audio_type) ||
248 audio_type == MEDIA_DEVICE_AUDIO_OUTPUT || 250 audio_type == MEDIA_DEVICE_AUDIO_OUTPUT ||
249 audio_type == MEDIA_NO_SERVICE); 251 audio_type == MEDIA_NO_SERVICE);
250 audio_type_ = audio_type; 252 audio_type_ = audio_type;
251 } 253 }
252 254
253 MediaStreamType audio_type() const { return audio_type_; } 255 MediaStreamType audio_type() const { return audio_type_; }
254 256
255 void SetVideoType(MediaStreamType video_type) { 257 void SetVideoType(MediaStreamType video_type) {
256 DCHECK(IsVideoMediaType(video_type) || video_type == MEDIA_NO_SERVICE); 258 DCHECK(IsVideoMediaType(video_type) || video_type == MEDIA_NO_SERVICE);
257 video_type_ = video_type; 259 video_type_ = video_type;
258 } 260 }
259 261
260 MediaStreamType video_type() const { return video_type_; } 262 MediaStreamType video_type() const { return video_type_; }
261 263
262 // Creates a MediaStreamRequest object that is used by this request when UI 264 // Creates a MediaStreamRequest object that is used by this request when UI
263 // is asked for permission and device selection. 265 // is asked for permission and device selection.
264 void CreateUIRequest(const std::string& requested_audio_device_id, 266 void CreateUIRequest(const std::string& requested_audio_device_id,
265 const std::string& requested_video_device_id) { 267 const std::string& requested_video_device_id) {
266 DCHECK(!ui_request_); 268 DCHECK(!ui_request_);
269 target_process_id_ = requesting_process_id;
270 target_frame_id_ = requesting_frame_id;
267 ui_request_.reset(new MediaStreamRequest(requesting_process_id, 271 ui_request_.reset(new MediaStreamRequest(requesting_process_id,
268 requesting_frame_id, 272 requesting_frame_id,
269 page_request_id, 273 page_request_id,
270 security_origin, 274 security_origin,
271 user_gesture, 275 user_gesture,
272 request_type, 276 request_type,
273 requested_audio_device_id, 277 requested_audio_device_id,
274 requested_video_device_id, 278 requested_video_device_id,
275 audio_type_, 279 audio_type_,
276 video_type_)); 280 video_type_));
277 } 281 }
278 282
279 // Creates a tab capture specific MediaStreamRequest object that is used by 283 // Creates a tab capture specific MediaStreamRequest object that is used by
280 // this request when UI is asked for permission and device selection. 284 // this request when UI is asked for permission and device selection.
281 void CreateTabCaptureUIRequest(int target_render_process_id, 285 void CreateTabCaptureUIRequest(int target_render_process_id,
282 int target_render_frame_id, 286 int target_render_frame_id) {
283 const std::string& tab_capture_id) {
284 DCHECK(!ui_request_); 287 DCHECK(!ui_request_);
288 target_process_id_ = target_render_process_id;
289 target_frame_id_ = target_render_frame_id;
285 ui_request_.reset(new MediaStreamRequest(target_render_process_id, 290 ui_request_.reset(new MediaStreamRequest(target_render_process_id,
286 target_render_frame_id, 291 target_render_frame_id,
287 page_request_id, 292 page_request_id,
288 security_origin, 293 security_origin,
289 user_gesture, 294 user_gesture,
290 request_type, 295 request_type,
291 "", 296 "",
292 "", 297 "",
293 audio_type_, 298 audio_type_,
294 video_type_)); 299 video_type_));
295 ui_request_->tab_capture_device_id = tab_capture_id;
296 } 300 }
297 301
298 const MediaStreamRequest* UIRequest() const { return ui_request_.get(); } 302 bool HasUIRequest() const { return ui_request_.get() != nullptr; }
303 scoped_ptr<MediaStreamRequest> DetachUIRequest() {
304 return ui_request_.Pass();
305 }
299 306
300 // Update the request state and notify observers. 307 // Update the request state and notify observers.
301 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { 308 void SetState(MediaStreamType stream_type, MediaRequestState new_state) {
302 if (stream_type == NUM_MEDIA_TYPES) { 309 if (stream_type == NUM_MEDIA_TYPES) {
303 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { 310 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) {
304 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); 311 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
305 state_[stream_type] = new_state; 312 state_[stream_type] = new_state;
306 } 313 }
307 } else { 314 } else {
308 state_[stream_type] = new_state; 315 state_[stream_type] = new_state;
309 } 316 }
310 317
311 MediaObserver* media_observer = 318 MediaObserver* media_observer =
312 GetContentClient()->browser()->GetMediaObserver(); 319 GetContentClient()->browser()->GetMediaObserver();
313 if (!media_observer) 320 if (!media_observer)
314 return; 321 return;
315 322
316 // If |ui_request_| doesn't exist, it means that the request has not yet
317 // been setup fully and there are no valid observers.
318 if (!ui_request_)
319 return;
320
321 media_observer->OnMediaRequestStateChanged( 323 media_observer->OnMediaRequestStateChanged(
322 ui_request_->render_process_id, ui_request_->render_frame_id, 324 target_process_id_, target_frame_id_, page_request_id, security_origin,
323 ui_request_->page_request_id, ui_request_->security_origin,
324 stream_type, new_state); 325 stream_type, new_state);
325 } 326 }
326 327
327 MediaRequestState state(MediaStreamType stream_type) const { 328 MediaRequestState state(MediaStreamType stream_type) const {
328 return state_[stream_type]; 329 return state_[stream_type];
329 } 330 }
330 331
331 MediaStreamRequester* const requester; // Can be NULL. 332 MediaStreamRequester* const requester; // Can be NULL.
332 333
333 334
(...skipping 24 matching lines...) Expand all
358 359
359 StreamDeviceInfoArray devices; 360 StreamDeviceInfoArray devices;
360 361
361 // Callback to the requester which audio/video devices have been selected. 362 // Callback to the requester which audio/video devices have been selected.
362 // It can be null if the requester has no interest to know the result. 363 // It can be null if the requester has no interest to know the result.
363 // Currently it is only used by |DEVICE_ACCESS| type. 364 // Currently it is only used by |DEVICE_ACCESS| type.
364 MediaStreamManager::MediaRequestResponseCallback callback; 365 MediaStreamManager::MediaRequestResponseCallback callback;
365 366
366 scoped_ptr<MediaStreamUIProxy> ui_proxy; 367 scoped_ptr<MediaStreamUIProxy> ui_proxy;
367 368
369 std::string tab_capture_device_id;
370
368 private: 371 private:
369 std::vector<MediaRequestState> state_; 372 std::vector<MediaRequestState> state_;
370 scoped_ptr<MediaStreamRequest> ui_request_; 373 scoped_ptr<MediaStreamRequest> ui_request_;
371 MediaStreamType audio_type_; 374 MediaStreamType audio_type_;
372 MediaStreamType video_type_; 375 MediaStreamType video_type_;
376 int target_process_id_;
377 int target_frame_id_;
378
tommi (sloooow) - chröme 2015/01/27 21:07:14 fix whitespace
373 }; 379 };
374 380
375 MediaStreamManager::EnumerationCache::EnumerationCache() 381 MediaStreamManager::EnumerationCache::EnumerationCache()
376 : valid(false) { 382 : valid(false) {
377 } 383 }
378 384
379 MediaStreamManager::EnumerationCache::~EnumerationCache() { 385 MediaStreamManager::EnumerationCache::~EnumerationCache() {
380 } 386 }
381 387
382 MediaStreamManager::MediaStreamManager() 388 MediaStreamManager::MediaStreamManager()
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 requests_.erase(request_it); 1162 requests_.erase(request_it);
1157 return; 1163 return;
1158 } 1164 }
1159 } 1165 }
1160 NOTREACHED(); 1166 NOTREACHED();
1161 } 1167 }
1162 1168
1163 void MediaStreamManager::PostRequestToUI(const std::string& label, 1169 void MediaStreamManager::PostRequestToUI(const std::string& label,
1164 DeviceRequest* request) { 1170 DeviceRequest* request) {
1165 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1171 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1166 DCHECK(request->UIRequest()); 1172 DCHECK(request->HasUIRequest());
1167 DVLOG(1) << "PostRequestToUI({label= " << label << "})"; 1173 DVLOG(1) << "PostRequestToUI({label= " << label << "})";
1168 1174
1169 const MediaStreamType audio_type = request->audio_type(); 1175 const MediaStreamType audio_type = request->audio_type();
1170 const MediaStreamType video_type = request->video_type(); 1176 const MediaStreamType video_type = request->video_type();
1171 1177
1172 // Post the request to UI and set the state. 1178 // Post the request to UI and set the state.
1173 if (IsAudioInputMediaType(audio_type)) 1179 if (IsAudioInputMediaType(audio_type))
1174 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 1180 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
1175 if (IsVideoMediaType(video_type)) 1181 if (IsVideoMediaType(video_type))
1176 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 1182 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
(...skipping 19 matching lines...) Expand all
1196 } 1202 }
1197 1203
1198 fake_ui_->SetAvailableDevices(devices); 1204 fake_ui_->SetAvailableDevices(devices);
1199 1205
1200 request->ui_proxy = fake_ui_.Pass(); 1206 request->ui_proxy = fake_ui_.Pass();
1201 } else { 1207 } else {
1202 request->ui_proxy = MediaStreamUIProxy::Create(); 1208 request->ui_proxy = MediaStreamUIProxy::Create();
1203 } 1209 }
1204 1210
1205 request->ui_proxy->RequestAccess( 1211 request->ui_proxy->RequestAccess(
1206 *request->UIRequest(), 1212 request->DetachUIRequest(),
1207 base::Bind(&MediaStreamManager::HandleAccessRequestResponse, 1213 base::Bind(&MediaStreamManager::HandleAccessRequestResponse,
1208 base::Unretained(this), label)); 1214 base::Unretained(this), label));
1209 } 1215 }
1210 1216
1211 void MediaStreamManager::SetupRequest(const std::string& label) { 1217 void MediaStreamManager::SetupRequest(const std::string& label) {
1212 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1218 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1213 DeviceRequest* request = FindRequest(label); 1219 DeviceRequest* request = FindRequest(label);
1214 if (!request) { 1220 if (!request) {
1215 DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!"; 1221 DVLOG(1) << "SetupRequest label " << label << " doesn't exist!!";
1216 return; // This can happen if the request has been canceled. 1222 return; // This can happen if the request has been canceled.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 1339
1334 bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget( 1340 bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
1335 capture_device_id, &target_render_process_id, &target_render_frame_id); 1341 capture_device_id, &target_render_process_id, &target_render_frame_id);
1336 if (!has_valid_device_id || 1342 if (!has_valid_device_id ||
1337 (request->audio_type() != MEDIA_TAB_AUDIO_CAPTURE && 1343 (request->audio_type() != MEDIA_TAB_AUDIO_CAPTURE &&
1338 request->audio_type() != MEDIA_NO_SERVICE) || 1344 request->audio_type() != MEDIA_NO_SERVICE) ||
1339 (request->video_type() != MEDIA_TAB_VIDEO_CAPTURE && 1345 (request->video_type() != MEDIA_TAB_VIDEO_CAPTURE &&
1340 request->video_type() != MEDIA_NO_SERVICE)) { 1346 request->video_type() != MEDIA_NO_SERVICE)) {
1341 return false; 1347 return false;
1342 } 1348 }
1349 request->tab_capture_device_id = capture_device_id;
1343 1350
1344 request->CreateTabCaptureUIRequest(target_render_process_id, 1351 request->CreateTabCaptureUIRequest(target_render_process_id,
1345 target_render_frame_id, 1352 target_render_frame_id);
1346 capture_device_id);
1347 1353
1348 DVLOG(3) << "SetupTabCaptureRequest " 1354 DVLOG(3) << "SetupTabCaptureRequest "
1349 << ", {capture_device_id = " << capture_device_id << "}" 1355 << ", {capture_device_id = " << capture_device_id << "}"
1350 << ", {target_render_process_id = " << target_render_process_id 1356 << ", {target_render_process_id = " << target_render_process_id
1351 << "}" 1357 << "}"
1352 << ", {target_render_frame_id = " << target_render_frame_id << "}"; 1358 << ", {target_render_frame_id = " << target_render_frame_id << "}";
1353 return true; 1359 return true;
1354 } 1360 }
1355 1361
1356 bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) { 1362 bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) {
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 // Process all newly-accepted devices for this request. 1912 // Process all newly-accepted devices for this request.
1907 bool found_audio = false; 1913 bool found_audio = false;
1908 bool found_video = false; 1914 bool found_video = false;
1909 for (MediaStreamDevices::const_iterator device_it = devices.begin(); 1915 for (MediaStreamDevices::const_iterator device_it = devices.begin();
1910 device_it != devices.end(); ++device_it) { 1916 device_it != devices.end(); ++device_it) {
1911 StreamDeviceInfo device_info; 1917 StreamDeviceInfo device_info;
1912 device_info.device = *device_it; 1918 device_info.device = *device_it;
1913 1919
1914 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || 1920 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE ||
1915 device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { 1921 device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) {
1916 device_info.device.id = request->UIRequest()->tab_capture_device_id; 1922 device_info.device.id = request->tab_capture_device_id;
1917 1923
1918 // Initialize the sample_rate and channel_layout here since for audio 1924 // Initialize the sample_rate and channel_layout here since for audio
1919 // mirroring, we don't go through EnumerateDevices where these are usually 1925 // mirroring, we don't go through EnumerateDevices where these are usually
1920 // initialized. 1926 // initialized.
1921 if (device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) { 1927 if (device_info.device.type == content::MEDIA_TAB_AUDIO_CAPTURE) {
1922 const media::AudioParameters parameters = 1928 const media::AudioParameters parameters =
1923 audio_manager_->GetDefaultOutputStreamParameters(); 1929 audio_manager_->GetDefaultOutputStreamParameters();
1924 int sample_rate = parameters.sample_rate(); 1930 int sample_rate = parameters.sample_rate();
1925 // If we weren't able to get the native sampling rate or the sample_rate 1931 // If we weren't able to get the native sampling rate or the sample_rate
1926 // is outside the valid range for input devices set reasonable defaults. 1932 // is outside the valid range for input devices set reasonable defaults.
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2156 } 2162 }
2157 } 2163 }
2158 2164
2159 void MediaStreamManager::SetKeyboardMicOnDeviceThread() { 2165 void MediaStreamManager::SetKeyboardMicOnDeviceThread() {
2160 DCHECK(device_task_runner_->BelongsToCurrentThread()); 2166 DCHECK(device_task_runner_->BelongsToCurrentThread());
2161 audio_manager_->SetHasKeyboardMic(); 2167 audio_manager_->SetHasKeyboardMic();
2162 } 2168 }
2163 #endif 2169 #endif
2164 2170
2165 } // namespace content 2171 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698