blob: 6e02fcf29c8011019d4de163ccf35ce25d1043a3 [file] [log] [blame]
// Copyright (c) 2012 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/content_settings/host_content_settings_map.h"
#include <utility>
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/clock.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/content_settings_custom_extension_provider.h"
#include "chrome/browser/content_settings/content_settings_default_provider.h"
#include "chrome/browser/content_settings/content_settings_details.h"
#include "chrome/browser/content_settings/content_settings_internal_extension_provider.h"
#include "chrome/browser/content_settings/content_settings_observable_provider.h"
#include "chrome/browser/content_settings/content_settings_policy_provider.h"
#include "chrome/browser/content_settings/content_settings_pref_provider.h"
#include "chrome/browser/content_settings/content_settings_provider.h"
#include "chrome/browser/content_settings/content_settings_rule.h"
#include "chrome/browser/content_settings/content_settings_utils.h"
#include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/constants.h"
#include "net/base/net_errors.h"
#include "net/base/static_cookie_policy.h"
#include "url/gurl.h"
using base::UserMetricsAction;
using content::BrowserThread;
namespace {
typedef std::vector<content_settings::Rule> Rules;
typedef std::pair<std::string, std::string> StringPair;
// TODO(bauerb): Expose constants.
const char* kProviderNames[] = {
"platform_app",
"policy",
"extension",
"preference",
"default"
};
content_settings::SettingSource kProviderSourceMap[] = {
content_settings::SETTING_SOURCE_EXTENSION,
content_settings::SETTING_SOURCE_POLICY,
content_settings::SETTING_SOURCE_EXTENSION,
content_settings::SETTING_SOURCE_USER,
content_settings::SETTING_SOURCE_USER,
};
COMPILE_ASSERT(arraysize(kProviderSourceMap) ==
HostContentSettingsMap::NUM_PROVIDER_TYPES,
kProviderSourceMap_has_incorrect_size);
// Returns true if the |content_type| supports a resource identifier.
// Resource identifiers are supported (but not required) for plug-ins.
bool SupportsResourceIdentifier(ContentSettingsType content_type) {
return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
}
} // namespace
HostContentSettingsMap::HostContentSettingsMap(
PrefService* prefs,
bool incognito) :
#ifndef NDEBUG
used_from_thread_id_(base::PlatformThread::CurrentId()),
#endif
prefs_(prefs),
is_off_the_record_(incognito) {
content_settings::ObservableProvider* policy_provider =
new content_settings::PolicyProvider(prefs_);
policy_provider->AddObserver(this);
content_settings_providers_[POLICY_PROVIDER] = policy_provider;
content_settings::ObservableProvider* pref_provider =
new content_settings::PrefProvider(prefs_, is_off_the_record_);
pref_provider->AddObserver(this);
content_settings_providers_[PREF_PROVIDER] = pref_provider;
content_settings::ObservableProvider* default_provider =
new content_settings::DefaultProvider(prefs_, is_off_the_record_);
default_provider->AddObserver(this);
content_settings_providers_[DEFAULT_PROVIDER] = default_provider;
if (!is_off_the_record_) {
// Migrate obsolete preferences.
MigrateObsoleteClearOnExitPref();
}
}
#if defined(ENABLE_EXTENSIONS)
void HostContentSettingsMap::RegisterExtensionService(
ExtensionService* extension_service) {
DCHECK(extension_service);
DCHECK(!content_settings_providers_[INTERNAL_EXTENSION_PROVIDER]);
DCHECK(!content_settings_providers_[CUSTOM_EXTENSION_PROVIDER]);
content_settings::InternalExtensionProvider* internal_extension_provider =
new content_settings::InternalExtensionProvider(extension_service);
internal_extension_provider->AddObserver(this);
content_settings_providers_[INTERNAL_EXTENSION_PROVIDER] =
internal_extension_provider;
content_settings::ObservableProvider* custom_extension_provider =
new content_settings::CustomExtensionProvider(
extensions::ContentSettingsService::Get(
extension_service->GetBrowserContext())->content_settings_store(),
is_off_the_record_);
custom_extension_provider->AddObserver(this);
content_settings_providers_[CUSTOM_EXTENSION_PROVIDER] =
custom_extension_provider;
#ifndef NDEBUG
DCHECK(used_from_thread_id_ != base::kInvalidThreadId)
<< "Used from multiple threads before initialization complete.";
#endif
OnContentSettingChanged(ContentSettingsPattern(),
ContentSettingsPattern(),
CONTENT_SETTINGS_TYPE_DEFAULT,
std::string());
}
#endif
// static
void HostContentSettingsMap::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterIntegerPref(
prefs::kContentSettingsWindowLastTabIndex,
0,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
registry->RegisterIntegerPref(
prefs::kContentSettingsDefaultWhitelistVersion,
0,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
registry->RegisterBooleanPref(
prefs::kContentSettingsClearOnExitMigrated,
false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
// Register the prefs for the content settings providers.
content_settings::DefaultProvider::RegisterProfilePrefs(registry);
content_settings::PrefProvider::RegisterProfilePrefs(registry);
content_settings::PolicyProvider::RegisterProfilePrefs(registry);
}
ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider(
ContentSettingsType content_type,
content_settings::ProviderInterface* provider) const {
scoped_ptr<content_settings::RuleIterator> rule_iterator(
provider->GetRuleIterator(content_type, std::string(), false));
ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard();
while (rule_iterator->HasNext()) {
content_settings::Rule rule = rule_iterator->Next();
if (rule.primary_pattern == wildcard &&
rule.secondary_pattern == wildcard) {
return content_settings::ValueToContentSetting(rule.value.get());
}
}
return CONTENT_SETTING_DEFAULT;
}
ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
ContentSettingsType content_type,
std::string* provider_id) const {
UsedContentSettingsProviders();
// Iterate through the list of providers and return the first non-NULL value
// that matches |primary_url| and |secondary_url|.
for (ConstProviderIterator provider = content_settings_providers_.begin();
provider != content_settings_providers_.end();
++provider) {
if (provider->first == PREF_PROVIDER)
continue;
ContentSetting default_setting =
GetDefaultContentSettingFromProvider(content_type, provider->second);
if (default_setting != CONTENT_SETTING_DEFAULT) {
if (provider_id)
*provider_id = kProviderNames[provider->first];
return default_setting;
}
}
// The method GetDefaultContentSetting always has to return an explicit
// value that is to be used as default. We here rely on the
// DefaultProvider to always provide a value.
NOTREACHED();
return CONTENT_SETTING_DEFAULT;
}
ContentSetting HostContentSettingsMap::GetContentSetting(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type,
const std::string& resource_identifier) const {
DCHECK(!ContentTypeHasCompoundValue(content_type));
scoped_ptr<base::Value> value(GetWebsiteSetting(
primary_url, secondary_url, content_type, resource_identifier, NULL));
return content_settings::ValueToContentSetting(value.get());
}
void HostContentSettingsMap::GetSettingsForOneType(
ContentSettingsType content_type,
const std::string& resource_identifier,
ContentSettingsForOneType* settings) const {
DCHECK(SupportsResourceIdentifier(content_type) ||
resource_identifier.empty());
DCHECK(settings);
UsedContentSettingsProviders();
settings->clear();
for (ConstProviderIterator provider = content_settings_providers_.begin();
provider != content_settings_providers_.end();
++provider) {
// For each provider, iterate first the incognito-specific rules, then the
// normal rules.
if (is_off_the_record_) {
AddSettingsForOneType(provider->second,
provider->first,
content_type,
resource_identifier,
settings,
true);
}
AddSettingsForOneType(provider->second,
provider->first,
content_type,
resource_identifier,
settings,
false);
}
}
void HostContentSettingsMap::SetDefaultContentSetting(
ContentSettingsType content_type,
ContentSetting setting) {
DCHECK(IsSettingAllowedForType(prefs_, setting, content_type));
base::Value* value = NULL;
if (setting != CONTENT_SETTING_DEFAULT)
value = new base::FundamentalValue(setting);
SetWebsiteSetting(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
content_type,
std::string(),
value);
}
void HostContentSettingsMap::SetWebsiteSetting(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const std::string& resource_identifier,
base::Value* value) {
DCHECK(IsValueAllowedForType(prefs_, value, content_type));
DCHECK(SupportsResourceIdentifier(content_type) ||
resource_identifier.empty());
UsedContentSettingsProviders();
for (ProviderIterator provider = content_settings_providers_.begin();
provider != content_settings_providers_.end();
++provider) {
if (provider->second->SetWebsiteSetting(primary_pattern,
secondary_pattern,
content_type,
resource_identifier,
value)) {
return;
}
}
NOTREACHED();
}
void HostContentSettingsMap::SetContentSetting(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const std::string& resource_identifier,
ContentSetting setting) {
DCHECK(!ContentTypeHasCompoundValue(content_type));
if (setting == CONTENT_SETTING_ALLOW &&
(content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS)) {
UpdateLastUsageByPattern(primary_pattern, secondary_pattern, content_type);
}
base::Value* value = NULL;
if (setting != CONTENT_SETTING_DEFAULT)
value = new base::FundamentalValue(setting);
SetWebsiteSetting(primary_pattern,
secondary_pattern,
content_type,
resource_identifier,
value);
}
ContentSetting HostContentSettingsMap::GetContentSettingAndMaybeUpdateLastUsage(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type,
const std::string& resource_identifier) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ContentSetting setting = GetContentSetting(
primary_url, secondary_url, content_type, resource_identifier);
if (setting == CONTENT_SETTING_ALLOW) {
UpdateLastUsageByPattern(
ContentSettingsPattern::FromURLNoWildcard(primary_url),
ContentSettingsPattern::FromURLNoWildcard(secondary_url),
content_type);
}
return setting;
}
void HostContentSettingsMap::UpdateLastUsage(const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type) {
UpdateLastUsageByPattern(
ContentSettingsPattern::FromURLNoWildcard(primary_url),
ContentSettingsPattern::FromURLNoWildcard(secondary_url),
content_type);
}
void HostContentSettingsMap::UpdateLastUsageByPattern(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type) {
UsedContentSettingsProviders();
GetPrefProvider()->UpdateLastUsage(
primary_pattern, secondary_pattern, content_type);
}
base::Time HostContentSettingsMap::GetLastUsage(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type) {
return GetLastUsageByPattern(
ContentSettingsPattern::FromURLNoWildcard(primary_url),
ContentSettingsPattern::FromURLNoWildcard(secondary_url),
content_type);
}
base::Time HostContentSettingsMap::GetLastUsageByPattern(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type) {
UsedContentSettingsProviders();
return GetPrefProvider()->GetLastUsage(
primary_pattern, secondary_pattern, content_type);
}
void HostContentSettingsMap::AddObserver(content_settings::Observer* observer) {
observers_.AddObserver(observer);
}
void HostContentSettingsMap::RemoveObserver(
content_settings::Observer* observer) {
observers_.RemoveObserver(observer);
}
void HostContentSettingsMap::SetPrefClockForTesting(
scoped_ptr<base::Clock> clock) {
UsedContentSettingsProviders();
GetPrefProvider()->SetClockForTesting(clock.Pass());
}
void HostContentSettingsMap::AddExceptionForURL(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type,
ContentSetting setting) {
// TODO(markusheintz): Until the UI supports pattern pairs, both urls must
// match.
DCHECK(primary_url == secondary_url);
DCHECK(!ContentTypeHasCompoundValue(content_type));
// Make sure there is no entry that would override the pattern we are about
// to insert for exactly this URL.
SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(primary_url),
ContentSettingsPattern::Wildcard(),
content_type,
std::string(),
CONTENT_SETTING_DEFAULT);
SetContentSetting(ContentSettingsPattern::FromURL(primary_url),
ContentSettingsPattern::Wildcard(),
content_type,
std::string(),
setting);
}
void HostContentSettingsMap::ClearSettingsForOneType(
ContentSettingsType content_type) {
UsedContentSettingsProviders();
for (ProviderIterator provider = content_settings_providers_.begin();
provider != content_settings_providers_.end();
++provider) {
provider->second->ClearAllContentSettingsRules(content_type);
}
}
bool HostContentSettingsMap::IsValueAllowedForType(
PrefService* prefs, const base::Value* value, ContentSettingsType type) {
return ContentTypeHasCompoundValue(type) || IsSettingAllowedForType(
prefs, content_settings::ValueToContentSetting(value), type);
}
// static
bool HostContentSettingsMap::IsSettingAllowedForType(
PrefService* prefs,
ContentSetting setting,
ContentSettingsType content_type) {
// We don't yet support stored content settings for mixed scripting.
if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT)
return false;
// BLOCK semantics are not implemented for fullscreen.
if (content_type == CONTENT_SETTINGS_TYPE_FULLSCREEN &&
setting == CONTENT_SETTING_BLOCK) {
return false;
}
// We don't support ALLOW for media default setting.
if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM &&
setting == CONTENT_SETTING_ALLOW) {
return false;
}
#if defined(OS_ANDROID)
// App banners store a dictionary.
if (content_type == CONTENT_SETTINGS_TYPE_APP_BANNER)
return false;
#endif
// DEFAULT, ALLOW and BLOCK are always allowed.
if (setting == CONTENT_SETTING_DEFAULT ||
setting == CONTENT_SETTING_ALLOW ||
setting == CONTENT_SETTING_BLOCK) {
return true;
}
switch (content_type) {
case CONTENT_SETTINGS_TYPE_COOKIES:
return setting == CONTENT_SETTING_SESSION_ONLY;
case CONTENT_SETTINGS_TYPE_PLUGINS:
case CONTENT_SETTINGS_TYPE_GEOLOCATION:
case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
case CONTENT_SETTINGS_TYPE_MOUSELOCK:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
case CONTENT_SETTINGS_TYPE_PPAPI_BROKER:
case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
return setting == CONTENT_SETTING_ASK;
default:
return false;
}
}
// static
bool HostContentSettingsMap::ContentTypeHasCompoundValue(
ContentSettingsType type) {
// Values for content type CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
// CONTENT_SETTINGS_TYPE_MEDIASTREAM, and
// CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS are of type dictionary/map.
// Compound types like dictionaries can't be mapped to the type
// |ContentSetting|.
#if defined(OS_ANDROID)
if (type == CONTENT_SETTINGS_TYPE_APP_BANNER)
return true;
#endif
return (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE ||
type == CONTENT_SETTINGS_TYPE_MEDIASTREAM ||
type == CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS);
}
void HostContentSettingsMap::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
std::string resource_identifier) {
const ContentSettingsDetails details(primary_pattern,
secondary_pattern,
content_type,
resource_identifier);
// TODO(dhnishi): Remove usage of this notification.
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
content::Source<HostContentSettingsMap>(this),
content::Details<const ContentSettingsDetails>(&details));
FOR_EACH_OBSERVER(content_settings::Observer,
observers_,
OnContentSettingChanged(primary_pattern,
secondary_pattern,
content_type,
resource_identifier));
}
HostContentSettingsMap::~HostContentSettingsMap() {
DCHECK(!prefs_);
STLDeleteValues(&content_settings_providers_);
}
void HostContentSettingsMap::ShutdownOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(prefs_);
prefs_ = NULL;
for (ProviderIterator it = content_settings_providers_.begin();
it != content_settings_providers_.end();
++it) {
it->second->ShutdownOnUIThread();
}
}
void HostContentSettingsMap::MigrateObsoleteClearOnExitPref() {
// Don't migrate more than once.
if (prefs_->HasPrefPath(prefs::kContentSettingsClearOnExitMigrated) &&
prefs_->GetBoolean(prefs::kContentSettingsClearOnExitMigrated)) {
return;
}
if (!prefs_->GetBoolean(prefs::kClearSiteDataOnExit)) {
// Nothing to be done
prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
return;
}
// Change the default cookie settings:
// old new
// ---------------- ----------------
// ALLOW SESSION_ONLY
// SESSION_ONLY SESSION_ONLY
// BLOCK BLOCK
ContentSetting default_setting = GetDefaultContentSettingFromProvider(
CONTENT_SETTINGS_TYPE_COOKIES,
content_settings_providers_[DEFAULT_PROVIDER]);
if (default_setting == CONTENT_SETTING_ALLOW) {
SetDefaultContentSetting(
CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY);
}
// Change the exceptions using the same rules.
ContentSettingsForOneType exceptions;
AddSettingsForOneType(content_settings_providers_[PREF_PROVIDER],
PREF_PROVIDER,
CONTENT_SETTINGS_TYPE_COOKIES,
std::string(),
&exceptions,
false);
for (ContentSettingsForOneType::iterator it = exceptions.begin();
it != exceptions.end(); ++it) {
if (it->setting != CONTENT_SETTING_ALLOW)
continue;
SetWebsiteSetting(it->primary_pattern,
it->secondary_pattern,
CONTENT_SETTINGS_TYPE_COOKIES,
std::string(),
new base::FundamentalValue(CONTENT_SETTING_SESSION_ONLY));
}
prefs_->SetBoolean(prefs::kContentSettingsClearOnExitMigrated, true);
}
void HostContentSettingsMap::AddSettingsForOneType(
const content_settings::ProviderInterface* provider,
ProviderType provider_type,
ContentSettingsType content_type,
const std::string& resource_identifier,
ContentSettingsForOneType* settings,
bool incognito) const {
scoped_ptr<content_settings::RuleIterator> rule_iterator(
provider->GetRuleIterator(content_type,
resource_identifier,
incognito));
while (rule_iterator->HasNext()) {
const content_settings::Rule& rule = rule_iterator->Next();
ContentSetting setting_value = CONTENT_SETTING_DEFAULT;
// TODO(bauerb): Return rules as a list of values, not content settings.
// Handle the case using compound values for its exceptions and arbitrary
// values for its default setting. Here we assume all the exceptions
// are granted as |CONTENT_SETTING_ALLOW|.
if (ContentTypeHasCompoundValue(content_type) &&
rule.value.get() &&
rule.primary_pattern != ContentSettingsPattern::Wildcard()) {
setting_value = CONTENT_SETTING_ALLOW;
} else {
setting_value = content_settings::ValueToContentSetting(rule.value.get());
}
settings->push_back(ContentSettingPatternSource(
rule.primary_pattern, rule.secondary_pattern,
setting_value,
kProviderNames[provider_type],
incognito));
}
}
void HostContentSettingsMap::UsedContentSettingsProviders() const {
#ifndef NDEBUG
if (used_from_thread_id_ == base::kInvalidThreadId)
return;
if (base::PlatformThread::CurrentId() != used_from_thread_id_)
used_from_thread_id_ = base::kInvalidThreadId;
#endif
}
bool HostContentSettingsMap::ShouldAllowAllContent(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type) {
if (content_type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION ||
content_type == CONTENT_SETTINGS_TYPE_MIDI_SYSEX) {
return false;
}
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
if (content_type == CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) {
return false;
}
#endif
if (secondary_url.SchemeIs(content::kChromeUIScheme) &&
content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
primary_url.SchemeIsSecure()) {
return true;
}
if (primary_url.SchemeIs(extensions::kExtensionScheme)) {
switch (content_type) {
case CONTENT_SETTINGS_TYPE_PLUGINS:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
return false;
case CONTENT_SETTINGS_TYPE_COOKIES:
return secondary_url.SchemeIs(extensions::kExtensionScheme);
default:
return true;
}
}
return primary_url.SchemeIs(content::kChromeDevToolsScheme) ||
primary_url.SchemeIs(content::kChromeUIScheme);
}
base::Value* HostContentSettingsMap::GetWebsiteSetting(
const GURL& primary_url,
const GURL& secondary_url,
ContentSettingsType content_type,
const std::string& resource_identifier,
content_settings::SettingInfo* info) const {
DCHECK(SupportsResourceIdentifier(content_type) ||
resource_identifier.empty());
// Check if the scheme of the requesting url is whitelisted.
if (ShouldAllowAllContent(primary_url, secondary_url, content_type)) {
if (info) {
info->source = content_settings::SETTING_SOURCE_WHITELIST;
info->primary_pattern = ContentSettingsPattern::Wildcard();
info->secondary_pattern = ContentSettingsPattern::Wildcard();
}
return new base::FundamentalValue(CONTENT_SETTING_ALLOW);
}
ContentSettingsPattern* primary_pattern = NULL;
ContentSettingsPattern* secondary_pattern = NULL;
if (info) {
primary_pattern = &info->primary_pattern;
secondary_pattern = &info->secondary_pattern;
}
// The list of |content_settings_providers_| is ordered according to their
// precedence.
for (ConstProviderIterator provider = content_settings_providers_.begin();
provider != content_settings_providers_.end();
++provider) {
base::Value* value = content_settings::GetContentSettingValueAndPatterns(
provider->second, primary_url, secondary_url, content_type,
resource_identifier, is_off_the_record_,
primary_pattern, secondary_pattern);
if (value) {
if (info)
info->source = kProviderSourceMap[provider->first];
return value;
}
}
if (info) {
info->source = content_settings::SETTING_SOURCE_NONE;
info->primary_pattern = ContentSettingsPattern();
info->secondary_pattern = ContentSettingsPattern();
}
return NULL;
}
// static
HostContentSettingsMap::ProviderType
HostContentSettingsMap::GetProviderTypeFromSource(
const std::string& source) {
for (size_t i = 0; i < arraysize(kProviderNames); ++i) {
if (source == kProviderNames[i])
return static_cast<ProviderType>(i);
}
NOTREACHED();
return DEFAULT_PROVIDER;
}
content_settings::PrefProvider* HostContentSettingsMap::GetPrefProvider() {
return static_cast<content_settings::PrefProvider*>(
content_settings_providers_[PREF_PROVIDER]);
}