Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / ui / content_settings / content_setting_image_model.cc
blob6adb4c504fa6b9be7123fa38953bd3535f906d71
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/tab_specific_content_settings.h"
8 #include "chrome/browser/prerender/prerender_manager.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/grit/generated_resources.h"
11 #include "components/content_settings/core/browser/host_content_settings_map.h"
12 #include "content/public/browser/web_contents.h"
13 #include "grit/theme_resources.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/resource/material_design/material_design_controller.h"
16 #include "ui/base/resource/resource_bundle.h"
18 #if !defined(OS_MACOSX)
19 #include "ui/gfx/paint_vector_icon.h"
20 #include "ui/gfx/vector_icons_public.h"
21 #include "ui/native_theme/common_theme.h"
22 #include "ui/native_theme/native_theme.h"
23 #endif
25 using content::WebContents;
27 namespace {
29 bool UseVectorGraphics() {
30 #if defined(OS_MACOSX)
31 return false;
32 #else
33 return ui::MaterialDesignController::IsModeMaterial();
34 #endif
37 } // namespace
39 class ContentSettingBlockedImageModel : public ContentSettingImageModel {
40 public:
41 explicit ContentSettingBlockedImageModel(
42 ContentSettingsType content_settings_type);
44 void UpdateFromWebContents(WebContents* web_contents) override;
47 class ContentSettingGeolocationImageModel : public ContentSettingImageModel {
48 public:
49 ContentSettingGeolocationImageModel();
51 void UpdateFromWebContents(WebContents* web_contents) override;
54 // Image model for displaying media icons in the location bar.
55 class ContentSettingMediaImageModel : public ContentSettingImageModel {
56 public:
57 explicit ContentSettingMediaImageModel(ContentSettingsType type);
59 void UpdateFromWebContents(WebContents* web_contents) override;
62 class ContentSettingRPHImageModel : public ContentSettingImageModel {
63 public:
64 ContentSettingRPHImageModel();
66 void UpdateFromWebContents(WebContents* web_contents) override;
69 class ContentSettingNotificationsImageModel : public ContentSettingImageModel {
70 public:
71 ContentSettingNotificationsImageModel();
73 void UpdateFromWebContents(WebContents* web_contents) override;
76 class ContentSettingMIDISysExImageModel : public ContentSettingImageModel {
77 public:
78 ContentSettingMIDISysExImageModel();
80 void UpdateFromWebContents(WebContents* web_contents) override;
83 namespace {
85 struct ContentSettingsTypeIdEntry {
86 ContentSettingsType type;
87 int id;
90 int GetIdForContentType(const ContentSettingsTypeIdEntry* entries,
91 size_t num_entries,
92 ContentSettingsType type) {
93 for (size_t i = 0; i < num_entries; ++i) {
94 if (entries[i].type == type)
95 return entries[i].id;
97 return 0;
100 } // namespace
102 ContentSettingBlockedImageModel::ContentSettingBlockedImageModel(
103 ContentSettingsType content_settings_type)
104 : ContentSettingImageModel(content_settings_type) {
107 void ContentSettingBlockedImageModel::UpdateFromWebContents(
108 WebContents* web_contents) {
109 set_visible(false);
110 if (!web_contents)
111 return;
113 ContentSettingsType type = get_content_settings_type();
114 static const ContentSettingsTypeIdEntry kBlockedIconIDs[] = {
115 {CONTENT_SETTINGS_TYPE_COOKIES, IDR_BLOCKED_COOKIES},
116 {CONTENT_SETTINGS_TYPE_IMAGES, IDR_BLOCKED_IMAGES},
117 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDR_BLOCKED_JAVASCRIPT},
118 {CONTENT_SETTINGS_TYPE_PLUGINS, IDR_BLOCKED_PLUGINS},
119 {CONTENT_SETTINGS_TYPE_POPUPS, IDR_BLOCKED_POPUPS},
120 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDR_BLOCKED_MIXED_CONTENT},
121 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
122 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_BLOCKED_DOWNLOADS},
124 int icon_id =
125 GetIdForContentType(kBlockedIconIDs, arraysize(kBlockedIconIDs), type);
127 #if !defined(OS_MACOSX)
128 gfx::VectorIconId vector_icon_id = gfx::VectorIconId::VECTOR_ICON_NONE;
129 switch (type) {
130 case CONTENT_SETTINGS_TYPE_COOKIES:
131 vector_icon_id = gfx::VectorIconId::COOKIE;
132 break;
133 case CONTENT_SETTINGS_TYPE_IMAGES:
134 vector_icon_id = gfx::VectorIconId::IMAGE;
135 break;
136 case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
137 vector_icon_id = gfx::VectorIconId::CODE;
138 break;
139 case CONTENT_SETTINGS_TYPE_PLUGINS:
140 vector_icon_id = gfx::VectorIconId::EXTENSION;
141 break;
142 case CONTENT_SETTINGS_TYPE_POPUPS:
143 vector_icon_id = gfx::VectorIconId::WEB;
144 break;
145 case CONTENT_SETTINGS_TYPE_MIXEDSCRIPT:
146 vector_icon_id = gfx::VectorIconId::MIXED_CONTENT;
147 break;
148 // TODO(estade): change this one?
149 case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
150 vector_icon_id = gfx::VectorIconId::EXTENSION;
151 break;
152 case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
153 vector_icon_id = gfx::VectorIconId::FILE_DOWNLOAD;
154 break;
155 default:
156 // If we didn't find a vector icon ID we shouldn't have found an
157 // asset ID either.
158 DCHECK_EQ(0, icon_id);
159 break;
161 #endif
163 static const ContentSettingsTypeIdEntry kBlockedTooltipIDs[] = {
164 {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_TITLE},
165 {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_TITLE},
166 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_TITLE},
167 {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_MESSAGE},
168 {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_TOOLTIP},
169 {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
170 IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT},
171 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE},
172 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE},
174 int tooltip_id = GetIdForContentType(kBlockedTooltipIDs,
175 arraysize(kBlockedTooltipIDs), type);
177 static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs[] = {
178 {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT},
179 {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT},
180 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
181 IDS_BLOCKED_DOWNLOADS_EXPLANATION},
183 int explanation_id = GetIdForContentType(
184 kBlockedExplanatoryTextIDs, arraysize(kBlockedExplanatoryTextIDs), type);
186 // For plugins, don't show the animated explanation unless the plugin was
187 // blocked despite the user's content settings being set to allow it (e.g.
188 // due to auto-blocking NPAPI plugins).
189 Profile* profile =
190 Profile::FromBrowserContext(web_contents->GetBrowserContext());
191 HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
192 if (type == CONTENT_SETTINGS_TYPE_PLUGINS) {
193 GURL url = web_contents->GetURL();
194 if (map->GetContentSetting(url, url, type, std::string()) !=
195 CONTENT_SETTING_ALLOW)
196 explanation_id = 0;
199 // If a content type is blocked by default and was accessed, display the
200 // content blocked page action.
201 TabSpecificContentSettings* content_settings =
202 TabSpecificContentSettings::FromWebContents(web_contents);
203 if (!content_settings)
204 return;
205 if (!content_settings->IsContentBlocked(type)) {
206 if (!content_settings->IsContentAllowed(type))
207 return;
209 // For cookies, only show the cookie blocked page action if cookies are
210 // blocked by default.
211 if (type == CONTENT_SETTINGS_TYPE_COOKIES &&
212 (map->GetDefaultContentSetting(type, NULL) != CONTENT_SETTING_BLOCK))
213 return;
215 static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = {
216 {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES},
217 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
218 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS},
220 icon_id = GetIdForContentType(kAccessedIconIDs, arraysize(kAccessedIconIDs),
221 type);
222 static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = {
223 {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
224 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
225 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
227 tooltip_id = GetIdForContentType(
228 kAccessedTooltipIDs, arraysize(kAccessedTooltipIDs), type);
229 explanation_id = 0;
231 set_visible(true);
232 if (!UseVectorGraphics()) {
233 DCHECK(icon_id);
234 SetIconByResourceId(icon_id);
235 #if !defined(OS_MACOSX)
236 } else {
237 DCHECK(gfx::VectorIconId::VECTOR_ICON_NONE != vector_icon_id);
238 SetIconByVectorId(vector_icon_id, content_settings->IsContentBlocked(type));
239 #endif
241 set_explanatory_string_id(explanation_id);
242 DCHECK(tooltip_id);
243 set_tooltip(l10n_util::GetStringUTF8(tooltip_id));
246 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
247 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) {
250 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
251 WebContents* web_contents) {
252 set_visible(false);
253 if (!web_contents)
254 return;
255 TabSpecificContentSettings* content_settings =
256 TabSpecificContentSettings::FromWebContents(web_contents);
257 if (!content_settings)
258 return;
259 const ContentSettingsUsagesState& usages_state = content_settings->
260 geolocation_usages_state();
261 if (usages_state.state_map().empty())
262 return;
263 set_visible(true);
265 // If any embedded site has access the allowed icon takes priority over the
266 // blocked icon.
267 unsigned int state_flags = 0;
268 usages_state.GetDetailedInfo(NULL, &state_flags);
269 bool allowed =
270 !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
271 if (!UseVectorGraphics())
272 SetIconByResourceId(allowed ? IDR_ALLOWED_LOCATION : IDR_BLOCKED_LOCATION);
273 #if !defined(OS_MACOSX)
274 else
275 SetIconByVectorId(gfx::VectorIconId::MY_LOCATION, !allowed);
276 #endif
277 set_tooltip(l10n_util::GetStringUTF8(allowed ?
278 IDS_GEOLOCATION_ALLOWED_TOOLTIP : IDS_GEOLOCATION_BLOCKED_TOOLTIP));
281 ContentSettingMediaImageModel::ContentSettingMediaImageModel(
282 ContentSettingsType type)
283 : ContentSettingImageModel(type) {
286 void ContentSettingMediaImageModel::UpdateFromWebContents(
287 WebContents* web_contents) {
288 set_visible(false);
290 // As long as a single icon is used to display the status of the camera and
291 // microphone usage only display an icon for the
292 // CONTENT_SETTINGS_TYPE_MEDIASTREAM. Don't display anything for
293 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
294 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
295 // FIXME: Remove this hack and either display a two omnibox icons (one for
296 // camera and one for microphone), or don't create one image model per
297 // content type but per icon to display. The later is probably the right
298 // thing to do, bebacuse this also allows to add more content settings type
299 // for which no omnibox icon exists.
300 if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
301 get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
302 return;
305 // The ContentSettingMediaImageModel must not be used with a content type
306 // other then: CONTENT_SETTINGS_TYPE_MEDIASTREAM,
307 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
308 // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
309 DCHECK_EQ(get_content_settings_type(), CONTENT_SETTINGS_TYPE_MEDIASTREAM);
311 if (!web_contents)
312 return;
314 TabSpecificContentSettings* content_settings =
315 TabSpecificContentSettings::FromWebContents(web_contents);
316 if (!content_settings)
317 return;
318 TabSpecificContentSettings::MicrophoneCameraState state =
319 content_settings->GetMicrophoneCameraState();
321 // If neither the microphone nor the camera stream was accessed then no icon
322 // is displayed in the omnibox.
323 if (state == TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED)
324 return;
326 bool is_mic = (state & TabSpecificContentSettings::MICROPHONE_ACCESSED) != 0;
327 bool is_cam = (state & TabSpecificContentSettings::CAMERA_ACCESSED) != 0;
328 DCHECK(is_mic || is_cam);
330 int id = IDS_CAMERA_BLOCKED;
331 if (state & (TabSpecificContentSettings::MICROPHONE_BLOCKED |
332 TabSpecificContentSettings::CAMERA_BLOCKED)) {
333 if (!UseVectorGraphics())
334 SetIconByResourceId(IDR_BLOCKED_CAMERA);
335 #if !defined(OS_MACOSX)
336 else
337 SetIconByVectorId(gfx::VectorIconId::VIDEOCAM, true);
338 #endif
339 if (is_mic)
340 id = is_cam ? IDS_MICROPHONE_CAMERA_BLOCKED : IDS_MICROPHONE_BLOCKED;
341 } else {
342 if (!UseVectorGraphics())
343 SetIconByResourceId(IDR_ALLOWED_CAMERA);
344 #if !defined(OS_MACOSX)
345 else
346 SetIconByVectorId(gfx::VectorIconId::VIDEOCAM, false);
347 #endif
348 id = IDS_CAMERA_ACCESSED;
349 if (is_mic)
350 id = is_cam ? IDS_MICROPHONE_CAMERA_ALLOWED : IDS_MICROPHONE_ACCESSED;
352 set_tooltip(l10n_util::GetStringUTF8(id));
353 set_visible(true);
356 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
357 : ContentSettingImageModel(
358 CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
359 // TODO(estade): get an MD icon for this one.
360 SetIconByResourceId(IDR_REGISTER_PROTOCOL_HANDLER);
361 set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
364 void ContentSettingRPHImageModel::UpdateFromWebContents(
365 WebContents* web_contents) {
366 set_visible(false);
367 if (!web_contents)
368 return;
370 TabSpecificContentSettings* content_settings =
371 TabSpecificContentSettings::FromWebContents(web_contents);
372 if (!content_settings)
373 return;
374 if (content_settings->pending_protocol_handler().IsEmpty())
375 return;
377 set_visible(true);
380 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
381 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
384 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
385 WebContents* web_contents) {
386 // Notifications do not have a bubble.
387 set_visible(false);
390 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
391 : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
394 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
395 WebContents* web_contents) {
396 set_visible(false);
397 if (!web_contents)
398 return;
399 TabSpecificContentSettings* content_settings =
400 TabSpecificContentSettings::FromWebContents(web_contents);
401 if (!content_settings)
402 return;
403 const ContentSettingsUsagesState& usages_state =
404 content_settings->midi_usages_state();
405 if (usages_state.state_map().empty())
406 return;
407 set_visible(true);
409 // If any embedded site has access the allowed icon takes priority over the
410 // blocked icon.
411 unsigned int state_flags = 0;
412 usages_state.GetDetailedInfo(NULL, &state_flags);
413 bool allowed =
414 !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
415 #if defined(OS_MACOSX)
416 SetIconByResourceId(allowed ? IDR_ALLOWED_MIDI_SYSEX
417 : IDR_BLOCKED_MIDI_SYSEX);
418 #else
419 SetIconByVectorId(gfx::VectorIconId::MIDI, !allowed);
420 #endif
421 set_tooltip(l10n_util::GetStringUTF8(allowed ?
422 IDS_MIDI_SYSEX_ALLOWED_TOOLTIP : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP));
425 ContentSettingImageModel::ContentSettingImageModel(
426 ContentSettingsType content_settings_type)
427 : content_settings_type_(content_settings_type),
428 is_visible_(false),
429 icon_id_(0),
430 explanatory_string_id_(0) {
433 // static
434 ContentSettingImageModel*
435 ContentSettingImageModel::CreateContentSettingImageModel(
436 ContentSettingsType content_settings_type) {
437 switch (content_settings_type) {
438 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
439 return new ContentSettingGeolocationImageModel();
440 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
441 return new ContentSettingNotificationsImageModel();
442 case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
443 return new ContentSettingRPHImageModel();
444 case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
445 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
446 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
447 return new ContentSettingMediaImageModel(content_settings_type);
448 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
449 return new ContentSettingMIDISysExImageModel();
450 default:
451 return new ContentSettingBlockedImageModel(content_settings_type);
455 void ContentSettingImageModel::SetIconByResourceId(int id) {
456 icon_id_ = id;
457 icon_ = ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(id);
460 #if !defined(OS_MACOSX)
461 void ContentSettingImageModel::SetIconByVectorId(gfx::VectorIconId id,
462 bool blocked) {
463 SkColor icon_color;
464 ui::CommonThemeGetSystemColor(ui::NativeTheme::kColorId_ChromeIconGrey,
465 &icon_color);
466 icon_ = gfx::Image(gfx::CreateVectorIconWithBadge(
467 id, 16, icon_color, blocked ? gfx::VectorIconId::BLOCKED_BADGE
468 : gfx::VectorIconId::VECTOR_ICON_NONE));
470 #endif