Index: chrome/browser/content_settings/host_content_settings_map.cc |
diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc |
index c2dea38574052137cd592b0370a3b2633c0bd22f..7de7a80beec5dc8ae6ba89d668969c67d2ac5723 100644 |
--- a/chrome/browser/content_settings/host_content_settings_map.cc |
+++ b/chrome/browser/content_settings/host_content_settings_map.cc |
@@ -9,6 +9,8 @@ |
#include "base/utf_string_conversions.h" |
#include "chrome/browser/browser_thread.h" |
#include "chrome/browser/content_settings/content_settings_details.h" |
+#include "chrome/browser/content_settings/policy_content_settings_provider.h" |
+#include "chrome/browser/content_settings/pref_content_settings_provider.h" |
#include "chrome/browser/metrics/user_metrics.h" |
#include "chrome/browser/prefs/pref_service.h" |
#include "chrome/browser/profiles/profile.h" |
@@ -20,19 +22,11 @@ |
#include "chrome/common/pref_names.h" |
#include "chrome/common/url_constants.h" |
#include "googleurl/src/gurl.h" |
-#include "googleurl/src/url_canon.h" |
-#include "googleurl/src/url_parse.h" |
-#include "net/base/dns_util.h" |
#include "net/base/net_util.h" |
#include "net/base/static_cookie_policy.h" |
namespace { |
-// Base pref path of the prefs that contain the managed default content |
-// settings values. |
-const std::string kManagedSettings = |
- "profile.managed_default_content_settings"; |
- |
// The preference keys where resource identifiers are stored for |
// ContentSettingsType values that support resource identifiers. |
const char* kResourceTypeNames[CONTENT_SETTINGS_NUM_TYPES] = { |
@@ -56,28 +50,6 @@ const char* kTypeNames[CONTENT_SETTINGS_NUM_TYPES] = { |
NULL, // Not used for Notifications |
}; |
-// The preferences used to manage ContentSettingsTypes. |
-const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = { |
- prefs::kManagedDefaultCookiesSetting, |
- prefs::kManagedDefaultImagesSetting, |
- prefs::kManagedDefaultJavaScriptSetting, |
- prefs::kManagedDefaultPluginsSetting, |
- prefs::kManagedDefaultPopupsSetting, |
- NULL, // Not used for Geolocation |
- NULL, // Not used for Notifications |
-}; |
- |
-// The default setting for each content type. |
-const ContentSetting kDefaultSettings[CONTENT_SETTINGS_NUM_TYPES] = { |
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_COOKIES |
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_IMAGES |
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_JAVASCRIPT |
- CONTENT_SETTING_ALLOW, // CONTENT_SETTINGS_TYPE_PLUGINS |
- CONTENT_SETTING_BLOCK, // CONTENT_SETTINGS_TYPE_POPUPS |
- CONTENT_SETTING_ASK, // Not used for Geolocation |
- CONTENT_SETTING_ASK, // Not used for Notifications |
-}; |
- |
// True if a given content settings type requires additional resource |
// identifiers. |
const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = { |
@@ -115,6 +87,12 @@ ContentSetting ClickToPlayFixup(ContentSettingsType content_type, |
return setting; |
} |
+typedef std::vector<linked_ptr<ContentSettingsProviderInterface> >::iterator |
+ provider_iterator; |
+typedef |
+ std::vector<linked_ptr<ContentSettingsProviderInterface> >::const_iterator |
+ const_provider_iterator; |
+ |
} // namespace |
@@ -125,10 +103,20 @@ struct HostContentSettingsMap::ExtendedContentSettings { |
HostContentSettingsMap::HostContentSettingsMap(Profile* profile) |
: profile_(profile), |
- block_third_party_cookies_(false), |
- is_block_third_party_cookies_managed_(false), |
is_off_the_record_(profile_->IsOffTheRecord()), |
- updating_preferences_(false) { |
+ updating_preferences_(false), |
+ block_third_party_cookies_(false), |
+ is_block_third_party_cookies_managed_(false) { |
+ // The order in which the content settings providers are created is critical, |
+ // as providers that are further down in the list (i.e. added later) override |
+ // providers further up. |
+ content_settings_providers_.push_back( |
+ linked_ptr<ContentSettingsProviderInterface>( |
+ new PrefContentSettingsProvider(profile))); |
+ content_settings_providers_.push_back( |
+ linked_ptr<ContentSettingsProviderInterface>( |
+ new PolicyContentSettingsProvider(profile))); |
+ |
PrefService* prefs = profile_->GetPrefs(); |
MigrateObsoleteCookiePref(prefs); |
@@ -137,11 +125,6 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile) |
MigrateObsoletePerhostPref(prefs); |
- // Read global defaults. |
- DCHECK_EQ(arraysize(kTypeNames), |
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); |
- ReadDefaultSettings(false); |
- |
// Read misc. global settings. |
block_third_party_cookies_ = |
prefs->GetBoolean(prefs::kBlockThirdPartyCookies); |
@@ -165,29 +148,15 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile) |
ReadExceptions(false); |
pref_change_registrar_.Init(prefs); |
- pref_change_registrar_.Add(prefs::kDefaultContentSettings, this); |
pref_change_registrar_.Add(prefs::kContentSettingsPatterns, this); |
pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this); |
pref_change_registrar_.Add(prefs::kBlockNonsandboxedPlugins, this); |
- // The following preferences are only used to indicate if a |
- // default-content-setting is managed and to hold the managed default-setting |
- // value. If the value for any of the following perferences is set then the |
- // corresponding default-content-setting is managed. These preferences exist |
- // in parallel to the preference default-content-settings. If a |
- // default-content-settings-type is managed any user defined excpetions |
- // (patterns) for this type are ignored. |
- pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this); |
- pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this); |
- pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this); |
- pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this); |
- pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this); |
notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, |
Source<Profile>(profile_)); |
} |
// static |
void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { |
- prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings); |
prefs->RegisterIntegerPref(prefs::kContentSettingsVersion, |
ContentSettingsPattern::kContentSettingsPatternVersion); |
prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns); |
@@ -195,19 +164,6 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { |
prefs->RegisterBooleanPref(prefs::kBlockNonsandboxedPlugins, false); |
prefs->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0); |
- // Preferences for default content setting policies. A policy is not set of |
- // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT. |
- prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting, |
- CONTENT_SETTING_DEFAULT); |
- prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting, |
- CONTENT_SETTING_DEFAULT); |
- prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting, |
- CONTENT_SETTING_DEFAULT); |
- prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting, |
- CONTENT_SETTING_DEFAULT); |
- prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting, |
- CONTENT_SETTING_DEFAULT); |
- |
// Obsolete prefs, for migration: |
prefs->RegisterIntegerPref(prefs::kCookieBehavior, |
net::StaticCookiePolicy::ALLOW_ALL_COOKIES); |
@@ -217,10 +173,21 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { |
ContentSetting HostContentSettingsMap::GetDefaultContentSetting( |
ContentSettingsType content_type) const { |
- AutoLock auto_lock(lock_); |
- if (IsDefaultContentSettingManaged(content_type)) |
- return managed_default_content_settings_.settings[content_type]; |
- return default_content_settings_.settings[content_type]; |
+ ContentSetting setting = CONTENT_SETTING_DEFAULT; |
+ for (const_provider_iterator provider = content_settings_providers_.begin(); |
+ provider != content_settings_providers_.end(); ++provider) { |
+ if (!(*provider)->CanProvideDefaultSetting(content_type)) |
+ continue; |
+ ContentSetting provided_setting = |
+ (*provider)->ProvideDefaultSetting(content_type); |
+ if (provided_setting != CONTENT_SETTING_DEFAULT) |
+ setting = provided_setting; |
+ } |
+ // The method GetDefaultContentSetting always has to return an explicit |
+ // value that is to be used as default. We here rely on the |
+ // PrefContentSettingProvider to always provide a value. |
+ CHECK_NE(CONTENT_SETTING_DEFAULT, setting); |
+ return setting; |
} |
ContentSetting HostContentSettingsMap::GetContentSetting( |
@@ -318,22 +285,17 @@ ContentSettings HostContentSettingsMap::GetContentSettings( |
const GURL& url) const { |
ContentSettings output = GetNonDefaultContentSettings(url); |
- AutoLock auto_lock(lock_); |
- |
// If we require a resource identifier, set the content settings to default, |
// otherwise make the defaults explicit. |
for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { |
if (RequiresResourceIdentifier(ContentSettingsType(j))) { |
output.settings[j] = CONTENT_SETTING_DEFAULT; |
} else { |
- if (output.settings[j] == CONTENT_SETTING_DEFAULT) { |
- output.settings[j] = default_content_settings_.settings[j]; |
- } |
// A managed default content setting has the highest priority and hence |
// will overwrite any previously set value. |
- if (IsDefaultContentSettingManaged(ContentSettingsType(j))) { |
- output.settings[j] = |
- managed_default_content_settings_.settings[j]; |
+ if ((output.settings[j] == CONTENT_SETTING_DEFAULT) || |
+ IsDefaultContentSettingManaged(ContentSettingsType(j))) { |
+ output.settings[j] = GetDefaultContentSetting(ContentSettingsType(j)); |
} |
} |
} |
@@ -441,7 +403,6 @@ void HostContentSettingsMap::SetDefaultContentSetting( |
setting != CONTENT_SETTING_ASK || |
CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kEnableClickToPlay)); |
- PrefService* prefs = profile_->GetPrefs(); |
// The default settings may not be directly modified for OTR sessions. |
// Instead, they are synced to the main profile's setting. |
@@ -450,29 +411,10 @@ void HostContentSettingsMap::SetDefaultContentSetting( |
return; |
} |
- DictionaryValue* default_settings_dictionary = |
- prefs->GetMutableDictionary(prefs::kDefaultContentSettings); |
- std::string dictionary_path(kTypeNames[content_type]); |
- updating_preferences_ = true; |
- { |
- AutoLock auto_lock(lock_); |
- ScopedPrefUpdate update(prefs, prefs::kDefaultContentSettings); |
- if ((setting == CONTENT_SETTING_DEFAULT) || |
- (setting == kDefaultSettings[content_type])) { |
- default_content_settings_.settings[content_type] = |
- kDefaultSettings[content_type]; |
- default_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, |
- NULL); |
- } else { |
- default_content_settings_.settings[content_type] = setting; |
- default_settings_dictionary->SetWithoutPathExpansion( |
- dictionary_path, Value::CreateIntegerValue(setting)); |
- } |
+ for (provider_iterator provider = content_settings_providers_.begin(); |
+ provider != content_settings_providers_.end(); ++provider) { |
+ (*provider)->UpdateDefaultSetting(content_type, setting); |
} |
- updating_preferences_ = false; |
- |
- NotifyObservers( |
- ContentSettingsDetails(ContentSettingsPattern(), content_type, "")); |
} |
void HostContentSettingsMap::SetContentSetting( |
@@ -727,10 +669,10 @@ void HostContentSettingsMap::ResetToDefaults() { |
{ |
AutoLock auto_lock(lock_); |
- default_content_settings_ = ContentSettings(); |
- ForceDefaultsToBeExplicit(); |
- // Clear all content settings map except the |
- // managed_default_content_settings. |
+ for (provider_iterator provider = content_settings_providers_.begin(); |
+ provider != content_settings_providers_.end(); ++provider) { |
+ (*provider)->ResetToDefaults(); |
+ } |
host_content_settings_.clear(); |
off_the_record_settings_.clear(); |
// Don't reset block third party cookies if they are managed. |
@@ -742,7 +684,6 @@ void HostContentSettingsMap::ResetToDefaults() { |
if (!is_off_the_record_) { |
PrefService* prefs = profile_->GetPrefs(); |
updating_preferences_ = true; |
- prefs->ClearPref(prefs::kDefaultContentSettings); |
prefs->ClearPref(prefs::kContentSettingsPatterns); |
// If the block third party cookies preference is managed we still must |
// clear it in order to restore the default value for later when the |
@@ -761,46 +702,25 @@ void HostContentSettingsMap::Observe(NotificationType type, |
const NotificationDetails& details) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (NotificationType::PREF_CHANGED == type) { |
+ if (type == NotificationType::PREF_CHANGED) { |
+ DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr()); |
if (updating_preferences_) |
return; |
std::string* name = Details<std::string>(details).ptr(); |
- if (prefs::kDefaultContentSettings == *name) { |
- ReadDefaultSettings(true); |
- } else if (prefs::kContentSettingsPatterns == *name) { |
+ if (*name == prefs::kContentSettingsPatterns) { |
ReadExceptions(true); |
- } else if (prefs::kBlockThirdPartyCookies == *name) { |
+ } else if (*name == prefs::kBlockThirdPartyCookies) { |
AutoLock auto_lock(lock_); |
block_third_party_cookies_ = profile_->GetPrefs()->GetBoolean( |
prefs::kBlockThirdPartyCookies); |
is_block_third_party_cookies_managed_ = |
profile_->GetPrefs()->IsManagedPreference( |
prefs::kBlockThirdPartyCookies); |
- } else if (prefs::kBlockNonsandboxedPlugins == *name) { |
+ } else if (*name == prefs::kBlockNonsandboxedPlugins) { |
AutoLock auto_lock(lock_); |
block_nonsandboxed_plugins_ = profile_->GetPrefs()->GetBoolean( |
prefs::kBlockNonsandboxedPlugins); |
- } else if (prefs::kManagedDefaultCookiesSetting == *name) { |
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES, |
- profile_->GetPrefs(), |
- &managed_default_content_settings_); |
- } else if (prefs::kManagedDefaultImagesSetting == *name) { |
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES, |
- profile_->GetPrefs(), |
- &managed_default_content_settings_); |
- } else if (prefs::kManagedDefaultJavaScriptSetting == *name) { |
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT, |
- profile_->GetPrefs(), |
- &managed_default_content_settings_); |
- } else if (prefs::kManagedDefaultPluginsSetting == *name) { |
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS, |
- profile_->GetPrefs(), |
- &managed_default_content_settings_); |
- } else if (prefs::kManagedDefaultPopupsSetting == *name) { |
- UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS, |
- profile_->GetPrefs(), |
- &managed_default_content_settings_); |
} else { |
NOTREACHED() << "Unexpected preference observed"; |
return; |
@@ -811,7 +731,8 @@ void HostContentSettingsMap::Observe(NotificationType type, |
CONTENT_SETTINGS_TYPE_DEFAULT, |
"")); |
} |
- } else if (NotificationType::PROFILE_DESTROYED == type) { |
+ } else if (type == NotificationType::PROFILE_DESTROYED) { |
+ DCHECK_EQ(profile_, Source<Profile>(source).ptr()); |
UnregisterObservers(); |
} else { |
NOTREACHED() << "Unexpected notification"; |
@@ -881,16 +802,6 @@ void HostContentSettingsMap::GetResourceSettingsFromDictionary( |
} |
} |
-void HostContentSettingsMap::ForceDefaultsToBeExplicit() { |
- DCHECK_EQ(arraysize(kDefaultSettings), |
- static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); |
- |
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { |
- if (default_content_settings_.settings[i] == CONTENT_SETTING_DEFAULT) |
- default_content_settings_.settings[i] = kDefaultSettings[i]; |
- } |
-} |
- |
bool HostContentSettingsMap::AllDefault( |
const ExtendedContentSettings& settings) const { |
for (size_t i = 0; i < arraysize(settings.content_settings.settings); ++i) { |
@@ -900,64 +811,19 @@ bool HostContentSettingsMap::AllDefault( |
return settings.content_settings_for_resources.empty(); |
} |
-void HostContentSettingsMap::ReadDefaultSettings(bool overwrite) { |
- PrefService* prefs = profile_->GetPrefs(); |
- const DictionaryValue* default_settings_dictionary = |
- prefs->GetDictionary(prefs::kDefaultContentSettings); |
- |
- if (overwrite) |
- default_content_settings_ = ContentSettings(); |
- |
- // Careful: The returned value could be NULL if the pref has never been set. |
- if (default_settings_dictionary != NULL) { |
- GetSettingsFromDictionary(default_settings_dictionary, |
- &default_content_settings_); |
- } |
- ForceDefaultsToBeExplicit(); |
- |
- // Read managed default content settings. |
- ReadManagedDefaultSettings(prefs, &managed_default_content_settings_); |
-} |
- |
-void HostContentSettingsMap::ReadManagedDefaultSettings( |
- const PrefService* prefs, ContentSettings* settings) { |
- for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) { |
- if (kPrefToManageType[type] == NULL) { |
- // TODO(markusheintz): Handle Geolocation and notification separately. |
- continue; |
- } |
- UpdateManagedDefaultSetting(ContentSettingsType(type), prefs, settings); |
- } |
-} |
- |
-void HostContentSettingsMap::UpdateManagedDefaultSetting( |
- ContentSettingsType type, |
- const PrefService* prefs, |
- ContentSettings* settings) { |
- // If a pref to manage a default-content-setting was not set (NOTICE: |
- // "HasPrefPath" returns false if no value was set for a registered pref) then |
- // the default value of the preference is used. The default value of a |
- // preference to manage a default-content-settings is |
- // CONTENT_SETTING_DEFAULT. This indicates that no managed value is set. If a |
- // pref was set, than it MUST be managed. |
- DCHECK(!prefs->HasPrefPath(kPrefToManageType[type]) || |
- prefs->IsManagedPreference(kPrefToManageType[type])); |
- AutoLock auto_lock(lock_); |
- settings->settings[type] = IntToContentSetting( |
- prefs->GetInteger(kPrefToManageType[type])); |
-} |
- |
bool HostContentSettingsMap::IsDefaultContentSettingManaged( |
ContentSettingsType content_type) const { |
- // All managed_default_content_settings_ are always set explicitly or |
- // initialized to CONTENT_SETTINGS_DEFAULT. Hence each content settings type |
- // that is set to CONTENT_SETTINGS_DEFAULT is not managed since it was not set |
- // explicitly. |
- return managed_default_content_settings_.settings[content_type] != |
- CONTENT_SETTING_DEFAULT; |
+ for (const_provider_iterator provider = content_settings_providers_.begin(); |
+ provider != content_settings_providers_.end(); ++provider) { |
+ if ((*provider)->DefaultSettingIsManaged(content_type)) |
+ return true; |
+ } |
+ return false; |
} |
void HostContentSettingsMap::ReadExceptions(bool overwrite) { |
+ AutoLock lock(lock_); |
+ |
PrefService* prefs = profile_->GetPrefs(); |
DictionaryValue* all_settings_dictionary = |
prefs->GetMutableDictionary(prefs::kContentSettingsPatterns); |