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

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

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

Powered by Google App Engine
This is Rietveld 408576698