1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/auto_reset.h"
6 #include "base/command_line.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
10 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
11 #include "chrome/browser/infobars/infobar_service.h"
12 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
13 #include "chrome/browser/media/media_stream_capture_indicator.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/pref_names.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "components/content_settings/core/browser/host_content_settings_map.h"
22 #include "components/content_settings/core/common/content_settings.h"
23 #include "components/infobars/core/infobar_delegate.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/test/web_contents_tester.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/base/l10n/l10n_util.h"
29 using content::WebContentsTester
;
31 class ContentSettingBubbleModelTest
: public ChromeRenderViewHostTestHarness
{
33 void SetUp() override
{
34 ChromeRenderViewHostTestHarness::SetUp();
35 TabSpecificContentSettings::CreateForWebContents(web_contents());
36 InfoBarService::CreateForWebContents(web_contents());
39 void CheckGeolocationBubble(size_t expected_domains
,
40 bool expect_clear_link
,
41 bool expect_reload_hint
) {
42 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
43 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
44 NULL
, web_contents(), profile(),
45 CONTENT_SETTINGS_TYPE_GEOLOCATION
));
46 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
47 content_setting_bubble_model
->bubble_content();
48 EXPECT_TRUE(bubble_content
.title
.empty());
49 EXPECT_TRUE(bubble_content
.radio_group
.radio_items
.empty());
50 EXPECT_TRUE(bubble_content
.list_items
.empty());
51 EXPECT_EQ(expected_domains
, bubble_content
.domain_lists
.size());
52 EXPECT_NE(expect_clear_link
|| expect_reload_hint
,
53 bubble_content
.custom_link
.empty());
54 EXPECT_EQ(expect_clear_link
, bubble_content
.custom_link_enabled
);
55 EXPECT_FALSE(bubble_content
.manage_link
.empty());
58 std::string
GetDefaultAudioDevice() {
59 PrefService
* prefs
= profile()->GetPrefs();
60 return prefs
->GetString(prefs::kDefaultAudioCaptureDevice
);
63 std::string
GetDefaultVideoDevice() {
64 PrefService
* prefs
= profile()->GetPrefs();
65 return prefs
->GetString(prefs::kDefaultVideoCaptureDevice
);
69 TEST_F(ContentSettingBubbleModelTest
, ImageRadios
) {
70 TabSpecificContentSettings
* content_settings
=
71 TabSpecificContentSettings::FromWebContents(web_contents());
72 content_settings
->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES
);
74 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
75 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
76 NULL
, web_contents(), profile(),
77 CONTENT_SETTINGS_TYPE_IMAGES
));
78 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
79 content_setting_bubble_model
->bubble_content();
80 EXPECT_FALSE(bubble_content
.title
.empty());
81 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
82 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
83 EXPECT_TRUE(bubble_content
.custom_link
.empty());
84 EXPECT_FALSE(bubble_content
.manage_link
.empty());
87 TEST_F(ContentSettingBubbleModelTest
, Cookies
) {
88 TabSpecificContentSettings
* content_settings
=
89 TabSpecificContentSettings::FromWebContents(web_contents());
90 content_settings
->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES
);
92 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
93 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
94 NULL
, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES
));
95 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
96 content_setting_bubble_model
->bubble_content();
97 std::string title
= bubble_content
.title
;
98 EXPECT_FALSE(title
.empty());
99 ASSERT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
100 std::string radio1
= bubble_content
.radio_group
.radio_items
[0];
101 std::string radio2
= bubble_content
.radio_group
.radio_items
[1];
102 EXPECT_FALSE(bubble_content
.custom_link
.empty());
103 EXPECT_TRUE(bubble_content
.custom_link_enabled
);
104 EXPECT_FALSE(bubble_content
.manage_link
.empty());
106 content_settings
->ClearCookieSpecificContentSettings();
107 content_settings
->OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES
);
108 content_setting_bubble_model
.reset(
109 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
110 NULL
, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES
));
111 const ContentSettingBubbleModel::BubbleContent
& bubble_content_2
=
112 content_setting_bubble_model
->bubble_content();
114 EXPECT_FALSE(bubble_content_2
.title
.empty());
115 EXPECT_NE(title
, bubble_content_2
.title
);
116 ASSERT_EQ(2U, bubble_content_2
.radio_group
.radio_items
.size());
117 // TODO(bauerb): Update this once the strings have been updated.
118 EXPECT_EQ(radio1
, bubble_content_2
.radio_group
.radio_items
[0]);
119 EXPECT_EQ(radio2
, bubble_content_2
.radio_group
.radio_items
[1]);
120 EXPECT_FALSE(bubble_content_2
.custom_link
.empty());
121 EXPECT_TRUE(bubble_content_2
.custom_link_enabled
);
122 EXPECT_FALSE(bubble_content_2
.manage_link
.empty());
125 TEST_F(ContentSettingBubbleModelTest
, MediastreamMicAndCamera
) {
126 // Required to break dependency on BrowserMainLoop.
127 MediaCaptureDevicesDispatcher::GetInstance()->
128 DisableDeviceEnumerationForTesting();
130 TabSpecificContentSettings
* content_settings
=
131 TabSpecificContentSettings::FromWebContents(web_contents());
132 std::string request_host
= "google.com";
133 GURL
security_origin("http://" + request_host
);
134 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
135 TabSpecificContentSettings::MICROPHONE_ACCESSED
|
136 TabSpecificContentSettings::CAMERA_ACCESSED
;
137 content_settings
->OnMediaStreamPermissionSet(security_origin
,
138 microphone_camera_state
,
139 GetDefaultAudioDevice(),
140 GetDefaultVideoDevice(),
144 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
145 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
146 NULL
, web_contents(), profile(),
147 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
148 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
149 content_setting_bubble_model
->bubble_content();
150 EXPECT_EQ(bubble_content
.title
,
151 l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED
));
152 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
153 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[0],
154 l10n_util::GetStringFUTF8(
155 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION
,
156 base::UTF8ToUTF16(request_host
)));
157 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[1],
158 l10n_util::GetStringUTF8(
159 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK
));
160 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
161 EXPECT_TRUE(bubble_content
.custom_link
.empty());
162 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
163 EXPECT_FALSE(bubble_content
.manage_link
.empty());
164 EXPECT_EQ(2U, bubble_content
.media_menus
.size());
167 TEST_F(ContentSettingBubbleModelTest
, BlockedMediastreamMicAndCamera
) {
168 // Required to break dependency on BrowserMainLoop.
169 MediaCaptureDevicesDispatcher::GetInstance()->
170 DisableDeviceEnumerationForTesting();
172 WebContentsTester::For(web_contents())->
173 NavigateAndCommit(GURL("https://www.example.com"));
174 GURL url
= web_contents()->GetURL();
176 HostContentSettingsMap
* host_content_settings_map
=
177 profile()->GetHostContentSettingsMap();
178 ContentSettingsPattern primary_pattern
=
179 ContentSettingsPattern::FromURL(url
);
180 ContentSetting setting
= CONTENT_SETTING_BLOCK
;
181 host_content_settings_map
->SetContentSetting(
183 ContentSettingsPattern::Wildcard(),
184 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
187 host_content_settings_map
->SetContentSetting(
189 ContentSettingsPattern::Wildcard(),
190 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
194 TabSpecificContentSettings
* content_settings
=
195 TabSpecificContentSettings::FromWebContents(web_contents());
196 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
197 TabSpecificContentSettings::MICROPHONE_ACCESSED
|
198 TabSpecificContentSettings::MICROPHONE_BLOCKED
|
199 TabSpecificContentSettings::CAMERA_ACCESSED
|
200 TabSpecificContentSettings::CAMERA_BLOCKED
;
201 content_settings
->OnMediaStreamPermissionSet(url
,
202 microphone_camera_state
,
203 GetDefaultAudioDevice(),
204 GetDefaultVideoDevice(),
208 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
209 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
210 NULL
, web_contents(), profile(),
211 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
212 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
213 content_setting_bubble_model
->bubble_content();
214 // Test if the correct radio item is selected for the blocked mediastream
216 EXPECT_EQ(1, bubble_content
.radio_group
.default_item
);
219 // Test that the media settings where not changed.
220 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
221 host_content_settings_map
->GetContentSetting(
224 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
226 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
227 host_content_settings_map
->GetContentSetting(
230 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
234 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
235 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
236 NULL
, web_contents(), profile(),
237 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
238 // Change the radio setting.
239 content_setting_bubble_model
->OnRadioClicked(0);
241 // Test that the media setting were change correctly.
242 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
243 host_content_settings_map
->GetContentSetting(
246 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
248 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
249 host_content_settings_map
->GetContentSetting(
252 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
,
256 // Tests whether a changed setting in the setting bubble is displayed again when
257 // the bubble is re-opened.
258 TEST_F(ContentSettingBubbleModelTest
, MediastreamContentBubble
) {
259 // Required to break dependency on BrowserMainLoop.
260 MediaCaptureDevicesDispatcher::GetInstance()->
261 DisableDeviceEnumerationForTesting();
263 WebContentsTester::For(web_contents())->
264 NavigateAndCommit(GURL("https://www.example.com"));
265 GURL url
= web_contents()->GetURL();
267 HostContentSettingsMap
* host_content_settings_map
=
268 profile()->GetHostContentSettingsMap();
269 ContentSettingsPattern primary_pattern
=
270 ContentSettingsPattern::FromURL(url
);
271 ContentSetting setting
= CONTENT_SETTING_BLOCK
;
272 host_content_settings_map
->SetContentSetting(
274 ContentSettingsPattern::Wildcard(),
275 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
279 TabSpecificContentSettings
* content_settings
=
280 TabSpecificContentSettings::FromWebContents(web_contents());
281 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
282 TabSpecificContentSettings::MICROPHONE_ACCESSED
|
283 TabSpecificContentSettings::MICROPHONE_BLOCKED
;
284 content_settings
->OnMediaStreamPermissionSet(url
,
285 microphone_camera_state
,
286 GetDefaultAudioDevice(),
291 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
292 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
293 NULL
, web_contents(), profile(),
294 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
295 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
296 content_setting_bubble_model
->bubble_content();
297 // Test if the correct radio item is selected for the blocked mediastream
299 EXPECT_EQ(1, bubble_content
.radio_group
.default_item
);
300 // Change the radio setting.
301 content_setting_bubble_model
->OnRadioClicked(0);
303 // Test that the setting was changed.
304 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
305 host_content_settings_map
->GetContentSetting(
308 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
312 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
313 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
314 NULL
, web_contents(), profile(),
315 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
316 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
317 content_setting_bubble_model
->bubble_content();
318 // Test that the reload hint is displayed.
319 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
320 EXPECT_EQ(bubble_content
.custom_link
, l10n_util::GetStringUTF8(
321 IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE
));
323 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
324 // Restore the radio setting (to block).
325 content_setting_bubble_model
->OnRadioClicked(1);
327 // Test that the media settings were changed again.
328 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
329 host_content_settings_map
->GetContentSetting(
332 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
,
336 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
337 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
338 NULL
, web_contents(), profile(),
339 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
340 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
341 content_setting_bubble_model
->bubble_content();
342 // Test that the reload hint is not displayed any more.
343 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
344 EXPECT_TRUE(bubble_content
.custom_link
.empty());
346 EXPECT_EQ(1, bubble_content
.radio_group
.default_item
);
350 // Tests whether the media menu settings are correctly persisted in the bubble.
351 TEST_F(ContentSettingBubbleModelTest
, MediastreamContentBubbleMediaMenus
) {
352 // Required to break dependency on BrowserMainLoop.
353 MediaCaptureDevicesDispatcher::GetInstance()->
354 DisableDeviceEnumerationForTesting();
356 WebContentsTester::For(web_contents())->
357 NavigateAndCommit(GURL("https://www.example.com"));
358 GURL url
= web_contents()->GetURL();
360 content::MediaStreamDevices audio_devices
;
361 content::MediaStreamDevice
fake_audio_device1(
362 content::MEDIA_DEVICE_AUDIO_CAPTURE
, "fake_dev1", "Fake Audio Device 1");
363 content::MediaStreamDevice
fake_audio_device2(
364 content::MEDIA_DEVICE_AUDIO_CAPTURE
, "fake_dev2", "Fake Audio Device 2");
365 content::MediaStreamDevice
fake_audio_device3(
366 content::MEDIA_DEVICE_AUDIO_CAPTURE
, "fake_dev3", "Fake Audio Device 3");
367 audio_devices
.push_back(fake_audio_device1
);
368 audio_devices
.push_back(fake_audio_device2
);
369 audio_devices
.push_back(fake_audio_device3
);
370 MediaCaptureDevicesDispatcher::GetInstance()->SetTestAudioCaptureDevices(
373 TabSpecificContentSettings
* content_settings
=
374 TabSpecificContentSettings::FromWebContents(web_contents());
375 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
376 TabSpecificContentSettings::MICROPHONE_ACCESSED
|
377 TabSpecificContentSettings::MICROPHONE_BLOCKED
;
378 content_settings
->OnMediaStreamPermissionSet(url
,
379 microphone_camera_state
,
380 GetDefaultAudioDevice(),
385 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
386 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
387 NULL
, web_contents(), profile(),
388 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
389 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
390 content_setting_bubble_model
->bubble_content();
391 EXPECT_TRUE(bubble_content
.custom_link
.empty());
393 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
394 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
395 bubble_content
.media_menus
.begin()->first
);
396 EXPECT_FALSE(bubble_content
.media_menus
.begin()->second
.disabled
);
397 // The first audio device should be selected by default.
398 EXPECT_TRUE(fake_audio_device1
.IsEqual(
399 bubble_content
.media_menus
.begin()->second
.selected_device
));
401 // Select a different (the second) device.
402 content_setting_bubble_model
->OnMediaMenuClicked(
403 content::MEDIA_DEVICE_AUDIO_CAPTURE
,
404 fake_audio_device2
.id
);
407 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
408 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
409 NULL
, web_contents(), profile(),
410 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
411 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
412 content_setting_bubble_model
->bubble_content();
413 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
414 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
415 bubble_content
.media_menus
.begin()->first
);
416 EXPECT_FALSE(bubble_content
.media_menus
.begin()->second
.disabled
);
417 // The second audio device should be selected.
418 EXPECT_TRUE(fake_audio_device2
.IsEqual(
419 bubble_content
.media_menus
.begin()->second
.selected_device
));
420 // The "settings changed" message should not be displayed when there is no
422 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
423 EXPECT_TRUE(bubble_content
.custom_link
.empty());
426 // Simulate that an audio stream is being captured.
427 scoped_refptr
<MediaStreamCaptureIndicator
> indicator
=
428 MediaCaptureDevicesDispatcher::GetInstance()->
429 GetMediaStreamCaptureIndicator();
430 scoped_ptr
<content::MediaStreamUI
> media_stream_ui
=
431 indicator
->RegisterMediaStream(web_contents(), audio_devices
);
432 media_stream_ui
->OnStarted(base::Closure());
433 microphone_camera_state
&= ~TabSpecificContentSettings::MICROPHONE_BLOCKED
;
434 content_settings
->OnMediaStreamPermissionSet(url
,
435 microphone_camera_state
,
436 GetDefaultAudioDevice(),
442 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
443 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
444 NULL
, web_contents(), profile(),
445 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
446 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
447 content_setting_bubble_model
->bubble_content();
448 // Settings not changed yet, so the "settings changed" message should not be
450 EXPECT_TRUE(bubble_content
.custom_link
.empty());
452 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
453 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
454 bubble_content
.media_menus
.begin()->first
);
455 EXPECT_FALSE(bubble_content
.media_menus
.begin()->second
.disabled
);
456 EXPECT_TRUE(fake_audio_device2
.IsEqual(
457 bubble_content
.media_menus
.begin()->second
.selected_device
));
459 // Select a different different device.
460 content_setting_bubble_model
->OnMediaMenuClicked(
461 content::MEDIA_DEVICE_AUDIO_CAPTURE
,
462 fake_audio_device3
.id
);
466 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
467 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
468 NULL
, web_contents(), profile(),
469 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
470 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
471 content_setting_bubble_model
->bubble_content();
472 // Test that the reload hint is displayed.
473 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
474 EXPECT_EQ(bubble_content
.custom_link
, l10n_util::GetStringUTF8(
475 IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE
));
478 // Simulate that yet another audio stream capture request was initiated.
479 microphone_camera_state
|= TabSpecificContentSettings::MICROPHONE_BLOCKED
;
480 content_settings
->OnMediaStreamPermissionSet(url
,
481 microphone_camera_state
,
482 GetDefaultAudioDevice(),
488 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
489 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
490 NULL
, web_contents(), profile(),
491 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
492 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
493 content_setting_bubble_model
->bubble_content();
494 // Test that the reload hint is not displayed any more, because this is a
495 // new permission request.
496 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
497 EXPECT_TRUE(bubble_content
.custom_link
.empty());
499 // Though the audio menu setting should have persisted.
500 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
501 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
502 bubble_content
.media_menus
.begin()->first
);
503 EXPECT_FALSE(bubble_content
.media_menus
.begin()->second
.disabled
);
504 EXPECT_TRUE(fake_audio_device3
.IsEqual(
505 bubble_content
.media_menus
.begin()->second
.selected_device
));
509 TEST_F(ContentSettingBubbleModelTest
, MediastreamMic
) {
510 // Required to break dependency on BrowserMainLoop.
511 MediaCaptureDevicesDispatcher::GetInstance()->
512 DisableDeviceEnumerationForTesting();
514 TabSpecificContentSettings
* content_settings
=
515 TabSpecificContentSettings::FromWebContents(web_contents());
516 std::string request_host
= "google.com";
517 GURL
security_origin("http://" + request_host
);
518 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
519 TabSpecificContentSettings::MICROPHONE_ACCESSED
;
520 content_settings
->OnMediaStreamPermissionSet(security_origin
,
521 microphone_camera_state
,
522 GetDefaultAudioDevice(),
527 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
528 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
529 NULL
, web_contents(), profile(),
530 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
531 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
532 content_setting_bubble_model
->bubble_content();
533 EXPECT_EQ(bubble_content
.title
,
534 l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED
));
535 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
536 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[0],
537 l10n_util::GetStringFUTF8(
538 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION
,
539 base::UTF8ToUTF16(request_host
)));
540 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[1],
541 l10n_util::GetStringUTF8(
542 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK
));
543 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
544 EXPECT_TRUE(bubble_content
.custom_link
.empty());
545 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
546 EXPECT_FALSE(bubble_content
.manage_link
.empty());
547 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
548 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
549 bubble_content
.media_menus
.begin()->first
);
551 // Change the microphone access.
552 microphone_camera_state
|= TabSpecificContentSettings::MICROPHONE_BLOCKED
;
553 content_settings
->OnMediaStreamPermissionSet(security_origin
,
554 microphone_camera_state
,
555 GetDefaultAudioDevice(),
559 content_setting_bubble_model
.reset(
560 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
561 NULL
, web_contents(), profile(),
562 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
563 const ContentSettingBubbleModel::BubbleContent
& new_bubble_content
=
564 content_setting_bubble_model
->bubble_content();
565 EXPECT_EQ(new_bubble_content
.title
,
566 l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED
));
567 EXPECT_EQ(2U, new_bubble_content
.radio_group
.radio_items
.size());
568 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[0],
569 l10n_util::GetStringFUTF8(
570 IDS_BLOCKED_MEDIASTREAM_MIC_ASK
,
571 base::UTF8ToUTF16(request_host
)));
572 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[1],
573 l10n_util::GetStringUTF8(
574 IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION
));
575 EXPECT_EQ(1, new_bubble_content
.radio_group
.default_item
);
576 EXPECT_TRUE(new_bubble_content
.custom_link
.empty());
577 EXPECT_FALSE(new_bubble_content
.custom_link_enabled
);
578 EXPECT_FALSE(new_bubble_content
.manage_link
.empty());
579 EXPECT_EQ(1U, new_bubble_content
.media_menus
.size());
580 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
581 new_bubble_content
.media_menus
.begin()->first
);
584 TEST_F(ContentSettingBubbleModelTest
, MediastreamCamera
) {
585 // Required to break dependency on BrowserMainLoop.
586 MediaCaptureDevicesDispatcher::GetInstance()->
587 DisableDeviceEnumerationForTesting();
589 TabSpecificContentSettings
* content_settings
=
590 TabSpecificContentSettings::FromWebContents(web_contents());
591 std::string request_host
= "google.com";
592 GURL
security_origin("http://" + request_host
);
593 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
594 TabSpecificContentSettings::CAMERA_ACCESSED
;
595 content_settings
->OnMediaStreamPermissionSet(security_origin
,
596 microphone_camera_state
,
598 GetDefaultVideoDevice(),
602 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
603 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
604 NULL
, web_contents(), profile(),
605 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
606 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
607 content_setting_bubble_model
->bubble_content();
608 EXPECT_EQ(bubble_content
.title
,
609 l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED
));
610 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
611 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[0],
612 l10n_util::GetStringFUTF8(
613 IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION
,
614 base::UTF8ToUTF16(request_host
)));
615 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[1],
616 l10n_util::GetStringUTF8(
617 IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK
));
618 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
619 EXPECT_TRUE(bubble_content
.custom_link
.empty());
620 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
621 EXPECT_FALSE(bubble_content
.manage_link
.empty());
622 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
623 EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE
,
624 bubble_content
.media_menus
.begin()->first
);
626 // Change the camera access.
627 microphone_camera_state
|= TabSpecificContentSettings::CAMERA_BLOCKED
;
628 content_settings
->OnMediaStreamPermissionSet(security_origin
,
629 microphone_camera_state
,
631 GetDefaultVideoDevice(),
634 content_setting_bubble_model
.reset(
635 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
636 NULL
, web_contents(), profile(),
637 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
638 const ContentSettingBubbleModel::BubbleContent
& new_bubble_content
=
639 content_setting_bubble_model
->bubble_content();
640 EXPECT_EQ(new_bubble_content
.title
,
641 l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED
));
642 EXPECT_EQ(2U, new_bubble_content
.radio_group
.radio_items
.size());
643 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[0],
644 l10n_util::GetStringFUTF8(
645 IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK
,
646 base::UTF8ToUTF16(request_host
)));
647 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[1],
648 l10n_util::GetStringUTF8(
649 IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION
));
650 EXPECT_EQ(1, new_bubble_content
.radio_group
.default_item
);
651 EXPECT_TRUE(new_bubble_content
.custom_link
.empty());
652 EXPECT_FALSE(new_bubble_content
.custom_link_enabled
);
653 EXPECT_FALSE(new_bubble_content
.manage_link
.empty());
654 EXPECT_EQ(1U, new_bubble_content
.media_menus
.size());
655 EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE
,
656 new_bubble_content
.media_menus
.begin()->first
);
659 TEST_F(ContentSettingBubbleModelTest
, AccumulateMediastreamMicAndCamera
) {
660 // Required to break dependency on BrowserMainLoop.
661 MediaCaptureDevicesDispatcher::GetInstance()->
662 DisableDeviceEnumerationForTesting();
664 TabSpecificContentSettings
* content_settings
=
665 TabSpecificContentSettings::FromWebContents(web_contents());
666 std::string request_host
= "google.com";
667 GURL
security_origin("http://" + request_host
);
669 // Firstly, add microphone access.
670 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state
=
671 TabSpecificContentSettings::MICROPHONE_ACCESSED
;
672 content_settings
->OnMediaStreamPermissionSet(security_origin
,
673 microphone_camera_state
,
674 GetDefaultAudioDevice(),
679 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
680 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
681 NULL
, web_contents(), profile(),
682 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
683 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
684 content_setting_bubble_model
->bubble_content();
685 EXPECT_EQ(bubble_content
.title
,
686 l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED
));
687 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
688 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[0],
689 l10n_util::GetStringFUTF8(
690 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION
,
691 base::UTF8ToUTF16(request_host
)));
692 EXPECT_EQ(bubble_content
.radio_group
.radio_items
[1],
693 l10n_util::GetStringUTF8(
694 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK
));
695 EXPECT_EQ(0, bubble_content
.radio_group
.default_item
);
696 EXPECT_EQ(1U, bubble_content
.media_menus
.size());
697 EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE
,
698 bubble_content
.media_menus
.begin()->first
);
700 // Then add camera access.
701 microphone_camera_state
|= TabSpecificContentSettings::CAMERA_ACCESSED
;
702 content_settings
->OnMediaStreamPermissionSet(security_origin
,
703 microphone_camera_state
,
704 GetDefaultAudioDevice(),
705 GetDefaultVideoDevice(),
709 content_setting_bubble_model
.reset(
710 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
711 NULL
, web_contents(), profile(),
712 CONTENT_SETTINGS_TYPE_MEDIASTREAM
));
713 const ContentSettingBubbleModel::BubbleContent
& new_bubble_content
=
714 content_setting_bubble_model
->bubble_content();
715 EXPECT_EQ(new_bubble_content
.title
,
716 l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED
));
717 EXPECT_EQ(2U, new_bubble_content
.radio_group
.radio_items
.size());
718 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[0],
719 l10n_util::GetStringFUTF8(
720 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION
,
721 base::UTF8ToUTF16(request_host
)));
722 EXPECT_EQ(new_bubble_content
.radio_group
.radio_items
[1],
723 l10n_util::GetStringUTF8(
724 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK
));
725 EXPECT_EQ(0, new_bubble_content
.radio_group
.default_item
);
726 EXPECT_EQ(2U, new_bubble_content
.media_menus
.size());
729 TEST_F(ContentSettingBubbleModelTest
, Plugins
) {
730 TabSpecificContentSettings
* content_settings
=
731 TabSpecificContentSettings::FromWebContents(web_contents());
732 const base::string16 plugin_name
= base::ASCIIToUTF16("plugin_name");
734 content_settings
->OnContentBlockedWithDetail(CONTENT_SETTINGS_TYPE_PLUGINS
,
737 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
738 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
739 NULL
, web_contents(), profile(),
740 CONTENT_SETTINGS_TYPE_PLUGINS
));
741 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
742 content_setting_bubble_model
->bubble_content();
743 EXPECT_FALSE(bubble_content
.title
.empty());
744 ASSERT_EQ(1U, bubble_content
.list_items
.size());
745 EXPECT_EQ(plugin_name
,
746 base::ASCIIToUTF16(bubble_content
.list_items
[0].title
));
747 EXPECT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
748 EXPECT_FALSE(bubble_content
.custom_link
.empty());
749 EXPECT_TRUE(bubble_content
.custom_link_enabled
);
750 EXPECT_FALSE(bubble_content
.manage_link
.empty());
751 EXPECT_FALSE(bubble_content
.learn_more_link
.empty());
754 TEST_F(ContentSettingBubbleModelTest
, PepperBroker
) {
755 TabSpecificContentSettings
* content_settings
=
756 TabSpecificContentSettings::FromWebContents(web_contents());
757 content_settings
->OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
759 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
760 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
761 NULL
, web_contents(), profile(),
762 CONTENT_SETTINGS_TYPE_PPAPI_BROKER
));
763 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
764 content_setting_bubble_model
->bubble_content();
766 std::string title
= bubble_content
.title
;
767 EXPECT_FALSE(title
.empty());
768 ASSERT_EQ(2U, bubble_content
.radio_group
.radio_items
.size());
769 std::string radio1
= bubble_content
.radio_group
.radio_items
[0];
770 std::string radio2
= bubble_content
.radio_group
.radio_items
[1];
771 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
772 EXPECT_FALSE(bubble_content
.manage_link
.empty());
774 content_settings
->ClearBlockedContentSettingsExceptForCookies();
775 content_settings
->OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER
);
776 content_setting_bubble_model
.reset(
777 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
778 NULL
, web_contents(), profile(),
779 CONTENT_SETTINGS_TYPE_PPAPI_BROKER
));
780 const ContentSettingBubbleModel::BubbleContent
& bubble_content_2
=
781 content_setting_bubble_model
->bubble_content();
783 EXPECT_FALSE(bubble_content_2
.title
.empty());
784 EXPECT_NE(title
, bubble_content_2
.title
);
785 ASSERT_EQ(2U, bubble_content_2
.radio_group
.radio_items
.size());
786 EXPECT_NE(radio1
, bubble_content_2
.radio_group
.radio_items
[0]);
787 EXPECT_NE(radio2
, bubble_content_2
.radio_group
.radio_items
[1]);
788 EXPECT_FALSE(bubble_content_2
.custom_link_enabled
);
789 EXPECT_FALSE(bubble_content_2
.manage_link
.empty());
792 TEST_F(ContentSettingBubbleModelTest
, Geolocation
) {
793 const GURL
page_url("http://toplevel.example/");
794 const GURL
frame1_url("http://host1.example/");
795 const GURL
frame2_url("http://host2.example:999/");
797 NavigateAndCommit(page_url
);
798 TabSpecificContentSettings
* content_settings
=
799 TabSpecificContentSettings::FromWebContents(web_contents());
801 // One permitted frame, but not in the content map: requires reload.
802 content_settings
->OnGeolocationPermissionSet(frame1_url
, true);
803 CheckGeolocationBubble(1, false, true);
805 // Add it to the content map, should now have a clear link.
806 HostContentSettingsMap
* setting_map
=
807 profile()->GetHostContentSettingsMap();
808 setting_map
->SetContentSetting(
809 ContentSettingsPattern::FromURLNoWildcard(frame1_url
),
810 ContentSettingsPattern::FromURLNoWildcard(page_url
),
811 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
813 CONTENT_SETTING_ALLOW
);
814 CheckGeolocationBubble(1, true, false);
816 // Change the default to allow: no message needed.
817 profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
818 CONTENT_SETTINGS_TYPE_GEOLOCATION
, CONTENT_SETTING_ALLOW
);
819 CheckGeolocationBubble(1, false, false);
821 // Second frame denied, but not stored in the content map: requires reload.
822 content_settings
->OnGeolocationPermissionSet(frame2_url
, false);
823 CheckGeolocationBubble(2, false, true);
825 // Change the default to block: offer a clear link for the persisted frame 1.
826 profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
827 CONTENT_SETTINGS_TYPE_GEOLOCATION
, CONTENT_SETTING_BLOCK
);
828 CheckGeolocationBubble(2, true, false);
831 TEST_F(ContentSettingBubbleModelTest
, FileURL
) {
832 std::string
file_url("file:///tmp/test.html");
833 NavigateAndCommit(GURL(file_url
));
834 TabSpecificContentSettings::FromWebContents(web_contents())->OnContentBlocked(
835 CONTENT_SETTINGS_TYPE_IMAGES
);
836 scoped_ptr
<ContentSettingBubbleModel
> content_setting_bubble_model(
837 ContentSettingBubbleModel::CreateContentSettingBubbleModel(
838 NULL
, web_contents(), profile(),
839 CONTENT_SETTINGS_TYPE_IMAGES
));
841 content_setting_bubble_model
->bubble_content().radio_group
.radio_items
[0];
842 ASSERT_NE(std::string::npos
, title
.find(file_url
));
845 TEST_F(ContentSettingBubbleModelTest
, RegisterProtocolHandler
) {
846 const GURL
page_url("http://toplevel.example/");
847 NavigateAndCommit(page_url
);
848 TabSpecificContentSettings
* content_settings
=
849 TabSpecificContentSettings::FromWebContents(web_contents());
850 content_settings
->set_pending_protocol_handler(
851 ProtocolHandler::CreateProtocolHandler(
852 "mailto", GURL("http://www.toplevel.example/")));
854 ContentSettingRPHBubbleModel
content_setting_bubble_model(
855 NULL
, web_contents(), profile(), NULL
);
857 const ContentSettingBubbleModel::BubbleContent
& bubble_content
=
858 content_setting_bubble_model
.bubble_content();
859 EXPECT_FALSE(bubble_content
.title
.empty());
860 EXPECT_FALSE(bubble_content
.radio_group
.radio_items
.empty());
861 EXPECT_TRUE(bubble_content
.list_items
.empty());
862 EXPECT_TRUE(bubble_content
.domain_lists
.empty());
863 EXPECT_TRUE(bubble_content
.custom_link
.empty());
864 EXPECT_FALSE(bubble_content
.custom_link_enabled
);
865 EXPECT_FALSE(bubble_content
.manage_link
.empty());
868 class FakeDelegate
: public ProtocolHandlerRegistry::Delegate
{
870 void RegisterExternalHandler(const std::string
& protocol
) override
{
871 // Overrides in order to not register the handler with the
872 // ChildProcessSecurityPolicy. That has persistent and unalterable
873 // side effects on other tests.
876 ShellIntegration::DefaultProtocolClientWorker
* CreateShellWorker(
877 ShellIntegration::DefaultWebClientObserver
* observer
,
878 const std::string
& protocol
) override
{
879 VLOG(1) << "CreateShellWorker";
883 ProtocolHandlerRegistry::DefaultClientObserver
* CreateShellObserver(
884 ProtocolHandlerRegistry
* registry
) override
{
888 void RegisterWithOSAsDefaultClient(
889 const std::string
& protocol
,
890 ProtocolHandlerRegistry
* registry
) override
{
891 VLOG(1) << "Register With OS";
895 TEST_F(ContentSettingBubbleModelTest
, RPHAllow
) {
896 ProtocolHandlerRegistry
registry(profile(), new FakeDelegate());
897 registry
.InitProtocolSettings();
899 const GURL
page_url("http://toplevel.example/");
900 NavigateAndCommit(page_url
);
901 TabSpecificContentSettings
* content_settings
=
902 TabSpecificContentSettings::FromWebContents(web_contents());
903 ProtocolHandler test_handler
= ProtocolHandler::CreateProtocolHandler(
904 "mailto", GURL("http://www.toplevel.example/"));
905 content_settings
->set_pending_protocol_handler(test_handler
);
907 ContentSettingRPHBubbleModel
content_setting_bubble_model(
908 NULL
, web_contents(), profile(), ®istry
);
911 ProtocolHandler handler
= registry
.GetHandlerFor("mailto");
912 EXPECT_TRUE(handler
.IsEmpty());
913 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
914 content_settings
->pending_protocol_handler_setting());
917 // "0" is the "Allow" radio button.
918 content_setting_bubble_model
.OnRadioClicked(0);
920 ProtocolHandler handler
= registry
.GetHandlerFor("mailto");
921 ASSERT_FALSE(handler
.IsEmpty());
922 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
923 content_settings
->pending_protocol_handler_setting());
926 // "1" is the "Deny" radio button.
927 content_setting_bubble_model
.OnRadioClicked(1);
929 ProtocolHandler handler
= registry
.GetHandlerFor("mailto");
930 EXPECT_TRUE(handler
.IsEmpty());
931 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
932 content_settings
->pending_protocol_handler_setting());
935 // "2" is the "Ignore button.
936 content_setting_bubble_model
.OnRadioClicked(2);
938 ProtocolHandler handler
= registry
.GetHandlerFor("mailto");
939 EXPECT_TRUE(handler
.IsEmpty());
940 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
941 content_settings
->pending_protocol_handler_setting());
942 EXPECT_TRUE(registry
.IsIgnored(test_handler
));
945 // "0" is the "Allow" radio button.
946 content_setting_bubble_model
.OnRadioClicked(0);
948 ProtocolHandler handler
= registry
.GetHandlerFor("mailto");
949 ASSERT_FALSE(handler
.IsEmpty());
950 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
951 content_settings
->pending_protocol_handler_setting());
952 EXPECT_FALSE(registry
.IsIgnored(test_handler
));