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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/webui/options2/content_settings_handler.cc
diff --git a/chrome/browser/ui/webui/options2/content_settings_handler.cc b/chrome/browser/ui/webui/options2/content_settings_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..67fb223d5f78e230e202a0483e08b55b7cc3c4fd
--- /dev/null
+++ b/chrome/browser/ui/webui/options2/content_settings_handler.cc
@@ -0,0 +1,879 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/options2/content_settings_handler.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/content_settings/content_settings_details.h"
+#include "chrome/browser/content_settings/content_settings_utils.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "chrome/browser/notifications/desktop_notification_service.h"
+#include "chrome/browser/notifications/desktop_notification_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_pattern.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/user_metrics.h"
+#include "content/public/common/content_switches.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using content::UserMetricsAction;
+
+namespace {
+
+struct ContentSettingsTypeNameEntry {
+ ContentSettingsType type;
+ const char* name;
+};
+
+typedef std::map<ContentSettingsPattern, ContentSetting> OnePatternSettings;
+typedef std::map<ContentSettingsPattern, OnePatternSettings>
+ AllPatternsSettings;
+
+const char* kDisplayPattern = "displayPattern";
+const char* kSetting = "setting";
+const char* kOrigin = "origin";
+const char* kSource = "source";
+const char* kEmbeddingOrigin = "embeddingOrigin";
+
+const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
+ {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"},
+ {CONTENT_SETTINGS_TYPE_IMAGES, "images"},
+ {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"},
+ {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"},
+ {CONTENT_SETTINGS_TYPE_POPUPS, "popups"},
+ {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"},
+ {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"},
+ {CONTENT_SETTINGS_TYPE_INTENTS, "intents"},
+ {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"},
+ {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"},
+ {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"},
+};
+COMPILE_ASSERT(arraysize(kContentSettingsTypeGroupNames) ==
+ CONTENT_SETTINGS_NUM_TYPES,
+ MISSING_CONTENT_SETTINGS_TYPE);
+
+ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) {
+ for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) {
+ if (name == kContentSettingsTypeGroupNames[i].name)
+ return kContentSettingsTypeGroupNames[i].type;
+ }
+
+ NOTREACHED() << name << " is not a recognized content settings type.";
+ return CONTENT_SETTINGS_TYPE_DEFAULT;
+}
+
+std::string ContentSettingToString(ContentSetting setting) {
+ switch (setting) {
+ case CONTENT_SETTING_ALLOW:
+ return "allow";
+ case CONTENT_SETTING_ASK:
+ return "ask";
+ case CONTENT_SETTING_BLOCK:
+ return "block";
+ case CONTENT_SETTING_SESSION_ONLY:
+ return "session";
+ case CONTENT_SETTING_DEFAULT:
+ return "default";
+ case CONTENT_SETTING_NUM_SETTINGS:
+ NOTREACHED();
+ }
+
+ return "";
+}
+
+ContentSetting ContentSettingFromString(const std::string& name) {
+ if (name == "allow")
+ return CONTENT_SETTING_ALLOW;
+ if (name == "ask")
+ return CONTENT_SETTING_ASK;
+ if (name == "block")
+ return CONTENT_SETTING_BLOCK;
+ if (name == "session")
+ return CONTENT_SETTING_SESSION_ONLY;
+
+ NOTREACHED() << name << " is not a recognized content setting.";
+ return CONTENT_SETTING_DEFAULT;
+}
+
+std::string GeolocationExceptionToString(
+ const ContentSettingsPattern& origin,
+ const ContentSettingsPattern& embedding_origin) {
+ if (origin == embedding_origin)
+ return origin.ToString();
+
+ // TODO(estade): the page needs to use CSS to indent the string.
+ std::string indent(" ");
+
+ if (embedding_origin == ContentSettingsPattern::Wildcard()) {
+ // NOTE: As long as the user cannot add/edit entries from the exceptions
+ // dialog, it's impossible to actually have a non-default setting for some
+ // origin "embedded on any other site", so this row will never appear. If
+ // we add the ability to add/edit exceptions, we'll need to decide when to
+ // display this and how "removing" it will function.
+ return indent +
+ l10n_util::GetStringUTF8(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER);
+ }
+
+ return indent + l10n_util::GetStringFUTF8(
+ IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
+ UTF8ToUTF16(embedding_origin.ToString()));
+}
+
+// Create a DictionaryValue* that will act as a data source for a single row
+// in a HostContentSettingsMap-controlled exceptions table (e.g., cookies).
+// Ownership of the pointer is passed to the caller.
+DictionaryValue* GetExceptionForPage(
+ const ContentSettingsPattern& pattern,
+ ContentSetting setting,
+ std::string provider_name) {
+ DictionaryValue* exception = new DictionaryValue();
+ exception->SetString(kDisplayPattern, pattern.ToString());
+ exception->SetString(kSetting, ContentSettingToString(setting));
+ exception->SetString(kSource, provider_name);
+ return exception;
+}
+
+// Create a DictionaryValue* that will act as a data source for a single row
+// in the Geolocation exceptions table. Ownership of the pointer is passed to
+// the caller.
+DictionaryValue* GetGeolocationExceptionForPage(
+ const ContentSettingsPattern& origin,
+ const ContentSettingsPattern& embedding_origin,
+ ContentSetting setting) {
+ DictionaryValue* exception = new DictionaryValue();
+ exception->SetString(kDisplayPattern,
+ GeolocationExceptionToString(origin, embedding_origin));
+ exception->SetString(kSetting, ContentSettingToString(setting));
+ exception->SetString(kOrigin, origin.ToString());
+ exception->SetString(kEmbeddingOrigin, embedding_origin.ToString());
+ return exception;
+}
+
+// Create a DictionaryValue* that will act as a data source for a single row
+// in the desktop notifications exceptions table. Ownership of the pointer is
+// passed to the caller.
+DictionaryValue* GetNotificationExceptionForPage(
+ const ContentSettingsPattern& pattern,
+ ContentSetting setting,
+ const std::string& provider_name) {
+ DictionaryValue* exception = new DictionaryValue();
+ exception->SetString(kDisplayPattern, pattern.ToString());
+ exception->SetString(kSetting, ContentSettingToString(setting));
+ exception->SetString(kOrigin, pattern.ToString());
+ exception->SetString(kSource, provider_name);
+ return exception;
+}
+
+} // namespace
+
+ContentSettingsHandler::ContentSettingsHandler() {
+}
+
+ContentSettingsHandler::~ContentSettingsHandler() {
+}
+
+void ContentSettingsHandler::GetLocalizedValues(
+ DictionaryValue* localized_strings) {
+ DCHECK(localized_strings);
+
+ static OptionsStringResource resources[] = {
+ { "content_exceptions", IDS_COOKIES_EXCEPTIONS_BUTTON },
+ { "allowException", IDS_EXCEPTIONS_ALLOW_BUTTON },
+ { "blockException", IDS_EXCEPTIONS_BLOCK_BUTTON },
+ { "sessionException", IDS_EXCEPTIONS_SESSION_ONLY_BUTTON },
+ { "askException", IDS_EXCEPTIONS_ASK_BUTTON },
+ { "addExceptionRow", IDS_EXCEPTIONS_ADD_BUTTON },
+ { "removeExceptionRow", IDS_EXCEPTIONS_REMOVE_BUTTON },
+ { "editExceptionRow", IDS_EXCEPTIONS_EDIT_BUTTON },
+ { "otr_exceptions_explanation", IDS_EXCEPTIONS_OTR_LABEL },
+ { "examplePattern", IDS_EXCEPTIONS_PATTERN_EXAMPLE },
+ { "addNewExceptionInstructions", IDS_EXCEPTIONS_ADD_NEW_INSTRUCTIONS },
+ { "manage_exceptions", IDS_EXCEPTIONS_MANAGE },
+ { "manage_handlers", IDS_HANDLERS_MANAGE },
+ { "exceptionPatternHeader", IDS_EXCEPTIONS_PATTERN_HEADER },
+ { "exceptionBehaviorHeader", IDS_EXCEPTIONS_ACTION_HEADER },
+ // Cookies filter.
+ { "cookies_tab_label", IDS_COOKIES_TAB_LABEL },
+ { "cookies_header", IDS_COOKIES_HEADER },
+ { "cookies_allow", IDS_COOKIES_ALLOW_RADIO },
+ { "cookies_block", IDS_COOKIES_BLOCK_RADIO },
+ { "cookies_session_only", IDS_COOKIES_SESSION_ONLY_RADIO },
+ { "cookies_block_3rd_party", IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX },
+ { "cookies_clear_when_close", IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX },
+ { "cookies_lso_clear_when_close", IDS_COOKIES_LSO_CLEAR_WHEN_CLOSE_CHKBOX },
+ { "cookies_show_cookies", IDS_COOKIES_SHOW_COOKIES_BUTTON },
+ { "flash_storage_settings", IDS_FLASH_STORAGE_SETTINGS },
+ { "flash_storage_url", IDS_FLASH_STORAGE_URL },
+ // Image filter.
+ { "images_tab_label", IDS_IMAGES_TAB_LABEL },
+ { "images_header", IDS_IMAGES_HEADER },
+ { "images_allow", IDS_IMAGES_LOAD_RADIO },
+ { "images_block", IDS_IMAGES_NOLOAD_RADIO },
+ // JavaScript filter.
+ { "javascript_tab_label", IDS_JAVASCRIPT_TAB_LABEL },
+ { "javascript_header", IDS_JAVASCRIPT_HEADER },
+ { "javascript_allow", IDS_JS_ALLOW_RADIO },
+ { "javascript_block", IDS_JS_DONOTALLOW_RADIO },
+ // Plug-ins filter.
+ { "plugins_tab_label", IDS_PLUGIN_TAB_LABEL },
+ { "plugins_header", IDS_PLUGIN_HEADER },
+ { "plugins_ask", IDS_PLUGIN_ASK_RADIO },
+ { "plugins_allow", IDS_PLUGIN_LOAD_RADIO },
+ { "plugins_block", IDS_PLUGIN_NOLOAD_RADIO },
+ { "disableIndividualPlugins", IDS_PLUGIN_SELECTIVE_DISABLE },
+ // Pop-ups filter.
+ { "popups_tab_label", IDS_POPUP_TAB_LABEL },
+ { "popups_header", IDS_POPUP_HEADER },
+ { "popups_allow", IDS_POPUP_ALLOW_RADIO },
+ { "popups_block", IDS_POPUP_BLOCK_RADIO },
+ // Location filter.
+ { "location_tab_label", IDS_GEOLOCATION_TAB_LABEL },
+ { "location_header", IDS_GEOLOCATION_HEADER },
+ { "location_allow", IDS_GEOLOCATION_ALLOW_RADIO },
+ { "location_ask", IDS_GEOLOCATION_ASK_RADIO },
+ { "location_block", IDS_GEOLOCATION_BLOCK_RADIO },
+ // Notifications filter.
+ { "notifications_tab_label", IDS_NOTIFICATIONS_TAB_LABEL },
+ { "notifications_header", IDS_NOTIFICATIONS_HEADER },
+ { "notifications_allow", IDS_NOTIFICATIONS_ALLOW_RADIO },
+ { "notifications_ask", IDS_NOTIFICATIONS_ASK_RADIO },
+ { "notifications_block", IDS_NOTIFICATIONS_BLOCK_RADIO },
+ // Intents filter.
+ { "intentsTabLabel", IDS_INTENTS_TAB_LABEL },
+ { "intentsAllow", IDS_INTENTS_ALLOW_RADIO },
+ { "intentsAsk", IDS_INTENTS_ASK_RADIO },
+ { "intentsBlock", IDS_INTENTS_BLOCK_RADIO },
+ { "intents_header", IDS_INTENTS_HEADER },
+ // Fullscreen filter.
+ { "fullscreen_tab_label", IDS_FULLSCREEN_TAB_LABEL },
+ { "fullscreen_header", IDS_FULLSCREEN_HEADER },
+ // Mouse Lock filter.
+ { "mouselock_tab_label", IDS_MOUSE_LOCK_TAB_LABEL },
+ { "mouselock_header", IDS_MOUSE_LOCK_HEADER },
+ { "mouselock_allow", IDS_MOUSE_LOCK_ALLOW_RADIO },
+ { "mouselock_ask", IDS_MOUSE_LOCK_ASK_RADIO },
+ { "mouselock_block", IDS_MOUSE_LOCK_BLOCK_RADIO },
+ };
+
+ RegisterStrings(localized_strings, resources, arraysize(resources));
+ RegisterTitle(localized_strings, "contentSettingsPage",
+ IDS_CONTENT_SETTINGS_TITLE);
+ localized_strings->SetBoolean("enable_click_to_play",
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableClickToPlay));
+ localized_strings->SetBoolean("enable_web_intents",
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableWebIntents));
+}
+
+void ContentSettingsHandler::Initialize() {
+ notification_registrar_.Add(
+ this, chrome::NOTIFICATION_PROFILE_CREATED,
+ content::NotificationService::AllSources());
+ notification_registrar_.Add(
+ this, chrome::NOTIFICATION_PROFILE_DESTROYED,
+ content::NotificationService::AllSources());
+
+ UpdateHandlersEnabledRadios();
+ UpdateAllExceptionsViewsFromModel();
+ notification_registrar_.Add(
+ this, chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
+ content::NotificationService::AllSources());
+ notification_registrar_.Add(
+ this, chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
+ content::NotificationService::AllSources());
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ notification_registrar_.Add(
+ this, chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED,
+ content::Source<Profile>(profile));
+
+ PrefService* prefs = profile->GetPrefs();
+ pref_change_registrar_.Init(prefs);
+ pref_change_registrar_.Add(prefs::kGeolocationContentSettings, this);
+}
+
+void ContentSettingsHandler::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_PROFILE_DESTROYED: {
+ if (content::Source<Profile>(source).ptr()->IsOffTheRecord()) {
+ web_ui_->CallJavascriptFunction(
+ "ContentSettingsExceptionsArea.OTRProfileDestroyed");
+ }
+ break;
+ }
+
+ case chrome::NOTIFICATION_PROFILE_CREATED: {
+ if (content::Source<Profile>(source).ptr()->IsOffTheRecord())
+ UpdateAllOTRExceptionsViewsFromModel();
+ break;
+ }
+
+ case chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED: {
+ // Filter out notifications from other profiles.
+ HostContentSettingsMap* map =
+ content::Source<HostContentSettingsMap>(source).ptr();
+ if (map != GetContentSettingsMap() &&
+ map != GetOTRContentSettingsMap())
+ break;
+
+ const ContentSettingsDetails* settings_details =
+ content::Details<const ContentSettingsDetails>(details).ptr();
+
+ // TODO(estade): we pretend update_all() is always true.
+ if (settings_details->update_all_types())
+ UpdateAllExceptionsViewsFromModel();
+ else
+ UpdateExceptionsViewFromModel(settings_details->type());
+ break;
+ }
+
+ case chrome::NOTIFICATION_PREF_CHANGED: {
+ const std::string& pref_name =
+ *content::Details<std::string>(details).ptr();
+ if (pref_name == prefs::kGeolocationContentSettings)
+ UpdateGeolocationExceptionsView();
+ break;
+ }
+
+ case chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED: {
+ UpdateNotificationExceptionsView();
+ break;
+ }
+
+ case chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED: {
+ UpdateHandlersEnabledRadios();
+ break;
+ }
+
+ default:
+ OptionsPage2UIHandler::Observe(type, source, details);
+ }
+}
+
+void ContentSettingsHandler::UpdateSettingDefaultFromModel(
+ ContentSettingsType type) {
+ DictionaryValue filter_settings;
+ std::string provider_id;
+ filter_settings.SetString(ContentSettingsTypeToGroupName(type) + ".value",
+ GetSettingDefaultFromModel(type, &provider_id));
+ filter_settings.SetString(
+ ContentSettingsTypeToGroupName(type) + ".managedBy",
+ provider_id);
+
+ web_ui_->CallJavascriptFunction(
+ "ContentSettings.setContentFilterSettingsValue", filter_settings);
+}
+
+std::string ContentSettingsHandler::GetSettingDefaultFromModel(
+ ContentSettingsType type, std::string* provider_id) {
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ ContentSetting default_setting;
+ if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
+ default_setting =
+ DesktopNotificationServiceFactory::GetForProfile(profile)->
+ GetDefaultContentSetting(provider_id);
+ } else {
+ default_setting =
+ profile->GetHostContentSettingsMap()->
+ GetDefaultContentSetting(type, provider_id);
+ }
+
+ return ContentSettingToString(default_setting);
+}
+
+void ContentSettingsHandler::UpdateHandlersEnabledRadios() {
+#if defined(ENABLE_REGISTER_PROTOCOL_HANDLER)
+ DCHECK(web_ui_);
+ base::FundamentalValue handlers_enabled(
+ GetProtocolHandlerRegistry()->enabled());
+
+ web_ui_->CallJavascriptFunction("ContentSettings.updateHandlersEnabledRadios",
+ handlers_enabled);
+#endif // defined(ENABLE_REGISTER_PROTOCOL_HANDLER)
+}
+
+void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() {
+ for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
+ type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
+ // The content settings type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
+ // is supposed to be set by policy only. Hence there is no user facing UI
+ // for this content type and we skip it here.
+ if (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE)
+ continue;
+ UpdateExceptionsViewFromModel(static_cast<ContentSettingsType>(type));
+ }
+}
+
+void ContentSettingsHandler::UpdateAllOTRExceptionsViewsFromModel() {
+ for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
+ type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
+ UpdateOTRExceptionsViewFromModel(static_cast<ContentSettingsType>(type));
+ }
+}
+
+void ContentSettingsHandler::UpdateExceptionsViewFromModel(
+ ContentSettingsType type) {
+ // Skip updating intents unless it's enabled from the command line.
+ if (type == CONTENT_SETTINGS_TYPE_INTENTS &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableWebIntents))
+ return;
+
+ switch (type) {
+ case CONTENT_SETTINGS_TYPE_GEOLOCATION:
+ UpdateGeolocationExceptionsView();
+ break;
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ UpdateNotificationExceptionsView();
+ break;
+ default:
+ UpdateExceptionsViewFromHostContentSettingsMap(type);
+ break;
+ }
+}
+
+void ContentSettingsHandler::UpdateOTRExceptionsViewFromModel(
+ ContentSettingsType type) {
+ switch (type) {
+ case CONTENT_SETTINGS_TYPE_GEOLOCATION:
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ case CONTENT_SETTINGS_TYPE_INTENTS:
+ case CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE:
+ break;
+ default:
+ UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
+ break;
+ }
+}
+
+void ContentSettingsHandler::UpdateGeolocationExceptionsView() {
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ HostContentSettingsMap* map = profile->GetHostContentSettingsMap();
+
+ ContentSettingsForOneType all_settings;
+ map->GetSettingsForOneType(
+ CONTENT_SETTINGS_TYPE_GEOLOCATION,
+ std::string(),
+ &all_settings);
+
+ // Group geolocation settings by primary_pattern.
+ AllPatternsSettings all_patterns_settings;
+ for (ContentSettingsForOneType::iterator i =
+ all_settings.begin();
+ i != all_settings.end();
+ ++i) {
+ // Don't add default settings.
+ if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
+ i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
+ i->source != "preferences") {
+ continue;
+ }
+ all_patterns_settings[i->primary_pattern][i->secondary_pattern] =
+ i->setting;
+ }
+
+ ListValue exceptions;
+ for (AllPatternsSettings::iterator i = all_patterns_settings.begin();
+ i != all_patterns_settings.end();
+ ++i) {
+ const ContentSettingsPattern& primary_pattern = i->first;
+ const OnePatternSettings& one_settings = i->second;
+
+ OnePatternSettings::const_iterator parent =
+ one_settings.find(primary_pattern);
+
+ // Add the "parent" entry for the non-embedded setting.
+ ContentSetting parent_setting =
+ parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second;
+ exceptions.Append(GetGeolocationExceptionForPage(primary_pattern,
+ primary_pattern,
+ parent_setting));
+
+ // Add the "children" for any embedded settings.
+ for (OnePatternSettings::const_iterator j = one_settings.begin();
+ j != one_settings.end();
+ ++j) {
+ // Skip the non-embedded setting which we already added above.
+ if (j == parent)
+ continue;
+
+ exceptions.Append(
+ GetGeolocationExceptionForPage(primary_pattern, j->first, j->second));
+ }
+ }
+
+ StringValue type_string(
+ ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_GEOLOCATION));
+ web_ui_->CallJavascriptFunction("ContentSettings.setExceptions",
+ type_string, exceptions);
+
+ // This is mainly here to keep this function ideologically parallel to
+ // UpdateExceptionsViewFromHostContentSettingsMap().
+ UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION);
+}
+
+void ContentSettingsHandler::UpdateNotificationExceptionsView() {
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ DesktopNotificationService* service =
+ DesktopNotificationServiceFactory::GetForProfile(profile);
+
+ ContentSettingsForOneType settings;
+ service->GetNotificationsSettings(&settings);
+
+ ListValue exceptions;
+ for (ContentSettingsForOneType::const_iterator i =
+ settings.begin();
+ i != settings.end();
+ ++i) {
+ // Don't add default settings.
+ if (i->primary_pattern == ContentSettingsPattern::Wildcard() &&
+ i->secondary_pattern == ContentSettingsPattern::Wildcard() &&
+ i->source != "preferences") {
+ continue;
+ }
+
+ exceptions.Append(
+ GetNotificationExceptionForPage(i->primary_pattern, i->setting,
+ i->source));
+ }
+
+ StringValue type_string(
+ ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
+ web_ui_->CallJavascriptFunction("ContentSettings.setExceptions",
+ type_string, exceptions);
+
+ // This is mainly here to keep this function ideologically parallel to
+ // UpdateExceptionsViewFromHostContentSettingsMap().
+ UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
+}
+
+void ContentSettingsHandler::UpdateExceptionsViewFromHostContentSettingsMap(
+ ContentSettingsType type) {
+ ContentSettingsForOneType entries;
+ GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries);
+
+ ListValue exceptions;
+ for (size_t i = 0; i < entries.size(); ++i) {
+ // Skip default settings from extensions and policy, and the default content
+ // settings; all of them will affect the default setting UI.
+ if (entries[i].primary_pattern == ContentSettingsPattern::Wildcard() &&
+ entries[i].secondary_pattern == ContentSettingsPattern::Wildcard() &&
+ entries[i].source != "preference") {
+ continue;
+ }
+ // The content settings UI does not support secondary content settings
+ // pattern yet. For content settings set through the content settings UI the
+ // secondary pattern is by default a wildcard pattern. Hence users are not
+ // able to modify content settings with a secondary pattern other than the
+ // wildcard pattern. So only show settings that the user is able to modify.
+ // TODO(bauerb): Support a read-only view for those patterns.
+ if (entries[i].secondary_pattern == ContentSettingsPattern::Wildcard()) {
+ exceptions.Append(
+ GetExceptionForPage(entries[i].primary_pattern, entries[i].setting,
+ entries[i].source));
+ } else {
+ LOG(ERROR) << "Secondary content settings patterns are not "
+ << "supported by the content settings UI";
+ }
+ }
+
+ StringValue type_string(ContentSettingsTypeToGroupName(type));
+ web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", type_string,
+ exceptions);
+
+ UpdateExceptionsViewFromOTRHostContentSettingsMap(type);
+
+ // TODO(koz): The default for fullscreen is always 'ask'.
+ // http://crbug.com/104683
+ if (type == CONTENT_SETTINGS_TYPE_FULLSCREEN)
+ return;
+
+ // The default may also have changed (we won't get a separate notification).
+ // If it hasn't changed, this call will be harmless.
+ UpdateSettingDefaultFromModel(type);
+}
+
+void ContentSettingsHandler::UpdateExceptionsViewFromOTRHostContentSettingsMap(
+ ContentSettingsType type) {
+ const HostContentSettingsMap* otr_settings_map = GetOTRContentSettingsMap();
+ if (!otr_settings_map)
+ return;
+
+ ContentSettingsForOneType otr_entries;
+ otr_settings_map->GetSettingsForOneType(type, "", &otr_entries);
+
+ ListValue otr_exceptions;
+ for (size_t i = 0; i < otr_entries.size(); ++i) {
+ // Off-the-record HostContentSettingsMap contains incognito content settings
+ // as well as normal content settings. Here, we use the incongnito settings
+ // only.
+ if (!otr_entries[i].incognito)
+ continue;
+ // The content settings UI does not support secondary content settings
+ // pattern yet. For content settings set through the content settings UI the
+ // secondary pattern is by default a wildcard pattern. Hence users are not
+ // able to modify content settings with a secondary pattern other than the
+ // wildcard pattern. So only show settings that the user is able to modify.
+ // TODO(bauerb): Support a read-only view for those patterns.
+ if (otr_entries[i].secondary_pattern ==
+ ContentSettingsPattern::Wildcard()) {
+ otr_exceptions.Append(
+ GetExceptionForPage(otr_entries[i].primary_pattern,
+ otr_entries[i].setting,
+ otr_entries[i].source));
+ } else {
+ LOG(ERROR) << "Secondary content settings patterns are not "
+ << "supported by the content settings UI";
+ }
+ }
+
+ StringValue type_string(ContentSettingsTypeToGroupName(type));
+ web_ui_->CallJavascriptFunction("ContentSettings.setOTRExceptions",
+ type_string, otr_exceptions);
+}
+
+void ContentSettingsHandler::RegisterMessages() {
+ web_ui_->RegisterMessageCallback("setContentFilter",
+ base::Bind(&ContentSettingsHandler::SetContentFilter,
+ base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("removeException",
+ base::Bind(&ContentSettingsHandler::RemoveException,
+ base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("setException",
+ base::Bind(&ContentSettingsHandler::SetException,
+ base::Unretained(this)));
+ web_ui_->RegisterMessageCallback("checkExceptionPatternValidity",
+ base::Bind(&ContentSettingsHandler::CheckExceptionPatternValidity,
+ base::Unretained(this)));
+}
+
+void ContentSettingsHandler::SetContentFilter(const ListValue* args) {
+ DCHECK_EQ(2U, args->GetSize());
+ std::string group, setting;
+ if (!(args->GetString(0, &group) &&
+ args->GetString(1, &setting))) {
+ NOTREACHED();
+ return;
+ }
+
+ ContentSetting default_setting = ContentSettingFromString(setting);
+ ContentSettingsType content_type = ContentSettingsTypeFromGroupName(group);
+ if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ DesktopNotificationServiceFactory::GetForProfile(profile)->
+ SetDefaultContentSetting(default_setting);
+ } else {
+ GetContentSettingsMap()->
+ SetDefaultContentSetting(content_type, default_setting);
+ }
+ switch (content_type) {
+ case CONTENT_SETTINGS_TYPE_COOKIES:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultCookieSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_IMAGES:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultImagesSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultJavaScriptSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_PLUGINS:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultPluginsSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_POPUPS:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultPopupsSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultNotificationsSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_GEOLOCATION:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultGeolocationSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_INTENTS:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultHandlersSettingChanged"));
+ break;
+ case CONTENT_SETTINGS_TYPE_MOUSELOCK:
+ content::RecordAction(
+ UserMetricsAction("Options_DefaultMouseLockSettingChanged"));
+ break;
+ default:
+ break;
+ }
+}
+
+void ContentSettingsHandler::RemoveException(const ListValue* args) {
+ size_t arg_i = 0;
+ std::string type_string;
+ CHECK(args->GetString(arg_i++, &type_string));
+
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string);
+ if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) {
+ std::string origin;
+ std::string embedding_origin;
+ bool rv = args->GetString(arg_i++, &origin);
+ DCHECK(rv);
+ rv = args->GetString(arg_i++, &embedding_origin);
+ DCHECK(rv);
+
+ profile->GetHostContentSettingsMap()->
+ SetContentSetting(ContentSettingsPattern::FromString(origin),
+ ContentSettingsPattern::FromString(embedding_origin),
+ CONTENT_SETTINGS_TYPE_GEOLOCATION,
+ std::string(),
+ CONTENT_SETTING_DEFAULT);
+ } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
+ std::string origin;
+ std::string setting;
+ bool rv = args->GetString(arg_i++, &origin);
+ DCHECK(rv);
+ rv = args->GetString(arg_i++, &setting);
+ DCHECK(rv);
+ ContentSetting content_setting = ContentSettingFromString(setting);
+
+ DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
+ content_setting == CONTENT_SETTING_BLOCK);
+ DesktopNotificationServiceFactory::GetForProfile(profile)->
+ ClearSetting(ContentSettingsPattern::FromString(origin));
+ } else {
+ std::string mode;
+ bool rv = args->GetString(arg_i++, &mode);
+ DCHECK(rv);
+
+ std::string pattern;
+ rv = args->GetString(arg_i++, &pattern);
+ DCHECK(rv);
+
+ HostContentSettingsMap* settings_map =
+ mode == "normal" ? GetContentSettingsMap() :
+ GetOTRContentSettingsMap();
+ // The settings map could be null if the mode was OTR but the OTR profile
+ // got destroyed before we received this message.
+ if (settings_map) {
+ settings_map->SetContentSetting(
+ ContentSettingsPattern::FromString(pattern),
+ ContentSettingsPattern::Wildcard(),
+ ContentSettingsTypeFromGroupName(type_string),
+ "",
+ CONTENT_SETTING_DEFAULT);
+ }
+ }
+}
+
+void ContentSettingsHandler::SetException(const ListValue* args) {
+ size_t arg_i = 0;
+ std::string type_string;
+ CHECK(args->GetString(arg_i++, &type_string));
+ std::string mode;
+ CHECK(args->GetString(arg_i++, &mode));
+ std::string pattern;
+ CHECK(args->GetString(arg_i++, &pattern));
+ std::string setting;
+ CHECK(args->GetString(arg_i++, &setting));
+
+ ContentSettingsType type = ContentSettingsTypeFromGroupName(type_string);
+ if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
+ type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
+ NOTREACHED();
+ return;
+ }
+
+ HostContentSettingsMap* settings_map =
+ mode == "normal" ? GetContentSettingsMap() :
+ GetOTRContentSettingsMap();
+
+ // The settings map could be null if the mode was OTR but the OTR profile
+ // got destroyed before we received this message.
+ if (!settings_map)
+ return;
+ settings_map->SetContentSetting(ContentSettingsPattern::FromString(pattern),
+ ContentSettingsPattern::Wildcard(),
+ type,
+ "",
+ ContentSettingFromString(setting));
+}
+
+void ContentSettingsHandler::CheckExceptionPatternValidity(
+ const ListValue* args) {
+ size_t arg_i = 0;
+ Value* type;
+ CHECK(args->Get(arg_i++, &type));
+ std::string mode_string;
+ CHECK(args->GetString(arg_i++, &mode_string));
+ std::string pattern_string;
+ CHECK(args->GetString(arg_i++, &pattern_string));
+
+ ContentSettingsPattern pattern =
+ ContentSettingsPattern::FromString(pattern_string);
+
+ scoped_ptr<Value> mode_value(Value::CreateStringValue(mode_string));
+ scoped_ptr<Value> pattern_value(Value::CreateStringValue(pattern_string));
+ scoped_ptr<Value> valid_value(Value::CreateBooleanValue(pattern.IsValid()));
+
+ web_ui_->CallJavascriptFunction(
+ "ContentSettings.patternValidityCheckComplete",
+ *type,
+ *mode_value.get(),
+ *pattern_value.get(),
+ *valid_value.get());
+}
+
+// static
+std::string ContentSettingsHandler::ContentSettingsTypeToGroupName(
+ ContentSettingsType type) {
+ for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) {
+ if (type == kContentSettingsTypeGroupNames[i].type)
+ return kContentSettingsTypeGroupNames[i].name;
+ }
+
+ NOTREACHED();
+ return std::string();
+}
+
+HostContentSettingsMap* ContentSettingsHandler::GetContentSettingsMap() {
+ return Profile::FromWebUI(web_ui_)->GetHostContentSettingsMap();
+}
+
+ProtocolHandlerRegistry* ContentSettingsHandler::GetProtocolHandlerRegistry() {
+ return Profile::FromWebUI(web_ui_)->GetProtocolHandlerRegistry();
+}
+
+HostContentSettingsMap*
+ ContentSettingsHandler::GetOTRContentSettingsMap() {
+ Profile* profile = Profile::FromWebUI(web_ui_);
+ if (profile->HasOffTheRecordProfile())
+ return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap();
+ return NULL;
+}

Powered by Google App Engine
This is Rietveld 408576698