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