Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / content_settings / content_setting_bubble_model_unittest.cc
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.
4
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"
28
29 using content::WebContentsTester;
30
31 class ContentSettingBubbleModelTest : public ChromeRenderViewHostTestHarness {
32  protected:
33   void SetUp() override {
34     ChromeRenderViewHostTestHarness::SetUp();
35     TabSpecificContentSettings::CreateForWebContents(web_contents());
36     InfoBarService::CreateForWebContents(web_contents());
37   }
38
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.popup_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());
56   }
57
58   std::string GetDefaultAudioDevice() {
59     PrefService* prefs = profile()->GetPrefs();
60     return prefs->GetString(prefs::kDefaultAudioCaptureDevice);
61   }
62
63   std::string GetDefaultVideoDevice() {
64     PrefService* prefs = profile()->GetPrefs();
65     return prefs->GetString(prefs::kDefaultVideoCaptureDevice);
66   }
67 };
68
69 TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
70   TabSpecificContentSettings* content_settings =
71       TabSpecificContentSettings::FromWebContents(web_contents());
72   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES);
73
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());
85 }
86
87 TEST_F(ContentSettingBubbleModelTest, Cookies) {
88   TabSpecificContentSettings* content_settings =
89       TabSpecificContentSettings::FromWebContents(web_contents());
90   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES);
91
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());
105
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();
113
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());
123 }
124
125 TEST_F(ContentSettingBubbleModelTest, MediastreamMicAndCamera) {
126   // Required to break dependency on BrowserMainLoop.
127   MediaCaptureDevicesDispatcher::GetInstance()->
128       DisableDeviceEnumerationForTesting();
129
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(),
141                                                std::string(),
142                                                std::string());
143
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());
165 }
166
167 TEST_F(ContentSettingBubbleModelTest, BlockedMediastreamMicAndCamera) {
168   // Required to break dependency on BrowserMainLoop.
169   MediaCaptureDevicesDispatcher::GetInstance()->
170       DisableDeviceEnumerationForTesting();
171
172   WebContentsTester::For(web_contents())->
173       NavigateAndCommit(GURL("https://www.example.com"));
174   GURL url = web_contents()->GetURL();
175
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(
182         primary_pattern,
183         ContentSettingsPattern::Wildcard(),
184         CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
185         std::string(),
186         setting);
187   host_content_settings_map->SetContentSetting(
188         primary_pattern,
189         ContentSettingsPattern::Wildcard(),
190         CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
191         std::string(),
192         setting);
193
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(),
205                                                std::string(),
206                                                std::string());
207   {
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
215     // setting.
216     EXPECT_EQ(1, bubble_content.radio_group.default_item);
217   }
218
219   // Test that the media settings where not changed.
220   EXPECT_EQ(CONTENT_SETTING_BLOCK,
221             host_content_settings_map->GetContentSetting(
222                 url,
223                 url,
224                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
225                 std::string()));
226   EXPECT_EQ(CONTENT_SETTING_BLOCK,
227             host_content_settings_map->GetContentSetting(
228                 url,
229                 url,
230                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
231                 std::string()));
232
233   {
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);
240   }
241   // Test that the media setting were change correctly.
242   EXPECT_EQ(CONTENT_SETTING_ALLOW,
243             host_content_settings_map->GetContentSetting(
244                 url,
245                 url,
246                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
247                 std::string()));
248   EXPECT_EQ(CONTENT_SETTING_ALLOW,
249             host_content_settings_map->GetContentSetting(
250                 url,
251                 url,
252                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
253                 std::string()));
254 }
255
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();
262
263   WebContentsTester::For(web_contents())->
264       NavigateAndCommit(GURL("https://www.example.com"));
265   GURL url = web_contents()->GetURL();
266
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(
273         primary_pattern,
274         ContentSettingsPattern::Wildcard(),
275         CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
276         std::string(),
277         setting);
278
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(),
287                                                std::string(),
288                                                std::string(),
289                                                std::string());
290   {
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
298     // setting.
299     EXPECT_EQ(1, bubble_content.radio_group.default_item);
300     // Change the radio setting.
301     content_setting_bubble_model->OnRadioClicked(0);
302   }
303   // Test that the setting was changed.
304   EXPECT_EQ(CONTENT_SETTING_ALLOW,
305             host_content_settings_map->GetContentSetting(
306                 url,
307                 url,
308                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
309                 std::string()));
310
311   {
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));
322
323     EXPECT_EQ(0, bubble_content.radio_group.default_item);
324     // Restore the radio setting (to block).
325     content_setting_bubble_model->OnRadioClicked(1);
326   }
327   // Test that the media settings were changed again.
328   EXPECT_EQ(CONTENT_SETTING_BLOCK,
329             host_content_settings_map->GetContentSetting(
330                 url,
331                 url,
332                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
333                 std::string()));
334
335   {
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());
345
346     EXPECT_EQ(1, bubble_content.radio_group.default_item);
347   }
348 }
349
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();
355
356   WebContentsTester::For(web_contents())->
357       NavigateAndCommit(GURL("https://www.example.com"));
358   GURL url = web_contents()->GetURL();
359
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(
371       audio_devices);
372
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(),
381                                                std::string(),
382                                                std::string(),
383                                                std::string());
384   {
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());
392
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));
400
401     // Select a different (the second) device.
402     content_setting_bubble_model->OnMediaMenuClicked(
403         content::MEDIA_DEVICE_AUDIO_CAPTURE,
404         fake_audio_device2.id);
405   }
406   {
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
421     // active capture.
422     EXPECT_FALSE(bubble_content.custom_link_enabled);
423     EXPECT_TRUE(bubble_content.custom_link.empty());
424   }
425
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(),
437                                                std::string(),
438                                                std::string(),
439                                                std::string());
440
441   {
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
449     // shown.
450     EXPECT_TRUE(bubble_content.custom_link.empty());
451
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));
458
459     // Select a different different device.
460     content_setting_bubble_model->OnMediaMenuClicked(
461         content::MEDIA_DEVICE_AUDIO_CAPTURE,
462         fake_audio_device3.id);
463   }
464
465   {
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));
476   }
477
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(),
483                                                std::string(),
484                                                std::string(),
485                                                std::string());
486
487   {
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());
498
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));
506   }
507 }
508
509 TEST_F(ContentSettingBubbleModelTest, MediastreamMic) {
510   // Required to break dependency on BrowserMainLoop.
511   MediaCaptureDevicesDispatcher::GetInstance()->
512       DisableDeviceEnumerationForTesting();
513
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(),
523                                                std::string(),
524                                                std::string(),
525                                                std::string());
526
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);
550
551   // Change the microphone access.
552   microphone_camera_state |= TabSpecificContentSettings::MICROPHONE_BLOCKED;
553   content_settings->OnMediaStreamPermissionSet(security_origin,
554                                                microphone_camera_state,
555                                                GetDefaultAudioDevice(),
556                                                std::string(),
557                                                std::string(),
558                                                std::string());
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);
582 }
583
584 TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) {
585   // Required to break dependency on BrowserMainLoop.
586   MediaCaptureDevicesDispatcher::GetInstance()->
587       DisableDeviceEnumerationForTesting();
588
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,
597                                                std::string(),
598                                                GetDefaultVideoDevice(),
599                                                std::string(),
600                                                std::string());
601
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);
625
626   // Change the camera access.
627   microphone_camera_state |= TabSpecificContentSettings::CAMERA_BLOCKED;
628   content_settings->OnMediaStreamPermissionSet(security_origin,
629                                                microphone_camera_state,
630                                                std::string(),
631                                                GetDefaultVideoDevice(),
632                                                std::string(),
633                                                std::string());
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);
657 }
658
659 TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) {
660   // Required to break dependency on BrowserMainLoop.
661   MediaCaptureDevicesDispatcher::GetInstance()->
662       DisableDeviceEnumerationForTesting();
663
664   TabSpecificContentSettings* content_settings =
665       TabSpecificContentSettings::FromWebContents(web_contents());
666   std::string request_host = "google.com";
667   GURL security_origin("http://" + request_host);
668
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(),
675                                                std::string(),
676                                                std::string(),
677                                                std::string());
678
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);
699
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(),
706                                                std::string(),
707                                                std::string());
708
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());
727 }
728
729 TEST_F(ContentSettingBubbleModelTest, Plugins) {
730   TabSpecificContentSettings* content_settings =
731       TabSpecificContentSettings::FromWebContents(web_contents());
732   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS);
733
734   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
735       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
736          NULL, web_contents(), profile(),
737          CONTENT_SETTINGS_TYPE_PLUGINS));
738   const ContentSettingBubbleModel::BubbleContent& bubble_content =
739       content_setting_bubble_model->bubble_content();
740   EXPECT_FALSE(bubble_content.title.empty());
741   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
742   EXPECT_FALSE(bubble_content.custom_link.empty());
743   EXPECT_TRUE(bubble_content.custom_link_enabled);
744   EXPECT_FALSE(bubble_content.manage_link.empty());
745   EXPECT_FALSE(bubble_content.learn_more_link.empty());
746 }
747
748 TEST_F(ContentSettingBubbleModelTest, PepperBroker) {
749   TabSpecificContentSettings* content_settings =
750       TabSpecificContentSettings::FromWebContents(web_contents());
751   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
752
753   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
754       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
755          NULL, web_contents(), profile(),
756          CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
757   const ContentSettingBubbleModel::BubbleContent& bubble_content =
758       content_setting_bubble_model->bubble_content();
759
760   std::string title = bubble_content.title;
761   EXPECT_FALSE(title.empty());
762   ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size());
763   std::string radio1 = bubble_content.radio_group.radio_items[0];
764   std::string radio2 = bubble_content.radio_group.radio_items[1];
765   EXPECT_FALSE(bubble_content.custom_link_enabled);
766   EXPECT_FALSE(bubble_content.manage_link.empty());
767
768   content_settings->ClearBlockedContentSettingsExceptForCookies();
769   content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
770   content_setting_bubble_model.reset(
771       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
772           NULL, web_contents(), profile(),
773           CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
774   const ContentSettingBubbleModel::BubbleContent& bubble_content_2 =
775       content_setting_bubble_model->bubble_content();
776
777   EXPECT_FALSE(bubble_content_2.title.empty());
778   EXPECT_NE(title, bubble_content_2.title);
779   ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size());
780   EXPECT_NE(radio1, bubble_content_2.radio_group.radio_items[0]);
781   EXPECT_NE(radio2, bubble_content_2.radio_group.radio_items[1]);
782   EXPECT_FALSE(bubble_content_2.custom_link_enabled);
783   EXPECT_FALSE(bubble_content_2.manage_link.empty());
784 }
785
786 TEST_F(ContentSettingBubbleModelTest, Geolocation) {
787   const GURL page_url("http://toplevel.example/");
788   const GURL frame1_url("http://host1.example/");
789   const GURL frame2_url("http://host2.example:999/");
790
791   NavigateAndCommit(page_url);
792   TabSpecificContentSettings* content_settings =
793       TabSpecificContentSettings::FromWebContents(web_contents());
794
795   // One permitted frame, but not in the content map: requires reload.
796   content_settings->OnGeolocationPermissionSet(frame1_url, true);
797   CheckGeolocationBubble(1, false, true);
798
799   // Add it to the content map, should now have a clear link.
800   HostContentSettingsMap* setting_map =
801       profile()->GetHostContentSettingsMap();
802   setting_map->SetContentSetting(
803       ContentSettingsPattern::FromURLNoWildcard(frame1_url),
804       ContentSettingsPattern::FromURLNoWildcard(page_url),
805       CONTENT_SETTINGS_TYPE_GEOLOCATION,
806       std::string(),
807       CONTENT_SETTING_ALLOW);
808   CheckGeolocationBubble(1, true, false);
809
810   // Change the default to allow: no message needed.
811   profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
812       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ALLOW);
813   CheckGeolocationBubble(1, false, false);
814
815   // Second frame denied, but not stored in the content map: requires reload.
816   content_settings->OnGeolocationPermissionSet(frame2_url, false);
817   CheckGeolocationBubble(2, false, true);
818
819   // Change the default to block: offer a clear link for the persisted frame 1.
820   profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
821       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_BLOCK);
822   CheckGeolocationBubble(2, true, false);
823 }
824
825 TEST_F(ContentSettingBubbleModelTest, FileURL) {
826   std::string file_url("file:///tmp/test.html");
827   NavigateAndCommit(GURL(file_url));
828   TabSpecificContentSettings::FromWebContents(web_contents())->OnContentBlocked(
829       CONTENT_SETTINGS_TYPE_IMAGES);
830   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
831       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
832           NULL, web_contents(), profile(),
833           CONTENT_SETTINGS_TYPE_IMAGES));
834   std::string title =
835       content_setting_bubble_model->bubble_content().radio_group.radio_items[0];
836   ASSERT_NE(std::string::npos, title.find(file_url));
837 }
838
839 TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) {
840   const GURL page_url("http://toplevel.example/");
841   NavigateAndCommit(page_url);
842   TabSpecificContentSettings* content_settings =
843       TabSpecificContentSettings::FromWebContents(web_contents());
844   content_settings->set_pending_protocol_handler(
845       ProtocolHandler::CreateProtocolHandler(
846           "mailto", GURL("http://www.toplevel.example/")));
847
848   ContentSettingRPHBubbleModel content_setting_bubble_model(
849           NULL, web_contents(), profile(), NULL,
850           CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
851
852   const ContentSettingBubbleModel::BubbleContent& bubble_content =
853       content_setting_bubble_model.bubble_content();
854   EXPECT_FALSE(bubble_content.title.empty());
855   EXPECT_FALSE(bubble_content.radio_group.radio_items.empty());
856   EXPECT_TRUE(bubble_content.popup_items.empty());
857   EXPECT_TRUE(bubble_content.domain_lists.empty());
858   EXPECT_TRUE(bubble_content.custom_link.empty());
859   EXPECT_FALSE(bubble_content.custom_link_enabled);
860   EXPECT_FALSE(bubble_content.manage_link.empty());
861 }
862
863 class FakeDelegate : public ProtocolHandlerRegistry::Delegate {
864  public:
865   void RegisterExternalHandler(const std::string& protocol) override {
866     // Overrides in order to not register the handler with the
867     // ChildProcessSecurityPolicy. That has persistent and unalterable
868     // side effects on other tests.
869   }
870
871   ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
872       ShellIntegration::DefaultWebClientObserver* observer,
873       const std::string& protocol) override {
874     VLOG(1) << "CreateShellWorker";
875     return NULL;
876   }
877
878   ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver(
879       ProtocolHandlerRegistry* registry) override {
880     return NULL;
881   }
882
883   void RegisterWithOSAsDefaultClient(
884       const std::string& protocol,
885       ProtocolHandlerRegistry* registry) override {
886     VLOG(1) << "Register With OS";
887   }
888 };
889
890 TEST_F(ContentSettingBubbleModelTest, RPHAllow) {
891   ProtocolHandlerRegistry registry(profile(), new FakeDelegate());
892   registry.InitProtocolSettings();
893
894   const GURL page_url("http://toplevel.example/");
895   NavigateAndCommit(page_url);
896   TabSpecificContentSettings* content_settings =
897       TabSpecificContentSettings::FromWebContents(web_contents());
898   ProtocolHandler test_handler = ProtocolHandler::CreateProtocolHandler(
899       "mailto", GURL("http://www.toplevel.example/"));
900   content_settings->set_pending_protocol_handler(test_handler);
901
902   ContentSettingRPHBubbleModel content_setting_bubble_model(
903           NULL, web_contents(), profile(), &registry,
904           CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
905
906   {
907     ProtocolHandler handler = registry.GetHandlerFor("mailto");
908     EXPECT_TRUE(handler.IsEmpty());
909     EXPECT_EQ(CONTENT_SETTING_DEFAULT,
910               content_settings->pending_protocol_handler_setting());
911   }
912
913   // "0" is the "Allow" radio button.
914   content_setting_bubble_model.OnRadioClicked(0);
915   {
916     ProtocolHandler handler = registry.GetHandlerFor("mailto");
917     ASSERT_FALSE(handler.IsEmpty());
918     EXPECT_EQ(CONTENT_SETTING_ALLOW,
919               content_settings->pending_protocol_handler_setting());
920   }
921
922   // "1" is the "Deny" radio button.
923   content_setting_bubble_model.OnRadioClicked(1);
924   {
925     ProtocolHandler handler = registry.GetHandlerFor("mailto");
926     EXPECT_TRUE(handler.IsEmpty());
927     EXPECT_EQ(CONTENT_SETTING_BLOCK,
928               content_settings->pending_protocol_handler_setting());
929   }
930
931   // "2" is the "Ignore button.
932   content_setting_bubble_model.OnRadioClicked(2);
933   {
934     ProtocolHandler handler = registry.GetHandlerFor("mailto");
935     EXPECT_TRUE(handler.IsEmpty());
936     EXPECT_EQ(CONTENT_SETTING_DEFAULT,
937               content_settings->pending_protocol_handler_setting());
938     EXPECT_TRUE(registry.IsIgnored(test_handler));
939   }
940
941   // "0" is the "Allow" radio button.
942   content_setting_bubble_model.OnRadioClicked(0);
943   {
944     ProtocolHandler handler = registry.GetHandlerFor("mailto");
945     ASSERT_FALSE(handler.IsEmpty());
946     EXPECT_EQ(CONTENT_SETTING_ALLOW,
947               content_settings->pending_protocol_handler_setting());
948     EXPECT_FALSE(registry.IsIgnored(test_handler));
949   }
950
951   registry.Shutdown();
952 }