// 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/options/content_settings_handler.h" #include "base/callback.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/host_content_settings_map.h" #include "chrome/browser/geolocation/geolocation_content_settings_map.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_switches.h" #include "chrome/common/content_settings_helper.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/common/notification_service.h" #include "content/common/notification_source.h" #include "content/common/notification_type.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "ui/base/l10n/l10n_util.h" namespace { const char* kDisplayPattern = "displayPattern"; const char* kSetting = "setting"; const char* kOrigin = "origin"; const char* kEmbeddingOrigin = "embeddingOrigin"; const char* const kContentSettingsTypeGroupNames[] = { "cookies", "images", "javascript", "plugins", "popups", "location", "notifications", "prerender", }; COMPILE_ASSERT(arraysize(kContentSettingsTypeGroupNames) == CONTENT_SETTINGS_NUM_TYPES, invalid_content_settings_type_group_names_size); ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { for (int content_settings_type = CONTENT_SETTINGS_TYPE_COOKIES; content_settings_type < CONTENT_SETTINGS_NUM_TYPES; ++content_settings_type) { if (name == kContentSettingsTypeGroupNames[content_settings_type]) return static_cast<ContentSettingsType>(content_settings_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 GURL& origin, const GURL& embedding_origin) { if (origin == embedding_origin) return content_settings_helper::OriginToString(origin); // TODO(estade): the page needs to use CSS to indent the string. std::string indent(" "); if (embedding_origin.is_empty()) { // 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(content_settings_helper::OriginToString(embedding_origin))); } // 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) { DictionaryValue* exception = new DictionaryValue(); exception->Set( kDisplayPattern, new StringValue(pattern.AsString())); exception->Set( kSetting, new StringValue(ContentSettingToString(setting))); 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 GURL& origin, const GURL& embedding_origin, ContentSetting setting) { DictionaryValue* exception = new DictionaryValue(); exception->Set( kDisplayPattern, new StringValue(GeolocationExceptionToString(origin, embedding_origin))); exception->Set( kSetting, new StringValue(ContentSettingToString(setting))); exception->Set( kOrigin, new StringValue(origin.spec())); exception->Set( kEmbeddingOrigin, new StringValue(embedding_origin.spec())); 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 GURL& url, ContentSetting setting) { DictionaryValue* exception = new DictionaryValue(); exception->Set( kDisplayPattern, new StringValue(content_settings_helper::OriginToString(url))); exception->Set( kSetting, new StringValue(ContentSettingToString(setting))); exception->Set( kOrigin, new StringValue(url.spec())); 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 }, { "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_ask", IDS_COOKIES_ASK_EVERY_TIME_RADIO }, { "cookies_block", IDS_COOKIES_BLOCK_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 }, { "disable_individual_plugins", 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 }, }; 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)); } void ContentSettingsHandler::Initialize() { const HostContentSettingsMap* settings_map = GetContentSettingsMap(); scoped_ptr<Value> block_3rd_party(Value::CreateBooleanValue( settings_map->BlockThirdPartyCookies())); web_ui_->CallJavascriptFunction("ContentSettings.setBlockThirdPartyCookies", *block_3rd_party.get()); notification_registrar_.Add( this, NotificationType::OTR_PROFILE_CREATED, NotificationService::AllSources()); notification_registrar_.Add( this, NotificationType::PROFILE_DESTROYED, NotificationService::AllSources()); UpdateAllExceptionsViewsFromModel(); notification_registrar_.Add( this, NotificationType::CONTENT_SETTINGS_CHANGED, NotificationService::AllSources()); notification_registrar_.Add( this, NotificationType::DESKTOP_NOTIFICATION_DEFAULT_CHANGED, NotificationService::AllSources()); notification_registrar_.Add( this, NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED, NotificationService::AllSources()); PrefService* prefs = web_ui_->GetProfile()->GetPrefs(); pref_change_registrar_.Init(prefs); pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); pref_change_registrar_.Add(prefs::kGeolocationContentSettings, this); } void ContentSettingsHandler::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { switch (type.value) { case NotificationType::PROFILE_DESTROYED: { Profile* profile = static_cast<Source<Profile> >(source).ptr(); if (profile->IsOffTheRecord()) { web_ui_->CallJavascriptFunction( "ContentSettingsExceptionsArea.OTRProfileDestroyed"); } break; } case NotificationType::OTR_PROFILE_CREATED: { UpdateAllOTRExceptionsViewsFromModel(); break; } case NotificationType::CONTENT_SETTINGS_CHANGED: { const ContentSettingsDetails* settings_details = 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 NotificationType::PREF_CHANGED: { const std::string& pref_name = *Details<std::string>(details).ptr(); if (pref_name == prefs::kGeolocationDefaultContentSetting) UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_GEOLOCATION); else if (pref_name == prefs::kGeolocationContentSettings) UpdateGeolocationExceptionsView(); break; } case NotificationType::DESKTOP_NOTIFICATION_DEFAULT_CHANGED: { UpdateSettingDefaultFromModel(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); break; } case NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED: { UpdateNotificationExceptionsView(); break; } default: OptionsPageUIHandler::Observe(type, source, details); } } void ContentSettingsHandler::UpdateSettingDefaultFromModel( ContentSettingsType type) { DictionaryValue filter_settings; filter_settings.SetString(ContentSettingsTypeToGroupName(type) + ".value", GetSettingDefaultFromModel(type)); filter_settings.SetBoolean(ContentSettingsTypeToGroupName(type) + ".managed", GetDefaultSettingManagedFromModel(type)); web_ui_->CallJavascriptFunction( "ContentSettings.setContentFilterSettingsValue", filter_settings); } std::string ContentSettingsHandler::GetSettingDefaultFromModel( ContentSettingsType type) { ContentSetting default_setting; if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { default_setting = web_ui_->GetProfile()-> GetGeolocationContentSettingsMap()->GetDefaultContentSetting(); } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { default_setting = DesktopNotificationServiceFactory::GetForProfile( web_ui_->GetProfile())->GetDefaultContentSetting(); } else { default_setting = GetContentSettingsMap()->GetDefaultContentSetting(type); } return ContentSettingToString(default_setting); } bool ContentSettingsHandler::GetDefaultSettingManagedFromModel( ContentSettingsType type) { if (type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { return web_ui_->GetProfile()-> GetGeolocationContentSettingsMap()->IsDefaultContentSettingManaged(); } else if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { return DesktopNotificationServiceFactory::GetForProfile( web_ui_->GetProfile())->IsDefaultContentSettingManaged(); } else { return GetContentSettingsMap()->IsDefaultContentSettingManaged(type); } } void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() { for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 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) { switch (type) { case CONTENT_SETTINGS_TYPE_GEOLOCATION: UpdateGeolocationExceptionsView(); break; case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: UpdateNotificationExceptionsView(); break; case CONTENT_SETTINGS_TYPE_PRERENDER: // Prerender is currently (02/24/2011) an experimental feature which is // only turned on via about:flags. There is intentionally no UI in // chrome://preferences for CONTENT_SETTINGS_TYPE_PRERENDER. // TODO(cbentzel): Change once prerender moves out of about:flags. 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_PRERENDER: break; default: UpdateExceptionsViewFromOTRHostContentSettingsMap(type); break; } } void ContentSettingsHandler::UpdateGeolocationExceptionsView() { GeolocationContentSettingsMap* map = web_ui_->GetProfile()->GetGeolocationContentSettingsMap(); GeolocationContentSettingsMap::AllOriginsSettings all_settings = map->GetAllOriginsSettings(); GeolocationContentSettingsMap::AllOriginsSettings::const_iterator i; ListValue exceptions; for (i = all_settings.begin(); i != all_settings.end(); ++i) { const GURL& origin = i->first; const GeolocationContentSettingsMap::OneOriginSettings& one_settings = i->second; GeolocationContentSettingsMap::OneOriginSettings::const_iterator parent = one_settings.find(origin); // Add the "parent" entry for the non-embedded setting. ContentSetting parent_setting = parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second; exceptions.Append( GetGeolocationExceptionForPage(origin, origin, parent_setting)); // Add the "children" for any embedded settings. GeolocationContentSettingsMap::OneOriginSettings::const_iterator j; for (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(origin, 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() { DesktopNotificationService* service = DesktopNotificationServiceFactory::GetForProfile(web_ui_->GetProfile()); std::vector<GURL> allowed(service->GetAllowedOrigins()); std::vector<GURL> blocked(service->GetBlockedOrigins()); ListValue exceptions; for (size_t i = 0; i < allowed.size(); ++i) { exceptions.Append( GetNotificationExceptionForPage(allowed[i], CONTENT_SETTING_ALLOW)); } for (size_t i = 0; i < blocked.size(); ++i) { exceptions.Append( GetNotificationExceptionForPage(blocked[i], CONTENT_SETTING_BLOCK)); } 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) { HostContentSettingsMap::SettingsForOneType entries; GetContentSettingsMap()->GetSettingsForOneType(type, "", &entries); ListValue exceptions; for (size_t i = 0; i < entries.size(); ++i) { exceptions.Append(GetExceptionForPage(entries[i].first, entries[i].second)); } StringValue type_string(ContentSettingsTypeToGroupName(type)); web_ui_->CallJavascriptFunction("ContentSettings.setExceptions", type_string, exceptions); UpdateExceptionsViewFromOTRHostContentSettingsMap(type); // 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; HostContentSettingsMap::SettingsForOneType otr_entries; otr_settings_map->GetSettingsForOneType(type, "", &otr_entries); ListValue otr_exceptions; for (size_t i = 0; i < otr_entries.size(); ++i) { otr_exceptions.Append(GetExceptionForPage(otr_entries[i].first, otr_entries[i].second)); } StringValue type_string(ContentSettingsTypeToGroupName(type)); web_ui_->CallJavascriptFunction("ContentSettings.setOTRExceptions", type_string, otr_exceptions); } void ContentSettingsHandler::RegisterMessages() { web_ui_->RegisterMessageCallback("setContentFilter", NewCallback(this, &ContentSettingsHandler::SetContentFilter)); web_ui_->RegisterMessageCallback("setAllowThirdPartyCookies", NewCallback(this, &ContentSettingsHandler::SetAllowThirdPartyCookies)); web_ui_->RegisterMessageCallback("removeException", NewCallback(this, &ContentSettingsHandler::RemoveException)); web_ui_->RegisterMessageCallback("setException", NewCallback(this, &ContentSettingsHandler::SetException)); web_ui_->RegisterMessageCallback("checkExceptionPatternValidity", NewCallback(this, &ContentSettingsHandler::CheckExceptionPatternValidity)); } 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_GEOLOCATION) { web_ui_->GetProfile()->GetGeolocationContentSettingsMap()-> SetDefaultContentSetting(default_setting); } else if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) { DesktopNotificationServiceFactory::GetForProfile(web_ui_->GetProfile())-> SetDefaultContentSetting(default_setting); } else { GetContentSettingsMap()-> SetDefaultContentSetting(content_type, default_setting); } } void ContentSettingsHandler::SetAllowThirdPartyCookies(const ListValue* args) { string16 allow = ExtractStringValue(args); GetContentSettingsMap()->SetBlockThirdPartyCookies( LowerCaseEqualsASCII(allow, "true")); } void ContentSettingsHandler::RemoveException(const ListValue* args) { size_t arg_i = 0; std::string type_string; CHECK(args->GetString(arg_i++, &type_string)); 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); web_ui_->GetProfile()->GetGeolocationContentSettingsMap()-> SetContentSetting(GURL(origin), GURL(embedding_origin), 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); if (content_setting == CONTENT_SETTING_ALLOW) { DesktopNotificationServiceFactory::GetForProfile(web_ui_->GetProfile())-> ResetAllowedOrigin(GURL(origin)); } else { DCHECK_EQ(content_setting, CONTENT_SETTING_BLOCK); DesktopNotificationServiceFactory::GetForProfile(web_ui_->GetProfile())-> ResetBlockedOrigin(GURL(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(pattern), 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(pattern), 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(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) { if (type < CONTENT_SETTINGS_TYPE_COOKIES || type >= CONTENT_SETTINGS_NUM_TYPES) { NOTREACHED(); return ""; } return kContentSettingsTypeGroupNames[type]; } HostContentSettingsMap* ContentSettingsHandler::GetContentSettingsMap() { return web_ui_->GetProfile()->GetHostContentSettingsMap(); } HostContentSettingsMap* ContentSettingsHandler::GetOTRContentSettingsMap() { Profile* profile = web_ui_->GetProfile(); if (profile->HasOffTheRecordProfile()) return profile->GetOffTheRecordProfile()->GetHostContentSettingsMap(); return NULL; }