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_PLUGINS, IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT},
    116     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
    117         IDS_BLOCKED_DOWNLOADS_EXPLANATION},
    118   };
    119 
    120   ContentSettingsType type = get_content_settings_type();
    121   int icon_id = GetIdForContentType(
    122       kBlockedIconIDs, arraysize(kBlockedIconIDs), type);
    123   int tooltip_id = GetIdForContentType(
    124       kBlockedTooltipIDs, arraysize(kBlockedTooltipIDs), type);
    125   int explanation_id = GetIdForContentType(
    126       kBlockedExplanatoryTextIDs, arraysize(kBlockedExplanatoryTextIDs), type);
    127 
    128   // For plugins, don't show the animated explanation unless the plugin was
    129   // blocked despite the user's content settings being set to allow it (e.g.
    130   // due to auto-blocking NPAPI plugins).
    131   Profile* profile =
    132       Profile::FromBrowserContext(web_contents->GetBrowserContext());
    133   HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
    134   if (type == CONTENT_SETTINGS_TYPE_PLUGINS) {
    135     GURL url = web_contents->GetURL();
    136     if (map->GetContentSetting(url, url, type, std::string()) !=
    137         CONTENT_SETTING_ALLOW)
    138       explanation_id = 0;
    139   }
    140 
    141   // If a content type is blocked by default and was accessed, display the
    142   // content blocked page action.
    143   TabSpecificContentSettings* content_settings =
    144       TabSpecificContentSettings::FromWebContents(web_contents);
    145   if (!content_settings)
    146     return;
    147   if (!content_settings->IsContentBlocked(type)) {
    148     if (!content_settings->IsContentAllowed(type))
    149       return;
    150 
    151     // For cookies, only show the cookie blocked page action if cookies are
    152     // blocked by default.
    153     if (type == CONTENT_SETTINGS_TYPE_COOKIES &&
    154         (map->GetDefaultContentSetting(type, NULL) != CONTENT_SETTING_BLOCK))
    155       return;
    156 
    157     static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = {
    158       {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES},
    159       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
    160       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS},
    161     };
    162     static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = {
    163       {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
    164       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
    165       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
    166     };
    167     icon_id = GetIdForContentType(
    168         kAccessedIconIDs, arraysize(kAccessedIconIDs), type);
    169     tooltip_id = GetIdForContentType(
    170         kAccessedTooltipIDs, arraysize(kAccessedTooltipIDs), type);
    171     explanation_id = 0;
    172   }
    173   set_visible(true);
    174   DCHECK(icon_id);
    175   set_icon(icon_id);
    176   set_explanatory_string_id(explanation_id);
    177   DCHECK(tooltip_id);
    178   set_tooltip(l10n_util::GetStringUTF8(tooltip_id));
    179 }
    180 
    181 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
    182     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) {
    183 }
    184 
    185 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
    186     WebContents* web_contents) {
    187   set_visible(false);
    188   if (!web_contents)
    189     return;
    190   TabSpecificContentSettings* content_settings =
    191       TabSpecificContentSettings::FromWebContents(web_contents);
    192   if (!content_settings)
    193     return;
    194   const ContentSettingsUsagesState& usages_state = content_settings->
    195       geolocation_usages_state();
    196   if (usages_state.state_map().empty())
    197     return;
    198   set_visible(true);
    199 
    200   // If any embedded site has access the allowed icon takes priority over the
    201   // blocked icon.
    202   unsigned int state_flags = 0;
    203   usages_state.GetDetailedInfo(NULL, &state_flags);
    204   bool allowed =
    205       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
    206   set_icon(allowed ? IDR_ALLOWED_LOCATION : IDR_BLOCKED_LOCATION);
    207   set_tooltip(l10n_util::GetStringUTF8(allowed ?
    208       IDS_GEOLOCATION_ALLOWED_TOOLTIP : IDS_GEOLOCATION_BLOCKED_TOOLTIP));
    209 }
    210 
    211 ContentSettingMediaImageModel::ContentSettingMediaImageModel(
    212     ContentSettingsType type)
    213     : ContentSettingImageModel(type) {
    214 }
    215 
    216 void ContentSettingMediaImageModel::UpdateFromWebContents(
    217     WebContents* web_contents) {
    218   set_visible(false);
    219 
    220   // As long as a single icon is used to display the status of the camera and
    221   // microphone usage only display an icon for the
    222   // CONTENT_SETTINGS_TYPE_MEDIASTREAM. Don't display anything for
    223   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    224   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
    225   // FIXME: Remove this hack and either display a two omnibox icons (one for
    226   // camera and one for microphone), or don't create one image model per
    227   // content type but per icon to display. The later is probably the right
    228   // thing to do, bebacuse this also allows to add more content settings type
    229   // for which no omnibox icon exists.
    230   if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
    231       get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
    232     return;
    233   }
    234 
    235   // The ContentSettingMediaImageModel must not be used with a content type
    236   // other then: CONTENT_SETTINGS_TYPE_MEDIASTREAM,
    237   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
    238   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
    239   DCHECK_EQ(get_content_settings_type(), CONTENT_SETTINGS_TYPE_MEDIASTREAM);
    240 
    241   if (!web_contents)
    242     return;
    243 
    244   TabSpecificContentSettings* content_settings =
    245       TabSpecificContentSettings::FromWebContents(web_contents);
    246   if (!content_settings)
    247     return;
    248   TabSpecificContentSettings::MicrophoneCameraState state =
    249       content_settings->GetMicrophoneCameraState();
    250 
    251   switch (state) {
    252     case TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED:
    253       // If neither the microphone nor the camera stream was accessed then no
    254       // icon is displayed in the omnibox.
    255       return;
    256     case TabSpecificContentSettings::MICROPHONE_ACCESSED:
    257       set_icon(IDR_ASK_MEDIA);
    258       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
    259       break;
    260     case TabSpecificContentSettings::CAMERA_ACCESSED:
    261       set_icon(IDR_ASK_MEDIA);
    262       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED));
    263       break;
    264     case TabSpecificContentSettings::MICROPHONE_CAMERA_ACCESSED:
    265       set_icon(IDR_ASK_MEDIA);
    266       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
    267       break;
    268     case TabSpecificContentSettings::MICROPHONE_BLOCKED:
    269       set_icon(IDR_BLOCKED_MEDIA);
    270       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
    271       break;
    272     case TabSpecificContentSettings::CAMERA_BLOCKED:
    273       set_icon(IDR_BLOCKED_MEDIA);
    274       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED));
    275       break;
    276     case TabSpecificContentSettings::MICROPHONE_CAMERA_BLOCKED:
    277       set_icon(IDR_BLOCKED_MEDIA);
    278       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_BLOCKED));
    279       break;
    280   }
    281   set_visible(true);
    282 }
    283 
    284 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
    285     : ContentSettingImageModel(
    286         CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
    287   set_icon(IDR_REGISTER_PROTOCOL_HANDLER);
    288   set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
    289 }
    290 
    291 void ContentSettingRPHImageModel::UpdateFromWebContents(
    292     WebContents* web_contents) {
    293   set_visible(false);
    294   if (!web_contents)
    295     return;
    296 
    297   TabSpecificContentSettings* content_settings =
    298       TabSpecificContentSettings::FromWebContents(web_contents);
    299   if (!content_settings)
    300     return;
    301   if (content_settings->pending_protocol_handler().IsEmpty())
    302     return;
    303 
    304   set_visible(true);
    305 }
    306 
    307 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
    308     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
    309 }
    310 
    311 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
    312     WebContents* web_contents) {
    313   // Notifications do not have a bubble.
    314   set_visible(false);
    315 }
    316 
    317 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
    318     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
    319 }
    320 
    321 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
    322     WebContents* web_contents) {
    323   set_visible(false);
    324   if (!web_contents)
    325     return;
    326   TabSpecificContentSettings* content_settings =
    327       TabSpecificContentSettings::FromWebContents(web_contents);
    328   if (!content_settings)
    329     return;
    330   const ContentSettingsUsagesState& usages_state =
    331       content_settings->midi_usages_state();
    332   if (usages_state.state_map().empty())
    333     return;
    334   set_visible(true);
    335 
    336   // If any embedded site has access the allowed icon takes priority over the
    337   // blocked icon.
    338   unsigned int state_flags = 0;
    339   usages_state.GetDetailedInfo(NULL, &state_flags);
    340   bool allowed =
    341       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
    342   set_icon(allowed ? IDR_ALLOWED_MIDI_SYSEX : IDR_BLOCKED_MIDI_SYSEX);
    343   set_tooltip(l10n_util::GetStringUTF8(allowed ?
    344       IDS_MIDI_SYSEX_ALLOWED_TOOLTIP : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP));
    345 }
    346 
    347 ContentSettingImageModel::ContentSettingImageModel(
    348     ContentSettingsType content_settings_type)
    349     : content_settings_type_(content_settings_type),
    350       is_visible_(false),
    351       icon_(0),
    352       explanatory_string_id_(0) {
    353 }
    354 
    355 // static
    356 ContentSettingImageModel*
    357     ContentSettingImageModel::CreateContentSettingImageModel(
    358     ContentSettingsType content_settings_type) {
    359   switch (content_settings_type) {
    360     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
    361       return new ContentSettingGeolocationImageModel();
    362     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
    363       return new ContentSettingNotificationsImageModel();
    364     case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
    365       return new ContentSettingRPHImageModel();
    366     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
    367     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
    368     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
    369       return new ContentSettingMediaImageModel(content_settings_type);
    370     case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
    371       return new ContentSettingMIDISysExImageModel();
    372     default:
    373       return new ContentSettingBlockedImageModel(content_settings_type);
    374   }
    375 }
    376