// 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;
}