| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <string> | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/metrics/field_trial.h" | |
| 9 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | |
| 10 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | |
| 11 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | |
| 12 #include "chrome/browser/media/media_stream_capture_indicator.h" | |
| 13 #include "chrome/browser/media/media_stream_device_permissions.h" | |
| 14 #include "chrome/browser/media/media_stream_devices_controller.h" | |
| 15 #include "chrome/browser/media/webrtc_browsertest_base.h" | |
| 16 #include "chrome/browser/permissions/permission_context_base.h" | |
| 17 #include "chrome/browser/permissions/permission_util.h" | |
| 18 #include "chrome/browser/profiles/profile.h" | |
| 19 #include "chrome/browser/ui/browser.h" | |
| 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 21 #include "chrome/common/pref_names.h" | |
| 22 #include "chrome/test/base/ui_test_utils.h" | |
| 23 #include "components/content_settings/core/browser/host_content_settings_map.h" | |
| 24 #include "components/prefs/pref_service.h" | |
| 25 #include "components/variations/variations_associated_data.h" | |
| 26 #include "content/public/common/media_stream_request.h" | |
| 27 #include "content/public/test/mock_render_process_host.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 | |
| 30 namespace { | |
| 31 | |
| 32 // Causes the controller to update the TabSpecificContentSettings associated | |
| 33 // with the same WebContents with the current permissions. This should be the | |
| 34 // last change made to the controller in the test. | |
| 35 void NotifyTabSpecificContentSettings( | |
| 36 MediaStreamDevicesController* controller) { | |
| 37 // Note that calling Deny() would have the same effect of passing the current | |
| 38 // permissions state to the TabSpecificContentSettings. Deny() and Accept() | |
| 39 // differ in their effect on the controller itself, but that is not important | |
| 40 // in the tests calling this. | |
| 41 if (controller->IsAskingForAudio() || controller->IsAskingForVideo()) | |
| 42 controller->PermissionGranted(); | |
| 43 } | |
| 44 | |
| 45 } // namespace | |
| 46 | |
| 47 class MediaStreamDevicesControllerTest : public WebRtcTestBase { | |
| 48 public: | |
| 49 MediaStreamDevicesControllerTest() | |
| 50 : example_audio_id_("fake_audio_dev"), | |
| 51 example_video_id_("fake_video_dev"), | |
| 52 media_stream_result_(content::NUM_MEDIA_REQUEST_RESULTS) {} | |
| 53 | |
| 54 // Dummy callback for when we deny the current request directly. | |
| 55 void OnMediaStreamResponse(const content::MediaStreamDevices& devices, | |
| 56 content::MediaStreamRequestResult result, | |
| 57 std::unique_ptr<content::MediaStreamUI> ui) { | |
| 58 media_stream_devices_ = devices; | |
| 59 media_stream_result_ = result; | |
| 60 } | |
| 61 | |
| 62 protected: | |
| 63 enum DeviceType { DEVICE_TYPE_AUDIO, DEVICE_TYPE_VIDEO }; | |
| 64 enum Access { ACCESS_ALLOWED, ACCESS_DENIED }; | |
| 65 | |
| 66 const GURL& example_url() const { return example_url_; } | |
| 67 | |
| 68 TabSpecificContentSettings* GetContentSettings() { | |
| 69 return TabSpecificContentSettings::FromWebContents(GetWebContents()); | |
| 70 } | |
| 71 | |
| 72 const std::string& example_audio_id() const { return example_audio_id_; } | |
| 73 const std::string& example_video_id() const { return example_video_id_; } | |
| 74 | |
| 75 content::MediaStreamRequestResult media_stream_result() const { | |
| 76 return media_stream_result_; | |
| 77 } | |
| 78 | |
| 79 // Sets the device policy-controlled |access| for |example_url_| to be for the | |
| 80 // selected |device_type|. | |
| 81 void SetDevicePolicy(DeviceType device_type, Access access) { | |
| 82 PrefService* prefs = Profile::FromBrowserContext( | |
| 83 GetWebContents()->GetBrowserContext())->GetPrefs(); | |
| 84 const char* policy_name = NULL; | |
| 85 switch (device_type) { | |
| 86 case DEVICE_TYPE_AUDIO: | |
| 87 policy_name = prefs::kAudioCaptureAllowed; | |
| 88 break; | |
| 89 case DEVICE_TYPE_VIDEO: | |
| 90 policy_name = prefs::kVideoCaptureAllowed; | |
| 91 break; | |
| 92 } | |
| 93 prefs->SetBoolean(policy_name, access == ACCESS_ALLOWED); | |
| 94 } | |
| 95 | |
| 96 // Set the content settings for mic/cam. | |
| 97 void SetContentSettings(ContentSetting mic_setting, | |
| 98 ContentSetting cam_setting) { | |
| 99 HostContentSettingsMap* content_settings = | |
| 100 HostContentSettingsMapFactory::GetForProfile( | |
| 101 Profile::FromBrowserContext(GetWebContents()->GetBrowserContext())); | |
| 102 content_settings->SetContentSettingDefaultScope( | |
| 103 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
| 104 std::string(), mic_setting); | |
| 105 content_settings->SetContentSettingDefaultScope( | |
| 106 example_url_, GURL(), CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | |
| 107 std::string(), cam_setting); | |
| 108 } | |
| 109 | |
| 110 // Checks whether the devices returned in OnMediaStreamResponse contains a | |
| 111 // microphone and/or camera device. | |
| 112 bool DevicesContains(bool needs_mic, bool needs_cam) { | |
| 113 bool has_mic = false; | |
| 114 bool has_cam = false; | |
| 115 for (const auto& device : media_stream_devices_) { | |
| 116 if (device.type == content::MEDIA_DEVICE_AUDIO_CAPTURE) | |
| 117 has_mic = true; | |
| 118 if (device.type == content::MEDIA_DEVICE_VIDEO_CAPTURE) | |
| 119 has_cam = true; | |
| 120 } | |
| 121 | |
| 122 return needs_mic == has_mic && needs_cam == has_cam; | |
| 123 } | |
| 124 | |
| 125 content::WebContents* GetWebContents() { | |
| 126 return browser()->tab_strip_model()->GetActiveWebContents(); | |
| 127 } | |
| 128 | |
| 129 // Creates a MediaStreamRequest, asking for those media types, which have a | |
| 130 // non-empty id string. | |
| 131 content::MediaStreamRequest CreateRequestWithType( | |
| 132 const std::string& audio_id, | |
| 133 const std::string& video_id, | |
| 134 content::MediaStreamRequestType request_type) { | |
| 135 content::MediaStreamType audio_type = | |
| 136 audio_id.empty() ? content::MEDIA_NO_SERVICE | |
| 137 : content::MEDIA_DEVICE_AUDIO_CAPTURE; | |
| 138 content::MediaStreamType video_type = | |
| 139 video_id.empty() ? content::MEDIA_NO_SERVICE | |
| 140 : content::MEDIA_DEVICE_VIDEO_CAPTURE; | |
| 141 return content::MediaStreamRequest(0, 0, 0, example_url(), false, | |
| 142 request_type, audio_id, video_id, | |
| 143 audio_type, video_type); | |
| 144 } | |
| 145 | |
| 146 content::MediaStreamRequest CreateRequest(const std::string& audio_id, | |
| 147 const std::string& video_id) { | |
| 148 return CreateRequestWithType(audio_id, video_id, | |
| 149 content::MEDIA_DEVICE_ACCESS); | |
| 150 } | |
| 151 | |
| 152 void InitWithUrl(const GURL& url) { | |
| 153 DCHECK(example_url_.is_empty()); | |
| 154 example_url_ = url; | |
| 155 ui_test_utils::NavigateToURL(browser(), example_url_); | |
| 156 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED, | |
| 157 GetContentSettings()->GetMicrophoneCameraState()); | |
| 158 } | |
| 159 | |
| 160 private: | |
| 161 void SetUpOnMainThread() override { | |
| 162 WebRtcTestBase::SetUpOnMainThread(); | |
| 163 | |
| 164 // Cleanup. | |
| 165 media_stream_devices_.clear(); | |
| 166 media_stream_result_ = content::NUM_MEDIA_REQUEST_RESULTS; | |
| 167 | |
| 168 content::MediaStreamDevices audio_devices; | |
| 169 content::MediaStreamDevice fake_audio_device( | |
| 170 content::MEDIA_DEVICE_AUDIO_CAPTURE, example_audio_id_, | |
| 171 "Fake Audio Device"); | |
| 172 audio_devices.push_back(fake_audio_device); | |
| 173 MediaCaptureDevicesDispatcher::GetInstance()->SetTestAudioCaptureDevices( | |
| 174 audio_devices); | |
| 175 | |
| 176 content::MediaStreamDevices video_devices; | |
| 177 content::MediaStreamDevice fake_video_device( | |
| 178 content::MEDIA_DEVICE_VIDEO_CAPTURE, example_video_id_, | |
| 179 "Fake Video Device"); | |
| 180 video_devices.push_back(fake_video_device); | |
| 181 MediaCaptureDevicesDispatcher::GetInstance()->SetTestVideoCaptureDevices( | |
| 182 video_devices); | |
| 183 } | |
| 184 | |
| 185 GURL example_url_; | |
| 186 const std::string example_audio_id_; | |
| 187 const std::string example_video_id_; | |
| 188 | |
| 189 content::MediaStreamDevices media_stream_devices_; | |
| 190 content::MediaStreamRequestResult media_stream_result_; | |
| 191 }; | |
| 192 | |
| 193 // Request and allow microphone access. | |
| 194 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndAllowMic) { | |
| 195 InitWithUrl(GURL("https://www.example.com")); | |
| 196 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); | |
| 197 MediaStreamDevicesController controller( | |
| 198 GetWebContents(), CreateRequest(example_audio_id(), std::string()), | |
| 199 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 200 base::Unretained(this))); | |
| 201 NotifyTabSpecificContentSettings(&controller); | |
| 202 | |
| 203 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 204 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 205 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 206 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 207 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED, | |
| 208 GetContentSettings()->GetMicrophoneCameraState()); | |
| 209 EXPECT_EQ(example_audio_id(), | |
| 210 GetContentSettings()->media_stream_requested_audio_device()); | |
| 211 EXPECT_EQ(example_audio_id(), | |
| 212 GetContentSettings()->media_stream_selected_audio_device()); | |
| 213 EXPECT_EQ(std::string(), | |
| 214 GetContentSettings()->media_stream_requested_video_device()); | |
| 215 EXPECT_EQ(std::string(), | |
| 216 GetContentSettings()->media_stream_selected_video_device()); | |
| 217 } | |
| 218 | |
| 219 // Request and allow camera access. | |
| 220 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndAllowCam) { | |
| 221 InitWithUrl(GURL("https://www.example.com")); | |
| 222 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 223 MediaStreamDevicesController controller( | |
| 224 GetWebContents(), CreateRequest(std::string(), example_video_id()), | |
| 225 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 226 base::Unretained(this))); | |
| 227 NotifyTabSpecificContentSettings(&controller); | |
| 228 | |
| 229 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 230 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 231 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 232 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 233 EXPECT_EQ(TabSpecificContentSettings::CAMERA_ACCESSED, | |
| 234 GetContentSettings()->GetMicrophoneCameraState()); | |
| 235 EXPECT_EQ(std::string(), | |
| 236 GetContentSettings()->media_stream_requested_audio_device()); | |
| 237 EXPECT_EQ(std::string(), | |
| 238 GetContentSettings()->media_stream_selected_audio_device()); | |
| 239 EXPECT_EQ(example_video_id(), | |
| 240 GetContentSettings()->media_stream_requested_video_device()); | |
| 241 EXPECT_EQ(example_video_id(), | |
| 242 GetContentSettings()->media_stream_selected_video_device()); | |
| 243 } | |
| 244 | |
| 245 // Request and block microphone access. | |
| 246 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndBlockMic) { | |
| 247 InitWithUrl(GURL("https://www.example.com")); | |
| 248 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED); | |
| 249 MediaStreamDevicesController controller( | |
| 250 GetWebContents(), CreateRequest(example_audio_id(), std::string()), | |
| 251 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 252 base::Unretained(this))); | |
| 253 NotifyTabSpecificContentSettings(&controller); | |
| 254 | |
| 255 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 256 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 257 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 258 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 259 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 260 TabSpecificContentSettings::MICROPHONE_BLOCKED, | |
| 261 GetContentSettings()->GetMicrophoneCameraState()); | |
| 262 EXPECT_EQ(example_audio_id(), | |
| 263 GetContentSettings()->media_stream_requested_audio_device()); | |
| 264 EXPECT_EQ(example_audio_id(), | |
| 265 GetContentSettings()->media_stream_selected_audio_device()); | |
| 266 EXPECT_EQ(std::string(), | |
| 267 GetContentSettings()->media_stream_requested_video_device()); | |
| 268 EXPECT_EQ(std::string(), | |
| 269 GetContentSettings()->media_stream_selected_video_device()); | |
| 270 } | |
| 271 | |
| 272 // Request and block camera access. | |
| 273 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, RequestAndBlockCam) { | |
| 274 InitWithUrl(GURL("https://www.example.com")); | |
| 275 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_DENIED); | |
| 276 MediaStreamDevicesController controller( | |
| 277 GetWebContents(), CreateRequest(std::string(), example_video_id()), | |
| 278 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 279 base::Unretained(this))); | |
| 280 NotifyTabSpecificContentSettings(&controller); | |
| 281 | |
| 282 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 283 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 284 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 285 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 286 EXPECT_EQ(TabSpecificContentSettings::CAMERA_ACCESSED | | |
| 287 TabSpecificContentSettings::CAMERA_BLOCKED, | |
| 288 GetContentSettings()->GetMicrophoneCameraState()); | |
| 289 EXPECT_EQ(std::string(), | |
| 290 GetContentSettings()->media_stream_requested_audio_device()); | |
| 291 EXPECT_EQ(std::string(), | |
| 292 GetContentSettings()->media_stream_selected_audio_device()); | |
| 293 EXPECT_EQ(example_video_id(), | |
| 294 GetContentSettings()->media_stream_requested_video_device()); | |
| 295 EXPECT_EQ(example_video_id(), | |
| 296 GetContentSettings()->media_stream_selected_video_device()); | |
| 297 } | |
| 298 | |
| 299 // Request and allow microphone and camera access. | |
| 300 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 301 RequestAndAllowMicCam) { | |
| 302 InitWithUrl(GURL("https://www.example.com")); | |
| 303 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); | |
| 304 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 305 MediaStreamDevicesController controller( | |
| 306 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 307 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 308 base::Unretained(this))); | |
| 309 NotifyTabSpecificContentSettings(&controller); | |
| 310 | |
| 311 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 312 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 313 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 314 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 315 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 316 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 317 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 318 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 319 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 320 TabSpecificContentSettings::CAMERA_ACCESSED, | |
| 321 GetContentSettings()->GetMicrophoneCameraState()); | |
| 322 EXPECT_EQ(example_audio_id(), | |
| 323 GetContentSettings()->media_stream_requested_audio_device()); | |
| 324 EXPECT_EQ(example_audio_id(), | |
| 325 GetContentSettings()->media_stream_selected_audio_device()); | |
| 326 EXPECT_EQ(example_video_id(), | |
| 327 GetContentSettings()->media_stream_requested_video_device()); | |
| 328 EXPECT_EQ(example_video_id(), | |
| 329 GetContentSettings()->media_stream_selected_video_device()); | |
| 330 } | |
| 331 | |
| 332 // Request and block microphone and camera access. | |
| 333 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 334 RequestAndBlockMicCam) { | |
| 335 InitWithUrl(GURL("https://www.example.com")); | |
| 336 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED); | |
| 337 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_DENIED); | |
| 338 MediaStreamDevicesController controller( | |
| 339 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 340 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 341 base::Unretained(this))); | |
| 342 NotifyTabSpecificContentSettings(&controller); | |
| 343 | |
| 344 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 345 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 346 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 347 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 348 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 349 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 350 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 351 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 352 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 353 TabSpecificContentSettings::MICROPHONE_BLOCKED | | |
| 354 TabSpecificContentSettings::CAMERA_ACCESSED | | |
| 355 TabSpecificContentSettings::CAMERA_BLOCKED, | |
| 356 GetContentSettings()->GetMicrophoneCameraState()); | |
| 357 EXPECT_EQ(example_audio_id(), | |
| 358 GetContentSettings()->media_stream_requested_audio_device()); | |
| 359 EXPECT_EQ(example_audio_id(), | |
| 360 GetContentSettings()->media_stream_selected_audio_device()); | |
| 361 EXPECT_EQ(example_video_id(), | |
| 362 GetContentSettings()->media_stream_requested_video_device()); | |
| 363 EXPECT_EQ(example_video_id(), | |
| 364 GetContentSettings()->media_stream_selected_video_device()); | |
| 365 } | |
| 366 | |
| 367 // Request microphone and camera access. Allow microphone, block camera. | |
| 368 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 369 RequestMicCamBlockCam) { | |
| 370 InitWithUrl(GURL("https://www.example.com")); | |
| 371 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); | |
| 372 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_DENIED); | |
| 373 MediaStreamDevicesController controller( | |
| 374 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 375 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 376 base::Unretained(this))); | |
| 377 NotifyTabSpecificContentSettings(&controller); | |
| 378 | |
| 379 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 380 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 381 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 382 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 383 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 384 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 385 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 386 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 387 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 388 TabSpecificContentSettings::CAMERA_ACCESSED | | |
| 389 TabSpecificContentSettings::CAMERA_BLOCKED, | |
| 390 GetContentSettings()->GetMicrophoneCameraState()); | |
| 391 EXPECT_EQ(example_audio_id(), | |
| 392 GetContentSettings()->media_stream_requested_audio_device()); | |
| 393 EXPECT_EQ(example_audio_id(), | |
| 394 GetContentSettings()->media_stream_selected_audio_device()); | |
| 395 EXPECT_EQ(example_video_id(), | |
| 396 GetContentSettings()->media_stream_requested_video_device()); | |
| 397 EXPECT_EQ(example_video_id(), | |
| 398 GetContentSettings()->media_stream_selected_video_device()); | |
| 399 } | |
| 400 | |
| 401 // Request microphone and camera access. Block microphone, allow camera. | |
| 402 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 403 RequestMicCamBlockMic) { | |
| 404 InitWithUrl(GURL("https://www.example.com")); | |
| 405 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED); | |
| 406 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 407 MediaStreamDevicesController controller( | |
| 408 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 409 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 410 base::Unretained(this))); | |
| 411 NotifyTabSpecificContentSettings(&controller); | |
| 412 | |
| 413 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 414 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 415 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 416 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 417 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 418 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 419 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 420 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 421 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 422 TabSpecificContentSettings::MICROPHONE_BLOCKED | | |
| 423 TabSpecificContentSettings::CAMERA_ACCESSED, | |
| 424 GetContentSettings()->GetMicrophoneCameraState()); | |
| 425 EXPECT_EQ(example_audio_id(), | |
| 426 GetContentSettings()->media_stream_requested_audio_device()); | |
| 427 EXPECT_EQ(example_audio_id(), | |
| 428 GetContentSettings()->media_stream_selected_audio_device()); | |
| 429 EXPECT_EQ(example_video_id(), | |
| 430 GetContentSettings()->media_stream_requested_video_device()); | |
| 431 EXPECT_EQ(example_video_id(), | |
| 432 GetContentSettings()->media_stream_selected_video_device()); | |
| 433 } | |
| 434 | |
| 435 // Request microphone access. Requesting camera should not change microphone | |
| 436 // state. | |
| 437 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 438 RequestCamDoesNotChangeMic) { | |
| 439 InitWithUrl(GURL("https://www.example.com")); | |
| 440 // Request mic and deny. | |
| 441 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED); | |
| 442 MediaStreamDevicesController mic_controller( | |
| 443 GetWebContents(), CreateRequest(example_audio_id(), std::string()), | |
| 444 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 445 base::Unretained(this))); | |
| 446 NotifyTabSpecificContentSettings(&mic_controller); | |
| 447 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 448 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 449 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 450 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 451 EXPECT_EQ(example_audio_id(), | |
| 452 GetContentSettings()->media_stream_requested_audio_device()); | |
| 453 EXPECT_EQ(example_audio_id(), | |
| 454 GetContentSettings()->media_stream_selected_audio_device()); | |
| 455 | |
| 456 // Request cam and allow | |
| 457 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 458 MediaStreamDevicesController cam_controller( | |
| 459 GetWebContents(), CreateRequest(std::string(), example_video_id()), | |
| 460 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 461 base::Unretained(this))); | |
| 462 NotifyTabSpecificContentSettings(&cam_controller); | |
| 463 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 464 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 465 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 466 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 467 EXPECT_EQ(example_video_id(), | |
| 468 GetContentSettings()->media_stream_requested_video_device()); | |
| 469 EXPECT_EQ(example_video_id(), | |
| 470 GetContentSettings()->media_stream_selected_video_device()); | |
| 471 | |
| 472 // Mic state should not have changed. | |
| 473 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 474 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 475 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 476 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 477 EXPECT_EQ(example_audio_id(), | |
| 478 GetContentSettings()->media_stream_requested_audio_device()); | |
| 479 EXPECT_EQ(example_audio_id(), | |
| 480 GetContentSettings()->media_stream_selected_audio_device()); | |
| 481 } | |
| 482 | |
| 483 // Denying mic access after camera access should still show the camera as state. | |
| 484 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 485 DenyMicDoesNotChangeCam) { | |
| 486 InitWithUrl(GURL("https://www.example.com")); | |
| 487 // Request cam and allow | |
| 488 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 489 MediaStreamDevicesController cam_controller( | |
| 490 GetWebContents(), CreateRequest(std::string(), example_video_id()), | |
| 491 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 492 base::Unretained(this))); | |
| 493 NotifyTabSpecificContentSettings(&cam_controller); | |
| 494 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 495 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 496 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 497 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 498 EXPECT_EQ(example_video_id(), | |
| 499 GetContentSettings()->media_stream_requested_video_device()); | |
| 500 EXPECT_EQ(example_video_id(), | |
| 501 GetContentSettings()->media_stream_selected_video_device()); | |
| 502 EXPECT_EQ(TabSpecificContentSettings::CAMERA_ACCESSED, | |
| 503 GetContentSettings()->GetMicrophoneCameraState()); | |
| 504 | |
| 505 // Simulate that an a video stream is now being captured. | |
| 506 content::MediaStreamDevice fake_video_device( | |
| 507 content::MEDIA_DEVICE_VIDEO_CAPTURE, example_video_id(), | |
| 508 example_video_id()); | |
| 509 content::MediaStreamDevices video_devices(1, fake_video_device); | |
| 510 MediaCaptureDevicesDispatcher* dispatcher = | |
| 511 MediaCaptureDevicesDispatcher::GetInstance(); | |
| 512 dispatcher->SetTestVideoCaptureDevices(video_devices); | |
| 513 std::unique_ptr<content::MediaStreamUI> video_stream_ui = | |
| 514 dispatcher->GetMediaStreamCaptureIndicator()->RegisterMediaStream( | |
| 515 GetWebContents(), video_devices); | |
| 516 video_stream_ui->OnStarted(base::Closure()); | |
| 517 | |
| 518 // Request mic and deny. | |
| 519 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_DENIED); | |
| 520 MediaStreamDevicesController mic_controller( | |
| 521 GetWebContents(), CreateRequest(example_audio_id(), std::string()), | |
| 522 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 523 base::Unretained(this))); | |
| 524 NotifyTabSpecificContentSettings(&mic_controller); | |
| 525 EXPECT_FALSE(GetContentSettings()->IsContentAllowed( | |
| 526 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 527 EXPECT_TRUE(GetContentSettings()->IsContentBlocked( | |
| 528 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); | |
| 529 EXPECT_EQ(example_audio_id(), | |
| 530 GetContentSettings()->media_stream_requested_audio_device()); | |
| 531 EXPECT_EQ(example_audio_id(), | |
| 532 GetContentSettings()->media_stream_selected_audio_device()); | |
| 533 | |
| 534 // Cam should still be included in the state. | |
| 535 EXPECT_TRUE(GetContentSettings()->IsContentAllowed( | |
| 536 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 537 EXPECT_FALSE(GetContentSettings()->IsContentBlocked( | |
| 538 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); | |
| 539 EXPECT_EQ(example_video_id(), | |
| 540 GetContentSettings()->media_stream_requested_video_device()); | |
| 541 EXPECT_EQ(example_video_id(), | |
| 542 GetContentSettings()->media_stream_selected_video_device()); | |
| 543 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 544 TabSpecificContentSettings::MICROPHONE_BLOCKED | | |
| 545 TabSpecificContentSettings::CAMERA_ACCESSED, | |
| 546 GetContentSettings()->GetMicrophoneCameraState()); | |
| 547 | |
| 548 // After ending the camera capture, the camera permission is no longer | |
| 549 // relevant, so it should no be included in the mic/cam state. | |
| 550 video_stream_ui.reset(); | |
| 551 EXPECT_EQ(TabSpecificContentSettings::MICROPHONE_ACCESSED | | |
| 552 TabSpecificContentSettings::MICROPHONE_BLOCKED, | |
| 553 GetContentSettings()->GetMicrophoneCameraState()); | |
| 554 } | |
| 555 | |
| 556 // Stores the ContentSettings inputs for a particular test and has functions | |
| 557 // which return the expected outputs for that test. | |
| 558 struct ContentSettingsTestData { | |
| 559 // The initial value of the mic/cam content settings. | |
| 560 ContentSetting mic; | |
| 561 ContentSetting cam; | |
| 562 // Whether the infobar should be accepted if it's shown. | |
| 563 bool accept_infobar; | |
| 564 | |
| 565 // Whether the infobar should be displayed to request mic/cam for the given | |
| 566 // content settings inputs. | |
| 567 bool ExpectMicInfobar() const { return mic == CONTENT_SETTING_ASK; } | |
| 568 bool ExpectCamInfobar() const { return cam == CONTENT_SETTING_ASK; } | |
| 569 | |
| 570 // Whether or not the mic/cam should be allowed after clicking accept/deny for | |
| 571 // the given inputs. | |
| 572 bool ExpectMicAllowed() const { | |
| 573 return mic == CONTENT_SETTING_ALLOW || | |
| 574 (mic == CONTENT_SETTING_ASK && accept_infobar); | |
| 575 } | |
| 576 bool ExpectCamAllowed() const { | |
| 577 return cam == CONTENT_SETTING_ALLOW || | |
| 578 (cam == CONTENT_SETTING_ASK && accept_infobar); | |
| 579 } | |
| 580 | |
| 581 // The expected media stream result after clicking accept/deny for the given | |
| 582 // inputs. | |
| 583 content::MediaStreamRequestResult ExpectedMediaStreamResult() const { | |
| 584 if (ExpectMicAllowed() || ExpectCamAllowed()) | |
| 585 return content::MEDIA_DEVICE_OK; | |
| 586 return content::MEDIA_DEVICE_PERMISSION_DENIED; | |
| 587 } | |
| 588 }; | |
| 589 | |
| 590 // Test all combinations of cam/mic content settings. Then tests the result of | |
| 591 // clicking both accept/deny on the infobar. Both cam/mic are requested. | |
| 592 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, ContentSettings) { | |
| 593 InitWithUrl(GURL("https://www.example.com")); | |
| 594 static const ContentSettingsTestData tests[] = { | |
| 595 // Settings that won't result in an infobar. | |
| 596 {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, false}, | |
| 597 {CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, false}, | |
| 598 {CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, false}, | |
| 599 {CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, false}, | |
| 600 | |
| 601 // Settings that will result in an infobar. Test both accept and deny. | |
| 602 {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, false}, | |
| 603 {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, true}, | |
| 604 | |
| 605 {CONTENT_SETTING_ASK, CONTENT_SETTING_ASK, false}, | |
| 606 {CONTENT_SETTING_ASK, CONTENT_SETTING_ASK, true}, | |
| 607 | |
| 608 {CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK, false}, | |
| 609 {CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK, true}, | |
| 610 | |
| 611 {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, false}, | |
| 612 {CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, true}, | |
| 613 | |
| 614 {CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK, false}, | |
| 615 {CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK, true}, | |
| 616 }; | |
| 617 | |
| 618 for (auto& test : tests) { | |
| 619 SetContentSettings(test.mic, test.cam); | |
| 620 MediaStreamDevicesController controller( | |
| 621 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 622 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 623 base::Unretained(this))); | |
| 624 | |
| 625 // Check that the infobar is requesting the expected cam/mic values. | |
| 626 ASSERT_EQ(test.ExpectMicInfobar(), controller.IsAskingForAudio()); | |
| 627 ASSERT_EQ(test.ExpectCamInfobar(), controller.IsAskingForVideo()); | |
| 628 | |
| 629 // Accept or deny the infobar if it's showing. | |
| 630 if (test.ExpectMicInfobar() || test.ExpectCamInfobar()) { | |
| 631 if (test.accept_infobar) | |
| 632 controller.PermissionGranted(); | |
| 633 else | |
| 634 controller.PermissionDenied(); | |
| 635 } | |
| 636 | |
| 637 // Check the media stream result is expected and the devices returned are | |
| 638 // expected; | |
| 639 ASSERT_EQ(test.ExpectedMediaStreamResult(), media_stream_result()); | |
| 640 ASSERT_TRUE( | |
| 641 DevicesContains(test.ExpectMicAllowed(), test.ExpectCamAllowed())); | |
| 642 } | |
| 643 } | |
| 644 | |
| 645 // Request and allow camera access on WebUI pages without prompting. | |
| 646 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 647 WebUIRequestAndAllowCam) { | |
| 648 InitWithUrl(GURL("chrome://test-page")); | |
| 649 MediaStreamDevicesController controller( | |
| 650 GetWebContents(), CreateRequest(std::string(), example_video_id()), | |
| 651 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 652 base::Unretained(this))); | |
| 653 | |
| 654 ASSERT_FALSE(controller.IsAskingForAudio()); | |
| 655 ASSERT_FALSE(controller.IsAskingForVideo()); | |
| 656 | |
| 657 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | |
| 658 ASSERT_TRUE(DevicesContains(false, true)); | |
| 659 } | |
| 660 | |
| 661 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 662 ExtensionRequestMicCam) { | |
| 663 InitWithUrl(GURL("chrome-extension://test-page")); | |
| 664 // Test that a prompt is required. | |
| 665 MediaStreamDevicesController controller( | |
| 666 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 667 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 668 base::Unretained(this))); | |
| 669 ASSERT_TRUE(controller.IsAskingForAudio()); | |
| 670 ASSERT_TRUE(controller.IsAskingForVideo()); | |
| 671 | |
| 672 // Accept the prompt. | |
| 673 controller.PermissionGranted(); | |
| 674 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | |
| 675 ASSERT_TRUE(DevicesContains(true, true)); | |
| 676 | |
| 677 // Check that re-requesting allows without prompting. | |
| 678 MediaStreamDevicesController controller2( | |
| 679 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 680 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 681 base::Unretained(this))); | |
| 682 ASSERT_FALSE(controller2.IsAskingForAudio()); | |
| 683 ASSERT_FALSE(controller2.IsAskingForVideo()); | |
| 684 | |
| 685 ASSERT_EQ(content::MEDIA_DEVICE_OK, media_stream_result()); | |
| 686 ASSERT_TRUE(DevicesContains(true, true)); | |
| 687 } | |
| 688 | |
| 689 // For Pepper request from insecure origin, even if it's ALLOW, it won't be | |
| 690 // changed to ASK. | |
| 691 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 692 PepperRequestInsecure) { | |
| 693 InitWithUrl(GURL("http://www.example.com")); | |
| 694 SetContentSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW); | |
| 695 | |
| 696 MediaStreamDevicesController controller( | |
| 697 GetWebContents(), | |
| 698 CreateRequestWithType(example_audio_id(), std::string(), | |
| 699 content::MEDIA_OPEN_DEVICE_PEPPER_ONLY), | |
| 700 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 701 base::Unretained(this))); | |
| 702 ASSERT_FALSE(controller.IsAskingForAudio()); | |
| 703 ASSERT_FALSE(controller.IsAskingForVideo()); | |
| 704 } | |
| 705 | |
| 706 // Request and block microphone and camera access with kill switch. | |
| 707 IN_PROC_BROWSER_TEST_F(MediaStreamDevicesControllerTest, | |
| 708 RequestAndKillSwitchMicCam) { | |
| 709 std::map<std::string, std::string> params; | |
| 710 params[PermissionUtil::GetPermissionString( | |
| 711 content::PermissionType::AUDIO_CAPTURE)] = | |
| 712 PermissionContextBase::kPermissionsKillSwitchBlockedValue; | |
| 713 params[PermissionUtil::GetPermissionString( | |
| 714 content::PermissionType::VIDEO_CAPTURE)] = | |
| 715 PermissionContextBase::kPermissionsKillSwitchBlockedValue; | |
| 716 variations::AssociateVariationParams( | |
| 717 PermissionContextBase::kPermissionsKillSwitchFieldStudy, | |
| 718 "TestGroup", params); | |
| 719 base::FieldTrialList::CreateFieldTrial( | |
| 720 PermissionContextBase::kPermissionsKillSwitchFieldStudy, | |
| 721 "TestGroup"); | |
| 722 InitWithUrl(GURL("https://www.example.com")); | |
| 723 SetDevicePolicy(DEVICE_TYPE_AUDIO, ACCESS_ALLOWED); | |
| 724 SetDevicePolicy(DEVICE_TYPE_VIDEO, ACCESS_ALLOWED); | |
| 725 MediaStreamDevicesController controller( | |
| 726 GetWebContents(), CreateRequest(example_audio_id(), example_video_id()), | |
| 727 base::Bind(&MediaStreamDevicesControllerTest::OnMediaStreamResponse, | |
| 728 base::Unretained(this))); | |
| 729 | |
| 730 EXPECT_FALSE(controller.IsAllowedForAudio()); | |
| 731 EXPECT_FALSE(controller.IsAllowedForVideo()); | |
| 732 EXPECT_FALSE(controller.IsAskingForAudio()); | |
| 733 EXPECT_FALSE(controller.IsAskingForVideo()); | |
| 734 } | |
| OLD | NEW |