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 |