Update To 11.40.268.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/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
16 using content::WebContents;
17
18 class ContentSettingBlockedImageModel : public ContentSettingImageModel {
19  public:
20   explicit ContentSettingBlockedImageModel(
21       ContentSettingsType content_settings_type);
22
23   void UpdateFromWebContents(WebContents* web_contents) override;
24 };
25
26 class ContentSettingGeolocationImageModel : public ContentSettingImageModel {
27  public:
28   ContentSettingGeolocationImageModel();
29
30   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   void UpdateFromWebContents(WebContents* web_contents) override;
39 };
40
41 class ContentSettingRPHImageModel : public ContentSettingImageModel {
42  public:
43   ContentSettingRPHImageModel();
44
45   void UpdateFromWebContents(WebContents* web_contents) override;
46 };
47
48 class ContentSettingNotificationsImageModel : public ContentSettingImageModel {
49  public:
50   ContentSettingNotificationsImageModel();
51
52   void UpdateFromWebContents(WebContents* web_contents) override;
53 };
54
55 class ContentSettingMIDISysExImageModel : public ContentSettingImageModel {
56  public:
57   ContentSettingMIDISysExImageModel();
58
59   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   // If neither the microphone nor the camera stream was accessed then no icon
252   // is displayed in the omnibox.
253   if (state == TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED)
254     return;
255
256   bool is_mic = (state & TabSpecificContentSettings::MICROPHONE_ACCESSED) != 0;
257   bool is_cam = (state & TabSpecificContentSettings::CAMERA_ACCESSED) != 0;
258   DCHECK(is_mic || is_cam);
259
260   int id = IDS_CAMERA_BLOCKED;
261   if (state & (TabSpecificContentSettings::MICROPHONE_BLOCKED |
262                TabSpecificContentSettings::CAMERA_BLOCKED)) {
263     set_icon(IDR_BLOCKED_MEDIA);
264     if (is_mic)
265       id = is_cam ? IDS_MICROPHONE_CAMERA_BLOCKED : IDS_MICROPHONE_BLOCKED;
266   } else {
267     set_icon(IDR_ASK_MEDIA);
268     id = IDS_CAMERA_ACCESSED;
269     if (is_mic)
270       id = is_cam ? IDS_MICROPHONE_CAMERA_ALLOWED : IDS_MICROPHONE_ACCESSED;
271   }
272   set_tooltip(l10n_util::GetStringUTF8(id));
273   set_visible(true);
274 }
275
276 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
277     : ContentSettingImageModel(
278         CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
279   set_icon(IDR_REGISTER_PROTOCOL_HANDLER);
280   set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
281 }
282
283 void ContentSettingRPHImageModel::UpdateFromWebContents(
284     WebContents* web_contents) {
285   set_visible(false);
286   if (!web_contents)
287     return;
288
289   TabSpecificContentSettings* content_settings =
290       TabSpecificContentSettings::FromWebContents(web_contents);
291   if (!content_settings)
292     return;
293   if (content_settings->pending_protocol_handler().IsEmpty())
294     return;
295
296   set_visible(true);
297 }
298
299 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
300     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
301 }
302
303 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
304     WebContents* web_contents) {
305   // Notifications do not have a bubble.
306   set_visible(false);
307 }
308
309 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
310     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
311 }
312
313 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
314     WebContents* web_contents) {
315   set_visible(false);
316   if (!web_contents)
317     return;
318   TabSpecificContentSettings* content_settings =
319       TabSpecificContentSettings::FromWebContents(web_contents);
320   if (!content_settings)
321     return;
322   const ContentSettingsUsagesState& usages_state =
323       content_settings->midi_usages_state();
324   if (usages_state.state_map().empty())
325     return;
326   set_visible(true);
327
328   // If any embedded site has access the allowed icon takes priority over the
329   // blocked icon.
330   unsigned int state_flags = 0;
331   usages_state.GetDetailedInfo(NULL, &state_flags);
332   bool allowed =
333       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
334   set_icon(allowed ? IDR_ALLOWED_MIDI_SYSEX : IDR_BLOCKED_MIDI_SYSEX);
335   set_tooltip(l10n_util::GetStringUTF8(allowed ?
336       IDS_MIDI_SYSEX_ALLOWED_TOOLTIP : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP));
337 }
338
339 ContentSettingImageModel::ContentSettingImageModel(
340     ContentSettingsType content_settings_type)
341     : content_settings_type_(content_settings_type),
342       is_visible_(false),
343       icon_(0),
344       explanatory_string_id_(0) {
345 }
346
347 // static
348 ContentSettingImageModel*
349     ContentSettingImageModel::CreateContentSettingImageModel(
350     ContentSettingsType content_settings_type) {
351   switch (content_settings_type) {
352     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
353       return new ContentSettingGeolocationImageModel();
354     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
355       return new ContentSettingNotificationsImageModel();
356     case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
357       return new ContentSettingRPHImageModel();
358     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
359     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
360     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
361       return new ContentSettingMediaImageModel(content_settings_type);
362     case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
363       return new ContentSettingMIDISysExImageModel();
364     default:
365       return new ContentSettingBlockedImageModel(content_settings_type);
366   }
367 }