Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / content_settings / content_setting_image_model.cc
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
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 }