- add sources.
[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 "content/public/browser/web_contents.h"
12 #include "grit/generated_resources.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 class ContentSettingSavePasswordImageModel : public ContentSettingImageModel {
63  public:
64   ContentSettingSavePasswordImageModel();
65
66   virtual void UpdateFromWebContents(WebContents* web_contents) OVERRIDE;
67   virtual bool ShouldShowBubbleOnBlockage() OVERRIDE;
68 };
69
70 namespace {
71
72 struct ContentSettingsTypeIdEntry {
73   ContentSettingsType type;
74   int id;
75 };
76
77 int GetIdForContentType(const ContentSettingsTypeIdEntry* entries,
78                         size_t num_entries,
79                         ContentSettingsType type) {
80   for (size_t i = 0; i < num_entries; ++i) {
81     if (entries[i].type == type)
82       return entries[i].id;
83   }
84   return 0;
85 }
86
87 }  // namespace
88
89 ContentSettingBlockedImageModel::ContentSettingBlockedImageModel(
90     ContentSettingsType content_settings_type)
91     : ContentSettingImageModel(content_settings_type) {
92 }
93
94 void ContentSettingBlockedImageModel::UpdateFromWebContents(
95     WebContents* web_contents) {
96   set_visible(false);
97   if (!web_contents)
98     return;
99
100   static const ContentSettingsTypeIdEntry kBlockedIconIDs[] = {
101     {CONTENT_SETTINGS_TYPE_COOKIES, IDR_BLOCKED_COOKIES},
102     {CONTENT_SETTINGS_TYPE_IMAGES, IDR_BLOCKED_IMAGES},
103     {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDR_BLOCKED_JAVASCRIPT},
104     {CONTENT_SETTINGS_TYPE_PLUGINS, IDR_BLOCKED_PLUGINS},
105     {CONTENT_SETTINGS_TYPE_POPUPS, IDR_BLOCKED_POPUPS},
106     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, IDR_BLOCKED_MIXED_CONTENT},
107     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
108     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_BLOCKED_DOWNLOADS},
109   };
110   static const ContentSettingsTypeIdEntry kBlockedTooltipIDs[] = {
111     {CONTENT_SETTINGS_TYPE_COOKIES, IDS_BLOCKED_COOKIES_TITLE},
112     {CONTENT_SETTINGS_TYPE_IMAGES, IDS_BLOCKED_IMAGES_TITLE},
113     {CONTENT_SETTINGS_TYPE_JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_TITLE},
114     {CONTENT_SETTINGS_TYPE_PLUGINS, IDS_BLOCKED_PLUGINS_MESSAGE},
115     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_TOOLTIP},
116     {CONTENT_SETTINGS_TYPE_MIXEDSCRIPT,
117         IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT},
118     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE},
119     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_BLOCKED_DOWNLOAD_TITLE},
120   };
121   static const ContentSettingsTypeIdEntry kBlockedExplanatoryTextIDs[] = {
122     {CONTENT_SETTINGS_TYPE_POPUPS, IDS_BLOCKED_POPUPS_EXPLANATORY_TEXT},
123     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
124         IDS_BLOCKED_DOWNLOADS_EXPLANATION},
125   };
126
127   ContentSettingsType type = get_content_settings_type();
128   int icon_id = GetIdForContentType(
129       kBlockedIconIDs, arraysize(kBlockedIconIDs), type);
130   int tooltip_id = GetIdForContentType(
131       kBlockedTooltipIDs, arraysize(kBlockedTooltipIDs), type);
132   int explanation_id = GetIdForContentType(
133       kBlockedExplanatoryTextIDs, arraysize(kBlockedExplanatoryTextIDs), type);
134
135   // If a content type is blocked by default and was accessed, display the
136   // accessed icon.
137   TabSpecificContentSettings* content_settings =
138       TabSpecificContentSettings::FromWebContents(web_contents);
139   if (!content_settings)
140     return;
141   Profile* profile =
142       Profile::FromBrowserContext(web_contents->GetBrowserContext());
143   if (!content_settings->IsContentBlocked(get_content_settings_type())) {
144     if (!content_settings->IsContentAllowed(get_content_settings_type()))
145       return;
146
147     // For cookies, only show the accessed bubble if cookies are blocked by
148     // default.
149     if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_COOKIES &&
150         (profile->GetHostContentSettingsMap()->
151             GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES, NULL) !=
152                 CONTENT_SETTING_BLOCK))
153       return;
154
155     static const ContentSettingsTypeIdEntry kAccessedIconIDs[] = {
156       {CONTENT_SETTINGS_TYPE_COOKIES, IDR_ACCESSED_COOKIES},
157       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDR_BLOCKED_PPAPI_BROKER},
158       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDR_ALLOWED_DOWNLOADS},
159     };
160     static const ContentSettingsTypeIdEntry kAccessedTooltipIDs[] = {
161       {CONTENT_SETTINGS_TYPE_COOKIES, IDS_ACCESSED_COOKIES_TITLE},
162       {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE},
163       {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, IDS_ALLOWED_DOWNLOAD_TITLE},
164     };
165     icon_id = GetIdForContentType(
166         kAccessedIconIDs, arraysize(kAccessedIconIDs), type);
167     tooltip_id = GetIdForContentType(
168         kAccessedTooltipIDs, arraysize(kAccessedTooltipIDs), type);
169     explanation_id = 0;
170   }
171   set_visible(true);
172   DCHECK(icon_id);
173   set_icon(icon_id);
174   set_explanatory_string_id(explanation_id);
175   DCHECK(tooltip_id);
176   set_tooltip(l10n_util::GetStringUTF8(tooltip_id));
177 }
178
179 ContentSettingGeolocationImageModel::ContentSettingGeolocationImageModel()
180     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_GEOLOCATION) {
181 }
182
183 void ContentSettingGeolocationImageModel::UpdateFromWebContents(
184     WebContents* web_contents) {
185   set_visible(false);
186   if (!web_contents)
187     return;
188   TabSpecificContentSettings* content_settings =
189       TabSpecificContentSettings::FromWebContents(web_contents);
190   if (!content_settings)
191     return;
192   const ContentSettingsUsagesState& usages_state = content_settings->
193       geolocation_usages_state();
194   if (usages_state.state_map().empty())
195     return;
196   set_visible(true);
197
198   // If any embedded site has access the allowed icon takes priority over the
199   // blocked icon.
200   unsigned int state_flags = 0;
201   usages_state.GetDetailedInfo(NULL, &state_flags);
202   bool allowed =
203       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
204   set_icon(allowed ? IDR_ALLOWED_LOCATION : IDR_BLOCKED_LOCATION);
205   set_tooltip(l10n_util::GetStringUTF8(allowed ?
206       IDS_GEOLOCATION_ALLOWED_TOOLTIP : IDS_GEOLOCATION_BLOCKED_TOOLTIP));
207 }
208
209 ContentSettingSavePasswordImageModel::ContentSettingSavePasswordImageModel()
210     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_SAVE_PASSWORD) {
211 }
212
213 void ContentSettingSavePasswordImageModel::UpdateFromWebContents(
214     WebContents* web_contents) {
215   set_visible(false);
216   if (!web_contents)
217     return;
218   TabSpecificContentSettings* content_settings =
219       TabSpecificContentSettings::FromWebContents(web_contents);
220   if (!content_settings)
221     return;
222
223   TabSpecificContentSettings::PasswordSavingState state =
224       content_settings->GetPasswordSavingState();
225   switch (state) {
226     case TabSpecificContentSettings::PASSWORD_TO_BE_SAVED:
227       set_icon(IDR_SAVE_PASSWORD);
228       set_visible(true);
229       break;
230     case TabSpecificContentSettings::NO_PASSWORD_TO_BE_SAVED:
231       set_icon(IDR_SAVE_PASSWORD);
232       set_visible(false);
233       break;
234   }
235 }
236
237 bool ContentSettingSavePasswordImageModel::ShouldShowBubbleOnBlockage() {
238   return true;
239 }
240
241 ContentSettingMediaImageModel::ContentSettingMediaImageModel(
242     ContentSettingsType type)
243     : ContentSettingImageModel(type) {
244 }
245
246 void ContentSettingMediaImageModel::UpdateFromWebContents(
247     WebContents* web_contents) {
248   set_visible(false);
249
250   // As long as a single icon is used to display the status of the camera and
251   // microphone usage only display an icon for the
252   // CONTENT_SETTINGS_TYPE_MEDIASTREAM. Don't display anything for
253   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
254   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
255   // FIXME: Remove this hack and either display a two omnibox icons (one for
256   // camera and one for microphone), or don't create one image model per
257   // content type but per icon to display. The later is probably the right
258   // thing to do, bebacuse this also allows to add more content settings type
259   // for which no omnibox icon exists.
260   if (get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
261       get_content_settings_type() == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
262     return;
263   }
264
265   // The ContentSettingMediaImageModel must not be used with a content type
266   // other then: CONTENT_SETTINGS_TYPE_MEDIASTREAM,
267   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
268   // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
269   DCHECK_EQ(get_content_settings_type(), CONTENT_SETTINGS_TYPE_MEDIASTREAM);
270
271   if (!web_contents)
272     return;
273
274   TabSpecificContentSettings* content_settings =
275       TabSpecificContentSettings::FromWebContents(web_contents);
276   if (!content_settings)
277     return;
278   TabSpecificContentSettings::MicrophoneCameraState state =
279       content_settings->GetMicrophoneCameraState();
280
281   switch (state) {
282     case TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED:
283       // If neither the microphone nor the camera stream was accessed then no
284       // icon is displayed in the omnibox.
285       return;
286     case TabSpecificContentSettings::MICROPHONE_ACCESSED:
287       set_icon(IDR_ASK_MEDIA);
288       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED));
289       break;
290     case TabSpecificContentSettings::CAMERA_ACCESSED:
291       set_icon(IDR_ASK_MEDIA);
292       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED));
293       break;
294     case TabSpecificContentSettings::MICROPHONE_CAMERA_ACCESSED:
295       set_icon(IDR_ASK_MEDIA);
296       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED));
297       break;
298     case TabSpecificContentSettings::MICROPHONE_BLOCKED:
299       set_icon(IDR_BLOCKED_MEDIA);
300       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED));
301       break;
302     case TabSpecificContentSettings::CAMERA_BLOCKED:
303       set_icon(IDR_BLOCKED_MEDIA);
304       set_tooltip(l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED));
305       break;
306     case TabSpecificContentSettings::MICROPHONE_CAMERA_BLOCKED:
307       set_icon(IDR_BLOCKED_MEDIA);
308       set_tooltip(l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_BLOCKED));
309       break;
310   }
311   set_visible(true);
312 }
313
314 ContentSettingRPHImageModel::ContentSettingRPHImageModel()
315     : ContentSettingImageModel(
316         CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
317   set_icon(IDR_REGISTER_PROTOCOL_HANDLER);
318   set_tooltip(l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_TOOLTIP));
319 }
320
321 void ContentSettingRPHImageModel::UpdateFromWebContents(
322     WebContents* web_contents) {
323   set_visible(false);
324   if (!web_contents)
325     return;
326
327   TabSpecificContentSettings* content_settings =
328       TabSpecificContentSettings::FromWebContents(web_contents);
329   if (!content_settings)
330     return;
331   if (content_settings->pending_protocol_handler().IsEmpty())
332     return;
333
334   set_visible(true);
335 }
336
337 ContentSettingNotificationsImageModel::ContentSettingNotificationsImageModel()
338     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
339 }
340
341 void ContentSettingNotificationsImageModel::UpdateFromWebContents(
342     WebContents* web_contents) {
343   // Notifications do not have a bubble.
344   set_visible(false);
345 }
346
347 ContentSettingMIDISysExImageModel::ContentSettingMIDISysExImageModel()
348     : ContentSettingImageModel(CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
349 }
350
351 void ContentSettingMIDISysExImageModel::UpdateFromWebContents(
352     WebContents* web_contents) {
353   set_visible(false);
354   if (!web_contents)
355     return;
356   TabSpecificContentSettings* content_settings =
357       TabSpecificContentSettings::FromWebContents(web_contents);
358   if (!content_settings)
359     return;
360   const ContentSettingsUsagesState& usages_state =
361       content_settings->midi_usages_state();
362   if (usages_state.state_map().empty())
363     return;
364   set_visible(true);
365
366   // If any embedded site has access the allowed icon takes priority over the
367   // blocked icon.
368   unsigned int state_flags = 0;
369   usages_state.GetDetailedInfo(NULL, &state_flags);
370   bool allowed =
371       !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
372   set_icon(allowed ? IDR_ALLOWED_MIDI_SYSEX : IDR_BLOCKED_MIDI_SYSEX);
373   set_tooltip(l10n_util::GetStringUTF8(allowed ?
374       IDS_MIDI_SYSEX_ALLOWED_TOOLTIP : IDS_MIDI_SYSEX_BLOCKED_TOOLTIP));
375 }
376
377 ContentSettingImageModel::ContentSettingImageModel(
378     ContentSettingsType content_settings_type)
379     : content_settings_type_(content_settings_type),
380       is_visible_(false),
381       icon_(0),
382       explanatory_string_id_(0) {
383 }
384
385 bool ContentSettingImageModel::ShouldShowBubbleOnBlockage() {
386   return false;
387 }
388
389 // static
390 ContentSettingImageModel*
391     ContentSettingImageModel::CreateContentSettingImageModel(
392     ContentSettingsType content_settings_type) {
393   switch (content_settings_type) {
394     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
395       return new ContentSettingGeolocationImageModel();
396     case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
397       return new ContentSettingNotificationsImageModel();
398     case CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS:
399       return new ContentSettingRPHImageModel();
400     case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
401     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
402     case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
403       return new ContentSettingMediaImageModel(content_settings_type);
404     case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
405       return new ContentSettingMIDISysExImageModel();
406     case CONTENT_SETTINGS_TYPE_SAVE_PASSWORD:
407       return new ContentSettingSavePasswordImageModel();
408     default:
409       return new ContentSettingBlockedImageModel(content_settings_type);
410   }
411 }