// Copyright (c) 2010 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/dom_ui/content_settings_handler.h"
#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
typedef HostContentSettingsMap::ContentSettingsDetails ContentSettingsDetails;
namespace {
std::string ContentSettingsTypeToGroupName(ContentSettingsType type) {
switch (type) {
case CONTENT_SETTINGS_TYPE_COOKIES:
return "cookies";
case CONTENT_SETTINGS_TYPE_IMAGES:
return "images";
case CONTENT_SETTINGS_TYPE_JAVASCRIPT:
return "javascript";
case CONTENT_SETTINGS_TYPE_PLUGINS:
return "plugins";
case CONTENT_SETTINGS_TYPE_POPUPS:
return "popups";
case CONTENT_SETTINGS_TYPE_GEOLOCATION:
return "location";
case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
return "notifications";
default:
NOTREACHED();
return "";
}
}
ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) {
if (name == "cookies")
return CONTENT_SETTINGS_TYPE_COOKIES;
if (name == "images")
return CONTENT_SETTINGS_TYPE_IMAGES;
if (name == "javascript")
return CONTENT_SETTINGS_TYPE_JAVASCRIPT;
if (name == "plugins")
return CONTENT_SETTINGS_TYPE_PLUGINS;
if (name == "popups")
return CONTENT_SETTINGS_TYPE_POPUPS;
if (name == "location")
return CONTENT_SETTINGS_TYPE_GEOLOCATION;
if (name == "notifications")
return CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
NOTREACHED();
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";
default:
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();
return CONTENT_SETTING_DEFAULT;
}
} // namespace
ContentSettingsHandler::ContentSettingsHandler() {
}
ContentSettingsHandler::~ContentSettingsHandler() {
}
void ContentSettingsHandler::GetLocalizedValues(
DictionaryValue* localized_strings) {
DCHECK(localized_strings);
localized_strings->SetString("content_exceptions",
l10n_util::GetStringUTF16(IDS_COOKIES_EXCEPTIONS_BUTTON));
localized_strings->SetString("contentSettingsPage",
l10n_util::GetStringUTF16(IDS_CONTENT_SETTINGS_TITLE));
localized_strings->SetString("allowException",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ALLOW_BUTTON));
localized_strings->SetString("blockException",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_BLOCK_BUTTON));
localized_strings->SetString("sessionException",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_SESSION_ONLY_BUTTON));
localized_strings->SetString("askException",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ASK_BUTTON));
localized_strings->SetString("addExceptionRow",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ADD_BUTTON));
localized_strings->SetString("removeExceptionRow",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_REMOVE_BUTTON));
localized_strings->SetString("editExceptionRow",
l10n_util::GetStringUTF16(IDS_EXCEPTIONS_EDIT_BUTTON));
// Cookies filter.
localized_strings->SetString("cookies_tab_label",
l10n_util::GetStringUTF16(IDS_COOKIES_TAB_LABEL));
localized_strings->SetString("cookies_modify",
l10n_util::GetStringUTF16(IDS_MODIFY_COOKIE_STORING_LABEL));
localized_strings->SetString("cookies_allow",
l10n_util::GetStringUTF16(IDS_COOKIES_ALLOW_RADIO));
localized_strings->SetString("cookies_ask",
l10n_util::GetStringUTF16(IDS_COOKIES_ASK_EVERY_TIME_RADIO));
localized_strings->SetString("cookies_block",
l10n_util::GetStringUTF16(IDS_COOKIES_BLOCK_RADIO));
localized_strings->SetString("cookies_block_3rd_party",
l10n_util::GetStringUTF16(IDS_COOKIES_BLOCK_3RDPARTY_CHKBOX));
localized_strings->SetString("cookies_clear_on_exit",
l10n_util::GetStringUTF16(IDS_COOKIES_CLEAR_WHEN_CLOSE_CHKBOX));
localized_strings->SetString("cookies_show_cookies",
l10n_util::GetStringUTF16(IDS_COOKIES_SHOW_COOKIES_BUTTON));
localized_strings->SetString("flash_storage_settings",
l10n_util::GetStringUTF16(IDS_FLASH_STORAGE_SETTINGS));
localized_strings->SetString("flash_storage_url",
l10n_util::GetStringUTF16(IDS_FLASH_STORAGE_URL));
// Image filter.
localized_strings->SetString("images_tab_label",
l10n_util::GetStringUTF16(IDS_IMAGES_TAB_LABEL));
localized_strings->SetString("images_setting",
l10n_util::GetStringUTF16(IDS_IMAGES_SETTING_LABEL));
localized_strings->SetString("images_allow",
l10n_util::GetStringUTF16(IDS_IMAGES_LOAD_RADIO));
localized_strings->SetString("images_block",
l10n_util::GetStringUTF16(IDS_IMAGES_NOLOAD_RADIO));
// JavaScript filter.
localized_strings->SetString("javascript_tab_label",
l10n_util::GetStringUTF16(IDS_JAVASCRIPT_TAB_LABEL));
localized_strings->SetString("javascript_setting",
l10n_util::GetStringUTF16(IDS_JS_SETTING_LABEL));
localized_strings->SetString("javascript_allow",
l10n_util::GetStringUTF16(IDS_JS_ALLOW_RADIO));
localized_strings->SetString("javascript_block",
l10n_util::GetStringUTF16(IDS_JS_DONOTALLOW_RADIO));
// Plug-ins filter.
localized_strings->SetString("plugins_tab_label",
l10n_util::GetStringUTF16(IDS_PLUGIN_TAB_LABEL));
localized_strings->SetString("plugins_setting",
l10n_util::GetStringUTF16(IDS_PLUGIN_SETTING_LABEL));
localized_strings->SetString("plugins_allow_sandboxed",
l10n_util::GetStringUTF16(IDS_PLUGIN_LOAD_SANDBOXED_RADIO));
localized_strings->SetString("plugins_allow",
l10n_util::GetStringUTF16(IDS_PLUGIN_LOAD_RADIO));
localized_strings->SetString("plugins_block",
l10n_util::GetStringUTF16(IDS_PLUGIN_NOLOAD_RADIO));
localized_strings->SetString("disable_individual_plugins",
l10n_util::GetStringUTF16(IDS_PLUGIN_SELECTIVE_DISABLE));
localized_strings->SetString("chrome_plugin_url",
chrome::kChromeUIPluginsURL);
// Pop-ups filter.
localized_strings->SetString("popups_tab_label",
l10n_util::GetStringUTF16(IDS_POPUP_TAB_LABEL));
localized_strings->SetString("popups_setting",
l10n_util::GetStringUTF16(IDS_POPUP_SETTING_LABEL));
localized_strings->SetString("popups_allow",
l10n_util::GetStringUTF16(IDS_POPUP_ALLOW_RADIO));
localized_strings->SetString("popups_block",
l10n_util::GetStringUTF16(IDS_POPUP_BLOCK_RADIO));
// Location filter.
localized_strings->SetString("location_tab_label",
l10n_util::GetStringUTF16(IDS_GEOLOCATION_TAB_LABEL));
localized_strings->SetString("location_setting",
l10n_util::GetStringUTF16(IDS_GEOLOCATION_SETTING_LABEL));
localized_strings->SetString("location_allow",
l10n_util::GetStringUTF16(IDS_GEOLOCATION_ALLOW_RADIO));
localized_strings->SetString("location_ask",
l10n_util::GetStringUTF16(IDS_GEOLOCATION_ASK_RADIO));
localized_strings->SetString("location_block",
l10n_util::GetStringUTF16(IDS_GEOLOCATION_BLOCK_RADIO));
// Notifications filter.
localized_strings->SetString("notifications_tab_label",
l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_TAB_LABEL));
localized_strings->SetString("notifications_setting",
l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_SETTING_LABEL));
localized_strings->SetString("notifications_allow",
l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_ALLOW_RADIO));
localized_strings->SetString("notifications_ask",
l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_ASK_RADIO));
localized_strings->SetString("notifications_block",
l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_BLOCK_RADIO));
}
void ContentSettingsHandler::Initialize() {
// We send a list of the IDs that should be checked.
DictionaryValue filter_settings;
const HostContentSettingsMap* settings_map =
dom_ui_->GetProfile()->GetHostContentSettingsMap();
for (int i = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
ContentSettingsType type = static_cast(i);
ContentSetting default_setting = settings_map->
GetDefaultContentSetting(type);
filter_settings.SetString(ContentSettingsTypeToGroupName(type),
ContentSettingToString(default_setting));
}
if (settings_map->GetBlockNonsandboxedPlugins()) {
filter_settings.SetString(
ContentSettingsTypeToGroupName(CONTENT_SETTINGS_TYPE_PLUGINS),
ContentSettingToString(CONTENT_SETTING_ASK));
}
dom_ui_->CallJavascriptFunction(
L"ContentSettings.setInitialContentFilterSettingsValue", filter_settings);
scoped_ptr block_3rd_party(Value::CreateBooleanValue(
settings_map->BlockThirdPartyCookies()));
dom_ui_->CallJavascriptFunction(
L"ContentSettings.setBlockThirdPartyCookies", *block_3rd_party.get());
scoped_ptr show_cookies_prompt(Value::CreateBooleanValue(
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableCookiePrompt)));
dom_ui_->CallJavascriptFunction(
L"ContentSettings.setCookiesPromptEnabled", *show_cookies_prompt.get());
UpdateAllExceptionsViewsFromModel();
notification_registrar_.Add(
this, NotificationType::CONTENT_SETTINGS_CHANGED,
Source(settings_map));
}
void ContentSettingsHandler::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
if (type != NotificationType::CONTENT_SETTINGS_CHANGED)
return OptionsPageUIHandler::Observe(type, source, details);
const ContentSettingsDetails* settings_details =
static_cast >(details).ptr();
// TODO(estade): we pretend update_all() is always true.
if (settings_details->update_all_types())
UpdateAllExceptionsViewsFromModel();
else
UpdateExceptionsViewFromModel(settings_details->type());
}
void ContentSettingsHandler::UpdateAllExceptionsViewsFromModel() {
for (int type = CONTENT_SETTINGS_TYPE_DEFAULT + 1;
type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
UpdateExceptionsViewFromModel(static_cast(type));
}
}
void ContentSettingsHandler::UpdateExceptionsViewFromModel(
ContentSettingsType type) {
HostContentSettingsMap::SettingsForOneType entries;
const HostContentSettingsMap* settings_map =
dom_ui_->GetProfile()->GetHostContentSettingsMap();
settings_map->GetSettingsForOneType(type, "", &entries);
ListValue exceptions;
for (size_t i = 0; i < entries.size(); ++i) {
ListValue* exception = new ListValue();
exception->Append(new StringValue(entries[i].first.AsString()));
exception->Append(
new StringValue(ContentSettingToString(entries[i].second)));
exceptions.Append(exception);
}
StringValue type_string(ContentSettingsTypeToGroupName(type));
dom_ui_->CallJavascriptFunction(
L"ContentSettings.setExceptions", type_string, exceptions);
}
void ContentSettingsHandler::RegisterMessages() {
dom_ui_->RegisterMessageCallback("setContentFilter",
NewCallback(this,
&ContentSettingsHandler::SetContentFilter));
dom_ui_->RegisterMessageCallback("setAllowThirdPartyCookies",
NewCallback(this,
&ContentSettingsHandler::SetAllowThirdPartyCookies));
dom_ui_->RegisterMessageCallback("removeExceptions",
NewCallback(this,
&ContentSettingsHandler::RemoveExceptions));
dom_ui_->RegisterMessageCallback("setException",
NewCallback(this,
&ContentSettingsHandler::SetException));
dom_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;
}
if (ContentSettingsTypeFromGroupName(group) ==
CONTENT_SETTINGS_TYPE_PLUGINS) {
bool block_nonsandboxed_plugins = false;
if (ContentSettingFromString(setting) == CONTENT_SETTING_ASK) {
setting = ContentSettingToString(CONTENT_SETTING_ALLOW);
block_nonsandboxed_plugins = true;
}
dom_ui_->GetProfile()->GetHostContentSettingsMap()->
SetBlockNonsandboxedPlugins(block_nonsandboxed_plugins);
}
dom_ui_->GetProfile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
ContentSettingsTypeFromGroupName(group),
ContentSettingFromString(setting));
}
void ContentSettingsHandler::SetAllowThirdPartyCookies(const ListValue* args) {
std::wstring allow = ExtractStringValue(args);
dom_ui_->GetProfile()->GetHostContentSettingsMap()->SetBlockThirdPartyCookies(
allow == L"true");
}
void ContentSettingsHandler::RemoveExceptions(const ListValue* args) {
size_t arg_i = 0;
std::string type_string;
CHECK(args->GetString(arg_i++, &type_string));
HostContentSettingsMap* settings_map =
dom_ui_->GetProfile()->GetHostContentSettingsMap();
while (arg_i < args->GetSize()) {
std::string pattern;
bool rv = args->GetString(arg_i++, &pattern);
DCHECK(rv);
settings_map->SetContentSetting(
HostContentSettingsMap::Pattern(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 pattern;
CHECK(args->GetString(arg_i++, &pattern));
std::string setting;
CHECK(args->GetString(arg_i++, &setting));
HostContentSettingsMap* settings_map =
dom_ui_->GetProfile()->GetHostContentSettingsMap();
settings_map->SetContentSetting(HostContentSettingsMap::Pattern(pattern),
ContentSettingsTypeFromGroupName(type_string),
"",
ContentSettingFromString(setting));
}
void ContentSettingsHandler::CheckExceptionPatternValidity(
const ListValue* args) {
size_t arg_i = 0;
Value* type;
CHECK(args->Get(arg_i++, &type));
std::string pattern_string;
CHECK(args->GetString(arg_i++, &pattern_string));
HostContentSettingsMap::Pattern pattern(pattern_string);
scoped_ptr pattern_value(Value::CreateStringValue(
pattern_string));
scoped_ptr valid_value(Value::CreateBooleanValue(
pattern.IsValid()));
dom_ui_->CallJavascriptFunction(
L"ContentSettings.patternValidityCheckComplete", *type,
*pattern_value.get(),
*valid_value.get());
}