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.
5 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
7 #include "chrome/browser/content_settings/host_content_settings_map_factory.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 "components/content_settings/core/browser/host_content_settings_map.h"
13 #include "content/public/browser/web_contents.h"
14 #include "grit/theme_resources.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/resource/material_design/material_design_controller.h"
17 #include "ui/base/resource/resource_bundle.h"
19 #if !defined(OS_MACOSX)
20 #include "ui/gfx/paint_vector_icon.h"
21 #include "ui/gfx/vector_icons_public.h"
22 #include "ui/native_theme/common_theme.h"
23 #include "ui/native_theme/native_theme.h"
26 using content::WebContents
;
30 bool UseVectorGraphics() {
31 #if defined(OS_MACOSX)
34 return ui::MaterialDesignController::IsModeMaterial();
38 #if !defined(OS_MACOSX)
39 // Gets a vector icon badged with |badge|.
40 gfx::Image
GetIcon(gfx::VectorIconId id
, gfx::VectorIconId badge
) {
42 ui::CommonThemeGetSystemColor(ui::NativeTheme::kColorId_ChromeIconGrey
,
44 return gfx::Image(gfx::CreateVectorIconWithBadge(id
, 16, icon_color
, badge
));
50 class ContentSettingBlockedImageModel
: public ContentSettingImageModel
{
52 explicit ContentSettingBlockedImageModel(
53 ContentSettingsType content_settings_type
);
55 void UpdateFromWebContents(WebContents
* web_contents
) override
;
58 class ContentSettingGeolocationImageModel
: public ContentSettingImageModel
{
60 ContentSettingGeolocationImageModel();
62 void UpdateFromWebContents(WebContents
* web_contents
) override
;
65 // Image model for displaying media icons in the location bar.
66 class ContentSettingMediaImageModel
: public ContentSettingImageModel
{
68 explicit ContentSettingMediaImageModel(ContentSettingsType type
);
70 void UpdateFromWebContents(WebContents
* web_contents
) override
;
73 class ContentSettingRPHImageModel
: public ContentSettingImageModel
{
75 ContentSettingRPHImageModel();
77 void UpdateFromWebContents(WebContents
* web_contents
) override
;
80 class ContentSettingNotificationsImageModel
: public ContentSettingImageModel
{
82 ContentSettingNotificationsImageModel();
84 void UpdateFromWebContents(WebContents
* web_contents
) override
;
87 class ContentSettingMIDISysExImageModel
: public ContentSettingImageModel
{
89 ContentSettingMIDISysExImageModel();
91 void UpdateFromWebContents(WebContents
* web_contents
) override
;
96 struct ContentSettingsTypeIdEntry
{
97 ContentSettingsType type
;
101 int GetIdForContentType(const ContentSettingsTypeIdEntry
* entries
,
103 ContentSettingsType type
) {
104 for (size_t i
= 0; i
< num_entries
; ++i
) {
105 if (entries
[i
].type
== type
)
106 return entries
[i
].id
;
113 ContentSettingBlockedImageModel::ContentSettingBlockedImageModel(
114 ContentSettingsType content_settings_type
)
115 : ContentSettingImageModel(content_settings_type
) {
118 void ContentSettingBlockedImageModel::UpdateFromWebContents(
119 WebContents
* web_contents
) {
124 ContentSettingsType type
= get_content_settings_type();
125 static const ContentSettingsTypeIdEntry kBlockedIconIDs
[] = {
126 {CONTENT_SETTINGS_TYPE_COOKIES
, IDR_BLOCKED_COOKIES
},
127 {CONTENT_SETTINGS_TYPE_IMAGES
, IDR_BLOCKED_IMAGES
},
128 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDR_BLOCKED_JAVASCRIPT
},
129 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDR_BLOCKED_PLUGINS
},
130 {CONTENT_SETTINGS_TYPE_POPUPS
, IDR_BLOCKED_POPUPS
},
131 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
, IDR_BLOCKED_MIXED_CONTENT
},
132 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDR_BLOCKED_PPAPI_BROKER
},
133 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDR_BLOCKED_DOWNLOADS
},
136 GetIdForContentType(kBlockedIconIDs
, arraysize(kBlockedIconIDs
), type
);
138 #if !defined(OS_MACOSX)
139 gfx::VectorIconId vector_icon_id
= gfx::VectorIconId::VECTOR_ICON_NONE
;
141 case CONTENT_SETTINGS_TYPE_COOKIES
:
142 vector_icon_id
= gfx::VectorIconId::COOKIE
;
144 case CONTENT_SETTINGS_TYPE_IMAGES
:
145 vector_icon_id
= gfx::VectorIconId::IMAGE
;
147 case CONTENT_SETTINGS_TYPE_JAVASCRIPT
:
148 vector_icon_id
= gfx::VectorIconId::CODE
;
150 case CONTENT_SETTINGS_TYPE_PLUGINS
:
151 vector_icon_id
= gfx::VectorIconId::EXTENSION
;
153 case CONTENT_SETTINGS_TYPE_POPUPS
:
154 vector_icon_id
= gfx::VectorIconId::WEB
;
156 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
:
157 vector_icon_id
= gfx::VectorIconId::MIXED_CONTENT
;
159 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER
:
160 vector_icon_id
= gfx::VectorIconId::EXTENSION
;
162 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
:
163 vector_icon_id
= gfx::VectorIconId::FILE_DOWNLOAD
;
166 // If we didn't find a vector icon ID we shouldn't have found an
168 DCHECK_EQ(0, icon_id
);
173 static const ContentSettingsTypeIdEntry kBlockedTooltipIDs
[] = {
174 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_BLOCKED_COOKIES_TITLE
},
175 {CONTENT_SETTINGS_TYPE_IMAGES
, IDS_BLOCKED_IMAGES_TITLE
},
176 {CONTENT_SETTINGS_TYPE_JAVASCRIPT
, IDS_BLOCKED_JAVASCRIPT_TITLE
},
177 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGINS_MESSAGE
},
178 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_TOOLTIP
},
179 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT
,
180 IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT
},
181 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_BLOCKED_PPAPI_BROKER_TITLE
},
182 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_BLOCKED_DOWNLOAD_TITLE
},
184 int tooltip_id
= GetIdForContentType(kBlockedTooltipIDs
,
185 arraysize(kBlockedTooltipIDs
), type
);
187 static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs
[] = {
188 {CONTENT_SETTINGS_TYPE_POPUPS
, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT
},
189 {CONTENT_SETTINGS_TYPE_PLUGINS
, IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT
},
190 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
,
191 IDS_BLOCKED_DOWNLOADS_EXPLANATION
},
193 int explanation_id
= GetIdForContentType(
194 kBlockedExplanatoryTextIDs
, arraysize(kBlockedExplanatoryTextIDs
), type
);
196 // For plugins, don't show the animated explanation unless the plugin was
197 // blocked despite the user's content settings being set to allow it (e.g.
198 // due to auto-blocking NPAPI plugins).
200 Profile::FromBrowserContext(web_contents
->GetBrowserContext());
201 HostContentSettingsMap
* map
=
202 HostContentSettingsMapFactory::GetForProfile(profile
);
203 if (type
== CONTENT_SETTINGS_TYPE_PLUGINS
) {
204 GURL url
= web_contents
->GetURL();
205 if (map
->GetContentSetting(url
, url
, type
, std::string()) !=
206 CONTENT_SETTING_ALLOW
)
210 // If a content type is blocked by default and was accessed, display the
211 // content blocked page action.
212 TabSpecificContentSettings
* content_settings
=
213 TabSpecificContentSettings::FromWebContents(web_contents
);
214 if (!content_settings
)
216 if (!content_settings
->IsContentBlocked(type
)) {
217 if (!content_settings
->IsContentAllowed(type
))
220 // For cookies, only show the cookie blocked page action if cookies are
221 // blocked by default.
222 if (type
== CONTENT_SETTINGS_TYPE_COOKIES
&&
223 (map
->GetDefaultContentSetting(type
, NULL
) != CONTENT_SETTING_BLOCK
))
226 static const ContentSettingsTypeIdEntry kAccessedIconIDs
[] = {
227 {CONTENT_SETTINGS_TYPE_COOKIES
, IDR_ACCESSED_COOKIES
},
228 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDR_BLOCKED_PPAPI_BROKER
},
229 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDR_ALLOWED_DOWNLOADS
},
231 icon_id
= GetIdForContentType(kAccessedIconIDs
, arraysize(kAccessedIconIDs
),
233 static const ContentSettingsTypeIdEntry kAccessedTooltipIDs
[] = {
234 {CONTENT_SETTINGS_TYPE_COOKIES
, IDS_ACCESSED_COOKIES_TITLE
},
235 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, IDS_ALLOWED_PPAPI_BROKER_TITLE
},
236 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS
, IDS_ALLOWED_DOWNLOAD_TITLE
},
238 tooltip_id
= GetIdForContentType(
239 kAccessedTooltipIDs
, arraysize(kAccessedTooltipIDs
), type
);
243 if (!UseVectorGraphics()) {
245 SetIconByResourceId(icon_id
);
246 #if !defined(OS_MACOSX)
248 DCHECK(gfx::VectorIconId::VECTOR_ICON_NONE
!= vector_icon_id
);
250 if (type
== CONTENT_SETTINGS_TYPE_PPAPI_BROKER
) {
251 set_icon(GetIcon(vector_icon_id
, gfx::VectorIconId::WARNING_BADGE
));
253 SetIconByVectorId(vector_icon_id
,
254 content_settings
->IsContentBlocked(type
));
258 set_explanatory_string_id(explanation_id
);
260 set_tooltip(l10n_util::GetStringUTF8(tooltip_id
));
263 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
264 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION
) {
267 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
268 WebContents
* web_contents
) {
272 TabSpecificContentSettings
* content_settings
=
273 TabSpecificContentSettings::FromWebContents(web_contents
);
274 if (!content_settings
)
276 const ContentSettingsUsagesState
& usages_state
= content_settings
->
277 geolocation_usages_state();
278 if (usages_state
.state_map().empty())
282 // If any embedded site has access the allowed icon takes priority over the
284 unsigned int state_flags
= 0;
285 usages_state
.GetDetailedInfo(NULL
, &state_flags
);
287 !!(state_flags
& ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED
);
288 if (!UseVectorGraphics())
289 SetIconByResourceId(allowed
? IDR_ALLOWED_LOCATION
: IDR_BLOCKED_LOCATION
);
290 #if !defined(OS_MACOSX)
292 SetIconByVectorId(gfx::VectorIconId::MY_LOCATION
, !allowed
);
294 set_tooltip(l10n_util::GetStringUTF8(allowed
?
295 IDS_GEOLOCATION_ALLOWED_TOOLTIP
: IDS_GEOLOCATION_BLOCKED_TOOLTIP
));
298 ContentSettingMediaImageModel::ContentSettingMediaImageModel(
299 ContentSettingsType type
)
300 : ContentSettingImageModel(type
) {
303 void ContentSettingMediaImageModel::UpdateFromWebContents(
304 WebContents
* web_contents
) {
307 // As long as a single icon is used to display the status of the camera and
308 // microphone usage only display an icon for the
309 // CONTENT_SETTINGS_TYPE_MEDIASTREAM. Don't display anything for
310 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
311 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
312 // FIXME: Remove this hack and either display a two omnibox icons (one for
313 // camera and one for microphone), or don't create one image model per
314 // content type but per icon to display. The later is probably the right
315 // thing to do, bebacuse this also allows to add more content settings type
316 // for which no omnibox icon exists.
317 if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
||
318 get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
) {
322 // The ContentSettingMediaImageModel must not be used with a content type
323 // other then: CONTENT_SETTINGS_TYPE_MEDIASTREAM,
324 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
325 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
326 DCHECK_EQ(get_content_settings_type(), CONTENT_SETTINGS_TYPE_MEDIASTREAM
);
331 TabSpecificContentSettings
* content_settings
=
332 TabSpecificContentSettings::FromWebContents(web_contents
);
333 if (!content_settings
)
335 TabSpecificContentSettings::MicrophoneCameraState state
=
336 content_settings
->GetMicrophoneCameraState();
338 // If neither the microphone nor the camera stream was accessed then no icon
339 // is displayed in the omnibox.
340 if (state
== TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED
)
343 bool is_mic
= (state
& TabSpecificContentSettings::MICROPHONE_ACCESSED
) != 0;
344 bool is_cam
= (state
& TabSpecificContentSettings::CAMERA_ACCESSED
) != 0;
345 DCHECK(is_mic
|| is_cam
);
347 int id
= IDS_CAMERA_BLOCKED
;
348 if (state
& (TabSpecificContentSettings::MICROPHONE_BLOCKED
|
349 TabSpecificContentSettings::CAMERA_BLOCKED
)) {
350 if (!UseVectorGraphics())
351 SetIconByResourceId(IDR_BLOCKED_CAMERA
);
352 #if !defined(OS_MACOSX)
354 SetIconByVectorId(gfx::VectorIconId::VIDEOCAM
, true);
357 id
= is_cam
? IDS_MICROPHONE_CAMERA_BLOCKED
: IDS_MICROPHONE_BLOCKED
;
359 if (!UseVectorGraphics())
360 SetIconByResourceId(IDR_ALLOWED_CAMERA
);
361 #if !defined(OS_MACOSX)
363 SetIconByVectorId(gfx::VectorIconId::VIDEOCAM
, false);
365 id
= IDS_CAMERA_ACCESSED
;
367 id
= is_cam
? IDS_MICROPHONE_CAMERA_ALLOWED
: IDS_MICROPHONE_ACCESSED
;
369 set_tooltip(l10n_util::GetStringUTF8(id
));
373 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
374 : ContentSettingImageModel(
375 CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
) {
376 if (!UseVectorGraphics())
377 SetIconByResourceId(IDR_REGISTER_PROTOCOL_HANDLER
);
378 #if !defined(OS_MACOSX)
380 SetIconByVectorId(gfx::VectorIconId::PROTOCOL_HANDLER
, false);
382 set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP
));
385 void ContentSettingRPHImageModel::UpdateFromWebContents(
386 WebContents
* web_contents
) {
391 TabSpecificContentSettings
* content_settings
=
392 TabSpecificContentSettings::FromWebContents(web_contents
);
393 if (!content_settings
)
395 if (content_settings
->pending_protocol_handler().IsEmpty())
401 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
402 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
) {
405 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
406 WebContents
* web_contents
) {
407 // Notifications do not have a bubble.
411 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
412 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
) {
415 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
416 WebContents
* web_contents
) {
420 TabSpecificContentSettings
* content_settings
=
421 TabSpecificContentSettings::FromWebContents(web_contents
);
422 if (!content_settings
)
424 const ContentSettingsUsagesState
& usages_state
=
425 content_settings
->midi_usages_state();
426 if (usages_state
.state_map().empty())
430 // If any embedded site has access the allowed icon takes priority over the
432 unsigned int state_flags
= 0;
433 usages_state
.GetDetailedInfo(NULL
, &state_flags
);
435 !!(state_flags
& ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED
);
436 #if defined(OS_MACOSX)
437 SetIconByResourceId(allowed
? IDR_ALLOWED_MIDI_SYSEX
438 : IDR_BLOCKED_MIDI_SYSEX
);
440 SetIconByVectorId(gfx::VectorIconId::MIDI
, !allowed
);
442 set_tooltip(l10n_util::GetStringUTF8(allowed
?
443 IDS_MIDI_SYSEX_ALLOWED_TOOLTIP
: IDS_MIDI_SYSEX_BLOCKED_TOOLTIP
));
446 ContentSettingImageModel::ContentSettingImageModel(
447 ContentSettingsType content_settings_type
)
448 : content_settings_type_(content_settings_type
),
451 explanatory_string_id_(0) {
455 ContentSettingImageModel
*
456 ContentSettingImageModel::CreateContentSettingImageModel(
457 ContentSettingsType content_settings_type
) {
458 switch (content_settings_type
) {
459 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
460 return new ContentSettingGeolocationImageModel();
461 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
462 return new ContentSettingNotificationsImageModel();
463 case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS
:
464 return new ContentSettingRPHImageModel();
465 case CONTENT_SETTINGS_TYPE_MEDIASTREAM
:
466 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
:
467 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA
:
468 return new ContentSettingMediaImageModel(content_settings_type
);
469 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
470 return new ContentSettingMIDISysExImageModel();
472 return new ContentSettingBlockedImageModel(content_settings_type
);
476 void ContentSettingImageModel::SetIconByResourceId(int id
) {
478 icon_
= ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(id
);
481 #if !defined(OS_MACOSX)
482 void ContentSettingImageModel::SetIconByVectorId(gfx::VectorIconId id
,
484 icon_
= GetIcon(id
, blocked
? gfx::VectorIconId::BLOCKED_BADGE
485 : gfx::VectorIconId::VECTOR_ICON_NONE
);