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 "chrome/grit/generated_resources.h" 12#include "content/public/browser/web_contents.h" 13#include "grit/theme_resources.h" 14#include "ui/base/l10n/l10n_util.h" 15 16using content::WebContents; 17 18class ContentSettingBlockedImageModel : public ContentSettingImageModel { 19 public: 20 explicit ContentSettingBlockedImageModel( 21 ContentSettingsType content_settings_type); 22 23 virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE; 24}; 25 26class 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. 34class ContentSettingMediaImageModel : public ContentSettingImageModel { 35 public: 36 explicit ContentSettingMediaImageModel(ContentSettingsType type); 37 38 virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE; 39}; 40 41class ContentSettingRPHImageModel : public ContentSettingImageModel { 42 public: 43 ContentSettingRPHImageModel(); 44 45 virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE; 46}; 47 48class ContentSettingNotificationsImageModel : public ContentSettingImageModel { 49 public: 50 ContentSettingNotificationsImageModel(); 51 52 virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE; 53}; 54 55class ContentSettingMIDISysExImageModel : public ContentSettingImageModel { 56 public: 57 ContentSettingMIDISysExImageModel(); 58 59 virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE; 60}; 61 62namespace { 63 64struct ContentSettingsTypeIdEntry { 65 ContentSettingsType type; 66 int id; 67}; 68 69int 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 81ContentSettingBlockedImageModel::ContentSettingBlockedImageModel( 82 ContentSettingsType content_settings_type) 83 : ContentSettingImageModel(content_settings_type) { 84} 85 86void 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 181ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel() 182 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) { 183} 184 185void 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 211ContentSettingMediaImageModel::ContentSettingMediaImageModel( 212 ContentSettingsType type) 213 : ContentSettingImageModel(type) { 214} 215 216void 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 284ContentSettingRPHImageModel::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 291void 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 307ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel() 308 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { 309} 310 311void ContentSettingNotificationsImageModel::UpdateFromWebContents( 312 WebContents* web_contents) { 313 // Notifications do not have a bubble. 314 set_visible(false); 315} 316 317ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel() 318 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) { 319} 320 321void 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 347ContentSettingImageModel::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 356ContentSettingImageModel* 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