Home | History | Annotate | Download | only in content_settings
      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/strings/utf_string_conversions.h"
      8 #include "chrome/browser/content_settings/host_content_settings_map.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_delegate.h"
     12 #include "chrome/browser/infobars/infobar_service.h"
     13 #include "chrome/browser/media/media_capture_devices_dispatcher.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/content_settings.h"
     18 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     19 #include "chrome/test/base/testing_profile.h"
     20 #include "content/public/browser/web_contents.h"
     21 #include "content/public/test/web_contents_tester.h"
     22 #include "grit/generated_resources.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "ui/base/l10n/l10n_util.h"
     25 
     26 using content::WebContentsTester;
     27 
     28 class ContentSettingBubbleModelTest : public ChromeRenderViewHostTestHarness {
     29  protected:
     30   virtual void SetUp() OVERRIDE {
     31     ChromeRenderViewHostTestHarness::SetUp();
     32     TabSpecificContentSettings::CreateForWebContents(web_contents());
     33     InfoBarService::CreateForWebContents(web_contents());
     34   }
     35 
     36   void CheckGeolocationBubble(size_t expected_domains,
     37                               bool expect_clear_link,
     38                               bool expect_reload_hint) {
     39     scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
     40         ContentSettingBubbleModel::CreateContentSettingBubbleModel(
     41             NULL, web_contents(), profile(),
     42             CONTENT_SETTINGS_TYPE_GEOLOCATION));
     43     const ContentSettingBubbleModel::BubbleContent& bubble_content =
     44         content_setting_bubble_model->bubble_content();
     45     EXPECT_TRUE(bubble_content.title.empty());
     46     EXPECT_TRUE(bubble_content.radio_group.radio_items.empty());
     47     EXPECT_TRUE(bubble_content.popup_items.empty());
     48     EXPECT_EQ(expected_domains, bubble_content.domain_lists.size());
     49     EXPECT_NE(expect_clear_link || expect_reload_hint,
     50               bubble_content.custom_link.empty());
     51     EXPECT_EQ(expect_clear_link, bubble_content.custom_link_enabled);
     52     EXPECT_FALSE(bubble_content.manage_link.empty());
     53   }
     54 };
     55 
     56 TEST_F(ContentSettingBubbleModelTest, ImageRadios) {
     57   TabSpecificContentSettings* content_settings =
     58       TabSpecificContentSettings::FromWebContents(web_contents());
     59   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES,
     60                                      std::string());
     61 
     62   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
     63       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
     64          NULL, web_contents(), profile(),
     65          CONTENT_SETTINGS_TYPE_IMAGES));
     66   const ContentSettingBubbleModel::BubbleContent& bubble_content =
     67       content_setting_bubble_model->bubble_content();
     68   EXPECT_FALSE(bubble_content.title.empty());
     69   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
     70   EXPECT_EQ(0, bubble_content.radio_group.default_item);
     71   EXPECT_TRUE(bubble_content.custom_link.empty());
     72   EXPECT_FALSE(bubble_content.manage_link.empty());
     73 }
     74 
     75 TEST_F(ContentSettingBubbleModelTest, Cookies) {
     76   TabSpecificContentSettings* content_settings =
     77       TabSpecificContentSettings::FromWebContents(web_contents());
     78   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES,
     79                                      std::string());
     80 
     81   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
     82       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
     83           NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES));
     84   const ContentSettingBubbleModel::BubbleContent& bubble_content =
     85       content_setting_bubble_model->bubble_content();
     86   std::string title = bubble_content.title;
     87   EXPECT_FALSE(title.empty());
     88   ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size());
     89   std::string radio1 = bubble_content.radio_group.radio_items[0];
     90   std::string radio2 = bubble_content.radio_group.radio_items[1];
     91   EXPECT_FALSE(bubble_content.custom_link.empty());
     92   EXPECT_TRUE(bubble_content.custom_link_enabled);
     93   EXPECT_FALSE(bubble_content.manage_link.empty());
     94 
     95   content_settings->ClearCookieSpecificContentSettings();
     96   content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_COOKIES);
     97   content_setting_bubble_model.reset(
     98       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
     99           NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES));
    100   const ContentSettingBubbleModel::BubbleContent& bubble_content_2 =
    101       content_setting_bubble_model->bubble_content();
    102 
    103   EXPECT_FALSE(bubble_content_2.title.empty());
    104   EXPECT_NE(title, bubble_content_2.title);
    105   ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size());
    106   // TODO(bauerb): Update this once the strings have been updated.
    107   EXPECT_EQ(radio1, bubble_content_2.radio_group.radio_items[0]);
    108   EXPECT_EQ(radio2, bubble_content_2.radio_group.radio_items[1]);
    109   EXPECT_FALSE(bubble_content_2.custom_link.empty());
    110   EXPECT_TRUE(bubble_content_2.custom_link_enabled);
    111   EXPECT_FALSE(bubble_content_2.manage_link.empty());
    112 }
    113 
    114 TEST_F(ContentSettingBubbleModelTest, MediastreamMicAndCamera) {
    115   // Required to break dependency on BrowserMainLoop.
    116   MediaCaptureDevicesDispatcher::GetInstance()->
    117       DisableDeviceEnumerationForTesting();
    118 
    119   TabSpecificContentSettings* content_settings =
    120       TabSpecificContentSettings::FromWebContents(web_contents());
    121   content_settings->OnMicrophoneAccessed();
    122   content_settings->OnCameraAccessed();
    123 
    124   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    125       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    126          NULL, web_contents(), profile(),
    127          CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    128   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    129       content_setting_bubble_model->bubble_content();
    130   EXPECT_EQ(bubble_content.title,
    131             l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
    132   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    133   EXPECT_EQ(bubble_content.radio_group.radio_items[0],
    134             l10n_util::GetStringFUTF8(
    135                 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION,
    136                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    137   EXPECT_EQ(bubble_content.radio_group.radio_items[1],
    138             l10n_util::GetStringUTF8(
    139                 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK));
    140   EXPECT_EQ(0, bubble_content.radio_group.default_item);
    141   EXPECT_TRUE(bubble_content.custom_link.empty());
    142   EXPECT_FALSE(bubble_content.custom_link_enabled);
    143   EXPECT_FALSE(bubble_content.manage_link.empty());
    144   EXPECT_EQ(2U, bubble_content.media_menus.size());
    145 }
    146 
    147 TEST_F(ContentSettingBubbleModelTest, BlockedMediastreamMicAndCamera) {
    148   // Required to break dependency on BrowserMainLoop.
    149   MediaCaptureDevicesDispatcher::GetInstance()->
    150       DisableDeviceEnumerationForTesting();
    151 
    152   WebContentsTester::For(web_contents())->
    153       NavigateAndCommit(GURL("https://www.example.com"));
    154   GURL url = web_contents()->GetURL();
    155 
    156   HostContentSettingsMap* host_content_settings_map =
    157       profile()->GetHostContentSettingsMap();
    158   ContentSettingsPattern primary_pattern =
    159       ContentSettingsPattern::FromURL(url);
    160   ContentSetting setting = CONTENT_SETTING_BLOCK;
    161   host_content_settings_map->SetContentSetting(
    162         primary_pattern,
    163         ContentSettingsPattern::Wildcard(),
    164         CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    165         std::string(),
    166         setting);
    167   host_content_settings_map->SetContentSetting(
    168         primary_pattern,
    169         ContentSettingsPattern::Wildcard(),
    170         CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
    171         std::string(),
    172         setting);
    173 
    174   TabSpecificContentSettings* content_settings =
    175       TabSpecificContentSettings::FromWebContents(web_contents());
    176   content_settings->OnMicrophoneAccessBlocked();
    177   content_settings->OnCameraAccessBlocked();
    178   {
    179     scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    180         ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    181            NULL, web_contents(), profile(),
    182            CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    183     const ContentSettingBubbleModel::BubbleContent& bubble_content =
    184         content_setting_bubble_model->bubble_content();
    185     // Test if the correct radio item is selected for the blocked mediastream
    186     // setting.
    187     EXPECT_EQ(1, bubble_content.radio_group.default_item);
    188   }
    189 
    190   // Test that the media settings where not changed.
    191   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    192             host_content_settings_map->GetContentSetting(
    193                 url,
    194                 url,
    195                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    196                 std::string()));
    197   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    198             host_content_settings_map->GetContentSetting(
    199                 url,
    200                 url,
    201                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
    202                 std::string()));
    203 
    204   {
    205     scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    206         ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    207            NULL, web_contents(), profile(),
    208            CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    209     // Change the radio setting.
    210     content_setting_bubble_model->OnRadioClicked(0);
    211   }
    212   // Test that the media setting were change correctly.
    213   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    214             host_content_settings_map->GetContentSetting(
    215                 url,
    216                 url,
    217                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    218                 std::string()));
    219   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    220             host_content_settings_map->GetContentSetting(
    221                 url,
    222                 url,
    223                 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
    224                 std::string()));
    225 
    226   // Removing an |InfoBarDelegate| from the |InfoBarService| does not delete
    227   // it. Hence the |delegate| must be cleaned up after it was removed from the
    228   // |infobar_service|.
    229   InfoBarService* infobar_service =
    230       InfoBarService::FromWebContents(web_contents());
    231   scoped_ptr<InfoBarDelegate> delegate(infobar_service->infobar_at(0));
    232   infobar_service->RemoveInfoBar(delegate.get());
    233 }
    234 
    235 TEST_F(ContentSettingBubbleModelTest, MediastreamMic) {
    236   // Required to break dependency on BrowserMainLoop.
    237   MediaCaptureDevicesDispatcher::GetInstance()->
    238       DisableDeviceEnumerationForTesting();
    239 
    240   TabSpecificContentSettings* content_settings =
    241       TabSpecificContentSettings::FromWebContents(web_contents());
    242   content_settings->OnMicrophoneAccessed();
    243 
    244   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    245       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    246           NULL, web_contents(), profile(),
    247           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    248   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    249       content_setting_bubble_model->bubble_content();
    250   EXPECT_EQ(bubble_content.title,
    251             l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
    252   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    253   EXPECT_EQ(bubble_content.radio_group.radio_items[0],
    254             l10n_util::GetStringFUTF8(
    255                 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION,
    256                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    257   EXPECT_EQ(bubble_content.radio_group.radio_items[1],
    258             l10n_util::GetStringUTF8(
    259                 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK));
    260   EXPECT_EQ(0, bubble_content.radio_group.default_item);
    261   EXPECT_TRUE(bubble_content.custom_link.empty());
    262   EXPECT_FALSE(bubble_content.custom_link_enabled);
    263   EXPECT_FALSE(bubble_content.manage_link.empty());
    264   EXPECT_EQ(1U, bubble_content.media_menus.size());
    265   EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
    266             bubble_content.media_menus.begin()->first);
    267 
    268   // Change the microphone access.
    269   content_settings->OnMicrophoneAccessBlocked();
    270   content_setting_bubble_model.reset(
    271       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    272           NULL, web_contents(), profile(),
    273           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    274   const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
    275       content_setting_bubble_model->bubble_content();
    276   EXPECT_EQ(new_bubble_content.title,
    277             l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
    278   EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
    279   EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
    280             l10n_util::GetStringFUTF8(
    281                 IDS_BLOCKED_MEDIASTREAM_MIC_ASK,
    282                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    283   EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
    284             l10n_util::GetStringUTF8(
    285                 IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION));
    286   EXPECT_EQ(1, new_bubble_content.radio_group.default_item);
    287   EXPECT_TRUE(new_bubble_content.custom_link.empty());
    288   EXPECT_FALSE(new_bubble_content.custom_link_enabled);
    289   EXPECT_FALSE(new_bubble_content.manage_link.empty());
    290   EXPECT_EQ(1U, new_bubble_content.media_menus.size());
    291   EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
    292             new_bubble_content.media_menus.begin()->first);
    293 }
    294 
    295 TEST_F(ContentSettingBubbleModelTest, MediastreamCamera) {
    296   // Required to break dependency on BrowserMainLoop.
    297   MediaCaptureDevicesDispatcher::GetInstance()->
    298       DisableDeviceEnumerationForTesting();
    299 
    300   TabSpecificContentSettings* content_settings =
    301       TabSpecificContentSettings::FromWebContents(web_contents());
    302   content_settings->OnCameraAccessed();
    303 
    304   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    305       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    306           NULL, web_contents(), profile(),
    307           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    308   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    309       content_setting_bubble_model->bubble_content();
    310   EXPECT_EQ(bubble_content.title,
    311             l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED));
    312   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    313   EXPECT_EQ(bubble_content.radio_group.radio_items[0],
    314             l10n_util::GetStringFUTF8(
    315                 IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION,
    316                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    317   EXPECT_EQ(bubble_content.radio_group.radio_items[1],
    318             l10n_util::GetStringUTF8(
    319                 IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK));
    320   EXPECT_EQ(0, bubble_content.radio_group.default_item);
    321   EXPECT_TRUE(bubble_content.custom_link.empty());
    322   EXPECT_FALSE(bubble_content.custom_link_enabled);
    323   EXPECT_FALSE(bubble_content.manage_link.empty());
    324   EXPECT_EQ(1U, bubble_content.media_menus.size());
    325   EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE,
    326             bubble_content.media_menus.begin()->first);
    327 
    328   // Change the camera access.
    329   content_settings->OnCameraAccessBlocked();
    330   content_setting_bubble_model.reset(
    331       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    332           NULL, web_contents(), profile(),
    333           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    334   const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
    335       content_setting_bubble_model->bubble_content();
    336   EXPECT_EQ(new_bubble_content.title,
    337             l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED));
    338   EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
    339   EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
    340             l10n_util::GetStringFUTF8(
    341                 IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK,
    342                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    343   EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
    344             l10n_util::GetStringUTF8(
    345                 IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION));
    346   EXPECT_EQ(1, new_bubble_content.radio_group.default_item);
    347   EXPECT_TRUE(new_bubble_content.custom_link.empty());
    348   EXPECT_FALSE(new_bubble_content.custom_link_enabled);
    349   EXPECT_FALSE(new_bubble_content.manage_link.empty());
    350   EXPECT_EQ(1U, new_bubble_content.media_menus.size());
    351   EXPECT_EQ(content::MEDIA_DEVICE_VIDEO_CAPTURE,
    352             new_bubble_content.media_menus.begin()->first);
    353 }
    354 
    355 TEST_F(ContentSettingBubbleModelTest, AccumulateMediastreamMicAndCamera) {
    356   // Required to break dependency on BrowserMainLoop.
    357   MediaCaptureDevicesDispatcher::GetInstance()->
    358       DisableDeviceEnumerationForTesting();
    359 
    360   TabSpecificContentSettings* content_settings =
    361       TabSpecificContentSettings::FromWebContents(web_contents());
    362 
    363   // Firstly, add microphone access.
    364   content_settings->OnMicrophoneAccessed();
    365 
    366   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    367       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    368           NULL, web_contents(), profile(),
    369           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    370   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    371       content_setting_bubble_model->bubble_content();
    372   EXPECT_EQ(bubble_content.title,
    373             l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
    374   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    375   EXPECT_EQ(bubble_content.radio_group.radio_items[0],
    376             l10n_util::GetStringFUTF8(
    377                 IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION,
    378                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    379   EXPECT_EQ(bubble_content.radio_group.radio_items[1],
    380             l10n_util::GetStringUTF8(
    381                 IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK));
    382   EXPECT_EQ(0, bubble_content.radio_group.default_item);
    383   EXPECT_EQ(1U, bubble_content.media_menus.size());
    384   EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE,
    385             bubble_content.media_menus.begin()->first);
    386 
    387   // Then add camera access.
    388   content_settings->OnCameraAccessed();
    389 
    390   content_setting_bubble_model.reset(
    391       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    392           NULL, web_contents(), profile(),
    393           CONTENT_SETTINGS_TYPE_MEDIASTREAM));
    394   const ContentSettingBubbleModel::BubbleContent& new_bubble_content =
    395       content_setting_bubble_model->bubble_content();
    396   EXPECT_EQ(new_bubble_content.title,
    397             l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
    398   EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size());
    399   EXPECT_EQ(new_bubble_content.radio_group.radio_items[0],
    400             l10n_util::GetStringFUTF8(
    401                 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION,
    402                 UTF8ToUTF16(web_contents()->GetURL().spec())));
    403   EXPECT_EQ(new_bubble_content.radio_group.radio_items[1],
    404             l10n_util::GetStringUTF8(
    405                 IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK));
    406   EXPECT_EQ(0, new_bubble_content.radio_group.default_item);
    407   EXPECT_EQ(2U, new_bubble_content.media_menus.size());
    408 }
    409 
    410 TEST_F(ContentSettingBubbleModelTest, Plugins) {
    411   TabSpecificContentSettings* content_settings =
    412       TabSpecificContentSettings::FromWebContents(web_contents());
    413   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS,
    414                                      std::string());
    415 
    416   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    417       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    418          NULL, web_contents(), profile(),
    419          CONTENT_SETTINGS_TYPE_PLUGINS));
    420   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    421       content_setting_bubble_model->bubble_content();
    422   EXPECT_FALSE(bubble_content.title.empty());
    423   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    424   EXPECT_FALSE(bubble_content.custom_link.empty());
    425   EXPECT_TRUE(bubble_content.custom_link_enabled);
    426   EXPECT_FALSE(bubble_content.manage_link.empty());
    427 }
    428 
    429 TEST_F(ContentSettingBubbleModelTest, MultiplePlugins) {
    430   CommandLine* cmd = CommandLine::ForCurrentProcess();
    431   base::AutoReset<CommandLine> auto_reset(cmd, *cmd);
    432   cmd->AppendSwitch(switches::kEnableResourceContentSettings);
    433 
    434   HostContentSettingsMap* map = profile()->GetHostContentSettingsMap();
    435   std::string fooPlugin = "foo";
    436   std::string barPlugin = "bar";
    437 
    438   // Navigating to some sample url prevents the GetURL method from returning an
    439   // invalid empty URL.
    440   WebContentsTester::For(web_contents())->
    441       NavigateAndCommit(GURL("http://www.example.com"));
    442   GURL url = web_contents()->GetURL();
    443   map->AddExceptionForURL(url,
    444                           url,
    445                           CONTENT_SETTINGS_TYPE_PLUGINS,
    446                           fooPlugin,
    447                           CONTENT_SETTING_ALLOW);
    448   map->AddExceptionForURL(url,
    449                           url,
    450                           CONTENT_SETTINGS_TYPE_PLUGINS,
    451                           barPlugin,
    452                           CONTENT_SETTING_ASK);
    453 
    454   TabSpecificContentSettings* content_settings =
    455       TabSpecificContentSettings::FromWebContents(web_contents());
    456   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS,
    457                                      fooPlugin);
    458   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PLUGINS,
    459                                      barPlugin);
    460 
    461   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    462       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    463           NULL, web_contents(), profile(),
    464           CONTENT_SETTINGS_TYPE_PLUGINS));
    465   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    466       content_setting_bubble_model->bubble_content();
    467   EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size());
    468   EXPECT_EQ(1, bubble_content.radio_group.default_item);
    469 
    470   content_setting_bubble_model->OnRadioClicked(0);
    471   // Nothing should have changed.
    472   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    473             map->GetContentSetting(url,
    474                                    url,
    475                                    CONTENT_SETTINGS_TYPE_PLUGINS,
    476                                    fooPlugin));
    477   EXPECT_EQ(CONTENT_SETTING_ASK,
    478             map->GetContentSetting(url,
    479                                    url,
    480                                    CONTENT_SETTINGS_TYPE_PLUGINS,
    481                                    barPlugin));
    482 
    483   content_setting_bubble_model.reset();
    484   // Both plug-ins should be click-to-play now.
    485   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    486             map->GetContentSetting(url,
    487                                    url,
    488                                    CONTENT_SETTINGS_TYPE_PLUGINS,
    489                                    fooPlugin));
    490   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    491             map->GetContentSetting(url,
    492                                    url,
    493                                    CONTENT_SETTINGS_TYPE_PLUGINS,
    494                                    barPlugin));
    495 }
    496 
    497 TEST_F(ContentSettingBubbleModelTest, PepperBroker) {
    498   TabSpecificContentSettings* content_settings =
    499       TabSpecificContentSettings::FromWebContents(web_contents());
    500   content_settings->OnContentBlocked(CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
    501                                      std::string());
    502 
    503   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    504       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    505          NULL, web_contents(), profile(),
    506          CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
    507   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    508       content_setting_bubble_model->bubble_content();
    509 
    510   std::string title = bubble_content.title;
    511   EXPECT_FALSE(title.empty());
    512   ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size());
    513   std::string radio1 = bubble_content.radio_group.radio_items[0];
    514   std::string radio2 = bubble_content.radio_group.radio_items[1];
    515   EXPECT_FALSE(bubble_content.custom_link_enabled);
    516   EXPECT_FALSE(bubble_content.manage_link.empty());
    517 
    518   content_settings->ClearBlockedContentSettingsExceptForCookies();
    519   content_settings->OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
    520   content_setting_bubble_model.reset(
    521       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    522           NULL, web_contents(), profile(),
    523           CONTENT_SETTINGS_TYPE_PPAPI_BROKER));
    524   const ContentSettingBubbleModel::BubbleContent& bubble_content_2 =
    525       content_setting_bubble_model->bubble_content();
    526 
    527   EXPECT_FALSE(bubble_content_2.title.empty());
    528   EXPECT_NE(title, bubble_content_2.title);
    529   ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size());
    530   EXPECT_NE(radio1, bubble_content_2.radio_group.radio_items[0]);
    531   EXPECT_NE(radio2, bubble_content_2.radio_group.radio_items[1]);
    532   EXPECT_FALSE(bubble_content_2.custom_link_enabled);
    533   EXPECT_FALSE(bubble_content_2.manage_link.empty());
    534 }
    535 
    536 TEST_F(ContentSettingBubbleModelTest, Geolocation) {
    537   const GURL page_url("http://toplevel.example/");
    538   const GURL frame1_url("http://host1.example/");
    539   const GURL frame2_url("http://host2.example:999/");
    540 
    541   NavigateAndCommit(page_url);
    542   TabSpecificContentSettings* content_settings =
    543       TabSpecificContentSettings::FromWebContents(web_contents());
    544 
    545   // One permitted frame, but not in the content map: requires reload.
    546   content_settings->OnGeolocationPermissionSet(frame1_url, true);
    547   CheckGeolocationBubble(1, false, true);
    548 
    549   // Add it to the content map, should now have a clear link.
    550   HostContentSettingsMap* setting_map =
    551       profile()->GetHostContentSettingsMap();
    552   setting_map->SetContentSetting(
    553       ContentSettingsPattern::FromURLNoWildcard(frame1_url),
    554       ContentSettingsPattern::FromURLNoWildcard(page_url),
    555       CONTENT_SETTINGS_TYPE_GEOLOCATION,
    556       std::string(),
    557       CONTENT_SETTING_ALLOW);
    558   CheckGeolocationBubble(1, true, false);
    559 
    560   // Change the default to allow: no message needed.
    561   profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    562       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ALLOW);
    563   CheckGeolocationBubble(1, false, false);
    564 
    565   // Second frame denied, but not stored in the content map: requires reload.
    566   content_settings->OnGeolocationPermissionSet(frame2_url, false);
    567   CheckGeolocationBubble(2, false, true);
    568 
    569   // Change the default to block: offer a clear link for the persisted frame 1.
    570   profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
    571       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_BLOCK);
    572   CheckGeolocationBubble(2, true, false);
    573 }
    574 
    575 TEST_F(ContentSettingBubbleModelTest, FileURL) {
    576   std::string file_url("file:///tmp/test.html");
    577   NavigateAndCommit(GURL(file_url));
    578   TabSpecificContentSettings::FromWebContents(web_contents())->OnContentBlocked(
    579       CONTENT_SETTINGS_TYPE_IMAGES, std::string());
    580   scoped_ptr<ContentSettingBubbleModel> content_setting_bubble_model(
    581       ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    582           NULL, web_contents(), profile(),
    583           CONTENT_SETTINGS_TYPE_IMAGES));
    584   std::string title =
    585       content_setting_bubble_model->bubble_content().radio_group.radio_items[0];
    586   ASSERT_NE(std::string::npos, title.find(file_url));
    587 }
    588 
    589 TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) {
    590   const GURL page_url("http://toplevel.example/");
    591   NavigateAndCommit(page_url);
    592   TabSpecificContentSettings* content_settings =
    593       TabSpecificContentSettings::FromWebContents(web_contents());
    594   content_settings->set_pending_protocol_handler(
    595       ProtocolHandler::CreateProtocolHandler("mailto",
    596           GURL("http://www.toplevel.example/"), ASCIIToUTF16("Handler")));
    597 
    598   ContentSettingRPHBubbleModel content_setting_bubble_model(
    599           NULL, web_contents(), profile(), NULL,
    600           CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
    601 
    602   const ContentSettingBubbleModel::BubbleContent& bubble_content =
    603       content_setting_bubble_model.bubble_content();
    604   EXPECT_FALSE(bubble_content.title.empty());
    605   EXPECT_FALSE(bubble_content.radio_group.radio_items.empty());
    606   EXPECT_TRUE(bubble_content.popup_items.empty());
    607   EXPECT_TRUE(bubble_content.domain_lists.empty());
    608   EXPECT_TRUE(bubble_content.custom_link.empty());
    609   EXPECT_FALSE(bubble_content.custom_link_enabled);
    610   EXPECT_FALSE(bubble_content.manage_link.empty());
    611 }
    612 
    613 class FakeDelegate : public ProtocolHandlerRegistry::Delegate {
    614  public:
    615   virtual void RegisterExternalHandler(const std::string& protocol) OVERRIDE {
    616     // Overrides in order to not register the handler with the
    617     // ChildProcessSecurityPolicy. That has persistent and unalterable
    618     // side effects on other tests.
    619   }
    620 
    621   virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
    622       ShellIntegration::DefaultWebClientObserver* observer,
    623       const std::string& protocol) OVERRIDE {
    624     VLOG(1) << "CreateShellWorker";
    625     return NULL;
    626   }
    627 
    628   virtual ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver(
    629       ProtocolHandlerRegistry* registry) OVERRIDE {
    630     return NULL;
    631   }
    632 
    633   virtual void RegisterWithOSAsDefaultClient(
    634       const std::string& protocol,
    635       ProtocolHandlerRegistry* registry) OVERRIDE {
    636     VLOG(1) << "Register With OS";
    637   }
    638 };
    639 
    640 TEST_F(ContentSettingBubbleModelTest, RPHAllow) {
    641   ProtocolHandlerRegistry registry(profile(), new FakeDelegate());
    642   registry.InitProtocolSettings();
    643 
    644   const GURL page_url("http://toplevel.example/");
    645   NavigateAndCommit(page_url);
    646   TabSpecificContentSettings* content_settings =
    647       TabSpecificContentSettings::FromWebContents(web_contents());
    648   ProtocolHandler test_handler = ProtocolHandler::CreateProtocolHandler(
    649       "mailto", GURL("http://www.toplevel.example/"),
    650       ASCIIToUTF16("Handler"));
    651   content_settings->set_pending_protocol_handler(test_handler);
    652 
    653   ContentSettingRPHBubbleModel content_setting_bubble_model(
    654           NULL, web_contents(), profile(), &registry,
    655           CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS);
    656 
    657   {
    658     ProtocolHandler handler = registry.GetHandlerFor("mailto");
    659     EXPECT_TRUE(handler.IsEmpty());
    660     EXPECT_EQ(CONTENT_SETTING_DEFAULT,
    661               content_settings->pending_protocol_handler_setting());
    662   }
    663 
    664   // "0" is the "Allow" radio button.
    665   content_setting_bubble_model.OnRadioClicked(0);
    666   {
    667     ProtocolHandler handler = registry.GetHandlerFor("mailto");
    668     ASSERT_FALSE(handler.IsEmpty());
    669     EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title());
    670     EXPECT_EQ(CONTENT_SETTING_ALLOW,
    671               content_settings->pending_protocol_handler_setting());
    672   }
    673 
    674   // "1" is the "Deny" radio button.
    675   content_setting_bubble_model.OnRadioClicked(1);
    676   {
    677     ProtocolHandler handler = registry.GetHandlerFor("mailto");
    678     EXPECT_TRUE(handler.IsEmpty());
    679     EXPECT_EQ(CONTENT_SETTING_BLOCK,
    680               content_settings->pending_protocol_handler_setting());
    681   }
    682 
    683   // "2" is the "Ignore button.
    684   content_setting_bubble_model.OnRadioClicked(2);
    685   {
    686     ProtocolHandler handler = registry.GetHandlerFor("mailto");
    687     EXPECT_TRUE(handler.IsEmpty());
    688     EXPECT_EQ(CONTENT_SETTING_DEFAULT,
    689               content_settings->pending_protocol_handler_setting());
    690     EXPECT_TRUE(registry.IsIgnored(test_handler));
    691   }
    692 
    693   // "0" is the "Allow" radio button.
    694   content_setting_bubble_model.OnRadioClicked(0);
    695   {
    696     ProtocolHandler handler = registry.GetHandlerFor("mailto");
    697     ASSERT_FALSE(handler.IsEmpty());
    698     EXPECT_EQ(ASCIIToUTF16("Handler"), handler.title());
    699     EXPECT_EQ(CONTENT_SETTING_ALLOW,
    700               content_settings->pending_protocol_handler_setting());
    701     EXPECT_FALSE(registry.IsIgnored(test_handler));
    702   }
    703 
    704   registry.Shutdown();
    705 }
    706