blob: 4ca3eb5d1d2a9ec74d1fe705b14e45490bca5ff5 [file] [log] [blame]
// Copyright 2015 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 "components/content_settings/core/browser/content_settings_registry.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/website_settings_registry.h"
#include "components/content_settings/core/common/content_settings.h"
namespace content_settings {
namespace {
base::LazyInstance<ContentSettingsRegistry> g_instance =
LAZY_INSTANCE_INITIALIZER;
// TODO(raymes): These overloaded functions make the registration code clearer.
// When initializer lists are available they won't be needed. The initializer
// list can be implicitly or explicitly converted to a std::vector.
std::vector<std::string> WhitelistedSchemes() {
return std::vector<std::string>();
}
std::vector<std::string> WhitelistedSchemes(const char* scheme1,
const char* scheme2) {
const char* schemes[] = {scheme1, scheme2};
return std::vector<std::string>(schemes, schemes + arraysize(schemes));
}
std::vector<std::string> WhitelistedSchemes(const char* scheme1,
const char* scheme2,
const char* scheme3) {
const char* schemes[] = {scheme1, scheme2, scheme3};
return std::vector<std::string>(schemes, schemes + arraysize(schemes));
}
std::set<ContentSetting> ValidSettings() {
return std::set<ContentSetting>();
}
std::set<ContentSetting> ValidSettings(ContentSetting setting1,
ContentSetting setting2) {
ContentSetting settings[] = {setting1, setting2};
return std::set<ContentSetting>(settings, settings + arraysize(settings));
}
std::set<ContentSetting> ValidSettings(ContentSetting setting1,
ContentSetting setting2,
ContentSetting setting3) {
ContentSetting settings[] = {setting1, setting2, setting3};
return std::set<ContentSetting>(settings, settings + arraysize(settings));
}
std::set<ContentSetting> ValidSettings(ContentSetting setting1,
ContentSetting setting2,
ContentSetting setting3,
ContentSetting setting4) {
ContentSetting settings[] = {setting1, setting2, setting3, setting4};
return std::set<ContentSetting>(settings, settings + arraysize(settings));
}
} // namespace
// static
ContentSettingsRegistry* ContentSettingsRegistry::GetInstance() {
return g_instance.Pointer();
}
ContentSettingsRegistry::ContentSettingsRegistry()
: ContentSettingsRegistry(WebsiteSettingsRegistry::GetInstance()) {}
ContentSettingsRegistry::ContentSettingsRegistry(
WebsiteSettingsRegistry* website_settings_registry)
// This object depends on WebsiteSettingsRegistry, so get it first so that
// they will be destroyed in reverse order.
: website_settings_registry_(website_settings_registry) {
Init();
}
void ContentSettingsRegistry::ResetForTest() {
website_settings_registry_->ResetForTest();
content_settings_info_.clear();
Init();
}
ContentSettingsRegistry::~ContentSettingsRegistry() {}
const ContentSettingsInfo* ContentSettingsRegistry::Get(
ContentSettingsType type) const {
const auto& it = content_settings_info_.find(type);
if (it != content_settings_info_.end())
return it->second;
return nullptr;
}
ContentSettingsRegistry::const_iterator ContentSettingsRegistry::begin() const {
return const_iterator(content_settings_info_.begin());
}
ContentSettingsRegistry::const_iterator ContentSettingsRegistry::end() const {
return const_iterator(content_settings_info_.end());
}
void ContentSettingsRegistry::Init() {
// TODO(raymes): This registration code should not have to be in a single
// location. It should be possible to register a setting from the code
// associated with it.
// WARNING: The string names of the permissions passed in below are used to
// generate preference names and should never be changed!
Register(CONTENT_SETTINGS_TYPE_COOKIES, "cookies", CONTENT_SETTING_ALLOW,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_SESSION_ONLY),
WebsiteSettingsInfo::REQUESTING_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_IMAGES, "images", CONTENT_SETTING_ALLOW,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme,
kExtensionScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript",
CONTENT_SETTING_ALLOW, WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme,
kExtensionScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_PLUGINS, "plugins",
CONTENT_SETTING_DETECT_IMPORTANT_CONTENT,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK,
CONTENT_SETTING_DETECT_IMPORTANT_CONTENT),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_POPUPS, "popups", CONTENT_SETTING_BLOCK,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme,
kExtensionScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_GEOLOCATION, "geolocation",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
Register(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen", CONTENT_SETTING_ASK,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
Register(CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock", CONTENT_SETTING_ASK,
WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, "media-stream-mic",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, "media-stream-camera",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "automatic-downloads",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(kChromeUIScheme, kChromeDevToolsScheme,
kExtensionScheme),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_MIDI_SYSEX, "midi-sysex", CONTENT_SETTING_ASK,
WebsiteSettingsInfo::SYNCABLE, WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
Register(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING, "push-messaging",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
Register(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
"protected-media-identifier", CONTENT_SETTING_ASK,
WebsiteSettingsInfo::UNSYNCABLE, WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
CONTENT_SETTING_ASK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
#endif
Register(CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, "durable-storage",
CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_KEYGEN, "keygen",
CONTENT_SETTING_BLOCK, WebsiteSettingsInfo::SYNCABLE,
WhitelistedSchemes(),
ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
WebsiteSettingsInfo::REQUESTING_ORIGIN_ONLY_SCOPE);
// Content settings that aren't used to store any data. TODO(raymes): use a
// different mechanism rather than content settings to represent these.
// Since nothing is stored in them, there is no real point in them being a
// content setting.
Register(CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, "protocol-handler",
CONTENT_SETTING_DEFAULT, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(), ValidSettings(),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
Register(CONTENT_SETTINGS_TYPE_MIXEDSCRIPT, "mixed-script",
CONTENT_SETTING_DEFAULT, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(), ValidSettings(),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
// Deprecated.
Register(CONTENT_SETTINGS_TYPE_MEDIASTREAM, "media-stream",
CONTENT_SETTING_DEFAULT, WebsiteSettingsInfo::UNSYNCABLE,
WhitelistedSchemes(), ValidSettings(),
WebsiteSettingsInfo::TOP_LEVEL_DOMAIN_ONLY_SCOPE);
}
void ContentSettingsRegistry::Register(
ContentSettingsType type,
const std::string& name,
ContentSetting initial_default_value,
WebsiteSettingsInfo::SyncStatus sync_status,
const std::vector<std::string>& whitelisted_schemes,
const std::set<ContentSetting>& valid_settings,
WebsiteSettingsInfo::ScopingType scoping_type) {
// Ensure that nothing has been registered yet for the given type.
DCHECK(!website_settings_registry_->Get(type));
scoped_ptr<base::Value> default_value(
new base::FundamentalValue(static_cast<int>(initial_default_value)));
const WebsiteSettingsInfo* website_settings_info =
website_settings_registry_->Register(
type, name, default_value.Pass(), sync_status,
WebsiteSettingsInfo::NOT_LOSSY, scoping_type);
DCHECK(!ContainsKey(content_settings_info_, type));
content_settings_info_.set(
type, make_scoped_ptr(new ContentSettingsInfo(
website_settings_info, whitelisted_schemes, valid_settings)));
}
} // namespace content_settings