Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: chrome/browser/ui/webui/options/content_settings_handler.cc

Issue 9814030: get rid of old options pages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixes Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/webui/options/content_settings_handler.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/utf_string_conversions.h"
15 #include "base/values.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/content_settings/content_settings_details.h"
18 #include "chrome/browser/content_settings/content_settings_utils.h"
19 #include "chrome/browser/content_settings/host_content_settings_map.h"
20 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
21 #include "chrome/browser/intents/web_intents_util.h"
22 #include "chrome/browser/notifications/desktop_notification_service.h"
23 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
24 #include "chrome/browser/prefs/pref_service.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/common/chrome_notification_types.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/content_settings.h"
30 #include "chrome/common/content_settings_pattern.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/notification_types.h"
36 #include "content/public/browser/user_metrics.h"
37 #include "content/public/browser/web_ui.h"
38 #include "content/public/common/content_switches.h"
39 #include "grit/generated_resources.h"
40 #include "grit/locale_settings.h"
41 #include "ui/base/l10n/l10n_util.h"
42
43 using content::UserMetricsAction;
44
45 namespace {
46
47 struct ContentSettingsTypeNameEntry {
48 ContentSettingsType type;
49 const char* name;
50 };
51
52 typedef std::map<ContentSettingsPattern, ContentSetting> OnePatternSettings;
53 typedef std::map<ContentSettingsPattern, OnePatternSettings>
54 AllPatternsSettings;
55
56 const char* kDisplayPattern = "displayPattern";
57 const char* kSetting = "setting";
58 const char* kOrigin = "origin";
59 const char* kSource = "source";
60 const char* kEmbeddingOrigin = "embeddingOrigin";
61
62 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
63 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"},
64 {CONTENT_SETTINGS_TYPE_IMAGES, "images"},
65 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"},
66 {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"},
67 {CONTENT_SETTINGS_TYPE_POPUPS, "popups"},
68 {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"},
69 {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"},
70 {CONTENT_SETTINGS_TYPE_INTENTS, "intents"},
71 {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"},
72 {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"},
73 {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"},
74 };
75 COMPILE_ASSERT(arraysize(kContentSettingsTypeGroupNames) ==
76 CONTENT_SETTINGS_NUM_TYPES,
77 MISSING_CONTENT_SETTINGS_TYPE);
78
79 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) {
80 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) {
81 if (name == kContentSettingsTypeGroupNames[i].name)
82 return kContentSettingsTypeGroupNames[i].type;
83 }
84
85 NOTREACHED() << name << " is not a recognized content settings type.";
86 return CONTENT_SETTINGS_TYPE_DEFAULT;
87 }
88
89 std::string ContentSettingToString(ContentSetting setting) {
90 switch (setting) {
91 case CONTENT_SETTING_ALLOW:
92 return "allow";
93 case CONTENT_SETTING_ASK:
94 return "ask";
95 case CONTENT_SETTING_BLOCK:
96 return "block";
97 case CONTENT_SETTING_SESSION_ONLY:
98 return "session";
99 case CONTENT_SETTING_DEFAULT:
100 return "default";
101 case CONTENT_SETTING_NUM_SETTINGS:
102 NOTREACHED();
103 }
104
105 return "";
106 }
107
108 ContentSetting ContentSettingFromString(const std::string& name) {
109 if (name == "allow")
110 return CONTENT_SETTING_ALLOW;
111 if (name == "ask")
112 return CONTENT_SETTING_ASK;
113 if (name == "block")
114 return CONTENT_SETTING_BLOCK;
115 if (name == "session")
116 return CONTENT_SETTING_SESSION_ONLY;
117
118 NOTREACHED() << name << " is not a recognized content setting.";
119 return CONTENT_SETTING_DEFAULT;
120 }
121
122 std::string GeolocationExceptionToString(
123 const ContentSettingsPattern& origin,
124 const ContentSettingsPattern& embedding_origin) {
125 if (origin == embedding_origin)
126 return origin.ToString();
127
128 // TODO(estade): the page needs to use CSS to indent the string.
129 std::string indent(" ");
130
131 if (embedding_origin == ContentSettingsPattern::Wildcard()) {
132 // NOTE: As long as the user cannot add/edit entries from the exceptions
133 // dialog, it's impossible to actually have a non-default setting for some
134 // origin "embedded on any other site", so this row will never appear. If
135 // we add the ability to add/edit exceptions, we'll need to decide when to
136 // display this and how "removing" it will function.
137 return indent +
138 l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER);
139 }
140
141 return indent + l10n_util::GetStringFUTF8(
142 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
143 UTF8ToUTF16(embedding_origin.ToString()));
144 }
145
146 // Create a DictionaryValue* that will act as a data source for a single row
147 // in a HostContentSettingsMap-controlled exceptions table (e.g., cookies).
148 // Ownership of the pointer is passed to the caller.
149 DictionaryValue* GetExceptionForPage(
150 const ContentSettingsPattern& pattern,
151 const ContentSetting& setting,
152 const std::string& provider_name) {
153 DictionaryValue* exception = new DictionaryValue();
154 exception->SetString(kDisplayPattern, pattern.ToString());
155 exception->SetString(kSetting, ContentSettingToString(setting));
156 exception->SetString(kSource, provider_name);
157 return exception;
158 }
159
160 // Create a DictionaryValue* that will act as a data source for a single row
161 // in the Geolocation exceptions table. Ownership of the pointer is passed to
162 // the caller.
163 DictionaryValue* GetGeolocationExceptionForPage(
164 const ContentSettingsPattern& origin,
165 const ContentSettingsPattern& embedding_origin,
166 ContentSetting setting) {
167 DictionaryValue* exception = new DictionaryValue();
168 exception->SetString(kDisplayPattern,
169 GeolocationExceptionToString(origin, embedding_origin));
170 exception->SetString(kSetting, ContentSettingToString(setting));
171 exception->SetString(kOrigin, origin.ToString());
172 exception->SetString(kEmbeddingOrigin, embedding_origin.ToString());
173 return exception;
174 }
175
176 // Create a DictionaryValue* that will act as a data source for a single row
177 // in the desktop notifications exceptions table. Ownership of the pointer is
178 // passed to the caller.
179 DictionaryValue* GetNotificationExceptionForPage(
180 const ContentSettingsPattern& pattern,
181 ContentSetting setting,
182 const std::string& provider_name) {
183 DictionaryValue* exception = new DictionaryValue();
184 exception->SetString(kDisplayPattern, pattern.ToString());
185 exception->SetString(kSetting, ContentSettingToString(setting));
186 exception->SetString(kOrigin, pattern.ToString());
187 exception->SetString(kSource, provider_name);
188 return exception;
189 }
190
191 } // namespace
192
193 ContentSettingsHandler::ContentSettingsHandler() {
194 }
195
196 ContentSettingsHandler::~ContentSettingsHandler() {
197 }
198
199 void ContentSettingsHandler::GetLocalizedValues(
200 DictionaryValue* localized_strings) {
201 DCHECK(localized_strings);
202
203 static OptionsStringResource resources[] = {
204 { "content_exceptions", IDS_COOKIES_EXCEPTIONS_BUTTON },
205 { "allowException", IDS_EXCEPTIONS_ALLOW_BUTTON },
206 { "blockException", IDS_EXCEPTIONS_BLOCK_BUTTON },
207 { "sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON },
208 { "askException", IDS_EXCEPTIONS_ASK_BUTTON },
209 { "addExceptionRow", IDS_EXCEPTIONS_ADD_BUTTON },
210 { "removeExceptionRow", IDS_EXCEPTIONS_REMOVE_BUTTON },
211 { "editExceptionRow", IDS_EXCEPTIONS_EDIT_BUTTON },
212 { "otr_exceptions_explanation", IDS_EXCEPTIONS_OTR_LABEL },
213 { "examplePattern", IDS_EXCEPTIONS_PATTERN_EXAMPLE },
214 { "addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS },
215 { "manage_exceptions", IDS_EXCEPTIONS_MANAGE },
216 { "manage_handlers", IDS_HANDLERS_MANAGE },
217 { "exceptionPatternHeader", IDS_EXCEPTIONS_PATTERN_HEADER },
218 { "exceptionBehaviorHeader", IDS_EXCEPTIONS_ACTION_HEADER },
219 // Cookies filter.
220 { "cookies_tab_label", IDS_COOKIES_TAB_LABEL },
221 { "cookies_header", IDS_COOKIES_HEADER },
222 { "cookies_allow", IDS_COOKIES_ALLOW_RADIO },
223 { "cookies_block", IDS_COOKIES_BLOCK_RADIO },
224 { "cookies_session_only", IDS_COOKIES_SESSION_ONLY_RADIO },
225 { "cookies_block_3rd_party", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX },
226 { "cookies_clear_when_close", IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX },
227 { "cookies_lso_clear_when_close", IDS_COOKIES_LSO_CLEAR_WHEN_CLOSE_CHKBOX },
228 { "cookies_show_cookies", IDS_COOKIES_SHOW_COOKIES_BUTTON },
229 { "flash_storage_settings", IDS_FLASH_STORAGE_SETTINGS },
230 { "flash_storage_url", IDS_FLASH_STORAGE_URL },
231 // Image filter.
232 { "images_tab_label", IDS_IMAGES_TAB_LABEL },
233 { "images_header", IDS_IMAGES_HEADER },
234 { "images_allow", IDS_IMAGES_LOAD_RADIO },
235 { "images_block", IDS_IMAGES_NOLOAD_RADIO },
236 // JavaScript filter.
237 { "javascript_tab_label", IDS_JAVASCRIPT_TAB_LABEL },
238 { "javascript_header", IDS_JAVASCRIPT_HEADER },
239 { "javascript_allow", IDS_JS_ALLOW_RADIO },
240 { "javascript_block", IDS_JS_DONOTALLOW_RADIO },
241 // Plug-ins filter.
242 { "plugins_tab_label", IDS_PLUGIN_TAB_LABEL },
243 { "plugins_header", IDS_PLUGIN_HEADER },
244 { "plugins_ask", IDS_PLUGIN_ASK_RADIO },
245 { "plugins_allow", IDS_PLUGIN_LOAD_RADIO },
246 { "plugins_block", IDS_PLUGIN_NOLOAD_RADIO },
247 { "disableIndividualPlugins", IDS_PLUGIN_SELECTIVE_DISABLE },
248 // Pop-ups filter.
249 { "popups_tab_label", IDS_POPUP_TAB_LABEL },
250 { "popups_header", IDS_POPUP_HEADER },
251 { "popups_allow", IDS_POPUP_ALLOW_RADIO },
252 { "popups_block", IDS_POPUP_BLOCK_RADIO },
253 // Location filter.
254 { "location_tab_label", IDS_GEOLOCATION_TAB_LABEL },
255 { "location_header", IDS_GEOLOCATION_HEADER },
256 { "location_allow", IDS_GEOLOCATION_ALLOW_RADIO },
257 { "location_ask", IDS_GEOLOCATION_ASK_RADIO },
258 { "location_block", IDS_GEOLOCATION_BLOCK_RADIO },
259 // Notifications filter.
260 { "notifications_tab_label", IDS_NOTIFICATIONS_TAB_LABEL },
261 { "notifications_header", IDS_NOTIFICATIONS_HEADER },
262 { "notifications_allow", IDS_NOTIFICATIONS_ALLOW_RADIO },
263 { "notifications_ask", IDS_NOTIFICATIONS_ASK_RADIO },
264 { "notifications_block", IDS_NOTIFICATIONS_BLOCK_RADIO },
265 // Intents filter.
266 { "webIntentsTabLabel", IDS_WEB_INTENTS_TAB_LABEL },
267 { "allowWebIntents", IDS_ALLOW_WEB_INTENTS },
268 // Fullscreen filter.
269 { "fullscreen_tab_label", IDS_FULLSCREEN_TAB_LABEL },
270 { "fullscreen_header", IDS_FULLSCREEN_HEADER },
271 // Mouse Lock filter.
272 { "mouselock_tab_label", IDS_MOUSE_LOCK_TAB_LABEL },
273 { "mouselock_header", IDS_MOUSE_LOCK_HEADER },
274 { "mouselock_allow", IDS_MOUSE_LOCK_ALLOW_RADIO },
275 { "mouselock_ask", IDS_MOUSE_LOCK_ASK_RADIO },
276 { "mouselock_block", IDS_MOUSE_LOCK_BLOCK_RADIO },
277 };
278
279 RegisterStrings(localized_strings, resources, arraysize(resources));
280 RegisterTitle(localized_strings, "contentSettingsPage",
281 IDS_CONTENT_SETTINGS_TITLE);
282 localized_strings->SetBoolean("enable_web_intents",
283 web_intents::IsWebIntentsEnabled());
284 }
285
286 void ContentSettingsHandler::InitializeHandler() {
287 notification_registrar_.Add(
288 this, chrome::NOTIFICATION_PROFILE_CREATED,
289 content::NotificationService::AllSources());
290 notification_registrar_.Add(
291 this, chrome::NOTIFICATION_PROFILE_DESTROYED,
292 content::NotificationService::AllSources());
293
294 UpdateHandlersEnabledRadios();
295 UpdateAllExceptionsViewsFromModel();
296 notification_registrar_.Add(
297 this, chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
298 content::NotificationService::AllSources());
299 notification_registrar_.Add(
300 this, chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
301 content::NotificationService::AllSources());
302 Profile* profile = Profile::FromWebUI(web_ui());
303 notification_registrar_.Add(
304 this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
305 content::Source<Profile>(profile));
306
307 PrefService* prefs = profile->GetPrefs();
308 pref_change_registrar_.Init(prefs);
309 pref_change_registrar_.Add(prefs::kGeolocationContentSettings, this);
310 }
311
312 void ContentSettingsHandler::Observe(
313 int type,
314 const content::NotificationSource& source,
315 const content::NotificationDetails& details) {
316 switch (type) {
317 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
318 if (content::Source<Profile>(source).ptr()->IsOffTheRecord()) {
319 web_ui()->CallJavascriptFunction(
320 "ContentSettingsExceptionsArea.OTRProfileDestroyed");
321 }
322 break;
323 }
324
325 case chrome::NOTIFICATION_PROFILE_CREATED: {
326 if (content::Source<Profile>(source).ptr()->IsOffTheRecord())
327 UpdateAllOTRExceptionsViewsFromModel();
328 break;
329 }
330
331 case chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED: {
332 // Filter out notifications from other profiles.
333 HostContentSettingsMap* map =
334 content::Source<HostContentSettingsMap>(source).ptr();
335 if (map != GetContentSettingsMap() &&
336 map != GetOTRContentSettingsMap())
337 break;
338
339 const ContentSettingsDetails* settings_details =
340 content::Details<const ContentSettingsDetails>(details).ptr();
341
342 // TODO(estade): we pretend update_all() is always true.
343 if (settings_details->update_all_types())
344 UpdateAllExceptionsViewsFromModel();
345 else
346 UpdateExceptionsViewFromModel(settings_details->type());
347 break;
348 }
349
350 case chrome::NOTIFICATION_PREF_CHANGED: {
351 const std::string& pref_name =
352 *content::Details<std::string>(details).ptr();
353 if (pref_name == prefs::kGeolocationContentSettings)
354 UpdateGeolocationExceptionsView();
355 break;
356 }
357
358 case chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED: {
359 UpdateNotificationExceptionsView();
360 break;
361 }
362
363 case chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED: {
364 UpdateHandlersEnabledRadios();
365 break;
366 }
367
368 default:
369 OptionsPageUIHandler::Observe(type, source, details);
370 }
371 }
372
373 void ContentSettingsHandler::UpdateSettingDefaultFromModel(
374 ContentSettingsType type) {
375 DictionaryValue filter_settings;
376 std::string provider_id;
377 filter_settings.SetString(ContentSettingsTypeToGroupName(type) + ".value",
378 GetSettingDefaultFromModel(type, &provider_id));
379 filter_settings.SetString(
380 ContentSettingsTypeToGroupName(type) + ".managedBy",
381 provider_id);
382
383 web_ui()->CallJavascriptFunction(
384 "ContentSettings.setContentFilterSettingsValue", filter_settings);
385 }
386
387 std::string ContentSettingsHandler::GetSettingDefaultFromModel(
388 ContentSettingsType type, std::string* provider_id) {
389 Profile* profile = Profile::FromWebUI(web_ui());
390 ContentSetting default_setting;
391 if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
392 default_setting =
393 DesktopNotificationServiceFactory::GetForProfile(profile)->
394 GetDefaultContentSetting(provider_id);
395 } else {
396 default_setting =
397 profile->GetHostContentSettingsMap()->
398 GetDefaultContentSetting(type, provider_id);
399 }
400
401 return ContentSettingToString(default_setting);
402 }
403
404 void ContentSettingsHandler::UpdateHandlersEnabledRadios() {
405 #if defined(ENABLE_REGISTER_PROTOCOL_HANDLER)
406 base::FundamentalValue handlers_enabled(
407 GetProtocolHandlerRegistry()->enabled());
408
409 web_ui()->CallJavascriptFunction(
410 "ContentSettings.updateHandlersEnabledRadios",
411 handlers_enabled);
412 #endif // defined(ENABLE_REGISTER_PROTOCOL_HANDLER)
413 }
414
415 void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() {
416 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
417 type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
418 // The content settings type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
419 // is supposed to be set by policy only. Hence there is no user facing UI
420 // for this content type and we skip it here.
421 if (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE)
422 continue;
423 UpdateExceptionsViewFromModel(static_cast<ContentSettingsType>(type));
424 }
425 }
426
427 void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() {
428 for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
429 type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
430 UpdateOTRExceptionsViewFromModel(static_cast<ContentSettingsType>(type));
431 }
432 }
433
434 void ContentSettingsHandler::UpdateExceptionsViewFromModel(
435 ContentSettingsType type) {
436 // Don't update intents settings at this point.
437 // Turn on when enable_web_intents_tag is enabled.
438 if (type == CONTENT_SETTINGS_TYPE_INTENTS)
439 return;
440
441 switch (type) {
442 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
443 UpdateGeolocationExceptionsView();
444 break;
445 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
446 UpdateNotificationExceptionsView();
447 break;
448 default:
449 UpdateExceptionsViewFromHostContentSettingsMap(type);
450 break;
451 }
452 }
453
454 void ContentSettingsHandler::UpdateOTRExceptionsViewFromModel(
455 ContentSettingsType type) {
456 switch (type) {
457 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
458 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
459 case CONTENT_SETTINGS_TYPE_INTENTS:
460 case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE:
461 break;
462 default:
463 UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
464 break;
465 }
466 }
467
468 void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
469 Profile* profile = Profile::FromWebUI(web_ui());
470 HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
471
472 ContentSettingsForOneType all_settings;
473 map->GetSettingsForOneType(
474 CONTENT_SETTINGS_TYPE_GEOLOCATION,
475 std::string(),
476 &all_settings);
477
478 // Group geolocation settings by primary_pattern.
479 AllPatternsSettings all_patterns_settings;
480 for (ContentSettingsForOneType::iterator i =
481 all_settings.begin();
482 i != all_settings.end();
483 ++i) {
484 // Don't add default settings.
485 if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
486 i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
487 i->source != "preferences") {
488 continue;
489 }
490 all_patterns_settings[i->primary_pattern][i->secondary_pattern] =
491 i->setting;
492 }
493
494 ListValue exceptions;
495 for (AllPatternsSettings::iterator i = all_patterns_settings.begin();
496 i != all_patterns_settings.end();
497 ++i) {
498 const ContentSettingsPattern& primary_pattern = i->first;
499 const OnePatternSettings& one_settings = i->second;
500
501 OnePatternSettings::const_iterator parent =
502 one_settings.find(primary_pattern);
503
504 // Add the "parent" entry for the non-embedded setting.
505 ContentSetting parent_setting =
506 parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second;
507 exceptions.Append(GetGeolocationExceptionForPage(primary_pattern,
508 primary_pattern,
509 parent_setting));
510
511 // Add the "children" for any embedded settings.
512 for (OnePatternSettings::const_iterator j = one_settings.begin();
513 j != one_settings.end();
514 ++j) {
515 // Skip the non-embedded setting which we already added above.
516 if (j == parent)
517 continue;
518
519 exceptions.Append(
520 GetGeolocationExceptionForPage(primary_pattern, j->first, j->second));
521 }
522 }
523
524 StringValue type_string(
525 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION));
526 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
527 type_string, exceptions);
528
529 // This is mainly here to keep this function ideologically parallel to
530 // UpdateExceptionsViewFromHostContentSettingsMap().
531 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION);
532 }
533
534 void ContentSettingsHandler::UpdateNotificationExceptionsView() {
535 Profile* profile = Profile::FromWebUI(web_ui());
536 DesktopNotificationService* service =
537 DesktopNotificationServiceFactory::GetForProfile(profile);
538
539 ContentSettingsForOneType settings;
540 service->GetNotificationsSettings(&settings);
541
542 ListValue exceptions;
543 for (ContentSettingsForOneType::const_iterator i =
544 settings.begin();
545 i != settings.end();
546 ++i) {
547 // Don't add default settings.
548 if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
549 i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
550 i->source != "preferences") {
551 continue;
552 }
553
554 exceptions.Append(
555 GetNotificationExceptionForPage(i->primary_pattern, i->setting,
556 i->source));
557 }
558
559 StringValue type_string(
560 ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
561 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions",
562 type_string, exceptions);
563
564 // This is mainly here to keep this function ideologically parallel to
565 // UpdateExceptionsViewFromHostContentSettingsMap().
566 UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
567 }
568
569 void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
570 ContentSettingsType type) {
571 ContentSettingsForOneType entries;
572 GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries);
573
574 ListValue exceptions;
575 for (size_t i = 0; i < entries.size(); ++i) {
576 // Skip default settings from extensions and policy, and the default content
577 // settings; all of them will affect the default setting UI.
578 if (entries[i].primary_pattern == ContentSettingsPattern::Wildcard() &&
579 entries[i].secondary_pattern == ContentSettingsPattern::Wildcard() &&
580 entries[i].source != "preference") {
581 continue;
582 }
583 // The content settings UI does not support secondary content settings
584 // pattern yet. For content settings set through the content settings UI the
585 // secondary pattern is by default a wildcard pattern. Hence users are not
586 // able to modify content settings with a secondary pattern other than the
587 // wildcard pattern. So only show settings that the user is able to modify.
588 // TODO(bauerb): Support a read-only view for those patterns.
589 if (entries[i].secondary_pattern == ContentSettingsPattern::Wildcard()) {
590 exceptions.Append(
591 GetExceptionForPage(entries[i].primary_pattern, entries[i].setting,
592 entries[i].source));
593 } else {
594 LOG(ERROR) << "Secondary content settings patterns are not "
595 << "supported by the content settings UI";
596 }
597 }
598
599 StringValue type_string(ContentSettingsTypeToGroupName(type));
600 web_ui()->CallJavascriptFunction("ContentSettings.setExceptions", type_string,
601 exceptions);
602
603 UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
604
605 // TODO(koz): The default for fullscreen is always 'ask'.
606 // http://crbug.com/104683
607 if (type == CONTENT_SETTINGS_TYPE_FULLSCREEN)
608 return;
609
610 // The default may also have changed (we won't get a separate notification).
611 // If it hasn't changed, this call will be harmless.
612 UpdateSettingDefaultFromModel(type);
613 }
614
615 void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
616 ContentSettingsType type) {
617 const HostContentSettingsMap* otr_settings_map = GetOTRContentSettingsMap();
618 if (!otr_settings_map)
619 return;
620
621 ContentSettingsForOneType otr_entries;
622 otr_settings_map->GetSettingsForOneType(type, "", &otr_entries);
623
624 ListValue otr_exceptions;
625 for (size_t i = 0; i < otr_entries.size(); ++i) {
626 // Off-the-record HostContentSettingsMap contains incognito content settings
627 // as well as normal content settings. Here, we use the incongnito settings
628 // only.
629 if (!otr_entries[i].incognito)
630 continue;
631 // The content settings UI does not support secondary content settings
632 // pattern yet. For content settings set through the content settings UI the
633 // secondary pattern is by default a wildcard pattern. Hence users are not
634 // able to modify content settings with a secondary pattern other than the
635 // wildcard pattern. So only show settings that the user is able to modify.
636 // TODO(bauerb): Support a read-only view for those patterns.
637 if (otr_entries[i].secondary_pattern ==
638 ContentSettingsPattern::Wildcard()) {
639 otr_exceptions.Append(
640 GetExceptionForPage(otr_entries[i].primary_pattern,
641 otr_entries[i].setting,
642 otr_entries[i].source));
643 } else {
644 LOG(ERROR) << "Secondary content settings patterns are not "
645 << "supported by the content settings UI";
646 }
647 }
648
649 StringValue type_string(ContentSettingsTypeToGroupName(type));
650 web_ui()->CallJavascriptFunction("ContentSettings.setOTRExceptions",
651 type_string, otr_exceptions);
652 }
653
654 void ContentSettingsHandler::RegisterMessages() {
655 web_ui()->RegisterMessageCallback("setContentFilter",
656 base::Bind(&ContentSettingsHandler::SetContentFilter,
657 base::Unretained(this)));
658 web_ui()->RegisterMessageCallback("removeException",
659 base::Bind(&ContentSettingsHandler::RemoveException,
660 base::Unretained(this)));
661 web_ui()->RegisterMessageCallback("setException",
662 base::Bind(&ContentSettingsHandler::SetException,
663 base::Unretained(this)));
664 web_ui()->RegisterMessageCallback("checkExceptionPatternValidity",
665 base::Bind(&ContentSettingsHandler::CheckExceptionPatternValidity,
666 base::Unretained(this)));
667 }
668
669 void ContentSettingsHandler::ApplyWhitelist(ContentSettingsType content_type,
670 ContentSetting default_setting) {
671 Profile* profile = Profile::FromWebUI(web_ui());
672 HostContentSettingsMap* map = GetContentSettingsMap();
673 if (content_type != CONTENT_SETTINGS_TYPE_PLUGINS)
674 return;
675 const int kDefaultWhitelistVersion = 1;
676 PrefService* prefs = profile->GetPrefs();
677 int version = prefs->GetInteger(
678 prefs::kContentSettingsDefaultWhitelistVersion);
679 if (version >= kDefaultWhitelistVersion)
680 return;
681 ContentSetting old_setting =
682 map->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, NULL);
683 if (old_setting == CONTENT_SETTING_ALLOW &&
684 default_setting == CONTENT_SETTING_ASK) {
685 map->SetWebsiteSetting(
686 ContentSettingsPattern::Wildcard(),
687 ContentSettingsPattern::Wildcard(),
688 CONTENT_SETTINGS_TYPE_PLUGINS,
689 "google-talk",
690 Value::CreateIntegerValue(CONTENT_SETTING_ALLOW));
691 }
692 prefs->SetInteger(prefs::kContentSettingsDefaultWhitelistVersion,
693 kDefaultWhitelistVersion);
694 }
695
696 void ContentSettingsHandler::SetContentFilter(const ListValue* args) {
697 DCHECK_EQ(2U, args->GetSize());
698 std::string group, setting;
699 if (!(args->GetString(0, &group) &&
700 args->GetString(1, &setting))) {
701 NOTREACHED();
702 return;
703 }
704
705 ContentSetting default_setting = ContentSettingFromString(setting);
706 ContentSettingsType content_type = ContentSettingsTypeFromGroupName(group);
707 Profile* profile = Profile::FromWebUI(web_ui());
708 if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
709 DesktopNotificationServiceFactory::GetForProfile(profile)->
710 SetDefaultContentSetting(default_setting);
711 } else {
712 HostContentSettingsMap* map = GetContentSettingsMap();
713 ApplyWhitelist(content_type, default_setting);
714 map->SetDefaultContentSetting(content_type, default_setting);
715 }
716 switch (content_type) {
717 case CONTENT_SETTINGS_TYPE_COOKIES:
718 content::RecordAction(
719 UserMetricsAction("Options_DefaultCookieSettingChanged"));
720 break;
721 case CONTENT_SETTINGS_TYPE_IMAGES:
722 content::RecordAction(
723 UserMetricsAction("Options_DefaultImagesSettingChanged"));
724 break;
725 case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
726 content::RecordAction(
727 UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
728 break;
729 case CONTENT_SETTINGS_TYPE_PLUGINS:
730 content::RecordAction(
731 UserMetricsAction("Options_DefaultPluginsSettingChanged"));
732 break;
733 case CONTENT_SETTINGS_TYPE_POPUPS:
734 content::RecordAction(
735 UserMetricsAction("Options_DefaultPopupsSettingChanged"));
736 break;
737 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
738 content::RecordAction(
739 UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
740 break;
741 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
742 content::RecordAction(
743 UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
744 break;
745 case CONTENT_SETTINGS_TYPE_INTENTS:
746 content::RecordAction(
747 UserMetricsAction("Options_DefaultHandlersSettingChanged"));
748 break;
749 case CONTENT_SETTINGS_TYPE_MOUSELOCK:
750 content::RecordAction(
751 UserMetricsAction("Options_DefaultMouseLockSettingChanged"));
752 break;
753 default:
754 break;
755 }
756 }
757
758 void ContentSettingsHandler::RemoveException(const ListValue* args) {
759 size_t arg_i = 0;
760 std::string type_string;
761 CHECK(args->GetString(arg_i++, &type_string));
762
763 Profile* profile = Profile::FromWebUI(web_ui());
764 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string);
765 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) {
766 std::string origin;
767 std::string embedding_origin;
768 bool rv = args->GetString(arg_i++, &origin);
769 DCHECK(rv);
770 rv = args->GetString(arg_i++, &embedding_origin);
771 DCHECK(rv);
772
773 profile->GetHostContentSettingsMap()->
774 SetContentSetting(ContentSettingsPattern::FromString(origin),
775 ContentSettingsPattern::FromString(embedding_origin),
776 CONTENT_SETTINGS_TYPE_GEOLOCATION,
777 std::string(),
778 CONTENT_SETTING_DEFAULT);
779 } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
780 std::string origin;
781 std::string setting;
782 bool rv = args->GetString(arg_i++, &origin);
783 DCHECK(rv);
784 rv = args->GetString(arg_i++, &setting);
785 DCHECK(rv);
786 ContentSetting content_setting = ContentSettingFromString(setting);
787
788 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
789 content_setting == CONTENT_SETTING_BLOCK);
790 DesktopNotificationServiceFactory::GetForProfile(profile)->
791 ClearSetting(ContentSettingsPattern::FromString(origin));
792 } else {
793 std::string mode;
794 bool rv = args->GetString(arg_i++, &mode);
795 DCHECK(rv);
796
797 std::string pattern;
798 rv = args->GetString(arg_i++, &pattern);
799 DCHECK(rv);
800
801 HostContentSettingsMap* settings_map =
802 mode == "normal" ? GetContentSettingsMap() :
803 GetOTRContentSettingsMap();
804 // The settings map could be null if the mode was OTR but the OTR profile
805 // got destroyed before we received this message.
806 if (settings_map) {
807 settings_map->SetContentSetting(
808 ContentSettingsPattern::FromString(pattern),
809 ContentSettingsPattern::Wildcard(),
810 ContentSettingsTypeFromGroupName(type_string),
811 "",
812 CONTENT_SETTING_DEFAULT);
813 }
814 }
815 }
816
817 void ContentSettingsHandler::SetException(const ListValue* args) {
818 size_t arg_i = 0;
819 std::string type_string;
820 CHECK(args->GetString(arg_i++, &type_string));
821 std::string mode;
822 CHECK(args->GetString(arg_i++, &mode));
823 std::string pattern;
824 CHECK(args->GetString(arg_i++, &pattern));
825 std::string setting;
826 CHECK(args->GetString(arg_i++, &setting));
827
828 ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string);
829 if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
830 type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
831 NOTREACHED();
832 return;
833 }
834
835 HostContentSettingsMap* settings_map =
836 mode == "normal" ? GetContentSettingsMap() :
837 GetOTRContentSettingsMap();
838
839 // The settings map could be null if the mode was OTR but the OTR profile
840 // got destroyed before we received this message.
841 if (!settings_map)
842 return;
843 settings_map->SetContentSetting(ContentSettingsPattern::FromString(pattern),
844 ContentSettingsPattern::Wildcard(),
845 type,
846 "",
847 ContentSettingFromString(setting));
848 }
849
850 void ContentSettingsHandler::CheckExceptionPatternValidity(
851 const ListValue* args) {
852 size_t arg_i = 0;
853 Value* type;
854 CHECK(args->Get(arg_i++, &type));
855 std::string mode_string;
856 CHECK(args->GetString(arg_i++, &mode_string));
857 std::string pattern_string;
858 CHECK(args->GetString(arg_i++, &pattern_string));
859
860 ContentSettingsPattern pattern =
861 ContentSettingsPattern::FromString(pattern_string);
862
863 scoped_ptr<Value> mode_value(Value::CreateStringValue(mode_string));
864 scoped_ptr<Value> pattern_value(Value::CreateStringValue(pattern_string));
865 scoped_ptr<Value> valid_value(Value::CreateBooleanValue(pattern.IsValid()));
866
867 web_ui()->CallJavascriptFunction(
868 "ContentSettings.patternValidityCheckComplete",
869 *type,
870 *mode_value.get(),
871 *pattern_value.get(),
872 *valid_value.get());
873 }
874
875 // static
876 std::string ContentSettingsHandler::ContentSettingsTypeToGroupName(
877 ContentSettingsType type) {
878 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) {
879 if (type == kContentSettingsTypeGroupNames[i].type)
880 return kContentSettingsTypeGroupNames[i].name;
881 }
882
883 NOTREACHED();
884 return std::string();
885 }
886
887 HostContentSettingsMap* ContentSettingsHandler::GetContentSettingsMap() {
888 return Profile::FromWebUI(web_ui())->GetHostContentSettingsMap();
889 }
890
891 ProtocolHandlerRegistry* ContentSettingsHandler::GetProtocolHandlerRegistry() {
892 return Profile::FromWebUI(web_ui())->GetProtocolHandlerRegistry();
893 }
894
895 HostContentSettingsMap*
896 ContentSettingsHandler::GetOTRContentSettingsMap() {
897 Profile* profile = Profile::FromWebUI(web_ui());
898 if (profile->HasOffTheRecordProfile())
899 return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap();
900 return NULL;
901 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698