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

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

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

Powered by Google App Engine
This is Rietveld 408576698