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

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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 344
345 void MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest( 345 void MediaCaptureDevicesDispatcher::ProcessDesktopCaptureAccessRequest(
346 content::WebContents* web_contents, 346 content::WebContents* web_contents,
347 const content::MediaStreamRequest& request, 347 const content::MediaStreamRequest& request,
348 const content::MediaResponseCallback& callback, 348 const content::MediaResponseCallback& callback,
349 const extensions::Extension* extension) { 349 const extensions::Extension* extension) {
350 content::MediaStreamDevices devices; 350 content::MediaStreamDevices devices;
351 scoped_ptr<content::MediaStreamUI> ui; 351 scoped_ptr<content::MediaStreamUI> ui;
352 352
353 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { 353 if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) {
354 callback.Run(devices, ui.Pass()); 354 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
355 return; 355 return;
356 } 356 }
357 357
358 // If the device id wasn't specified then this is a screen capture request 358 // If the device id wasn't specified then this is a screen capture request
359 // (i.e. chooseDesktopMedia() API wasn't used to generate device id). 359 // (i.e. chooseDesktopMedia() API wasn't used to generate device id).
360 if (request.requested_video_device_id.empty()) { 360 if (request.requested_video_device_id.empty()) {
361 ProcessScreenCaptureAccessRequest( 361 ProcessScreenCaptureAccessRequest(
362 web_contents, request, callback, extension); 362 web_contents, request, callback, extension);
363 return; 363 return;
364 } 364 }
365 365
366 // The extension name that the stream is registered with. 366 // The extension name that the stream is registered with.
367 std::string original_extension_name; 367 std::string original_extension_name;
368 // Resolve DesktopMediaID for the specified device id. 368 // Resolve DesktopMediaID for the specified device id.
369 content::DesktopMediaID media_id = 369 content::DesktopMediaID media_id =
370 GetDesktopStreamsRegistry()->RequestMediaForStreamId( 370 GetDesktopStreamsRegistry()->RequestMediaForStreamId(
371 request.requested_video_device_id, request.render_process_id, 371 request.requested_video_device_id, request.render_process_id,
372 request.render_view_id, request.security_origin, 372 request.render_view_id, request.security_origin,
373 &original_extension_name); 373 &original_extension_name);
374 374
375 // Received invalid device id. 375 // Received invalid device id.
376 if (media_id.type == content::DesktopMediaID::TYPE_NONE) { 376 if (media_id.type == content::DesktopMediaID::TYPE_NONE) {
377 callback.Run(devices, ui.Pass()); 377 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
378 return; 378 return;
379 } 379 }
380 380
381 bool loopback_audio_supported = false; 381 bool loopback_audio_supported = false;
382 #if defined(USE_CRAS) || defined(OS_WIN) 382 #if defined(USE_CRAS) || defined(OS_WIN)
383 // Currently loopback audio capture is supported only on Windows and ChromeOS. 383 // Currently loopback audio capture is supported only on Windows and ChromeOS.
384 loopback_audio_supported = true; 384 loopback_audio_supported = true;
385 #endif 385 #endif
386 386
387 // Audio is only supported for screen capture streams. 387 // Audio is only supported for screen capture streams.
388 bool capture_audio = 388 bool capture_audio =
389 (media_id.type == content::DesktopMediaID::TYPE_SCREEN && 389 (media_id.type == content::DesktopMediaID::TYPE_SCREEN &&
390 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && 390 request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE &&
391 loopback_audio_supported); 391 loopback_audio_supported);
392 392
393 ui = GetDevicesForDesktopCapture( 393 ui = GetDevicesForDesktopCapture(
394 devices, media_id, capture_audio, true, 394 devices, media_id, capture_audio, true,
395 GetApplicationTitle(web_contents, extension), 395 GetApplicationTitle(web_contents, extension),
396 base::UTF8ToUTF16(original_extension_name)); 396 base::UTF8ToUTF16(original_extension_name));
397 397
398 callback.Run(devices, ui.Pass()); 398 callback.Run(devices, content::MEDIA_DEVICE_OK, ui.Pass());
399 } 399 }
400 400
401 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( 401 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest(
402 content::WebContents* web_contents, 402 content::WebContents* web_contents,
403 const content::MediaStreamRequest& request, 403 const content::MediaStreamRequest& request,
404 const content::MediaResponseCallback& callback, 404 const content::MediaResponseCallback& callback,
405 const extensions::Extension* extension) { 405 const extensions::Extension* extension) {
406 content::MediaStreamDevices devices; 406 content::MediaStreamDevices devices;
407 scoped_ptr<content::MediaStreamUI> ui; 407 scoped_ptr<content::MediaStreamUI> ui;
408 408
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 // Unless we're being invoked from a component extension, register to 478 // Unless we're being invoked from a component extension, register to
479 // display the notification for stream capture. 479 // display the notification for stream capture.
480 bool display_notification = !component_extension; 480 bool display_notification = !component_extension;
481 481
482 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, 482 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio,
483 display_notification, application_title, 483 display_notification, application_title,
484 application_title); 484 application_title);
485 } 485 }
486 } 486 }
487 487
488 callback.Run(devices, ui.Pass()); 488 callback.Run(
489 devices,
490 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE :
491 content::MEDIA_DEVICE_OK,
492 ui.Pass());
489 } 493 }
490 494
491 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( 495 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest(
492 content::WebContents* web_contents, 496 content::WebContents* web_contents,
493 const content::MediaStreamRequest& request, 497 const content::MediaStreamRequest& request,
494 const content::MediaResponseCallback& callback, 498 const content::MediaResponseCallback& callback,
495 const extensions::Extension* extension) { 499 const extensions::Extension* extension) {
496 content::MediaStreamDevices devices; 500 content::MediaStreamDevices devices;
497 scoped_ptr<content::MediaStreamUI> ui; 501 scoped_ptr<content::MediaStreamUI> ui;
498 502
499 #if defined(OS_ANDROID) 503 #if defined(OS_ANDROID)
500 // Tab capture is not supported on Android. 504 // Tab capture is not supported on Android.
501 callback.Run(devices, ui.Pass()); 505 callback.Run(devices, content::MEDIA_DEVICE_TAB_CAPTURE_FAILURE, ui.Pass());
502 #else // defined(OS_ANDROID) 506 #else // defined(OS_ANDROID)
503 Profile* profile = 507 Profile* profile =
504 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 508 Profile::FromBrowserContext(web_contents->GetBrowserContext());
505 extensions::TabCaptureRegistry* tab_capture_registry = 509 extensions::TabCaptureRegistry* tab_capture_registry =
506 extensions::TabCaptureRegistry::Get(profile); 510 extensions::TabCaptureRegistry::Get(profile);
507 if (!tab_capture_registry) { 511 if (!tab_capture_registry) {
508 NOTREACHED(); 512 NOTREACHED();
509 callback.Run(devices, ui.Pass()); 513 callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, ui.Pass());
510 return; 514 return;
511 } 515 }
512 bool tab_capture_allowed = 516 bool tab_capture_allowed =
513 tab_capture_registry->VerifyRequest(request.render_process_id, 517 tab_capture_registry->VerifyRequest(request.render_process_id,
514 request.render_view_id); 518 request.render_view_id);
515 519
516 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE && 520 if (request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE &&
517 tab_capture_allowed && 521 tab_capture_allowed &&
518 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) { 522 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) {
519 devices.push_back(content::MediaStreamDevice( 523 devices.push_back(content::MediaStreamDevice(
520 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string())); 524 content::MEDIA_TAB_AUDIO_CAPTURE, std::string(), std::string()));
521 } 525 }
522 526
523 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE && 527 if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE &&
524 tab_capture_allowed && 528 tab_capture_allowed &&
525 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) { 529 extension->HasAPIPermission(extensions::APIPermission::kTabCapture)) {
526 devices.push_back(content::MediaStreamDevice( 530 devices.push_back(content::MediaStreamDevice(
527 content::MEDIA_TAB_VIDEO_CAPTURE, std::string(), std::string())); 531 content::MEDIA_TAB_VIDEO_CAPTURE, std::string(), std::string()));
528 } 532 }
529 533
530 if (!devices.empty()) { 534 if (!devices.empty()) {
531 ui = media_stream_capture_indicator_->RegisterMediaStream( 535 ui = media_stream_capture_indicator_->RegisterMediaStream(
532 web_contents, devices); 536 web_contents, devices);
533 } 537 }
534 callback.Run(devices, ui.Pass()); 538 callback.Run(
539 devices,
540 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE :
541 content::MEDIA_DEVICE_OK,
542 ui.Pass());
535 #endif // !defined(OS_ANDROID) 543 #endif // !defined(OS_ANDROID)
536 } 544 }
537 545
538 void MediaCaptureDevicesDispatcher:: 546 void MediaCaptureDevicesDispatcher::
539 ProcessMediaAccessRequestFromPlatformAppOrExtension( 547 ProcessMediaAccessRequestFromPlatformAppOrExtension(
540 content::WebContents* web_contents, 548 content::WebContents* web_contents,
541 const content::MediaStreamRequest& request, 549 const content::MediaStreamRequest& request,
542 const content::MediaResponseCallback& callback, 550 const content::MediaResponseCallback& callback,
543 const extensions::Extension* extension) { 551 const extensions::Extension* extension) {
544 content::MediaStreamDevices devices; 552 content::MediaStreamDevices devices;
545 Profile* profile = 553 Profile* profile =
546 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 554 Profile::FromBrowserContext(web_contents->GetBrowserContext());
547 555
548 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE && 556 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
549 extension->HasAPIPermission(extensions::APIPermission::kAudioCapture)) { 557 extension->HasAPIPermission(extensions::APIPermission::kAudioCapture)) {
550 GetDefaultDevicesForProfile(profile, true, false, &devices); 558 GetDefaultDevicesForProfile(profile, true, false, &devices);
551 } 559 }
552 560
553 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && 561 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
554 extension->HasAPIPermission(extensions::APIPermission::kVideoCapture)) { 562 extension->HasAPIPermission(extensions::APIPermission::kVideoCapture)) {
555 GetDefaultDevicesForProfile(profile, false, true, &devices); 563 GetDefaultDevicesForProfile(profile, false, true, &devices);
556 } 564 }
557 565
558 scoped_ptr<content::MediaStreamUI> ui; 566 scoped_ptr<content::MediaStreamUI> ui;
559 if (!devices.empty()) { 567 if (!devices.empty()) {
560 ui = media_stream_capture_indicator_->RegisterMediaStream( 568 ui = media_stream_capture_indicator_->RegisterMediaStream(
561 web_contents, devices); 569 web_contents, devices);
562 } 570 }
563 callback.Run(devices, ui.Pass()); 571 callback.Run(
572 devices,
573 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE :
574 content::MEDIA_DEVICE_OK,
575 ui.Pass());
564 } 576 }
565 577
566 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( 578 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest(
567 content::WebContents* web_contents, 579 content::WebContents* web_contents,
568 const content::MediaStreamRequest& request, 580 const content::MediaStreamRequest& request,
569 const content::MediaResponseCallback& callback) { 581 const content::MediaResponseCallback& callback) {
570 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
571 583
572 RequestsQueue& queue = pending_requests_[web_contents]; 584 RequestsQueue& queue = pending_requests_[web_contents];
573 queue.push_back(PendingAccessRequest(request, callback)); 585 queue.push_back(PendingAccessRequest(request, callback));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 // when we've transitioned to bubbles. (crbug/337458) 620 // when we've transitioned to bubbles. (crbug/337458)
609 MediaStreamInfoBarDelegate::Create( 621 MediaStreamInfoBarDelegate::Create(
610 web_contents, it->second.front().request, 622 web_contents, it->second.front().request,
611 base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse, 623 base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse,
612 base::Unretained(this), web_contents)); 624 base::Unretained(this), web_contents));
613 } 625 }
614 626
615 void MediaCaptureDevicesDispatcher::OnAccessRequestResponse( 627 void MediaCaptureDevicesDispatcher::OnAccessRequestResponse(
616 content::WebContents* web_contents, 628 content::WebContents* web_contents,
617 const content::MediaStreamDevices& devices, 629 const content::MediaStreamDevices& devices,
630 content::MediaStreamRequestResult result,
618 scoped_ptr<content::MediaStreamUI> ui) { 631 scoped_ptr<content::MediaStreamUI> ui) {
619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 632 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
620 633
621 std::map<content::WebContents*, RequestsQueue>::iterator it = 634 std::map<content::WebContents*, RequestsQueue>::iterator it =
622 pending_requests_.find(web_contents); 635 pending_requests_.find(web_contents);
623 if (it == pending_requests_.end()) { 636 if (it == pending_requests_.end()) {
624 // WebContents has been destroyed. Don't need to do anything. 637 // WebContents has been destroyed. Don't need to do anything.
625 return; 638 return;
626 } 639 }
627 640
628 RequestsQueue& queue(it->second); 641 RequestsQueue& queue(it->second);
629 if (queue.empty()) 642 if (queue.empty())
630 return; 643 return;
631 644
632 content::MediaResponseCallback callback = queue.front().callback; 645 content::MediaResponseCallback callback = queue.front().callback;
633 queue.pop_front(); 646 queue.pop_front();
634 647
635 if (!queue.empty()) { 648 if (!queue.empty()) {
636 // Post a task to process next queued request. It has to be done 649 // Post a task to process next queued request. It has to be done
637 // asynchronously to make sure that calling infobar is not destroyed until 650 // asynchronously to make sure that calling infobar is not destroyed until
638 // after this function returns. 651 // after this function returns.
639 BrowserThread::PostTask( 652 BrowserThread::PostTask(
640 BrowserThread::UI, FROM_HERE, 653 BrowserThread::UI, FROM_HERE,
641 base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest, 654 base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest,
642 base::Unretained(this), web_contents)); 655 base::Unretained(this), web_contents));
643 } 656 }
644 657
645 callback.Run(devices, ui.Pass()); 658 callback.Run(devices, result, ui.Pass());
646 } 659 }
647 660
648 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile( 661 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile(
649 Profile* profile, 662 Profile* profile,
650 bool audio, 663 bool audio,
651 bool video, 664 bool video,
652 content::MediaStreamDevices* devices) { 665 content::MediaStreamDevices* devices) {
653 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
654 DCHECK(audio || video); 667 DCHECK(audio || video);
655 668
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 // info for content::WebContentsUserData). 924 // info for content::WebContentsUserData).
912 AudioStreamMonitor::CreateForWebContents(web_contents); 925 AudioStreamMonitor::CreateForWebContents(web_contents);
913 } 926 }
914 #endif 927 #endif
915 } 928 }
916 929
917 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() { 930 bool MediaCaptureDevicesDispatcher::IsDesktopCaptureInProgress() {
918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
919 return desktop_capture_sessions_.size() > 0; 932 return desktop_capture_sessions_.size() > 0;
920 } 933 }
OLDNEW
« no previous file with comments | « chrome/browser/media/media_capture_devices_dispatcher.h ('k') | chrome/browser/media/media_stream_devices_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698