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 "chrome/browser/ui/content_settings/content_setting_image_model.h"
      6 
      7 #include "chrome/browser/content_settings/host_content_settings_map.h"
      8 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
      9 #include "chrome/browser/prerender/prerender_manager.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "content/public/browser/web_contents.h"
     12 #include "grit/generated_resources.h"
     13 #include "grit/theme_resources.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 
     16 using content::WebContents;
     17 
     18 class ContentSettingBlockedImageModel : public ContentSettingImageModel {
     19  public:
     20   explicit ContentSettingBlockedImageModel(
     21       ContentSettingsType content_settings_type);
     22 
     23   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     24 };
     25 
     26 class ContentSettingGeolocationImageModel : public ContentSettingImageModel {
     27  public:
     28   ContentSettingGeolocationImageModel();
     29 
     30   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     31 };
     32 
     33 // Image model for displaying media icons in the location bar.
     34 class ContentSettingMediaImageModel : public ContentSettingImageModel {
     35  public:
     36   explicit ContentSettingMediaImageModel(ContentSettingsType type);
     37 
     38   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     39 };
     40 
     41 class ContentSettingRPHImageModel : public ContentSettingImageModel {
     42  public:
     43   ContentSettingRPHImageModel();
     44 
     45   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     46 };
     47 
     48 class ContentSettingNotificationsImageModel : public ContentSettingImageModel {
     49  public:
     50   ContentSettingNotificationsImageModel();
     51 
     52   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     53 };
     54 
     55 class ContentSettingMIDISysExImageModel : public ContentSettingImageModel {
     56  public:
     57   ContentSettingMIDISysExImageModel();
     58 
     59   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
     60 };
     61 
     62 namespace {
     63 
     64 struct ContentSettingsTypeIdEntry {
     65   ContentSettingsType type;
     66   int id;
     67 };
     68 
     69 int GetIdForContentType(const ContentSettingsTypeIdEntry* entries,
     70                         size_t num_entries,
     71                         ContentSettingsType type) {
     72   for (size_t i = 0; i < num_entries; ++i) {
     73     if (entries[i].type == type)
     74       return entries[i].id;
     75   }
     76   return 0;
     77 }
     78 
     79 }  // namespace
     80 
     81 ContentSettingBlockedImageModel::ContentSettingBlockedImageModel(
     82     ContentSettingsType content_settings_type)
     83     : ContentSettingImageModel(content_settings_type) {
     84 }
     85 
     86 void ContentSettingBlockedImageModel::UpdateFromWebContents(
     87     WebContents* web_contents) {
     88   set_visible(false);
     89   if (!web_contents)
     90     return;
     91 
     92   static const ContentSettingsTypeIdEntry kBlockedIconIDs[] = {
     93     {CONTENT_SETTINGS_TYPE_COOKIES, IDR_BLOCKED_COOKIES},
     94     {CONTENT_SETTINGS_TYPE_IMAGES, IDR_BLOCKED_IMAGES},
     95     {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDR_BLOCKED_JAVASCRIPT},
     96     {CONTENT_SETTINGS_TYPE_PLUGINS, IDR_BLOCKED_PLUGINS},
     97     {CONTENT_SETTINGS_TYPE_POPUPS, IDR_BLOCKED_POPUPS},
     98     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDR_BLOCKED_MIXED_CONTENT},
     99     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
    100     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_BLOCKED_DOWNLOADS},
    101   };
    102   static const ContentSettingsTypeIdEntry kBlockedTooltipIDs[] = {
    103     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_TITLE},
    104     {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_TITLE},
    105     {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_TITLE},
    106     {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_MESSAGE},
    107     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_TOOLTIP},
    108     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
    109         IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT},
    110     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE},
    111     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE},
    112   };
    113   static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs[] = {
    114     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT},
    115     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
    116         IDS_BLOCKED_DOWNLOADS_EXPLANATION},
    117   };
    118 
    119   ContentSettingsType type = get_content_settings_type();
    120   int icon_id = GetIdForContentType(
    121       kBlockedIconIDs, arraysize(kBlockedIconIDs), type);
    122   int tooltip_id = GetIdForContentType(
    123       kBlockedTooltipIDs, arraysize(kBlockedTooltipIDs), type);
    124   int explanation_id = GetIdForContentType(
    125       kBlockedExplanatoryTextIDs, arraysize(kBlockedExplanatoryTextIDs), type);
    126 
    127   // If a content type is blocked by default and was accessed, display the
    128   // accessed icon.
    129   TabSpecificContentSettings* content_settings =
    130       TabSpecificContentSettings::FromWebContents(web_contents);
    131   if (!content_settings)
    132     return;
    133   Profile* profile =
    134       Profile::FromBrowserContext(web_contents->GetBrowserContext());
    135   if (!content_settings->IsContentBlocked(get_content_settings_type())) {
    136     if (!content_settings->IsContentAllowed(get_content_settings_type()))
    137       return;
    138 
    139     // For cookies, only show the accessed bubble if cookies are blocked by
    140     // default.
    141     if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_COOKIES &&
    142         (profile->GetHostContentSettingsMap()->
    143             GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES, NULL) !=
    144                 CONTENT_SETTING_BLOCK))
    145       return;
    146 
    147     static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = {
    148       {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES},
    149       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
    150       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS},
    151     };
    152     static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = {
    153       {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
    154       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
    155       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
    156     };
    157     icon_id = GetIdForContentType(
    158         kAccessedIconIDs, arraysize(kAccessedIconIDs), type);
    159     tooltip_id = GetIdForContentType(
    160         kAccessedTooltipIDs, arraysize(kAccessedTooltipIDs), type);
    161     explanation_id = 0;
    162   }
    163   set_visible(true);
    164   DCHECK(icon_id);
    165   set_icon(icon_id);
    166   set_explanatory_string_id(explanation_id);
    167   DCHECK(tooltip_id);
    168   set_tooltip(l10n_util::GetStringUTF8(tooltip_id));
    169 }
    170 
    171 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
    172     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) {
    173 }
    174 
    175 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
    176     WebContents* web_contents) {
    177   set_visible(false);
    178   if (!web_contents)
    179     return;
    180   TabSpecificContentSettings* content_settings =
    181       TabSpecificContentSettings::FromWebContents(web_contents);
    182   if (!content_settings)
    183     return;
    184   const ContentSettingsUsagesState& usages_state = content_settings->
    185       geolocation_usages_state();
    186   if (usages_state.state_map().empty())
    187     return;
    188   set_visible(true);
    189 
    190   // If any embedded site has access the allowed icon takes priority over the
    191   // blocked icon.
    192   unsigned int state_flags = 0;
    193   usages_state.GetDetailedInfo(NULL, &state_flags);
    194   bool allowed =
    195       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
    196   set_icon(allowed ? IDR_ALLOWED_LOCATION : IDR_BLOCKED_LOCATION);
    197   set_tooltip(l10n_util::GetStringUTF8(allowed ?
    198       IDS_GEOLOCATION_ALLOWED_TOOLTIP : IDS_GEOLOCATION_BLOCKED_TOOLTIP));
    199 }
    200 
    201 ContentSettingMediaImageModel::ContentSettingMediaImageModel(
    202     ContentSettingsType type)
    203     : ContentSettingImageModel(type) {
    204 }
    205 
    206 void ContentSettingMediaImageModel::UpdateFromWebContents(
    207     WebContents* web_contents) {
    208   set_visible(false);
    209 
    210   // As long as a single icon is used to display the status of the camera and
    211   // microphone usage only display an icon for the
    212   // CONTENT_SETTINGS_TYPE_MEDIASTREAM. Don't display anything for
    213   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    214   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
    215   // FIXME: Remove this hack and either display a two omnibox icons (one for
    216   // camera and one for microphone), or don't create one image model per
    217   // content type but per icon to display. The later is probably the right
    218   // thing to do, bebacuse this also allows to add more content settings type
    219   // for which no omnibox icon exists.
    220   if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
    221       get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
    222     return;
    223   }
    224 
    225   // The ContentSettingMediaImageModel must not be used with a content type
    226   // other then: CONTENT_SETTINGS_TYPE_MEDIASTREAM,
    227   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    228   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
    229   DCHECK_EQ(get_content_settings_type(), CONTENT_SETTINGS_TYPE_MEDIASTREAM);
    230 
    231   if (!web_contents)
    232     return;
    233 
    234   TabSpecificContentSettings* content_settings =
    235       TabSpecificContentSettings::FromWebContents(web_contents);
    236   if (!content_settings)
    237     return;
    238   TabSpecificContentSettings::MicrophoneCameraState state =
    239       content_settings->GetMicrophoneCameraState();
    240 
    241   switch (state) {
    242     case TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED:
    243       // If neither the microphone nor the camera stream was accessed then no
    244       // icon is displayed in the omnibox.
    245       return;
    246     case TabSpecificContentSettings::MICROPHONE_ACCESSED:
    247       set_icon(IDR_ASK_MEDIA);
    248       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
    249       break;
    250     case TabSpecificContentSettings::CAMERA_ACCESSED:
    251       set_icon(IDR_ASK_MEDIA);
    252       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED));
    253       break;
    254     case TabSpecificContentSettings::MICROPHONE_CAMERA_ACCESSED:
    255       set_icon(IDR_ASK_MEDIA);
    256       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
    257       break;
    258     case TabSpecificContentSettings::MICROPHONE_BLOCKED:
    259       set_icon(IDR_BLOCKED_MEDIA);
    260       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
    261       break;
    262     case TabSpecificContentSettings::CAMERA_BLOCKED:
    263       set_icon(IDR_BLOCKED_MEDIA);
    264       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED));
    265       break;
    266     case TabSpecificContentSettings::MICROPHONE_CAMERA_BLOCKED:
    267       set_icon(IDR_BLOCKED_MEDIA);
    268       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_BLOCKED));
    269       break;
    270   }
    271   set_visible(true);
    272 }
    273 
    274 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
    275     : ContentSettingImageModel(
    276         CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
    277   set_icon(IDR_REGISTER_PROTOCOL_HANDLER);
    278   set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
    279 }
    280 
    281 void ContentSettingRPHImageModel::UpdateFromWebContents(
    282     WebContents* web_contents) {
    283   set_visible(false);
    284   if (!web_contents)
    285     return;
    286 
    287   TabSpecificContentSettings* content_settings =
    288       TabSpecificContentSettings::FromWebContents(web_contents);
    289   if (!content_settings)
    290     return;
    291   if (content_settings->pending_protocol_handler().IsEmpty())
    292     return;
    293 
    294   set_visible(true);
    295 }
    296 
    297 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
    298     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
    299 }
    300 
    301 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
    302     WebContents* web_contents) {
    303   // Notifications do not have a bubble.
    304   set_visible(false);
    305 }
    306 
    307 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
    308     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
    309 }
    310 
    311 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
    312     WebContents* web_contents) {
    313   set_visible(false);
    314   if (!web_contents)
    315     return;
    316   TabSpecificContentSettings* content_settings =
    317       TabSpecificContentSettings::FromWebContents(web_contents);
    318   if (!content_settings)
    319     return;
    320   const ContentSettingsUsagesState& usages_state =
    321       content_settings->midi_usages_state();
    322   if (usages_state.state_map().empty())
    323     return;
    324   set_visible(true);
    325 
    326   // If any embedded site has access the allowed icon takes priority over the
    327   // blocked icon.
    328   unsigned int state_flags = 0;
    329   usages_state.GetDetailedInfo(NULL, &state_flags);
    330   bool allowed =
    331       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
    332   set_icon(allowed ? IDR_ALLOWED_MIDI_SYSEX : IDR_BLOCKED_MIDI_SYSEX);
    333   set_tooltip(l10n_util::GetStringUTF8(allowed ?
    334       IDS_MIDI_SYSEX_ALLOWED_TOOLTIP : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP));
    335 }
    336 
    337 ContentSettingImageModel::ContentSettingImageModel(
    338     ContentSettingsType content_settings_type)
    339     : content_settings_type_(content_settings_type),
    340       is_visible_(false),
    341       icon_(0),
    342       explanatory_string_id_(0) {
    343 }
    344 
    345 // static
    346 ContentSettingImageModel*
    347     ContentSettingImageModel::CreateContentSettingImageModel(
    348     ContentSettingsType content_settings_type) {
    349   switch (content_settings_type) {
    350     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
    351       return new ContentSettingGeolocationImageModel();
    352     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
    353       return new ContentSettingNotificationsImageModel();
    354     case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
    355       return new ContentSettingRPHImageModel();
    356     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
    357     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
    358     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
    359       return new ContentSettingMediaImageModel(content_settings_type);
    360     case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
    361       return new ContentSettingMIDISysExImageModel();
    362     default:
    363       return new ContentSettingBlockedImageModel(content_settings_type);
    364   }
    365 }
    366