| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 9 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 10 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 10 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 controller->PermissionGranted(); | 42 controller->PermissionGranted(); |
| 43 } | 43 } |
| 44 | 44 |
| 45 } // namespace | 45 } // namespace |
| 46 | 46 |
| 47 class MediaStreamDevicesControllerTest : public WebRtcTestBase { | 47 class MediaStreamDevicesControllerTest : public WebRtcTestBase { |
| 48 public: | 48 public: |
| 49 MediaStreamDevicesControllerTest() | 49 MediaStreamDevicesControllerTest() |
| 50 : example_audio_id_("fake_audio_dev"), | 50 : example_audio_id_("fake_audio_dev"), |
| 51 example_video_id_("fake_video_dev"), | 51 example_video_id_("fake_video_dev"), |
| 52 example_screen_id_("fake_screen_dev"), |
| 52 media_stream_result_(content::NUM_MEDIA_REQUEST_RESULTS) {} | 53 media_stream_result_(content::NUM_MEDIA_REQUEST_RESULTS) {} |
| 53 | 54 |
| 54 // Dummy callback for when we deny the current request directly. | 55 // Dummy callback for when we deny the current request directly. |
| 55 void OnMediaStreamResponse(const content::MediaStreamDevices& devices, | 56 void OnMediaStreamResponse(const content::MediaStreamDevices& devices, |
| 56 content::MediaStreamRequestResult result, | 57 content::MediaStreamRequestResult result, |
| 57 std::unique_ptr<content::MediaStreamUI> ui) { | 58 std::unique_ptr<content::MediaStreamUI> ui) { |
| 58 media_stream_devices_ = devices; | 59 media_stream_devices_ = devices; |
| 59 media_stream_result_ = result; | 60 media_stream_result_ = result; |
| 60 } | 61 } |
| 61 | 62 |
| 62 protected: | 63 protected: |
| 63 enum DeviceType { DEVICE_TYPE_AUDIO, DEVICE_TYPE_VIDEO }; | 64 enum DeviceType { DEVICE_TYPE_AUDIO, DEVICE_TYPE_VIDEO }; |
| 64 enum Access { ACCESS_ALLOWED, ACCESS_DENIED }; | 65 enum Access { ACCESS_ALLOWED, ACCESS_DENIED }; |
| 65 | 66 |
| 66 const GURL& example_url() const { return example_url_; } | 67 const GURL& example_url() const { return example_url_; } |
| 67 | 68 |
| 68 TabSpecificContentSettings* GetContentSettings() { | 69 TabSpecificContentSettings* GetContentSettings() { |
| 69 return TabSpecificContentSettings::FromWebContents(GetWebContents()); | 70 return TabSpecificContentSettings::FromWebContents(GetWebContents()); |
| 70 } | 71 } |
| 71 | 72 |
| 72 const std::string& example_audio_id() const { return example_audio_id_; } | 73 const std::string& example_audio_id() const { return example_audio_id_; } |
| 73 const std::string& example_video_id() const { return example_video_id_; } | 74 const std::string& example_video_id() const { return example_video_id_; } |
| 75 const std::string& example_screen_id() const { return example_screen_id_; } |
| 74 | 76 |
| 75 content::MediaStreamRequestResult media_stream_result() const { | 77 content::MediaStreamRequestResult media_stream_result() const { |
| 76 return media_stream_result_; | 78 return media_stream_result_; |
| 77 } | 79 } |
| 78 | 80 |
| 79 // Sets the device policy-controlled |access| for |example_url_| to be for the | 81 // Sets the device policy-controlled |access| for |example_url_| to be for the |
| 80 // selected |device_type|. | 82 // selected |device_type|. |
| 81 void SetDevicePolicy(DeviceType device_type, Access access) { | 83 void SetDevicePolicy(DeviceType device_type, Access access) { |
| 82 PrefService* prefs = Profile::FromBrowserContext( | 84 PrefService* prefs = Profile::FromBrowserContext( |
| 83 GetWebContents()->GetBrowserContext())->GetPrefs(); | 85 GetWebContents()->GetBrowserContext())->GetPrefs(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 102 content_settings->SetContentSettingDefaultScope( | 104 content_settings->SetContentSettingDefaultScope( |
| 103 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | 105 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
| 104 std::string(), mic_setting); | 106 std::string(), mic_setting); |
| 105 content_settings->SetContentSettingDefaultScope( | 107 content_settings->SetContentSettingDefaultScope( |
| 106 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | 108 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
| 107 std::string(), cam_setting); | 109 std::string(), cam_setting); |
| 108 } | 110 } |
| 109 | 111 |
| 110 // Checks whether the devices returned in OnMediaStreamResponse contains a | 112 // Checks whether the devices returned in OnMediaStreamResponse contains a |
| 111 // microphone and/or camera device. | 113 // microphone and/or camera device. |
| 112 bool DevicesContains(bool needs_mic, bool needs_cam) { | 114 bool CheckDevicesListContains(content::MediaStreamType type) { |
| 113 bool has_mic = false; | |
| 114 bool has_cam = false; | |
| 115 for (const auto& device : media_stream_devices_) { | 115 for (const auto& device : media_stream_devices_) { |
| 116 if (device.type == content::MEDIA_DEVICE_AUDIO_CAPTURE) | 116 if (device.type == type) { |
| 117 has_mic = true; | 117 return true; |
| 118 if (device.type == content::MEDIA_DEVICE_VIDEO_CAPTURE) | 118 } |
| 119 has_cam = true; | |
| 120 } | 119 } |
| 121 | 120 return false; |
| 122 return needs_mic == has_mic && needs_cam == has_cam; | |
| 123 } | 121 } |
| 124 | 122 |
| 125 content::WebContents* GetWebContents() { | 123 content::WebContents* GetWebContents() { |
| 126 return browser()->tab_strip_model()->GetActiveWebContents(); | 124 return browser()->tab_strip_model()->GetActiveWebContents(); |
| 127 } | 125 } |
| 128 | 126 |
| 129 // Creates a MediaStreamRequest, asking for those media types, which have a | 127 // Creates a MediaStreamRequest, asking for those media types, which have a |
| 130 // non-empty id string. | 128 // non-empty id string. |
| 131 content::MediaStreamRequest CreateRequestWithType( | 129 content::MediaStreamRequest CreateRequestWithType( |
| 132 const std::string& audio_id, | 130 const std::string& audio_id, |
| 133 const std::string& video_id, | 131 const std::string& video_id, |
| 134 content::MediaStreamRequestType request_type) { | 132 content::MediaStreamRequestType request_type) { |
| 135 content::MediaStreamType audio_type = | 133 content::MediaStreamType audio_type = |
| 136 audio_id.empty() ? content::MEDIA_NO_SERVICE | 134 audio_id.empty() ? content::MEDIA_NO_SERVICE |
| 137 : content::MEDIA_DEVICE_AUDIO_CAPTURE; | 135 : content::MEDIA_DEVICE_AUDIO_CAPTURE; |
| 138 content::MediaStreamType video_type = | 136 content::MediaStreamType video_type = |
| 139 video_id.empty() ? content::MEDIA_NO_SERVICE | 137 video_id.empty() ? content::MEDIA_NO_SERVICE |
| 140 : content::MEDIA_DEVICE_VIDEO_CAPTURE; | 138 : content::MEDIA_DEVICE_VIDEO_CAPTURE; |
| 139 #if defined(OS_ANDROID) |
| 140 if (!video_id.compare(example_screen_id())) |
| 141 video_type = content::MEDIA_DESKTOP_VIDEO_CAPTURE; |
| 142 #endif |
| 143 |
| 141 return content::MediaStreamRequest(0, 0, 0, example_url(), false, | 144 return content::MediaStreamRequest(0, 0, 0, example_url(), false, |
| 142 request_type, audio_id, video_id, | 145 request_type, audio_id, video_id, |
| 143 audio_type, video_type); | 146 audio_type, video_type); |
| 144 } | 147 } |
| 145 | 148 |
| 146 content::MediaStreamRequest CreateRequest(const std::string& audio_id, | 149 content::MediaStreamRequest CreateRequest(const std::string& audio_id, |
| 147 const std::string& video_id) { | 150 const std::string& video_id) { |
| 148 return CreateRequestWithType(audio_id, video_id, | 151 return CreateRequestWithType(audio_id, video_id, |
| 149 content::MEDIA_DEVICE_ACCESS); | 152 content::MEDIA_DEVICE_ACCESS); |
| 150 } | 153 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 178 content::MEDIA_DEVICE_VIDEO_CAPTURE, example_video_id_, | 181 content::MEDIA_DEVICE_VIDEO_CAPTURE, example_video_id_, |
| 179 "Fake Video Device"); | 182 "Fake Video Device"); |
| 180 video_devices.push_back(fake_video_device); | 183 video_devices.push_back(fake_video_device); |
| 181 MediaCaptureDevicesDispatcher::GetInstance()->SetTestVideoCaptureDevices( | 184 MediaCaptureDevicesDispatcher::GetInstance()->SetTestVideoCaptureDevices( |
| 182 video_devices); | 185 video_devices); |
| 183 } | 186 } |
| 184 | 187 |
| 185 GURL example_url_; | 188 GURL example_url_; |
| 186 const std::string example_audio_id_; | 189 const std::string example_audio_id_; |
| 187 const std::string example_video_id_; | 190 const std::string example_video_id_; |
| 191 const std::string example_screen_id_; |
| 188 | 192 |
| 189 content::MediaStreamDevices media_stream_devices_; | 193 content::MediaStreamDevices media_stream_devices_; |
| 190 content::MediaStreamRequestResult media_stream_result_; | 194 content::MediaStreamRequestResult media_stream_result_; |
| 191 }; | 195 }; |
| 192 | 196 |
| 193 // Request and allow microphone access. | 197 // Request and allow microphone access. |
| 194 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndAllowMic) { | 198 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndAllowMic) { |
| 195 InitWithUrl(GURL("https://www.example.com")); | 199 InitWithUrl(GURL("https://www.example.com")); |
| 196 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); | 200 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); |
| 197 MediaStreamDevicesController controller( | 201 MediaStreamDevicesController controller( |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 if (test.ExpectMicInfobar() || test.ExpectCamInfobar()) { | 634 if (test.ExpectMicInfobar() || test.ExpectCamInfobar()) { |
| 631 if (test.accept_infobar) | 635 if (test.accept_infobar) |
| 632 controller.PermissionGranted(); | 636 controller.PermissionGranted(); |
| 633 else | 637 else |
| 634 controller.PermissionDenied(); | 638 controller.PermissionDenied(); |
| 635 } | 639 } |
| 636 | 640 |
| 637 // Check the media stream result is expected and the devices returned are | 641 // Check the media stream result is expected and the devices returned are |
| 638 // expected; | 642 // expected; |
| 639 ASSERT_EQ(test.ExpectedMediaStreamResult(), media_stream_result()); | 643 ASSERT_EQ(test.ExpectedMediaStreamResult(), media_stream_result()); |
| 640 ASSERT_TRUE( | 644 ASSERT_EQ(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE), |
| 641 DevicesContains(test.ExpectMicAllowed(), test.ExpectCamAllowed())); | 645 test.ExpectMicAllowed()); |
| 646 ASSERT_EQ(CheckDevicesListContains(content::MEDIA_DEVICE_VIDEO_CAPTURE), |
| 647 test.ExpectCamAllowed()); |
| 642 } | 648 } |
| 643 } | 649 } |
| 644 | 650 |
| 645 // Request and allow camera access on WebUI pages without prompting. | 651 // Request and allow camera access on WebUI pages without prompting. |
| 646 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | 652 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, |
| 647 WebUIRequestAndAllowCam) { | 653 WebUIRequestAndAllowCam) { |
| 648 InitWithUrl(GURL("chrome://test-page")); | 654 InitWithUrl(GURL("chrome://test-page")); |
| 649 MediaStreamDevicesController controller( | 655 MediaStreamDevicesController controller( |
| 650 GetWebContents(), CreateRequest(std::string(), example_video_id()), | 656 GetWebContents(), CreateRequest(std::string(), example_video_id()), |
| 651 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | 657 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 652 base::Unretained(this))); | 658 base::Unretained(this))); |
| 653 | 659 |
| 654 ASSERT_FALSE(controller.IsAskingForAudio()); | 660 ASSERT_FALSE(controller.IsAskingForAudio()); |
| 655 ASSERT_FALSE(controller.IsAskingForVideo()); | 661 ASSERT_FALSE(controller.IsAskingForVideo()); |
| 656 | 662 |
| 657 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | 663 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); |
| 658 ASSERT_TRUE(DevicesContains(false, true)); | 664 ASSERT_FALSE(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE)); |
| 665 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DEVICE_VIDEO_CAPTURE)); |
| 659 } | 666 } |
| 660 | 667 |
| 661 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | 668 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, |
| 662 ExtensionRequestMicCam) { | 669 ExtensionRequestMicCam) { |
| 663 InitWithUrl(GURL("chrome-extension://test-page")); | 670 InitWithUrl(GURL("chrome-extension://test-page")); |
| 664 // Test that a prompt is required. | 671 // Test that a prompt is required. |
| 665 MediaStreamDevicesController controller( | 672 MediaStreamDevicesController controller( |
| 666 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | 673 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), |
| 667 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | 674 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 668 base::Unretained(this))); | 675 base::Unretained(this))); |
| 669 ASSERT_TRUE(controller.IsAskingForAudio()); | 676 ASSERT_TRUE(controller.IsAskingForAudio()); |
| 670 ASSERT_TRUE(controller.IsAskingForVideo()); | 677 ASSERT_TRUE(controller.IsAskingForVideo()); |
| 671 | 678 |
| 672 // Accept the prompt. | 679 // Accept the prompt. |
| 673 controller.PermissionGranted(); | 680 controller.PermissionGranted(); |
| 674 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | 681 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); |
| 675 ASSERT_TRUE(DevicesContains(true, true)); | 682 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE)); |
| 683 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DEVICE_VIDEO_CAPTURE)); |
| 676 | 684 |
| 677 // Check that re-requesting allows without prompting. | 685 // Check that re-requesting allows without prompting. |
| 678 MediaStreamDevicesController controller2( | 686 MediaStreamDevicesController controller2( |
| 679 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | 687 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), |
| 680 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | 688 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 681 base::Unretained(this))); | 689 base::Unretained(this))); |
| 682 ASSERT_FALSE(controller2.IsAskingForAudio()); | 690 ASSERT_FALSE(controller2.IsAskingForAudio()); |
| 683 ASSERT_FALSE(controller2.IsAskingForVideo()); | 691 ASSERT_FALSE(controller2.IsAskingForVideo()); |
| 684 | 692 |
| 685 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | 693 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); |
| 686 ASSERT_TRUE(DevicesContains(true, true)); | 694 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE)); |
| 695 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DEVICE_VIDEO_CAPTURE)); |
| 687 } | 696 } |
| 688 | 697 |
| 689 // For Pepper request from insecure origin, even if it's ALLOW, it won't be | 698 // For Pepper request from insecure origin, even if it's ALLOW, it won't be |
| 690 // changed to ASK. | 699 // changed to ASK. |
| 691 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | 700 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, |
| 692 PepperRequestInsecure) { | 701 PepperRequestInsecure) { |
| 693 InitWithUrl(GURL("http://www.example.com")); | 702 InitWithUrl(GURL("http://www.example.com")); |
| 694 SetContentSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW); | 703 SetContentSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW); |
| 695 | 704 |
| 696 MediaStreamDevicesController controller( | 705 MediaStreamDevicesController controller( |
| (...skipping 28 matching lines...) Expand all Loading... |
| 725 MediaStreamDevicesController controller( | 734 MediaStreamDevicesController controller( |
| 726 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | 735 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), |
| 727 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | 736 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 728 base::Unretained(this))); | 737 base::Unretained(this))); |
| 729 | 738 |
| 730 EXPECT_FALSE(controller.IsAllowedForAudio()); | 739 EXPECT_FALSE(controller.IsAllowedForAudio()); |
| 731 EXPECT_FALSE(controller.IsAllowedForVideo()); | 740 EXPECT_FALSE(controller.IsAllowedForVideo()); |
| 732 EXPECT_FALSE(controller.IsAskingForAudio()); | 741 EXPECT_FALSE(controller.IsAskingForAudio()); |
| 733 EXPECT_FALSE(controller.IsAskingForVideo()); | 742 EXPECT_FALSE(controller.IsAskingForVideo()); |
| 734 } | 743 } |
| 744 |
| 745 #if defined(OS_ANDROID) |
| 746 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, |
| 747 RequestAndAllowScreenCapture) { |
| 748 InitWithUrl(GURL("https://www.example.com")); |
| 749 // Test that a prompt is required. |
| 750 MediaStreamDevicesController controller( |
| 751 GetWebContents(), CreateRequest(std::string(), example_screen_id()), |
| 752 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 753 base::Unretained(this))); |
| 754 ASSERT_TRUE(controller.IsAskingForScreenCapture()); |
| 755 |
| 756 // Accept the prompt. |
| 757 controller.PermissionGranted(); |
| 758 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); |
| 759 ASSERT_FALSE(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE)); |
| 760 ASSERT_TRUE(CheckDevicesListContains(content::MEDIA_DESKTOP_VIDEO_CAPTURE)); |
| 761 |
| 762 // Check that re-requesting still requires prompting. |
| 763 MediaStreamDevicesController controller2( |
| 764 GetWebContents(), CreateRequest(std::string(), example_screen_id()), |
| 765 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 766 base::Unretained(this))); |
| 767 ASSERT_TRUE(controller2.IsAskingForScreenCapture()); |
| 768 } |
| 769 |
| 770 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, |
| 771 RequestAndBlockScreenCapture) { |
| 772 InitWithUrl(GURL("https://www.example.com")); |
| 773 // Test that a prompt is required. |
| 774 MediaStreamDevicesController controller( |
| 775 GetWebContents(), CreateRequest(std::string(), example_screen_id()), |
| 776 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 777 base::Unretained(this))); |
| 778 ASSERT_TRUE(controller.IsAskingForScreenCapture()); |
| 779 |
| 780 // Block the prompt. |
| 781 controller.PermissionDenied(); |
| 782 ASSERT_NE(content::MEDIA_DEVICE_OK, media_stream_result()); |
| 783 ASSERT_FALSE(CheckDevicesListContains(content::MEDIA_DEVICE_AUDIO_CAPTURE)); |
| 784 ASSERT_FALSE(CheckDevicesListContains(content::MEDIA_DESKTOP_VIDEO_CAPTURE)); |
| 785 |
| 786 // Check that re-requesting still requires prompting. |
| 787 MediaStreamDevicesController controller2( |
| 788 GetWebContents(), CreateRequest(std::string(), example_screen_id()), |
| 789 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, |
| 790 base::Unretained(this))); |
| 791 ASSERT_TRUE(controller2.IsAskingForScreenCapture()); |
| 792 } |
| 793 #endif // defined(OS_ANDROID) |
| OLD | NEW |