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

Side by Side Diff: chrome/browser/media/media_capture_devices_dispatcher.cc

Issue 180633008: Add different error codes for getUserMedia. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed comments Created 6 years, 9 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 | Annotate | Revision Log
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 "chrome/browser/media/media_capture_devices_dispatcher.h" 5 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/prefs/scoped_user_pref_update.h"
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 293
294 void MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest( 294 void MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest(
295 content::WebContents* web_contents, 295 content::WebContents* web_contents,
296 const content::MediaStreamRequest& request, 296 const content::MediaStreamRequest& request,
297 const content::MediaResponseCallback& callback, 297 const content::MediaResponseCallback& callback,
298 const extensions::Extension* extension) { 298 const extensions::Extension* extension) {
299 content::MediaStreamDevices devices; 299 content::MediaStreamDevices devices;
300 scoped_ptr<content::MediaStreamUI> ui; 300 scoped_ptr<content::MediaStreamUI> ui;
301 301
302 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { 302 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) {
303 callback.Run(devices, ui.Pass()); 303 callback.Run(devices, content::INVALID_STATE, ui.Pass());
304 return; 304 return;
305 } 305 }
306 306
307 // If the device id wasn't specified then this is a screen capture request 307 // If the device id wasn't specified then this is a screen capture request
308 // (i.e. chooseDesktopMedia() API wasn't used to generate device id). 308 // (i.e. chooseDesktopMedia() API wasn't used to generate device id).
309 if (request.requested_video_device_id.empty()) { 309 if (request.requested_video_device_id.empty()) {
310 ProcessScreenCaptureAccessRequest( 310 ProcessScreenCaptureAccessRequest(
311 web_contents, request, callback, extension); 311 web_contents, request, callback, extension);
312 return; 312 return;
313 } 313 }
314 314
315 // Resolve DesktopMediaID for the specified device id. 315 // Resolve DesktopMediaID for the specified device id.
316 content::DesktopMediaID media_id = 316 content::DesktopMediaID media_id =
317 GetDesktopStreamsRegistry()->RequestMediaForStreamId( 317 GetDesktopStreamsRegistry()->RequestMediaForStreamId(
318 request.requested_video_device_id, request.render_process_id, 318 request.requested_video_device_id, request.render_process_id,
319 request.render_view_id, request.security_origin); 319 request.render_view_id, request.security_origin);
320 320
321 // Received invalid device id. 321 // Received invalid device id.
322 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { 322 if (media_id.type == content::DesktopMediaID::TYPE_NONE) {
323 callback.Run(devices, ui.Pass()); 323 callback.Run(devices, content::INVALID_STATE, ui.Pass());
324 return; 324 return;
325 } 325 }
326 326
327 bool loopback_audio_supported = false; 327 bool loopback_audio_supported = false;
328 #if defined(USE_CRAS) || defined(OS_WIN) 328 #if defined(USE_CRAS) || defined(OS_WIN)
329 // Currently loopback audio capture is supported only on Windows and ChromeOS. 329 // Currently loopback audio capture is supported only on Windows and ChromeOS.
330 loopback_audio_supported = true; 330 loopback_audio_supported = true;
331 #endif 331 #endif
332 332
333 // Audio is only supported for screen capture streams. 333 // Audio is only supported for screen capture streams.
334 bool capture_audio = 334 bool capture_audio =
335 (media_id.type == content::DesktopMediaID::TYPE_SCREEN && 335 (media_id.type == content::DesktopMediaID::TYPE_SCREEN &&
336 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && 336 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE &&
337 loopback_audio_supported); 337 loopback_audio_supported);
338 338
339 ui = GetDevicesForDesktopCapture( 339 ui = GetDevicesForDesktopCapture(
340 devices, media_id, capture_audio, true, 340 devices, media_id, capture_audio, true,
341 GetApplicationTitle(web_contents, extension)); 341 GetApplicationTitle(web_contents, extension));
342 342
343 callback.Run(devices, ui.Pass()); 343 callback.Run(devices, content::OK, ui.Pass());
344 } 344 }
345 345
346 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( 346 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest(
347 content::WebContents* web_contents, 347 content::WebContents* web_contents,
348 const content::MediaStreamRequest& request, 348 const content::MediaStreamRequest& request,
349 const content::MediaResponseCallback& callback, 349 const content::MediaResponseCallback& callback,
350 const extensions::Extension* extension) { 350 const extensions::Extension* extension) {
351 content::MediaStreamDevices devices; 351 content::MediaStreamDevices devices;
352 scoped_ptr<content::MediaStreamUI> ui; 352 scoped_ptr<content::MediaStreamUI> ui;
353 353
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 422
423 // Unless we're being invoked from a component extension, register to 423 // Unless we're being invoked from a component extension, register to
424 // display the notification for stream capture. 424 // display the notification for stream capture.
425 bool display_notification = !component_extension; 425 bool display_notification = !component_extension;
426 426
427 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, 427 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio,
428 display_notification, application_title); 428 display_notification, application_title);
429 } 429 }
430 } 430 }
431 431
432 callback.Run(devices, ui.Pass()); 432 callback.Run(
433 devices,
434 devices.empty() ? content::INVALID_STATE: content::OK,
435 ui.Pass());
433 } 436 }
434 437
435 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( 438 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest(
436 content::WebContents* web_contents, 439 content::WebContents* web_contents,
437 const content::MediaStreamRequest& request, 440 const content::MediaStreamRequest& request,
438 const content::MediaResponseCallback& callback, 441 const content::MediaResponseCallback& callback,
439 const extensions::Extension* extension) { 442 const extensions::Extension* extension) {
440 content::MediaStreamDevices devices; 443 content::MediaStreamDevices devices;
441 scoped_ptr<content::MediaStreamUI> ui; 444 scoped_ptr<content::MediaStreamUI> ui;
442 445
443 #if defined(OS_ANDROID) 446 #if defined(OS_ANDROID)
444 // Tab capture is not supported on Android. 447 // Tab capture is not supported on Android.
445 callback.Run(devices, ui.Pass()); 448 callback.Run(devices, ui.Pass());
446 #else // defined(OS_ANDROID) 449 #else // defined(OS_ANDROID)
447 Profile* profile = 450 Profile* profile =
448 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 451 Profile::FromBrowserContext(web_contents->GetBrowserContext());
449 extensions::TabCaptureRegistry* tab_capture_registry = 452 extensions::TabCaptureRegistry* tab_capture_registry =
450 extensions::TabCaptureRegistry::Get(profile); 453 extensions::TabCaptureRegistry::Get(profile);
451 if (!tab_capture_registry) { 454 if (!tab_capture_registry) {
452 NOTREACHED(); 455 NOTREACHED();
453 callback.Run(devices, ui.Pass()); 456 callback.Run(devices, content::INVALID_STATE, ui.Pass());
454 return; 457 return;
455 } 458 }
456 bool tab_capture_allowed = 459 bool tab_capture_allowed =
457 tab_capture_registry->VerifyRequest(request.render_process_id, 460 tab_capture_registry->VerifyRequest(request.render_process_id,
458 request.render_view_id); 461 request.render_view_id);
459 462
460 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE && 463 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE &&
461 tab_capture_allowed && 464 tab_capture_allowed &&
462 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) { 465 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) {
463 devices.push_back(content::MediaStreamDevice( 466 devices.push_back(content::MediaStreamDevice(
464 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string())); 467 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string()));
465 } 468 }
466 469
467 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE && 470 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE &&
468 tab_capture_allowed && 471 tab_capture_allowed &&
469 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) { 472 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) {
470 devices.push_back(content::MediaStreamDevice( 473 devices.push_back(content::MediaStreamDevice(
471 content::MEDIA_TAB_VIDEO_CAPTURE, std::string(), std::string())); 474 content::MEDIA_TAB_VIDEO_CAPTURE, std::string(), std::string()));
472 } 475 }
473 476
474 if (!devices.empty()) { 477 if (!devices.empty()) {
475 ui = media_stream_capture_indicator_->RegisterMediaStream( 478 ui = media_stream_capture_indicator_->RegisterMediaStream(
476 web_contents, devices); 479 web_contents, devices);
477 } 480 }
478 callback.Run(devices, ui.Pass()); 481 callback.Run(
482 devices,
483 devices.empty() ? content::INVALID_STATE: content::OK,
484 ui.Pass());
479 #endif // !defined(OS_ANDROID) 485 #endif // !defined(OS_ANDROID)
480 } 486 }
481 487
482 void MediaCaptureDevicesDispatcher:: 488 void MediaCaptureDevicesDispatcher::
483 ProcessMediaAccessRequestFromPlatformAppOrExtension( 489 ProcessMediaAccessRequestFromPlatformAppOrExtension(
484 content::WebContents* web_contents, 490 content::WebContents* web_contents,
485 const content::MediaStreamRequest& request, 491 const content::MediaStreamRequest& request,
486 const content::MediaResponseCallback& callback, 492 const content::MediaResponseCallback& callback,
487 const extensions::Extension* extension) { 493 const extensions::Extension* extension) {
488 content::MediaStreamDevices devices; 494 content::MediaStreamDevices devices;
489 Profile* profile = 495 Profile* profile =
490 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 496 Profile::FromBrowserContext(web_contents->GetBrowserContext());
491 497
492 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE && 498 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
493 extension->HasAPIPermission(extensions::APIPermission::kAudioCapture)) { 499 extension->HasAPIPermission(extensions::APIPermission::kAudioCapture)) {
494 GetDefaultDevicesForProfile(profile, true, false, &devices); 500 GetDefaultDevicesForProfile(profile, true, false, &devices);
495 } 501 }
496 502
497 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && 503 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
498 extension->HasAPIPermission(extensions::APIPermission::kVideoCapture)) { 504 extension->HasAPIPermission(extensions::APIPermission::kVideoCapture)) {
499 GetDefaultDevicesForProfile(profile, false, true, &devices); 505 GetDefaultDevicesForProfile(profile, false, true, &devices);
500 } 506 }
501 507
502 scoped_ptr<content::MediaStreamUI> ui; 508 scoped_ptr<content::MediaStreamUI> ui;
503 if (!devices.empty()) { 509 if (!devices.empty()) {
504 ui = media_stream_capture_indicator_->RegisterMediaStream( 510 ui = media_stream_capture_indicator_->RegisterMediaStream(
505 web_contents, devices); 511 web_contents, devices);
506 } 512 }
507 callback.Run(devices, ui.Pass()); 513 callback.Run(
514 devices,
515 devices.empty() ? content::INVALID_STATE: content::OK,
516 ui.Pass());
508 } 517 }
509 518
510 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( 519 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest(
511 content::WebContents* web_contents, 520 content::WebContents* web_contents,
512 const content::MediaStreamRequest& request, 521 const content::MediaStreamRequest& request,
513 const content::MediaResponseCallback& callback) { 522 const content::MediaResponseCallback& callback) {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
515 524
516 RequestsQueue& queue = pending_requests_[web_contents]; 525 RequestsQueue& queue = pending_requests_[web_contents];
517 queue.push_back(PendingAccessRequest(request, callback)); 526 queue.push_back(PendingAccessRequest(request, callback));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 // when we've transitioned to bubbles. (crbug/337458) 561 // when we've transitioned to bubbles. (crbug/337458)
553 MediaStreamInfoBarDelegate::Create( 562 MediaStreamInfoBarDelegate::Create(
554 web_contents, it->second.front().request, 563 web_contents, it->second.front().request,
555 base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse, 564 base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse,
556 base::Unretained(this), web_contents)); 565 base::Unretained(this), web_contents));
557 } 566 }
558 567
559 void MediaCaptureDevicesDispatcher::OnAccessRequestResponse( 568 void MediaCaptureDevicesDispatcher::OnAccessRequestResponse(
560 content::WebContents* web_contents, 569 content::WebContents* web_contents,
561 const content::MediaStreamDevices& devices, 570 const content::MediaStreamDevices& devices,
571 content::MediaStreamRequestResult result,
562 scoped_ptr<content::MediaStreamUI> ui) { 572 scoped_ptr<content::MediaStreamUI> ui) {
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 573 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
564 574
565 std::map<content::WebContents*, RequestsQueue>::iterator it = 575 std::map<content::WebContents*, RequestsQueue>::iterator it =
566 pending_requests_.find(web_contents); 576 pending_requests_.find(web_contents);
567 if (it == pending_requests_.end()) { 577 if (it == pending_requests_.end()) {
568 // WebContents has been destroyed. Don't need to do anything. 578 // WebContents has been destroyed. Don't need to do anything.
569 return; 579 return;
570 } 580 }
571 581
572 RequestsQueue& queue(it->second); 582 RequestsQueue& queue(it->second);
573 if (queue.empty()) 583 if (queue.empty())
574 return; 584 return;
575 585
576 content::MediaResponseCallback callback = queue.front().callback; 586 content::MediaResponseCallback callback = queue.front().callback;
577 queue.pop_front(); 587 queue.pop_front();
578 588
579 if (!queue.empty()) { 589 if (!queue.empty()) {
580 // Post a task to process next queued request. It has to be done 590 // Post a task to process next queued request. It has to be done
581 // asynchronously to make sure that calling infobar is not destroyed until 591 // asynchronously to make sure that calling infobar is not destroyed until
582 // after this function returns. 592 // after this function returns.
583 BrowserThread::PostTask( 593 BrowserThread::PostTask(
584 BrowserThread::UI, FROM_HERE, 594 BrowserThread::UI, FROM_HERE,
585 base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest, 595 base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest,
586 base::Unretained(this), web_contents)); 596 base::Unretained(this), web_contents));
587 } 597 }
588 598
589 callback.Run(devices, ui.Pass()); 599 callback.Run(devices, result, ui.Pass());
590 } 600 }
591 601
592 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile( 602 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile(
593 Profile* profile, 603 Profile* profile,
594 bool audio, 604 bool audio,
595 bool video, 605 bool video,
596 content::MediaStreamDevices* devices) { 606 content::MediaStreamDevices* devices) {
597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 607 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
598 DCHECK(audio || video); 608 DCHECK(audio || video);
599 609
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 int render_frame_id) { 834 int render_frame_id) {
825 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 835 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
826 FOR_EACH_OBSERVER(Observer, observers_, 836 FOR_EACH_OBSERVER(Observer, observers_,
827 OnCreatingAudioStream(render_process_id, render_frame_id)); 837 OnCreatingAudioStream(render_process_id, render_frame_id));
828 } 838 }
829 839
830 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { 840 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() {
831 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 841 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
832 return desktop_capture_sessions_.size() > 0; 842 return desktop_capture_sessions_.size() > 0;
833 } 843 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698