OLD | NEW |
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/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 switches::kEnableUserMediaScreenCapturing) || | 559 switches::kEnableUserMediaScreenCapturing) || |
560 IsOriginForCasting(request.security_origin) || | 560 IsOriginForCasting(request.security_origin) || |
561 IsBuiltInExtension(request.security_origin); | 561 IsBuiltInExtension(request.security_origin); |
562 | 562 |
563 const bool origin_is_secure = | 563 const bool origin_is_secure = |
564 request.security_origin.SchemeIsSecure() || | 564 request.security_origin.SchemeIsSecure() || |
565 request.security_origin.SchemeIs(extensions::kExtensionScheme) || | 565 request.security_origin.SchemeIs(extensions::kExtensionScheme) || |
566 CommandLine::ForCurrentProcess()->HasSwitch( | 566 CommandLine::ForCurrentProcess()->HasSwitch( |
567 switches::kAllowHttpScreenCapture); | 567 switches::kAllowHttpScreenCapture); |
568 | 568 |
| 569 // If basic conditions (screen capturing is enabled and origin is secure) |
| 570 // aren't fulfilled, we'll use "invalid state" as result. Otherwise, we set |
| 571 // it after checking permission. |
| 572 // TODO(grunell): It would be good to change this result for something else, |
| 573 // probably a new one. |
| 574 content::MediaStreamRequestResult result = |
| 575 content::MEDIA_DEVICE_INVALID_STATE; |
| 576 |
569 // Approve request only when the following conditions are met: | 577 // Approve request only when the following conditions are met: |
570 // 1. Screen capturing is enabled via command line switch or white-listed for | 578 // 1. Screen capturing is enabled via command line switch or white-listed for |
571 // the given origin. | 579 // the given origin. |
572 // 2. Request comes from a page with a secure origin or from an extension. | 580 // 2. Request comes from a page with a secure origin or from an extension. |
573 if (screen_capture_enabled && origin_is_secure) { | 581 if (screen_capture_enabled && origin_is_secure) { |
574 // Get title of the calling application prior to showing the message box. | 582 // Get title of the calling application prior to showing the message box. |
575 // chrome::ShowMessageBox() starts a nested message loop which may allow | 583 // chrome::ShowMessageBox() starts a nested message loop which may allow |
576 // |web_contents| to be destroyed on the UI thread before the message box | 584 // |web_contents| to be destroyed on the UI thread before the message box |
577 // is closed. See http://crbug.com/326690. | 585 // is closed. See http://crbug.com/326690. |
578 base::string16 application_title = | 586 base::string16 application_title = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && | 627 (request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE && |
620 loopback_audio_supported); | 628 loopback_audio_supported); |
621 | 629 |
622 // Unless we're being invoked from a component extension, register to | 630 // Unless we're being invoked from a component extension, register to |
623 // display the notification for stream capture. | 631 // display the notification for stream capture. |
624 bool display_notification = !component_extension; | 632 bool display_notification = !component_extension; |
625 | 633 |
626 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, | 634 ui = GetDevicesForDesktopCapture(devices, screen_id, capture_audio, |
627 display_notification, application_title, | 635 display_notification, application_title, |
628 application_title); | 636 application_title); |
| 637 DCHECK(!devices.empty()); |
629 } | 638 } |
| 639 |
| 640 // The only case when devices can be empty is if the user has denied |
| 641 // permission. |
| 642 result = devices.empty() ? content::MEDIA_DEVICE_PERMISSION_DENIED |
| 643 : content::MEDIA_DEVICE_OK; |
630 } | 644 } |
631 | 645 |
632 callback.Run( | 646 callback.Run(devices, result, ui.Pass()); |
633 devices, | |
634 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : | |
635 content::MEDIA_DEVICE_OK, | |
636 ui.Pass()); | |
637 } | 647 } |
638 | 648 |
639 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( | 649 void MediaCaptureDevicesDispatcher::ProcessTabCaptureAccessRequest( |
640 content::WebContents* web_contents, | 650 content::WebContents* web_contents, |
641 const content::MediaStreamRequest& request, | 651 const content::MediaStreamRequest& request, |
642 const content::MediaResponseCallback& callback, | 652 const content::MediaResponseCallback& callback, |
643 const extensions::Extension* extension) { | 653 const extensions::Extension* extension) { |
644 content::MediaStreamDevices devices; | 654 content::MediaStreamDevices devices; |
645 scoped_ptr<content::MediaStreamUI> ui; | 655 scoped_ptr<content::MediaStreamUI> ui; |
646 | 656 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 bool video_allowed = | 714 bool video_allowed = |
705 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && | 715 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && |
706 extension->permissions_data()->HasAPIPermission( | 716 extension->permissions_data()->HasAPIPermission( |
707 extensions::APIPermission::kVideoCapture); | 717 extensions::APIPermission::kVideoCapture); |
708 | 718 |
709 bool get_default_audio_device = audio_allowed; | 719 bool get_default_audio_device = audio_allowed; |
710 bool get_default_video_device = video_allowed; | 720 bool get_default_video_device = video_allowed; |
711 | 721 |
712 content::MediaStreamDevices devices; | 722 content::MediaStreamDevices devices; |
713 | 723 |
| 724 // Set an initial error result. If neither audio or video is allowed, we'll |
| 725 // never try to get any device below but will just create |ui| and return an |
| 726 // empty list with "invalid state" result. If at least one is allowed, we'll |
| 727 // try to get device(s), and if failure, we want to return "no hardware" |
| 728 // result. |
| 729 // TODO(grunell): The invalid state result should be changed to a new denied |
| 730 // result + a dcheck to ensure at least one of audio or video types is |
| 731 // capture. |
| 732 content::MediaStreamRequestResult result = |
| 733 (audio_allowed || video_allowed) ? content::MEDIA_DEVICE_NO_HARDWARE |
| 734 : content::MEDIA_DEVICE_INVALID_STATE; |
| 735 |
714 // Get the exact audio or video device if an id is specified. | 736 // Get the exact audio or video device if an id is specified. |
| 737 // We only set any error result here and before running the callback change |
| 738 // it to OK if we have any device. |
715 if (audio_allowed && !request.requested_audio_device_id.empty()) { | 739 if (audio_allowed && !request.requested_audio_device_id.empty()) { |
716 const content::MediaStreamDevice* audio_device = | 740 const content::MediaStreamDevice* audio_device = |
717 GetRequestedAudioDevice(request.requested_audio_device_id); | 741 GetRequestedAudioDevice(request.requested_audio_device_id); |
718 if (audio_device) { | 742 if (audio_device) { |
719 devices.push_back(*audio_device); | 743 devices.push_back(*audio_device); |
720 get_default_audio_device = false; | 744 get_default_audio_device = false; |
721 } | 745 } |
722 } | 746 } |
723 if (video_allowed && !request.requested_video_device_id.empty()) { | 747 if (video_allowed && !request.requested_video_device_id.empty()) { |
724 const content::MediaStreamDevice* video_device = | 748 const content::MediaStreamDevice* video_device = |
(...skipping 10 matching lines...) Expand all Loading... |
735 Profile* profile = | 759 Profile* profile = |
736 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 760 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
737 GetDefaultDevicesForProfile(profile, | 761 GetDefaultDevicesForProfile(profile, |
738 get_default_audio_device, | 762 get_default_audio_device, |
739 get_default_video_device, | 763 get_default_video_device, |
740 &devices); | 764 &devices); |
741 } | 765 } |
742 | 766 |
743 scoped_ptr<content::MediaStreamUI> ui; | 767 scoped_ptr<content::MediaStreamUI> ui; |
744 if (!devices.empty()) { | 768 if (!devices.empty()) { |
| 769 result = content::MEDIA_DEVICE_OK; |
745 ui = media_stream_capture_indicator_->RegisterMediaStream( | 770 ui = media_stream_capture_indicator_->RegisterMediaStream( |
746 web_contents, devices); | 771 web_contents, devices); |
747 } | 772 } |
748 callback.Run( | 773 |
749 devices, | 774 callback.Run(devices, result, ui.Pass()); |
750 devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : | |
751 content::MEDIA_DEVICE_OK, | |
752 ui.Pass()); | |
753 } | 775 } |
754 | 776 |
755 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( | 777 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( |
756 content::WebContents* web_contents, | 778 content::WebContents* web_contents, |
757 const content::MediaStreamRequest& request, | 779 const content::MediaStreamRequest& request, |
758 const content::MediaResponseCallback& callback) { | 780 const content::MediaResponseCallback& callback) { |
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 781 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
760 | 782 |
761 RequestsQueue& queue = pending_requests_[web_contents]; | 783 RequestsQueue& queue = pending_requests_[web_contents]; |
762 queue.push_back(PendingAccessRequest(request, callback)); | 784 queue.push_back(PendingAccessRequest(request, callback)); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 | 1086 |
1065 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( | 1087 void MediaCaptureDevicesDispatcher::SetTestAudioCaptureDevices( |
1066 const MediaStreamDevices& devices) { | 1088 const MediaStreamDevices& devices) { |
1067 test_audio_devices_ = devices; | 1089 test_audio_devices_ = devices; |
1068 } | 1090 } |
1069 | 1091 |
1070 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( | 1092 void MediaCaptureDevicesDispatcher::SetTestVideoCaptureDevices( |
1071 const MediaStreamDevices& devices) { | 1093 const MediaStreamDevices& devices) { |
1072 test_video_devices_ = devices; | 1094 test_video_devices_ = devices; |
1073 } | 1095 } |
OLD | NEW |