diff options
author | marja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-10 09:04:16 +0000 |
---|---|---|
committer | marja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-10 09:04:16 +0000 |
commit | bf98782c26763e79c37bff93873b56a693ffa88b (patch) | |
tree | 2ee066fe416dcdf76cf1b42dc930a429483484a1 | |
parent | dad21bfdae162c31845b4b66ed2711722dc1f2f4 (diff) | |
download | chromium_src-bf98782c26763e79c37bff93873b56a693ffa88b.zip chromium_src-bf98782c26763e79c37bff93873b56a693ffa88b.tar.gz chromium_src-bf98782c26763e79c37bff93873b56a693ffa88b.tar.bz2 |
Remove content settings default providers from the host content settings map.
Add a DefaultProvider for user default settings and integrate the DefaultPolicyProvider into the PolicyProvider.
The real work was done by markusheintz@chromium.org and the original CL is
http://codereview.chromium.org/7976032/
BUG=63656
TEST=host_content_settings_map_unittest.cc,
content_settings_policy_provider_unittest.cc,
content_settings_default_provider_unittest.cc
Review URL: http://codereview.chromium.org/8137024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104704 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 1127 insertions, 1219 deletions
diff --git a/chrome/browser/content_settings/content_settings_default_provider.cc b/chrome/browser/content_settings/content_settings_default_provider.cc new file mode 100644 index 0000000..9c3d24c --- /dev/null +++ b/chrome/browser/content_settings/content_settings_default_provider.cc @@ -0,0 +1,320 @@ +// 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/content_settings/content_settings_default_provider.h" + +#include <string> +#include <vector> + +#include "base/auto_reset.h" +#include "base/basictypes.h" +#include "base/command_line.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/browser/content_settings/content_settings_rule.h" +#include "chrome/browser/content_settings/content_settings_utils.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/content_settings.h" +#include "chrome/common/content_settings_pattern.h" +#include "chrome/common/pref_names.h" +#include "content/browser/browser_thread.h" +#include "content/browser/user_metrics.h" +#include "content/common/notification_service.h" +#include "content/common/notification_source.h" +#include "googleurl/src/gurl.h" +#include "net/base/net_util.h" + +namespace { + +// The default setting for each content type. +const ContentSetting kDefaultSettings[] = { + 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, // CONTENT_SETTINGS_TYPE_GEOLOCATION + CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_NOTIFICATIONS + CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_INTENTS + CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE +}; +COMPILE_ASSERT(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES, + default_settings_incorrect_size); + +} // namespace + +namespace content_settings { + +// static +void DefaultProvider::RegisterUserPrefs(PrefService* prefs) { + // The registration of the preference prefs::kDefaultContentSettings should + // also include the default values for default content settings. This allows + // functional tests to get default content settings by reading the preference + // prefs::kDefaultContentSettings via pyauto. + // TODO(markusheintz): Write pyauto hooks for the content settings map as + // content settings should be read from the host content settings map. + DictionaryValue* default_content_settings = new DictionaryValue(); + prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings, + default_content_settings, + PrefService::SYNCABLE_PREF); + + // Obsolete prefs, for migrations: + prefs->RegisterIntegerPref( + prefs::kDesktopNotificationDefaultContentSetting, + kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS], + PrefService::SYNCABLE_PREF); + prefs->RegisterIntegerPref( + prefs::kGeolocationDefaultContentSetting, + kDefaultSettings[CONTENT_SETTINGS_TYPE_GEOLOCATION], + PrefService::UNSYNCABLE_PREF); +} + +DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) + : prefs_(prefs), + is_incognito_(incognito), + updating_preferences_(false) { + DCHECK(prefs_); + MigrateObsoleteNotificationPref(); + MigrateObsoleteGeolocationPref(); + + // Read global defaults. + ReadDefaultSettings(true); + if (default_content_settings_.settings[CONTENT_SETTINGS_TYPE_COOKIES] == + CONTENT_SETTING_BLOCK) { + UserMetrics::RecordAction( + UserMetricsAction("CookieBlockingEnabledPerDefault")); + } else { + UserMetrics::RecordAction( + UserMetricsAction("CookieBlockingDisabledPerDefault")); + } + + pref_change_registrar_.Init(prefs_); + pref_change_registrar_.Add(prefs::kDefaultContentSettings, this); + pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); +} + +DefaultProvider::~DefaultProvider() { +} + +void DefaultProvider::SetContentSetting( + const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting setting) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(prefs_); + + // Ignore non default settings + if (primary_pattern != ContentSettingsPattern::Wildcard() || + secondary_pattern != ContentSettingsPattern::Wildcard()) { + return; + } + + // The default settings may not be directly modified for OTR sessions. + // Instead, they are synced to the main profile's setting. + if (is_incognito_) + return; + + std::string dictionary_path = GetTypeName(content_type); + { + AutoReset<bool> auto_reset(&updating_preferences_, true); + DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); + DictionaryValue* default_settings_dictionary = update.Get(); + + // |DefaultProvider| should not send any notifications when holding + // |lock_|. |DictionaryPrefUpdate| destructor and + // |PrefService::SetInteger()| send out notifications. As a response, the + // upper layers may call |GetAllContentSettingRules| which acquires |lock_| + // again. + { + base::AutoLock lock(lock_); + 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)); + } + } + + // Keep the obsolete pref in sync as long as backwards compatibility is + // required. This is required to keep sync working correctly. + if (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { + prefs_->SetInteger(prefs::kGeolocationDefaultContentSetting, + setting == CONTENT_SETTING_DEFAULT ? + kDefaultSettings[content_type] : setting); + } + } + + NotifyObservers(ContentSettingsPattern(), + ContentSettingsPattern(), + content_type, + std::string()); +} + +ContentSetting DefaultProvider::GetContentSetting( + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const { + base::AutoLock lock(lock_); + return default_content_settings_.settings[content_type]; +} + +Value* DefaultProvider::GetContentSettingValue( + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const { + base::AutoLock lock(lock_); + return Value::CreateIntegerValue( + default_content_settings_.settings[content_type]); +} + +void DefaultProvider::GetAllContentSettingsRules( + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + std::vector<Rule>* content_setting_rules) const { + base::AutoLock lock(lock_); + content_setting_rules->push_back(Rule( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + default_content_settings_.settings[content_type])); +} + +void DefaultProvider::ClearAllContentSettingsRules( + ContentSettingsType content_type) { + // TODO(markusheintz): This method is only called when the + // |DesktopNotificationService| calls |ClearAllSettingsForType| method on the + // |HostContentSettingsMap|. Don't implement this method yet, otherwise the + // default notification settings will be cleared as well. +} + +void DefaultProvider::ShutdownOnUIThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(prefs_); + RemoveAllObservers(); + pref_change_registrar_.RemoveAll(); + prefs_ = NULL; +} + +void DefaultProvider::Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (type == chrome::NOTIFICATION_PREF_CHANGED) { + DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); + if (updating_preferences_) + return; + + std::string* name = Details<std::string>(details).ptr(); + if (*name == prefs::kDefaultContentSettings) { + ReadDefaultSettings(true); + } else if (*name == prefs::kGeolocationDefaultContentSetting) { + MigrateObsoleteGeolocationPref(); + // Return and don't send a notifications. Migrating the obsolete + // geolocation pref will change the prefs::kDefaultContentSettings and + // cause the notification to be fired. + return; + } else { + NOTREACHED() << "Unexpected preference observed"; + return; + } + + NotifyObservers(ContentSettingsPattern(), + ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_DEFAULT, + std::string()); + } else { + NOTREACHED() << "Unexpected notification"; + } +} + +void DefaultProvider::ReadDefaultSettings(bool overwrite) { + base::AutoLock lock(lock_); + 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) { + GetSettingsFromDictionary(default_settings_dictionary, + &default_content_settings_); + } + ForceDefaultsToBeExplicit(); +} + +void DefaultProvider::ForceDefaultsToBeExplicit() { + 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]; + } +} + +void DefaultProvider::GetSettingsFromDictionary( + const DictionaryValue* dictionary, + ContentSettings* settings) { + for (DictionaryValue::key_iterator i(dictionary->begin_keys()); + i != dictionary->end_keys(); ++i) { + const std::string& content_type(*i); + for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { + if (content_type == GetTypeName(ContentSettingsType(type))) { + int setting = CONTENT_SETTING_DEFAULT; + bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, + &setting); + DCHECK(found); + settings->settings[type] = IntToContentSetting(setting); + break; + } + } + } + // Migrate obsolete cookie prompt mode/ + if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] == + CONTENT_SETTING_ASK) + settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; + + settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = + ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, + settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); +} + +void DefaultProvider::MigrateObsoleteNotificationPref() { + if (prefs_->HasPrefPath(prefs::kDesktopNotificationDefaultContentSetting)) { + ContentSetting setting = IntToContentSetting( + prefs_->GetInteger(prefs::kDesktopNotificationDefaultContentSetting)); + SetContentSetting( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_NOTIFICATIONS, + std::string(), + setting); + prefs_->ClearPref(prefs::kDesktopNotificationDefaultContentSetting); + } +} + +void DefaultProvider::MigrateObsoleteGeolocationPref() { + if (prefs_->HasPrefPath(prefs::kGeolocationDefaultContentSetting)) { + ContentSetting setting = IntToContentSetting( + prefs_->GetInteger(prefs::kGeolocationDefaultContentSetting)); + // Do not clear the old preference yet as long as we need to maintain + // backward compatibility. + SetContentSetting( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + setting); + } +} + +} // namespace diff --git a/chrome/browser/content_settings/content_settings_default_provider.h b/chrome/browser/content_settings/content_settings_default_provider.h new file mode 100644 index 0000000..2850ce0 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_default_provider.h @@ -0,0 +1,106 @@ +// 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. + +#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DEFAULT_PROVIDER_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DEFAULT_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/synchronization/lock.h" +#include "chrome/browser/content_settings/content_settings_observable_provider.h" +#include "chrome/browser/prefs/pref_change_registrar.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" + +namespace content_settings { + +// Provider that provides default content settings based on +// user prefs. If no default values are set by the user we use the hard coded +// default values. +class DefaultProvider : public ObservableProvider, + public NotificationObserver { + public: + static void RegisterUserPrefs(PrefService* prefs); + + DefaultProvider(PrefService* prefs, + bool incognito); + virtual ~DefaultProvider(); + + // ProviderInterface implementations. + virtual void SetContentSetting( + const ContentSettingsPattern& primary_pattern, + const ContentSettingsPattern& secondary_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + ContentSetting content_setting) OVERRIDE; + + virtual ContentSetting GetContentSetting( + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const OVERRIDE; + + virtual Value* GetContentSettingValue( + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const OVERRIDE; + + virtual void GetAllContentSettingsRules( + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + std::vector<Rule>* content_setting_rules) const OVERRIDE; + + virtual void ClearAllContentSettingsRules( + ContentSettingsType content_type) OVERRIDE; + + virtual void ShutdownOnUIThread() OVERRIDE; + + // NotificationObserver implementation. + virtual void Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) OVERRIDE; + + private: + // Sets the fields of |settings| based on the values in |dictionary|. + void GetSettingsFromDictionary(const base::DictionaryValue* dictionary, + ContentSettings* settings); + + // Forces the default settings to be explicitly set instead of themselves + // being CONTENT_SETTING_DEFAULT. + void ForceDefaultsToBeExplicit(); + + // Reads the default settings from the preferences service. If |overwrite| is + // true and the preference is missing, the local copy will be cleared as well. + void ReadDefaultSettings(bool overwrite); + + void MigrateObsoleteNotificationPref(); + void MigrateObsoleteGeolocationPref(); + + // Copies of the pref data, so that we can read it on the IO thread. + ContentSettings default_content_settings_; + + PrefService* prefs_; + + // Whether this settings map is for an Incognito session. + bool is_incognito_; + + // Used around accesses to the |default_content_settings_| object to guarantee + // thread safety. + mutable base::Lock lock_; + + PrefChangeRegistrar pref_change_registrar_; + + // Whether we are currently updating preferences, this is used to ignore + // notifications from the preferences service that we triggered ourself. + bool updating_preferences_; + + DISALLOW_COPY_AND_ASSIGN(DefaultProvider); +}; + +} // namespace content_settings + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DEFAULT_PROVIDER_H_ diff --git a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc new file mode 100644 index 0000000..1f2930d9 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc @@ -0,0 +1,251 @@ +// 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 "base/memory/scoped_ptr.h" +#include "chrome/browser/content_settings/content_settings_default_provider.h" +#include "chrome/browser/content_settings/content_settings_mock_observer.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_pref_service.h" +#include "chrome/test/base/testing_profile.h" +#include "content/browser/browser_thread.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +class DefaultProviderTest : public testing::Test { + public: + DefaultProviderTest() + : ui_thread_(BrowserThread::UI, &message_loop_), + provider_(profile_.GetPrefs(), false) { + } + ~DefaultProviderTest() { + provider_.ShutdownOnUIThread(); + } + + protected: + MessageLoop message_loop_; + BrowserThread ui_thread_; + TestingProfile profile_; + content_settings::DefaultProvider provider_; +}; + +TEST_F(DefaultProviderTest, DefaultValues) { + // Check setting defaults. + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + EXPECT_EQ(CONTENT_SETTING_ASK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string())); + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string())); +} + +TEST_F(DefaultProviderTest, IgnoreNonDefaultSettings) { + GURL primary_url("http://www.google.com"); + GURL secondary_url("http://www.google.com"); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(primary_url, + secondary_url, + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + provider_.SetContentSetting(ContentSettingsPattern::FromURL(primary_url), + ContentSettingsPattern::FromURL(secondary_url), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(primary_url, + secondary_url, + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); +} + + +TEST_F(DefaultProviderTest, Observer) { + content_settings::MockObserver mock_observer; + EXPECT_CALL(mock_observer, + OnContentSettingChanged( + _, _, CONTENT_SETTINGS_TYPE_IMAGES, "")); + provider_.AddObserver(&mock_observer); + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_IMAGES, + std::string(), + CONTENT_SETTING_BLOCK); + + EXPECT_CALL(mock_observer, + OnContentSettingChanged( + _, _, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + CONTENT_SETTING_BLOCK); +} + + +TEST_F(DefaultProviderTest, ObserveDefaultPref) { + PrefService* prefs = profile_.GetPrefs(); + + // Make a copy of the default pref value so we can reset it later. + scoped_ptr<Value> default_value(prefs->FindPreference( + prefs::kDefaultContentSettings)->GetValue()->DeepCopy()); + + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + // Make a copy of the pref's new value so we can reset it later. + scoped_ptr<Value> new_value(prefs->FindPreference( + prefs::kDefaultContentSettings)->GetValue()->DeepCopy()); + + // Clearing the backing pref should also clear the internal cache. + prefs->Set(prefs::kDefaultContentSettings, *default_value); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + // Reseting the pref to its previous value should update the cache. + prefs->Set(prefs::kDefaultContentSettings, *new_value); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); +} + +TEST_F(DefaultProviderTest, OffTheRecord) { + content_settings::DefaultProvider otr_provider(profile_.GetPrefs(), true); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + otr_provider.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + // Changing content settings on the main provider should also affect the + // incognito map. + provider_.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), + CONTENT_SETTING_BLOCK); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + EXPECT_EQ(CONTENT_SETTING_BLOCK, + otr_provider.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + // Changing content settings on the incognito provider should be ignored. + otr_provider.SetContentSetting(ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), + CONTENT_SETTING_ALLOW); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + + EXPECT_EQ(CONTENT_SETTING_BLOCK, + otr_provider.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_COOKIES, + std::string())); + otr_provider.ShutdownOnUIThread(); +} + +TEST_F(DefaultProviderTest, MigrateDefaultGeolocationContentSettingAfterSync) { + EXPECT_EQ(CONTENT_SETTING_ASK, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string())); + + content_settings::MockObserver mock_observer; + EXPECT_CALL(mock_observer, + OnContentSettingChanged( + _, _, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); + provider_.AddObserver(&mock_observer); + + // Set obsolete preference and test if it is migrated correctly. This can + // happen when an old version of chrome syncs the obsolete default geolocation + // preference. + PrefService* prefs = profile_.GetPrefs(); + prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, + CONTENT_SETTING_ALLOW); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider_.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string())); +} + +TEST_F(DefaultProviderTest, MigrateDefaultGeolocationContentSettingAtStartup) { + TestingProfile profile; + TestingPrefService* prefs = profile.GetTestingPrefService(); + + // Set obsolete preference and test if it is migrated correctly. + prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, + CONTENT_SETTING_ALLOW); + // Create a new |DefaultProvider| to test whether the obsolete default + // geolocation setting is correctly migrated. The migrated settings should be + // available right after creation of the provider. + content_settings::DefaultProvider provider(prefs, false); + + EXPECT_EQ(CONTENT_SETTING_ALLOW, + provider.GetContentSetting(GURL(), + GURL(), + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string())); + provider.ShutdownOnUIThread(); +} diff --git a/chrome/browser/content_settings/content_settings_mock_provider.cc b/chrome/browser/content_settings/content_settings_mock_provider.cc index c0a231b..a5ec92d 100644 --- a/chrome/browser/content_settings/content_settings_mock_provider.cc +++ b/chrome/browser/content_settings/content_settings_mock_provider.cc @@ -6,40 +6,6 @@ namespace content_settings { -MockDefaultProvider::MockDefaultProvider( - ContentSettingsType content_type, - ContentSetting setting, - bool is_managed, - bool can_override) - : content_type_(content_type), - setting_(setting), - is_managed_(is_managed), - can_override_(can_override) { -} - -MockDefaultProvider::~MockDefaultProvider() { -} - -ContentSetting MockDefaultProvider::ProvideDefaultSetting( - ContentSettingsType content_type) const { - return content_type == content_type_ ? setting_ : CONTENT_SETTING_DEFAULT; -} - -void MockDefaultProvider::UpdateDefaultSetting( - ContentSettingsType content_type, - ContentSetting setting) { - if (can_override_ && content_type == content_type_) - setting_ = setting; -} - -bool MockDefaultProvider::DefaultSettingIsManaged( - ContentSettingsType content_type) const { - return content_type == content_type_ && is_managed_; -} - -void MockDefaultProvider::ShutdownOnUIThread() { -} - MockProvider::MockProvider() : requesting_url_pattern_(ContentSettingsPattern()), embedding_url_pattern_(ContentSettingsPattern()), @@ -107,4 +73,8 @@ void MockProvider::SetContentSetting( setting_ = content_setting; } +void MockProvider::ShutdownOnUIThread() { + RemoveAllObservers(); +} + } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_mock_provider.h b/chrome/browser/content_settings/content_settings_mock_provider.h index 0aeca2c..3dfcd2a 100644 --- a/chrome/browser/content_settings/content_settings_mock_provider.h +++ b/chrome/browser/content_settings/content_settings_mock_provider.h @@ -6,43 +6,16 @@ #define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_MOCK_PROVIDER_H_ #pragma once +#include <vector> + #include "base/basictypes.h" -#include "chrome/browser/content_settings/content_settings_provider.h" +#include "chrome/browser/content_settings/content_settings_observable_provider.h" #include "chrome/common/content_settings_pattern.h" namespace content_settings { -// The class MockDefaultProvider is a mock for a default content settings -// provider. -class MockDefaultProvider : public DefaultProviderInterface { - public: - // Create a content settings provider that provides a given setting for a - // given type. - MockDefaultProvider(ContentSettingsType content_type, - ContentSetting setting, - bool is_managed, - bool can_override); - virtual ~MockDefaultProvider(); - - // DefaultProviderInterface implementation. - virtual ContentSetting ProvideDefaultSetting( - ContentSettingsType content_type) const; - virtual void UpdateDefaultSetting(ContentSettingsType content_type, - ContentSetting setting); - virtual bool DefaultSettingIsManaged(ContentSettingsType content_type) const; - virtual void ShutdownOnUIThread(); - - private: - ContentSettingsType content_type_; - ContentSetting setting_; - bool is_managed_; - bool can_override_; - - DISALLOW_COPY_AND_ASSIGN(MockDefaultProvider); -}; - // The class MockProvider is a mock for a non default content settings provider. -class MockProvider : public ProviderInterface { +class MockProvider : public ObservableProvider { public: MockProvider(); MockProvider(ContentSettingsPattern requesting_url_pattern, @@ -84,7 +57,7 @@ class MockProvider : public ProviderInterface { virtual void ClearAllContentSettingsRules( ContentSettingsType content_type) {} - virtual void ShutdownOnUIThread() {} + virtual void ShutdownOnUIThread(); // Accessors void set_requesting_url_pattern(ContentSettingsPattern pattern) { diff --git a/chrome/browser/content_settings/content_settings_observable_provider.cc b/chrome/browser/content_settings/content_settings_observable_provider.cc index e0bf774..0c1ae7e 100644 --- a/chrome/browser/content_settings/content_settings_observable_provider.cc +++ b/chrome/browser/content_settings/content_settings_observable_provider.cc @@ -9,41 +9,6 @@ namespace content_settings { // //////////////////////////////////////////////////////////////////////////// -// ObservableDefaultProvider -// -ObservableDefaultProvider::ObservableDefaultProvider() { -} - -ObservableDefaultProvider::~ObservableDefaultProvider() { -} - -void ObservableDefaultProvider::AddObserver(Observer* observer) { - observer_list_.AddObserver(observer); -} - -void ObservableDefaultProvider::RemoveObserver(Observer* observer) { - observer_list_.RemoveObserver(observer); -} - -void ObservableDefaultProvider::RemoveAllObservers() { - observer_list_.Clear(); -} - -void ObservableDefaultProvider::NotifyObservers( - ContentSettingsPattern primary_pattern, - ContentSettingsPattern secondary_pattern, - ContentSettingsType content_type, - std::string resource_identifier) { - FOR_EACH_OBSERVER(Observer, - observer_list_, - OnContentSettingChanged( - primary_pattern, - secondary_pattern, - content_type, - resource_identifier)); -} - -// //////////////////////////////////////////////////////////////////////////// // ObservableProvider // diff --git a/chrome/browser/content_settings/content_settings_observable_provider.h b/chrome/browser/content_settings/content_settings_observable_provider.h index 84e0d4e..86dd80c 100644 --- a/chrome/browser/content_settings/content_settings_observable_provider.h +++ b/chrome/browser/content_settings/content_settings_observable_provider.h @@ -14,25 +14,6 @@ namespace content_settings { -class ObservableDefaultProvider : public DefaultProviderInterface { - public: - ObservableDefaultProvider(); - virtual ~ObservableDefaultProvider(); - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - protected: - void NotifyObservers(ContentSettingsPattern primary_pattern, - ContentSettingsPattern secondary_pattern, - ContentSettingsType content_type, - std::string resource_identifier); - void RemoveAllObservers(); - - private: - ObserverList<Observer, true> observer_list_; -}; - class ObservableProvider : public ProviderInterface { public: ObservableProvider(); diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc index 0b41120..2d3d78e 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider.cc @@ -105,154 +105,6 @@ const PrefsForManagedContentSettingsMapEntry namespace content_settings { -PolicyDefaultProvider::PolicyDefaultProvider(PrefService* prefs) - : prefs_(prefs) { - // Read global defaults. - DCHECK_EQ(arraysize(kPrefToManageType), - static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); - ReadManagedDefaultSettings(); - - pref_change_registrar_.Init(prefs_); - // 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); - pref_change_registrar_.Add(prefs::kManagedDefaultGeolocationSetting, this); - pref_change_registrar_.Add(prefs::kManagedDefaultNotificationsSetting, this); -} - -PolicyDefaultProvider::~PolicyDefaultProvider() { - DCHECK(!prefs_); -} - -ContentSetting PolicyDefaultProvider::ProvideDefaultSetting( - ContentSettingsType content_type) const { - base::AutoLock auto_lock(lock_); - return managed_default_content_settings_.settings[content_type]; -} - -void PolicyDefaultProvider::UpdateDefaultSetting( - ContentSettingsType content_type, - ContentSetting setting) { -} - -bool PolicyDefaultProvider::DefaultSettingIsManaged( - ContentSettingsType content_type) const { - base::AutoLock lock(lock_); - if (managed_default_content_settings_.settings[content_type] != - CONTENT_SETTING_DEFAULT) { - return true; - } else { - return false; - } -} - -void PolicyDefaultProvider::Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (type == chrome::NOTIFICATION_PREF_CHANGED) { - DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); - std::string* name = Details<std::string>(details).ptr(); - if (*name == prefs::kManagedDefaultCookiesSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES); - } else if (*name == prefs::kManagedDefaultImagesSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES); - } else if (*name == prefs::kManagedDefaultJavaScriptSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT); - } else if (*name == prefs::kManagedDefaultPluginsSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS); - } else if (*name == prefs::kManagedDefaultPopupsSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS); - } else if (*name == prefs::kManagedDefaultGeolocationSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION); - } else if (*name == prefs::kManagedDefaultNotificationsSetting) { - UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); - } else { - NOTREACHED() << "Unexpected preference observed"; - return; - } - - NotifyObservers(ContentSettingsPattern(), - ContentSettingsPattern(), - CONTENT_SETTINGS_TYPE_DEFAULT, - std::string()); - } else { - NOTREACHED() << "Unexpected notification"; - } -} - -void PolicyDefaultProvider::ShutdownOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(prefs_); - RemoveAllObservers(); - pref_change_registrar_.RemoveAll(); - prefs_ = NULL; -} - -void PolicyDefaultProvider::ReadManagedDefaultSettings() { - for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) { - if (kPrefToManageType[type] == NULL) { - continue; - } - UpdateManagedDefaultSetting(ContentSettingsType(type)); - } -} - -void PolicyDefaultProvider::UpdateManagedDefaultSetting( - ContentSettingsType type) { - // 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])); - base::AutoLock auto_lock(lock_); - managed_default_content_settings_.settings[type] = IntToContentSetting( - prefs_->GetInteger(kPrefToManageType[type])); -} - -// static -void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) { - // 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, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultGeolocationSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); - prefs->RegisterIntegerPref(prefs::kManagedDefaultNotificationsSetting, - CONTENT_SETTING_DEFAULT, - PrefService::UNSYNCABLE_PREF); -} - -// //////////////////////////////////////////////////////////////////////////// -// PolicyProvider - // static void PolicyProvider::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls, @@ -283,12 +135,35 @@ void PolicyProvider::RegisterUserPrefs(PrefService* prefs) { PrefService::UNSYNCABLE_PREF); prefs->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls, PrefService::UNSYNCABLE_PREF); + // Preferences for default content setting policies. If a policy is not set of + // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT. + prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultGeolocationSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); + prefs->RegisterIntegerPref(prefs::kManagedDefaultNotificationsSetting, + CONTENT_SETTING_DEFAULT, + PrefService::UNSYNCABLE_PREF); } -PolicyProvider::PolicyProvider(PrefService* prefs, - DefaultProviderInterface* default_provider) - : prefs_(prefs), - default_provider_(default_provider) { +PolicyProvider::PolicyProvider(PrefService* prefs) : prefs_(prefs) { + DCHECK_EQ(arraysize(kPrefToManageType), + static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); + ReadManagedDefaultSettings(); ReadManagedContentSettings(false); pref_change_registrar_.Init(prefs_); @@ -306,6 +181,20 @@ PolicyProvider::PolicyProvider(PrefService* prefs, pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this); pref_change_registrar_.Add(prefs::kManagedNotificationsAllowedForUrls, this); pref_change_registrar_.Add(prefs::kManagedNotificationsBlockedForUrls, 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); + pref_change_registrar_.Add(prefs::kManagedDefaultGeolocationSetting, this); + pref_change_registrar_.Add(prefs::kManagedDefaultNotificationsSetting, this); } PolicyProvider::~PolicyProvider() { @@ -439,6 +328,45 @@ void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences( } } +void PolicyProvider::ReadManagedDefaultSettings() { + for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) { + if (kPrefToManageType[type] == NULL) { + continue; + } + UpdateManagedDefaultSetting(ContentSettingsType(type)); + } +} + +void PolicyProvider::UpdateManagedDefaultSetting( + ContentSettingsType content_type) { + // 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[content_type]) || + prefs_->IsManagedPreference(kPrefToManageType[content_type])); + base::AutoLock auto_lock(lock_); + + int setting = prefs_->GetInteger(kPrefToManageType[content_type]); + if (setting == CONTENT_SETTING_DEFAULT) { + value_map_.DeleteValue( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + content_type, + std::string()); + } else { + value_map_.SetValue( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + content_type, + std::string(), + Value::CreateIntegerValue(setting)); + } +} + + void PolicyProvider::ReadManagedContentSettings(bool overwrite) { base::AutoLock auto_lock(lock_); if (overwrite) @@ -466,14 +394,10 @@ ContentSetting PolicyProvider::GetContentSetting( // Resource identifier are not supported by policies as long as the feature is // behind a flag. So resource identifiers are simply ignored. base::AutoLock auto_lock(lock_); - ContentSetting setting = - ValueToContentSetting(value_map_.GetValue(primary_url, - secondary_url, - content_type, - resource_identifier)); - if (setting == CONTENT_SETTING_DEFAULT && default_provider_) - setting = default_provider_->ProvideDefaultSetting(content_type); - return setting; + return ValueToContentSetting(value_map_.GetValue(primary_url, + secondary_url, + content_type, + resource_identifier)); } base::Value* PolicyProvider::GetContentSettingValue( @@ -495,10 +419,7 @@ void PolicyProvider::GetAllContentSettingsRules( ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, std::vector<Rule>* content_setting_rules) const { - DCHECK_NE(RequiresResourceIdentifier(content_type), - resource_identifier.empty()); DCHECK(content_setting_rules); - content_setting_rules->clear(); base::AutoLock auto_lock(lock_); scoped_ptr<RuleIterator> rule( @@ -528,7 +449,21 @@ void PolicyProvider::Observe(int type, if (type == chrome::NOTIFICATION_PREF_CHANGED) { DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); std::string* name = Details<std::string>(details).ptr(); - if (*name == prefs::kManagedAutoSelectCertificateForUrls || + if (*name == prefs::kManagedDefaultCookiesSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES); + } else if (*name == prefs::kManagedDefaultImagesSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES); + } else if (*name == prefs::kManagedDefaultJavaScriptSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT); + } else if (*name == prefs::kManagedDefaultPluginsSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS); + } else if (*name == prefs::kManagedDefaultPopupsSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS); + } else if (*name == prefs::kManagedDefaultGeolocationSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION); + } else if (*name == prefs::kManagedDefaultNotificationsSetting) { + UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); + } else if (*name == prefs::kManagedAutoSelectCertificateForUrls || *name == prefs::kManagedCookiesAllowedForUrls || *name == prefs::kManagedCookiesBlockedForUrls || *name == prefs::kManagedCookiesSessionOnlyForUrls || @@ -543,14 +478,16 @@ void PolicyProvider::Observe(int type, *name == prefs::kManagedNotificationsAllowedForUrls || *name == prefs::kManagedNotificationsBlockedForUrls) { ReadManagedContentSettings(true); - NotifyObservers(ContentSettingsPattern(), - ContentSettingsPattern(), - CONTENT_SETTINGS_TYPE_DEFAULT, - std::string()); + ReadManagedDefaultSettings(); } } else { NOTREACHED() << "Unexpected notification"; + return; } + NotifyObservers(ContentSettingsPattern(), + ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_DEFAULT, + std::string()); } } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_policy_provider.h b/chrome/browser/content_settings/content_settings_policy_provider.h index caa59aa..f4f253f 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider.h +++ b/chrome/browser/content_settings/content_settings_policy_provider.h @@ -25,56 +25,11 @@ class PrefService; namespace content_settings { -class PolicyDefaultProvider : public ObservableDefaultProvider, - public NotificationObserver { - public: - explicit PolicyDefaultProvider(PrefService* prefs); - virtual ~PolicyDefaultProvider(); - - // DefaultContentSettingsProvider implementation. - virtual ContentSetting ProvideDefaultSetting( - ContentSettingsType content_type) const; - virtual void UpdateDefaultSetting(ContentSettingsType content_type, - ContentSetting setting); - virtual bool DefaultSettingIsManaged(ContentSettingsType content_type) const; - - virtual void ShutdownOnUIThread(); - - static void RegisterUserPrefs(PrefService* prefs); - - // NotificationObserver implementation. - virtual void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details); - - private: - // Reads the policy managed default settings. - void ReadManagedDefaultSettings(); - - // Reads the policy controlled default settings for a specific content type. - void UpdateManagedDefaultSetting(ContentSettingsType content_type); - - // Copies of the pref data, so that we can read it on the IO thread. - ContentSettings managed_default_content_settings_; - - PrefService* prefs_; - - // Used around accesses to the managed_default_content_settings_ object to - // guarantee thread safety. - mutable base::Lock lock_; - - PrefChangeRegistrar pref_change_registrar_; - NotificationRegistrar notification_registrar_; - - DISALLOW_COPY_AND_ASSIGN(PolicyDefaultProvider); -}; - // PolicyProvider that provider managed content-settings. class PolicyProvider : public ObservableProvider, public NotificationObserver { public: - PolicyProvider(PrefService* prefs, - DefaultProviderInterface* default_provider); + explicit PolicyProvider(PrefService* prefs); virtual ~PolicyProvider(); static void RegisterUserPrefs(PrefService* prefs); @@ -113,6 +68,12 @@ class PolicyProvider : public ObservableProvider, const NotificationSource& source, const NotificationDetails& details); private: + // Reads the policy managed default settings. + void ReadManagedDefaultSettings(); + + // Reads the policy controlled default settings for a specific content type. + void UpdateManagedDefaultSetting(ContentSettingsType content_type); + void ReadManagedContentSettings(bool overwrite); void GetContentSettingsFromPreferences(OriginIdentifierValueMap* rules); @@ -126,9 +87,6 @@ class PolicyProvider : public ObservableProvider, PrefService* prefs_; - // Weak, owned by HostContentSettingsMap. - DefaultProviderInterface* default_provider_; - PrefChangeRegistrar pref_change_registrar_; // Used around accesses to the content_settings_ object to guarantee diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc index 9129523..12ea264 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc @@ -10,6 +10,8 @@ #include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/content_settings/content_settings_mock_observer.h" +#include "chrome/browser/content_settings/content_settings_rule.h" +#include "chrome/browser/content_settings/content_settings_utils.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -24,76 +26,90 @@ using ::testing::_; namespace content_settings { -class PolicyDefaultProviderTest : public testing::Test { +typedef std::vector<Rule> Rules; + +class PolicyProviderTest : public testing::Test { public: - PolicyDefaultProviderTest() + PolicyProviderTest() : ui_thread_(BrowserThread::UI, &message_loop_) { } protected: + // TODO(markusheintz): Check if it's possible to derive the provider class + // from NonThreadSafe and to use native thread identifiers instead of + // BrowserThread IDs. Then we could get rid of the message_loop and ui_thread + // fields. MessageLoop message_loop_; BrowserThread ui_thread_; }; -TEST_F(PolicyDefaultProviderTest, DefaultValues) { +TEST_F(PolicyProviderTest, DefaultGeolocationContentSetting) { TestingProfile profile; TestingPrefService* prefs = profile.GetTestingPrefService(); - PolicyDefaultProvider provider(prefs); + PolicyProvider provider(prefs); - // By default, policies should be off. - ASSERT_FALSE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES)); + Rules rules; - // Set managed-default-content-setting through the coresponding preferences. - prefs->SetManagedPref(prefs::kManagedDefaultCookiesSetting, - Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); - ASSERT_TRUE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES)); - ASSERT_EQ(CONTENT_SETTING_BLOCK, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Remove managed-default-content-settings-preferences. - prefs->RemoveManagedPref(prefs::kManagedDefaultCookiesSetting); - ASSERT_FALSE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES)); - - provider.ShutdownOnUIThread(); -} - -TEST_F(PolicyDefaultProviderTest, DefaultGeolocationContentSetting) { - TestingProfile profile; - TestingPrefService* prefs = profile.GetTestingPrefService(); - PolicyDefaultProvider provider(prefs); - - // By default, policies should be off. - EXPECT_FALSE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - EXPECT_EQ(CONTENT_SETTING_DEFAULT, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); + provider.GetAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + &rules); + EXPECT_EQ(0U, rules.size()); prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, CONTENT_SETTING_ALLOW); - EXPECT_FALSE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - EXPECT_EQ(CONTENT_SETTING_DEFAULT, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); + provider.GetAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + &rules); + EXPECT_EQ(0U, rules.size()); - // prefs->SetManagedPref(prefs::kGeolocationDefaultContentSetting, Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); - EXPECT_FALSE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - EXPECT_EQ(CONTENT_SETTING_DEFAULT, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); + provider.GetAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + &rules); + EXPECT_EQ(0U, rules.size()); // Change the managed value of the default geolocation setting prefs->SetManagedPref(prefs::kManagedDefaultGeolocationSetting, Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); - EXPECT_TRUE( - provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); + provider.GetAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_GEOLOCATION, + std::string(), + &rules); + EXPECT_EQ(1U, rules.size()); + EXPECT_EQ(ContentSettingsPattern::Wildcard(), rules[0].primary_pattern); + EXPECT_EQ(ContentSettingsPattern::Wildcard(), rules[0].secondary_pattern); + EXPECT_EQ(CONTENT_SETTING_BLOCK, rules[0].content_setting); + + provider.ShutdownOnUIThread(); +} + +TEST_F(PolicyProviderTest, ManagedDefaultContentSettings) { + // This feature is currently behind a flag. + CommandLine* cmd = CommandLine::ForCurrentProcess(); + AutoReset<CommandLine> auto_reset(cmd, *cmd); + cmd->AppendSwitch(switches::kEnableResourceContentSettings); + + TestingProfile profile; + TestingPrefService* prefs = profile.GetTestingPrefService(); + PolicyProvider provider(prefs); + + prefs->SetManagedPref(prefs::kManagedDefaultPluginsSetting, + Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); + + Rules rules; + provider.GetAllContentSettingsRules( + CONTENT_SETTINGS_TYPE_PLUGINS, + std::string(), + &rules); + EXPECT_EQ(1U, rules.size()); + EXPECT_EQ(ContentSettingsPattern::Wildcard(), rules[0].primary_pattern); + EXPECT_EQ(ContentSettingsPattern::Wildcard(), rules[0].secondary_pattern); + EXPECT_EQ(CONTENT_SETTING_BLOCK, rules[0].content_setting); provider.ShutdownOnUIThread(); } @@ -101,10 +117,10 @@ TEST_F(PolicyDefaultProviderTest, DefaultGeolocationContentSetting) { // When a default-content-setting is set to a managed setting a // CONTENT_SETTINGS_CHANGED notification should be fired. The same should happen // if the managed setting is removed. -TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { +TEST_F(PolicyProviderTest, ObserveManagedSettingsChange) { TestingProfile profile; TestingPrefService* prefs = profile.GetTestingPrefService(); - PolicyDefaultProvider provider(prefs); + PolicyProvider provider(prefs); MockObserver mock_observer; EXPECT_CALL(mock_observer, @@ -118,7 +134,6 @@ TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting, Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); ::testing::Mock::VerifyAndClearExpectations(&mock_observer); - EXPECT_CALL(mock_observer, OnContentSettingChanged(_, _, @@ -129,21 +144,6 @@ TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { provider.ShutdownOnUIThread(); } -class PolicyProviderTest : public testing::Test { - public: - PolicyProviderTest() - : ui_thread_(BrowserThread::UI, &message_loop_) { - } - - protected: - // TODO(markusheintz): Check if it's possible to derive the provider class - // from NonThreadSafe and to use native thread identifiers instead of - // BrowserThread IDs. Then we could get rid of the message_loop and ui_thread - // fields. - MessageLoop message_loop_; - BrowserThread ui_thread_; -}; - TEST_F(PolicyProviderTest, GettingManagedContentSettings) { TestingProfile profile; TestingPrefService* prefs = profile.GetTestingPrefService(); @@ -153,7 +153,7 @@ TEST_F(PolicyProviderTest, GettingManagedContentSettings) { prefs->SetManagedPref(prefs::kManagedImagesBlockedForUrls, value); - PolicyProvider provider(prefs, NULL); + PolicyProvider provider(prefs); ContentSettingsPattern yt_url_pattern = ContentSettingsPattern::FromString("www.youtube.com"); @@ -205,7 +205,7 @@ TEST_F(PolicyProviderTest, ResourceIdentifier) { prefs->SetManagedPref(prefs::kManagedPluginsAllowedForUrls, value); - PolicyProvider provider(prefs, NULL); + PolicyProvider provider(prefs); GURL youtube_url("http://www.youtube.com"); GURL google_url("http://mail.google.com"); @@ -241,7 +241,7 @@ TEST_F(PolicyProviderTest, AutoSelectCertificateList) { TestingProfile profile; TestingPrefService* prefs = profile.GetTestingPrefService(); - PolicyProvider provider(prefs, NULL); + PolicyProvider provider(prefs); GURL google_url("https://mail.google.com"); // Tests the default setting for auto selecting certificates EXPECT_EQ(NULL, diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc index 0112c2e..0fe3444 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider.cc @@ -35,78 +35,6 @@ namespace { typedef std::pair<std::string, std::string> StringPair; typedef std::map<std::string, std::string> StringMap; -// The preference keys where resource identifiers are stored for -// ContentSettingsType values that support resource identifiers. -const char* kResourceTypeNames[] = { - NULL, - NULL, - NULL, - "per_plugin", - NULL, - NULL, - NULL, - NULL, - NULL, -}; -COMPILE_ASSERT(arraysize(kResourceTypeNames) == CONTENT_SETTINGS_NUM_TYPES, - resource_type_names_incorrect_size); - -// The default setting for each content type. -const ContentSetting kDefaultSettings[] = { - 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, // CONTENT_SETTINGS_TYPE_GEOLOCATION - CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_NOTIFICATIONS - CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_INTENTS - CONTENT_SETTING_ASK, // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE -}; -COMPILE_ASSERT(arraysize(kDefaultSettings) == CONTENT_SETTINGS_NUM_TYPES, - default_settings_incorrect_size); - -// The names of the ContentSettingsType values, for use with dictionary prefs. -const char* kTypeNames[] = { - "cookies", - "images", - "javascript", - "plugins", - "popups", - "geolocation", - "notifications", - "intents", - "auto-select-certificate" -}; -COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES, - type_names_incorrect_size); - -void SetDefaultContentSettings(DictionaryValue* default_settings) { - default_settings->Clear(); - - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (kTypeNames[i] != NULL) { - default_settings->SetInteger(kTypeNames[i], - kDefaultSettings[i]); - } - } -} - -ContentSettingsType StringToContentSettingsType( - const std::string& content_type_str) { - for (size_t type = 0; type < arraysize(kTypeNames); ++type) { - if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type_str)) - return ContentSettingsType(type); - } - for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { - if ((kResourceTypeNames[type] != NULL) && - (kResourceTypeNames[type] == content_type_str)) { - return ContentSettingsType(type); - } - } - return CONTENT_SETTINGS_TYPE_DEFAULT; -} - ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, ContentSetting setting) { if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && @@ -120,7 +48,7 @@ ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, // dictionary. void ClearSettings(ContentSettingsType type, DictionaryValue* pattern_pairs) { - std::string type_name(kTypeNames[type]); + std::string type_name(content_settings::GetTypeName(type)); for (DictionaryValue::key_iterator i = pattern_pairs->begin_keys(); i != pattern_pairs->end_keys(); ++i) { @@ -138,240 +66,6 @@ void ClearSettings(ContentSettingsType type, namespace content_settings { -PrefDefaultProvider::PrefDefaultProvider(PrefService* prefs, - bool incognito) - : prefs_(prefs), - is_incognito_(incognito), - updating_preferences_(false) { - DCHECK(prefs_); - MigrateObsoleteNotificationPref(); - MigrateObsoleteGeolocationPref(); - - // Read global defaults. - DCHECK_EQ(arraysize(kTypeNames), - static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES)); - ReadDefaultSettings(true); - if (default_content_settings_.settings[CONTENT_SETTINGS_TYPE_COOKIES] == - CONTENT_SETTING_BLOCK) { - UserMetrics::RecordAction( - UserMetricsAction("CookieBlockingEnabledPerDefault")); - } else { - UserMetrics::RecordAction( - UserMetricsAction("CookieBlockingDisabledPerDefault")); - } - - pref_change_registrar_.Init(prefs_); - pref_change_registrar_.Add(prefs::kDefaultContentSettings, this); - pref_change_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); -} - -PrefDefaultProvider::~PrefDefaultProvider() { - DCHECK(!prefs_); -} - -ContentSetting PrefDefaultProvider::ProvideDefaultSetting( - ContentSettingsType content_type) const { - base::AutoLock lock(lock_); - return default_content_settings_.settings[content_type]; -} - -void PrefDefaultProvider::UpdateDefaultSetting( - ContentSettingsType content_type, - ContentSetting setting) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(prefs_); - DCHECK(kTypeNames[content_type] != NULL); - - // The default settings may not be directly modified for OTR sessions. - // Instead, they are synced to the main profile's setting. - if (is_incognito_) - return; - - std::string dictionary_path(kTypeNames[content_type]); - { - AutoReset<bool> auto_reset(&updating_preferences_, true); - DictionaryPrefUpdate update(prefs_, prefs::kDefaultContentSettings); - DictionaryValue* default_settings_dictionary = update.Get(); - - // PrefDefaultProvider should not send any notifications when holding - // |lock_|. |DictionaryPrefUpdate| destructor and - // |PrefService::SetInteger()| send out notifications. As a response, the - // upper layers may call |ProvideDefaultContentSetting| which acquires - // |lock_| again. - { - base::AutoLock lock(lock_); - 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)); - } - } - - // Keep the obsolete pref in sync as long as backwards compatibility is - // required. This is required to keep sync working correctly. - if (content_type == CONTENT_SETTINGS_TYPE_GEOLOCATION) { - prefs_->SetInteger(prefs::kGeolocationDefaultContentSetting, - setting == CONTENT_SETTING_DEFAULT ? - kDefaultSettings[content_type] : setting); - } - } - - NotifyObservers(ContentSettingsPattern(), - ContentSettingsPattern(), - content_type, - std::string()); -} - -bool PrefDefaultProvider::DefaultSettingIsManaged( - ContentSettingsType content_type) const { - return false; -} - -void PrefDefaultProvider::Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (type == chrome::NOTIFICATION_PREF_CHANGED) { - DCHECK_EQ(prefs_, Source<PrefService>(source).ptr()); - if (updating_preferences_) - return; - - std::string* name = Details<std::string>(details).ptr(); - if (*name == prefs::kDefaultContentSettings) { - ReadDefaultSettings(true); - } else if (*name == prefs::kGeolocationDefaultContentSetting) { - MigrateObsoleteGeolocationPref(); - // Return and don't send a notifications. Migrating the obsolete - // geolocation pref will change the prefs::kDefaultContentSettings and - // cause the notification to be fired. - return; - } else { - NOTREACHED() << "Unexpected preference observed"; - return; - } - - NotifyObservers(ContentSettingsPattern(), - ContentSettingsPattern(), - CONTENT_SETTINGS_TYPE_DEFAULT, - std::string()); - } else { - NOTREACHED() << "Unexpected notification"; - } -} - -void PrefDefaultProvider::ShutdownOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(prefs_); - RemoveAllObservers(); - pref_change_registrar_.RemoveAll(); - prefs_ = NULL; -} - -void PrefDefaultProvider::ReadDefaultSettings(bool overwrite) { - const DictionaryValue* default_settings_dictionary = - prefs_->GetDictionary(prefs::kDefaultContentSettings); - - base::AutoLock lock(lock_); - - 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(); -} - -void PrefDefaultProvider::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]; - } -} - -void PrefDefaultProvider::GetSettingsFromDictionary( - const DictionaryValue* dictionary, - ContentSettings* settings) { - for (DictionaryValue::key_iterator i(dictionary->begin_keys()); - i != dictionary->end_keys(); ++i) { - const std::string& content_type(*i); - for (size_t type = 0; type < arraysize(kTypeNames); ++type) { - if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) { - int setting = CONTENT_SETTING_DEFAULT; - bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, - &setting); - DCHECK(found); - settings->settings[type] = IntToContentSetting(setting); - break; - } - } - } - // Migrate obsolete cookie prompt mode. - if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] == - CONTENT_SETTING_ASK) - settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; - - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = - ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); -} - -void PrefDefaultProvider::MigrateObsoleteNotificationPref() { - if (prefs_->HasPrefPath(prefs::kDesktopNotificationDefaultContentSetting)) { - ContentSetting setting = IntToContentSetting( - prefs_->GetInteger(prefs::kDesktopNotificationDefaultContentSetting)); - UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting); - prefs_->ClearPref(prefs::kDesktopNotificationDefaultContentSetting); - } -} - -void PrefDefaultProvider::MigrateObsoleteGeolocationPref() { - if (prefs_->HasPrefPath(prefs::kGeolocationDefaultContentSetting)) { - ContentSetting setting = IntToContentSetting( - prefs_->GetInteger(prefs::kGeolocationDefaultContentSetting)); - UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION, setting); - // Do not clear the old preference yet as long as we need to maintain - // backward compatibility. - } -} - -// static -void PrefDefaultProvider::RegisterUserPrefs(PrefService* prefs) { - // The registration of the preference prefs::kDefaultContentSettings should - // also include the default values for default content settings. This allows - // functional tests to get default content settings by reading the preference - // prefs::kDefaultContentSettings via pyauto. - // TODO(markusheintz): Write pyauto hooks for the content settings map as - // content settings should be read from the host content settings map. - DictionaryValue* default_content_settings = new DictionaryValue(); - SetDefaultContentSettings(default_content_settings); - prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings, - default_content_settings, - PrefService::SYNCABLE_PREF); - - // Obsolete prefs, for migrations: - prefs->RegisterIntegerPref( - prefs::kDesktopNotificationDefaultContentSetting, - kDefaultSettings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS], - PrefService::SYNCABLE_PREF); - prefs->RegisterIntegerPref( - prefs::kGeolocationDefaultContentSetting, - kDefaultSettings[CONTENT_SETTINGS_TYPE_GEOLOCATION], - PrefService::UNSYNCABLE_PREF); -} - // //////////////////////////////////////////////////////////////////////////// // PrefProvider: // @@ -485,7 +179,6 @@ void PrefProvider::GetAllContentSettingsRules( const ResourceIdentifier& resource_identifier, std::vector<Rule>* content_setting_rules) const { DCHECK(content_setting_rules); - content_setting_rules->clear(); const OriginIdentifierValueMap* map_to_return = is_incognito_ ? &incognito_value_map_ : &value_map_; @@ -505,7 +198,6 @@ void PrefProvider::SetContentSetting( ContentSetting setting) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(prefs_); - DCHECK(kTypeNames[content_type] != NULL); // Update in memory value map. OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; @@ -547,7 +239,6 @@ void PrefProvider::SetContentSetting( void PrefProvider::ClearAllContentSettingsRules( ContentSettingsType content_type) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. DCHECK(prefs_); OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; @@ -721,8 +412,9 @@ void PrefProvider::ReadContentSettingsFromPref(bool overwrite) { for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { ContentSettingsType content_type = static_cast<ContentSettingsType>(i); - if (RequiresResourceIdentifier(content_type)) { - const std::string content_type_str = kResourceTypeNames[i]; + if (SupportsResourceIdentifier(content_type)) { + const std::string content_type_str = + GetResourceTypeName(ContentSettingsType(i)); DictionaryValue* resource_dictionary = NULL; if (settings_dictionary->GetDictionary( content_type_str, &resource_dictionary)) { @@ -744,8 +436,9 @@ void PrefProvider::ReadContentSettingsFromPref(bool overwrite) { Value::CreateIntegerValue(setting)); } } - } else if (kTypeNames[i]) { - const std::string content_type_str(kTypeNames[i]); + } else { + const std::string content_type_str = + GetTypeName(ContentSettingsType(i)); int setting = CONTENT_SETTING_DEFAULT; if (settings_dictionary->GetIntegerWithoutPathExpansion( content_type_str, &setting)) { @@ -789,9 +482,9 @@ void PrefProvider::UpdateObsoletePatternsPref( } if (settings_dictionary) { - if (RequiresResourceIdentifier(content_type)) { + if (SupportsResourceIdentifier(content_type)) { // Get resource dictionary. - std::string res_dictionary_path(kResourceTypeNames[content_type]); + std::string res_dictionary_path(GetResourceTypeName(content_type)); DictionaryValue* resource_dictionary = NULL; found = settings_dictionary->GetDictionary( res_dictionary_path, &resource_dictionary); @@ -815,7 +508,7 @@ void PrefProvider::UpdateObsoletePatternsPref( } } else { // Update settings dictionary. - std::string setting_path(kTypeNames[content_type]); + std::string setting_path = GetTypeName(content_type); if (setting == CONTENT_SETTING_DEFAULT) { settings_dictionary->RemoveWithoutPathExpansion(setting_path, NULL); @@ -853,9 +546,9 @@ void PrefProvider::UpdatePatternPairsSettings( } if (settings_dictionary) { - if (RequiresResourceIdentifier(content_type)) { + if (SupportsResourceIdentifier(content_type)) { // Get resource dictionary. - std::string res_dictionary_path(kResourceTypeNames[content_type]); + std::string res_dictionary_path = GetResourceTypeName(content_type); DictionaryValue* resource_dictionary = NULL; found = settings_dictionary->GetDictionary( res_dictionary_path, &resource_dictionary); @@ -879,7 +572,7 @@ void PrefProvider::UpdatePatternPairsSettings( } } else { // Update settings dictionary. - std::string setting_path(kTypeNames[content_type]); + std::string setting_path = GetTypeName(content_type); if (setting == CONTENT_SETTING_DEFAULT) { settings_dictionary->RemoveWithoutPathExpansion(setting_path, NULL); @@ -1053,7 +746,7 @@ void PrefProvider::MigrateObsoletePerhostPref() { continue; } - if (!RequiresResourceIdentifier(content_type)) { + if (!SupportsResourceIdentifier(content_type)) { int setting_int_value = CONTENT_SETTING_DEFAULT; bool found = host_settings_dictionary->GetIntegerWithoutPathExpansion( @@ -1208,8 +901,7 @@ void PrefProvider::SyncObsoletePatternPref() { for (size_t i = CONTENT_SETTINGS_TYPE_COOKIES; i <= CONTENT_SETTINGS_TYPE_POPUPS; ++i) { - DCHECK(kTypeNames[i]); - std::string type_name(kTypeNames[i]); + std::string type_name = GetTypeName(ContentSettingsType(i)); if (settings_dictionary->HasKey(type_name)) { Value* value = NULL; bool found = settings_dictionary->GetWithoutPathExpansion( @@ -1362,7 +1054,7 @@ void PrefProvider::SyncObsoletePrefs() { int setting_value = 0; if (settings_dictionary->GetInteger( - kTypeNames[CONTENT_SETTINGS_TYPE_NOTIFICATIONS], &setting_value)) { + GetTypeName(CONTENT_SETTINGS_TYPE_NOTIFICATIONS), &setting_value)) { UpdateObsoleteNotificationsSettings(pattern_pair.first, pattern_pair.second, ContentSetting(setting_value), @@ -1372,7 +1064,7 @@ void PrefProvider::SyncObsoletePrefs() { setting_value = 0; if (settings_dictionary->GetInteger( - kTypeNames[CONTENT_SETTINGS_TYPE_GEOLOCATION], &setting_value)) { + GetTypeName(CONTENT_SETTINGS_TYPE_GEOLOCATION), &setting_value)) { UpdateObsoleteGeolocationPref(pattern_pair.first, pattern_pair.second, ContentSetting(setting_value)); diff --git a/chrome/browser/content_settings/content_settings_pref_provider.h b/chrome/browser/content_settings/content_settings_pref_provider.h index 520a788..13a2db2 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider.h +++ b/chrome/browser/content_settings/content_settings_pref_provider.h @@ -11,6 +11,7 @@ #include <map> #include <string> #include <utility> +#include <vector> #include "base/basictypes.h" #include "base/synchronization/lock.h" @@ -31,68 +32,6 @@ class DictionaryValue; namespace content_settings { -// Content settings provider that provides default content settings based on -// user prefs. -class PrefDefaultProvider : public ObservableDefaultProvider, - public NotificationObserver { - public: - PrefDefaultProvider(PrefService* prefs, - bool incognito); - virtual ~PrefDefaultProvider(); - - // DefaultContentSettingsProvider implementation. - virtual ContentSetting ProvideDefaultSetting( - ContentSettingsType content_type) const; - virtual void UpdateDefaultSetting(ContentSettingsType content_type, - ContentSetting setting); - virtual bool DefaultSettingIsManaged(ContentSettingsType content_type) const; - - virtual void ShutdownOnUIThread(); - - static void RegisterUserPrefs(PrefService* prefs); - - // NotificationObserver implementation. - virtual void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details); - - private: - // Sets the fields of |settings| based on the values in |dictionary|. - void GetSettingsFromDictionary(const base::DictionaryValue* dictionary, - ContentSettings* settings); - - // Forces the default settings to be explicitly set instead of themselves - // being CONTENT_SETTING_DEFAULT. - void ForceDefaultsToBeExplicit(); - - // Reads the default settings from the preferences service. If |overwrite| is - // true and the preference is missing, the local copy will be cleared as well. - void ReadDefaultSettings(bool overwrite); - - void MigrateObsoleteNotificationPref(); - void MigrateObsoleteGeolocationPref(); - - // Copies of the pref data, so that we can read it on the IO thread. - ContentSettings default_content_settings_; - - PrefService* prefs_; - - // Whether this settings map is for an Incognito session. - bool is_incognito_; - - // Used around accesses to the default_content_settings_ object to guarantee - // thread safety. - mutable base::Lock lock_; - - PrefChangeRegistrar pref_change_registrar_; - - // Whether we are currently updating preferences, this is used to ignore - // notifications from the preferences service that we triggered ourself. - bool updating_preferences_; - - DISALLOW_COPY_AND_ASSIGN(PrefDefaultProvider); -}; - // Content settings provider that provides content settings from the user // preference. class PrefProvider : public ObservableProvider, diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index cb6e81a..d927bf3 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc @@ -47,166 +47,6 @@ void ExpectObsoleteGeolocationSetting( namespace content_settings { -class PrefDefaultProviderTest : public testing::Test { - public: - PrefDefaultProviderTest() - : ui_thread_(BrowserThread::UI, &message_loop_), - provider_(profile_.GetPrefs(), false) { - } - ~PrefDefaultProviderTest() { - provider_.ShutdownOnUIThread(); - } - - protected: - MessageLoop message_loop_; - BrowserThread ui_thread_; - TestingProfile profile_; - PrefDefaultProvider provider_; -}; - -TEST_F(PrefDefaultProviderTest, DefaultValues) { - ASSERT_FALSE( - provider_.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Check setting defaults. - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - provider_.UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - EXPECT_EQ(CONTENT_SETTING_ASK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - provider_.UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); -} - -TEST_F(PrefDefaultProviderTest, Observer) { - MockObserver mock_observer; - EXPECT_CALL(mock_observer, - OnContentSettingChanged(_, - _, - CONTENT_SETTINGS_TYPE_IMAGES, - "")); - provider_.AddObserver(&mock_observer); - - provider_.UpdateDefaultSetting( - CONTENT_SETTINGS_TYPE_IMAGES, CONTENT_SETTING_BLOCK); - - EXPECT_CALL(mock_observer, - OnContentSettingChanged( - _, _, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); - provider_.UpdateDefaultSetting( - CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_BLOCK); -} - -TEST_F(PrefDefaultProviderTest, ObserveDefaultPref) { - PrefService* prefs = profile_.GetPrefs(); - - // Make a copy of the default pref value so we can reset it later. - scoped_ptr<Value> default_value(prefs->FindPreference( - prefs::kDefaultContentSettings)->GetValue()->DeepCopy()); - - provider_.UpdateDefaultSetting( - CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Make a copy of the pref's new value so we can reset it later. - scoped_ptr<Value> new_value(prefs->FindPreference( - prefs::kDefaultContentSettings)->GetValue()->DeepCopy()); - - // Clearing the backing pref should also clear the internal cache. - prefs->Set(prefs::kDefaultContentSettings, *default_value); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Reseting the pref to its previous value should update the cache. - prefs->Set(prefs::kDefaultContentSettings, *new_value); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); -} - -TEST_F(PrefDefaultProviderTest, OffTheRecord) { - PrefDefaultProvider otr_provider(profile_.GetPrefs(), - true); - - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - otr_provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Changing content settings on the main provider should also affect the - // incognito map. - provider_.UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - otr_provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - // Changing content settings on the incognito provider should be ignored. - otr_provider.UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_ALLOW); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider_.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - otr_provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - - otr_provider.ShutdownOnUIThread(); -} - -TEST_F(PrefDefaultProviderTest, MigrateDefaultGeolocationContentSetting) { - TestingProfile profile; - TestingPrefService* prefs = profile.GetTestingPrefService(); - - // Set obsolete preference and test if it is migrated correctly. - prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, - CONTENT_SETTING_ALLOW); - PrefDefaultProvider provider(prefs, false); - - MockObserver mock_observer; - EXPECT_CALL(mock_observer, - OnContentSettingChanged( - _, _, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); - provider.AddObserver(&mock_observer); - - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - - // Change obsolete preference and test if it migrated correctly. - prefs->SetInteger(prefs::kGeolocationDefaultContentSetting, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION)); - - provider.ShutdownOnUIThread(); -} - -TEST_F(PrefDefaultProviderTest, AutoSubmitCertificateContentSetting) { - TestingProfile profile; - TestingPrefService* prefs = profile.GetTestingPrefService(); - - PrefDefaultProvider provider(prefs, false); - - EXPECT_EQ(CONTENT_SETTING_ASK, - provider.ProvideDefaultSetting( - CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE)); - provider.UpdateDefaultSetting( - CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, CONTENT_SETTING_ALLOW); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider.ProvideDefaultSetting( - CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE)); - provider.ShutdownOnUIThread(); -} - -// //////////////////////////////////////////////////////////////////////////// -// PrefProviderTest -// - bool SettingsEqual(const ContentSettings& settings1, const ContentSettings& settings2) { for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { diff --git a/chrome/browser/content_settings/content_settings_provider.h b/chrome/browser/content_settings/content_settings_provider.h index a0ebaa6..e891a19 100644 --- a/chrome/browser/content_settings/content_settings_provider.h +++ b/chrome/browser/content_settings/content_settings_provider.h @@ -11,6 +11,7 @@ #define NO_RESOURCE_IDENTIFIER "" #include <string> +#include <vector> #include "base/values.h" #include "chrome/common/content_settings.h" @@ -24,30 +25,6 @@ struct Rule; typedef std::string ResourceIdentifier; -class DefaultProviderInterface { - public: - virtual ~DefaultProviderInterface() {} - - // Returns the default content setting this provider has for the given - // |content_type|, or CONTENT_SETTING_DEFAULT if nothing be provided for this - // type. - virtual ContentSetting ProvideDefaultSetting( - ContentSettingsType content_type) const = 0; - - // Notifies the provider that the host content settings map would like to - // update the default setting for the given |content_type|. The provider may - // ignore this. - virtual void UpdateDefaultSetting(ContentSettingsType content_type, - ContentSetting setting) = 0; - - // True if the default setting for the |content_type| is policy managed, i.e., - // there shouldn't be any UI shown to modify this setting. - virtual bool DefaultSettingIsManaged( - ContentSettingsType content_type) const = 0; - - virtual void ShutdownOnUIThread() = 0; -}; - class ProviderInterface { public: virtual ~ProviderInterface() {} diff --git a/chrome/browser/content_settings/content_settings_provider_unittest.cc b/chrome/browser/content_settings/content_settings_provider_unittest.cc index 0b67be4..cbd1e19 100644 --- a/chrome/browser/content_settings/content_settings_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_provider_unittest.cc @@ -11,21 +11,6 @@ namespace content_settings { TEST(ContentSettingsProviderTest, Mock) { - MockDefaultProvider provider(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_ALLOW, - false, - true); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - EXPECT_EQ(CONTENT_SETTING_DEFAULT, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS)); - EXPECT_FALSE(provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_COOKIES)); - EXPECT_FALSE(provider.DefaultSettingIsManaged(CONTENT_SETTINGS_TYPE_POPUPS)); - provider.UpdateDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES, - CONTENT_SETTING_BLOCK); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - ContentSettingsPattern pattern = ContentSettingsPattern::FromString("[*.]youtube.com"); GURL url("http://www.youtube.com"); diff --git a/chrome/browser/content_settings/content_settings_utils.cc b/chrome/browser/content_settings/content_settings_utils.cc index b7475cc..ab189e1 100644 --- a/chrome/browser/content_settings/content_settings_utils.cc +++ b/chrome/browser/content_settings/content_settings_utils.cc @@ -5,7 +5,6 @@ #include "chrome/browser/content_settings/content_settings_utils.h" #include <string> -#include <utility> #include <vector> #include "base/command_line.h" @@ -17,16 +16,51 @@ namespace { // True if a given content settings type requires additional resource // identifiers. -const bool kRequiresResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = { +const bool kSupportsResourceIdentifier[CONTENT_SETTINGS_NUM_TYPES] = { false, // CONTENT_SETTINGS_TYPE_COOKIES false, // CONTENT_SETTINGS_TYPE_IMAGES false, // CONTENT_SETTINGS_TYPE_JAVASCRIPT true, // CONTENT_SETTINGS_TYPE_PLUGINS false, // CONTENT_SETTINGS_TYPE_POPUPS - false, // Not used for Geolocation - false, // Not used for Notifications - false, // Not used for Intents. + false, // CONTENT_SETTINGS_TYPE_GEOLOCATION + false, // CONTENT_SETTINGS_TYPE_NOTIFICATIONS + false, // CONTENT_SETTINGS_TYPE_INTENTS + false, // CONTENT_SETTINGS_TYPE_AUTO_SUBMIT_CERTIFICATE }; +COMPILE_ASSERT(arraysize(kSupportsResourceIdentifier) == + CONTENT_SETTINGS_NUM_TYPES, + resource_type_names_incorrect_size); + +// The preference keys where resource identifiers are stored for +// ContentSettingsType values that support resource identifiers. +const char* kResourceTypeNames[] = { + NULL, + NULL, + NULL, + "per_plugin", + NULL, + NULL, + NULL, + NULL, + NULL, +}; +COMPILE_ASSERT(arraysize(kResourceTypeNames) == CONTENT_SETTINGS_NUM_TYPES, + resource_type_names_incorrect_size); + +// The names of the ContentSettingsType values, for use with dictionary prefs. +const char* kTypeNames[] = { + "cookies", + "images", + "javascript", + "plugins", + "popups", + "geolocation", + "notifications", + "intents", + "auto-select-certificate" +}; +COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES, + type_names_incorrect_size); const char* kPatternSeparator = ","; @@ -34,10 +68,33 @@ const char* kPatternSeparator = ","; namespace content_settings { -bool RequiresResourceIdentifier(ContentSettingsType content_type) { +std::string GetTypeName(ContentSettingsType type) { + return std::string(kTypeNames[type]); +} + +std::string GetResourceTypeName(ContentSettingsType type) { + return std::string(kResourceTypeNames[type]); +} + +ContentSettingsType StringToContentSettingsType( + const std::string& content_type_str) { + for (size_t type = 0; type < arraysize(kTypeNames); ++type) { + if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type_str)) + return ContentSettingsType(type); + } + for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { + if ((kResourceTypeNames[type] != NULL) && + (kResourceTypeNames[type] == content_type_str)) { + return ContentSettingsType(type); + } + } + return CONTENT_SETTINGS_TYPE_DEFAULT; +} + +bool SupportsResourceIdentifier(ContentSettingsType content_type) { if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableResourceContentSettings)) { - return kRequiresResourceIdentifier[content_type]; + return kSupportsResourceIdentifier[content_type]; } else { return false; } diff --git a/chrome/browser/content_settings/content_settings_utils.h b/chrome/browser/content_settings/content_settings_utils.h index 7da12f3..f5865d4 100644 --- a/chrome/browser/content_settings/content_settings_utils.h +++ b/chrome/browser/content_settings/content_settings_utils.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_UTILS_H_ #include <string> +#include <utility> #include "base/logging.h" #include "chrome/common/content_settings.h" @@ -20,8 +21,15 @@ namespace content_settings { typedef std::pair<ContentSettingsPattern, ContentSettingsPattern> PatternPair; -// Returns true if the |content_type| requires a resource identifier. -bool RequiresResourceIdentifier(ContentSettingsType content_type); +std::string GetTypeName(ContentSettingsType type); + +std::string GetResourceTypeName(ContentSettingsType type); + +ContentSettingsType StringToContentSettingsType( + const std::string& content_type_str); + +// Returns true if the |content_type| supports a resource identifier. +bool SupportsResourceIdentifier(ContentSettingsType content_type); // Maps CONTENT_SETTING_ASK for the CONTENT_SETTINGS_TYPE_PLUGINS to // CONTENT_SETTING_BLOCK if click-to-play is not enabled. diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index e5dbc89..259f947 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/string_util.h" #include "base/utf_string_conversions.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_extension_provider.h" #include "chrome/browser/content_settings/content_settings_observable_provider.h" @@ -51,16 +52,11 @@ static bool ShouldAllowAllContent(const GURL& url, url.SchemeIs(chrome::kExtensionScheme); } -typedef linked_ptr<content_settings::DefaultProviderInterface> - DefaultContentSettingsProviderPtr; -typedef std::vector<DefaultContentSettingsProviderPtr>::iterator - DefaultProviderIterator; -typedef std::vector<DefaultContentSettingsProviderPtr>::const_iterator - ConstDefaultProviderIterator; - typedef linked_ptr<content_settings::ProviderInterface> ProviderPtr; -typedef std::vector<ProviderPtr>::iterator ProviderIterator; -typedef std::vector<ProviderPtr>::const_iterator ConstProviderIterator; +typedef std::map<HostContentSettingsMap::ProviderType, ProviderPtr> + ProviderMap; +typedef ProviderMap::iterator ProviderIterator; +typedef ProviderMap::const_iterator ConstProviderIterator; typedef std::vector<content_settings::Rule> Rules; @@ -69,7 +65,8 @@ typedef std::pair<std::string, std::string> StringPair; const char* kProviderNames[] = { "policy", "extension", - "preference" + "preference", + "default" }; bool ContentTypeHasCompoundValue(ContentSettingsType type) { @@ -79,6 +76,18 @@ bool ContentTypeHasCompoundValue(ContentSettingsType type) { return type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE; } +ContentSetting GetDefaultSetting(Rules rules) { + for (Rules::iterator rule = rules.begin(); + rule != rules.end(); + ++rule) { + if (rule->primary_pattern == ContentSettingsPattern::Wildcard() && + rule->secondary_pattern == ContentSettingsPattern::Wildcard()) { + return rule->content_setting; + } + } + return CONTENT_SETTING_DEFAULT; +} + } // namespace HostContentSettingsMap::HostContentSettingsMap( @@ -90,23 +99,35 @@ HostContentSettingsMap::HostContentSettingsMap( updating_preferences_(false), block_third_party_cookies_(false), is_block_third_party_cookies_managed_(false) { - // The order in which the default 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::PrefDefaultProvider* default_provider = - new content_settings::PrefDefaultProvider(prefs_, is_off_the_record_); - default_provider->AddObserver(this); - default_content_settings_providers_.push_back( - make_linked_ptr(default_provider)); + content_settings::ObservableProvider* policy_provider = + new content_settings::PolicyProvider(prefs_); + policy_provider->AddObserver(this); + content_settings_providers_[POLICY_PROVIDER] = + make_linked_ptr(policy_provider); - content_settings::PolicyDefaultProvider* policy_default_provider = - new content_settings::PolicyDefaultProvider(prefs_); - policy_default_provider->AddObserver(this); - default_content_settings_providers_.push_back( - make_linked_ptr(policy_default_provider)); + if (extension_service) { + // |extension_service| can be NULL in unit tests. + content_settings::ObservableProvider* extension_provider = + new content_settings::ExtensionProvider( + extension_service->GetExtensionContentSettingsStore(), + is_off_the_record_); + extension_provider->AddObserver(this); + content_settings_providers_[EXTENSION_PROVIDER] = + make_linked_ptr(extension_provider); + } + + content_settings::ObservableProvider* pref_provider = + new content_settings::PrefProvider(prefs_, is_off_the_record_); + pref_provider->AddObserver(this); + content_settings_providers_[PREF_PROVIDER] = + make_linked_ptr(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] = + make_linked_ptr(default_provider); - // TODO(markusheintz): Discuss whether it is sensible to move migration code - // to PrefContentSettingsProvider. MigrateObsoleteCookiePref(); // Read misc. global settings. @@ -122,27 +143,6 @@ HostContentSettingsMap::HostContentSettingsMap( is_block_third_party_cookies_managed_ = prefs_->IsManagedPreference(prefs::kBlockThirdPartyCookies); - // User defined non default content settings are provided by the PrefProvider. - // The order in which the content settings providers are created is critical, - // as providers that are further up in the list (i.e. added earlier) override - // providers further down. - content_settings::ObservableProvider* provider = - new content_settings::PolicyProvider(prefs_, policy_default_provider); - provider->AddObserver(this); - content_settings_providers_.push_back(make_linked_ptr(provider)); - - if (extension_service) { - // |extension_service| can be NULL in unit tests. - provider = new content_settings::ExtensionProvider( - extension_service->GetExtensionContentSettingsStore(), - is_off_the_record_); - provider->AddObserver(this); - content_settings_providers_.push_back(make_linked_ptr(provider)); - } - provider = new content_settings::PrefProvider(prefs_, is_off_the_record_); - provider->AddObserver(this); - content_settings_providers_.push_back(make_linked_ptr(provider)); - pref_change_registrar_.Init(prefs_); pref_change_registrar_.Add(prefs::kBlockThirdPartyCookies, this); } @@ -162,8 +162,7 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { PrefService::UNSYNCABLE_PREF); // Register the prefs for the content settings providers. - content_settings::PrefDefaultProvider::RegisterUserPrefs(prefs); - content_settings::PolicyDefaultProvider::RegisterUserPrefs(prefs); + content_settings::DefaultProvider::RegisterUserPrefs(prefs); content_settings::PrefProvider::RegisterUserPrefs(prefs); content_settings::PolicyProvider::RegisterUserPrefs(prefs); } @@ -171,20 +170,28 @@ void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { ContentSetting HostContentSettingsMap::GetDefaultContentSetting( ContentSettingsType content_type) const { DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE); - ContentSetting setting = CONTENT_SETTING_DEFAULT; - for (ConstDefaultProviderIterator provider = - default_content_settings_providers_.begin(); - provider != default_content_settings_providers_.end(); ++provider) { - ContentSetting provided_setting = - (*provider)->ProvideDefaultSetting(content_type); - if (provided_setting != CONTENT_SETTING_DEFAULT) - setting = provided_setting; - } + ContentSetting default_setting = CONTENT_SETTING_DEFAULT; + + // First check if there is a default setting set by policy. + ProviderPtr provider = + content_settings_providers_.find(POLICY_PROVIDER)->second; + Rules rules; + provider->GetAllContentSettingsRules(content_type, std::string(), &rules); + + default_setting = GetDefaultSetting(rules); + if (default_setting != CONTENT_SETTING_DEFAULT) + return default_setting; + + // Get the default setting. + provider = content_settings_providers_.find(DEFAULT_PROVIDER)->second; + provider->GetAllContentSettingsRules(content_type, std::string(), &rules); + default_setting = GetDefaultSetting(rules); + // 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; + CHECK_NE(CONTENT_SETTING_DEFAULT, default_setting); + return default_setting; } ContentSettings HostContentSettingsMap::GetDefaultContentSettings() const { @@ -204,8 +211,21 @@ ContentSetting HostContentSettingsMap::GetCookieContentSetting( return CONTENT_SETTING_ALLOW; // First get any host-specific settings. - ContentSetting setting = GetNonDefaultContentSetting(url, - first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, ""); + ContentSetting setting = CONTENT_SETTING_DEFAULT; + for (ConstProviderIterator provider = content_settings_providers_.begin(); + provider != content_settings_providers_.end(); + ++provider) { + if (provider->first == DEFAULT_PROVIDER) + continue; + + setting = provider->second->GetContentSetting( + url, + first_party_url, + CONTENT_SETTINGS_TYPE_COOKIES, + std::string()); + if (setting != CONTENT_SETTING_DEFAULT) + break; + } // If no explicit exception has been made and third-party cookies are blocked // by default, apply that rule. @@ -238,10 +258,23 @@ ContentSetting HostContentSettingsMap::GetContentSetting( ContentSettingsType content_type, const std::string& resource_identifier) const { DCHECK_NE(CONTENT_SETTINGS_TYPE_COOKIES, content_type); - DCHECK_NE(content_settings::RequiresResourceIdentifier(content_type), - resource_identifier.empty()); - return GetContentSettingInternal( - primary_url, secondary_url, content_type, resource_identifier); + DCHECK(content_settings::SupportsResourceIdentifier(content_type) || + resource_identifier.empty()); + + if (ShouldAllowAllContent(secondary_url, content_type)) + return CONTENT_SETTING_ALLOW; + + // Iterate through the list of providers and break when the first non default + // setting is found. + for (ConstProviderIterator provider = content_settings_providers_.begin(); + provider != content_settings_providers_.end(); + ++provider) { + ContentSetting provided_setting = provider->second->GetContentSetting( + primary_url, secondary_url, content_type, resource_identifier); + if (provided_setting != CONTENT_SETTING_DEFAULT) + return provided_setting; + } + return CONTENT_SETTING_DEFAULT; } Value* HostContentSettingsMap::GetContentSettingValue( @@ -259,7 +292,7 @@ Value* HostContentSettingsMap::GetContentSettingValue( for (ConstProviderIterator provider = content_settings_providers_.begin(); provider != content_settings_providers_.end(); ++provider) { - Value* value = (*provider)->GetContentSettingValue( + Value* value = provider->second->GetContentSettingValue( primary_url, secondary_url, content_type, resource_identifier); if (value) return value; @@ -274,73 +307,25 @@ Value* HostContentSettingsMap::GetContentSettingValue( return Value::CreateIntegerValue(GetDefaultContentSetting(content_type)); } -ContentSetting HostContentSettingsMap::GetContentSettingInternal( - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier) const { - ContentSetting setting = GetNonDefaultContentSetting( - primary_url, secondary_url, content_type, resource_identifier); - if (setting == CONTENT_SETTING_DEFAULT) - return GetDefaultContentSetting(content_type); - return setting; -} - -ContentSetting HostContentSettingsMap::GetNonDefaultContentSetting( - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier) const { - if (ShouldAllowAllContent(secondary_url, content_type)) - return CONTENT_SETTING_ALLOW; - - // Iterate through the list of providers and break when the first non default - // setting is found. - ContentSetting provided_setting(CONTENT_SETTING_DEFAULT); - for (ConstProviderIterator provider = content_settings_providers_.begin(); - provider != content_settings_providers_.end(); - ++provider) { - provided_setting = (*provider)->GetContentSetting( - primary_url, secondary_url, content_type, resource_identifier); - if (provided_setting != CONTENT_SETTING_DEFAULT) - return provided_setting; - } - return provided_setting; -} - ContentSettings HostContentSettingsMap::GetContentSettings( const GURL& primary_url, const GURL& secondary_url) const { - ContentSettings output = GetNonDefaultContentSettings( - primary_url, secondary_url); - + ContentSettings output; // If we require a resource identifier, set the content settings to default, // otherwise make the defaults explicit. Values for content type // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE can't be mapped to the type // |ContentSetting|. So we ignore them here. for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { - // A managed default content setting has the highest priority and hence - // will overwrite any previously set value. - if (output.settings[j] == CONTENT_SETTING_DEFAULT && - j != CONTENT_SETTINGS_TYPE_PLUGINS && - !ContentTypeHasCompoundValue(ContentSettingsType(j))) { - output.settings[j] = GetDefaultContentSetting(ContentSettingsType(j)); - } - } - return output; -} - -ContentSettings HostContentSettingsMap::GetNonDefaultContentSettings( - const GURL& primary_url, - const GURL& secondary_url) const { - ContentSettings output(CONTENT_SETTING_DEFAULT); - for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { - if (!ContentTypeHasCompoundValue(ContentSettingsType(j))) { - output.settings[j] = GetNonDefaultContentSetting( + ContentSettingsType type = ContentSettingsType(j); + if (type == CONTENT_SETTINGS_TYPE_COOKIES) { + output.settings[j] = GetCookieContentSetting( + primary_url, secondary_url, false); + } else if (!ContentTypeHasCompoundValue(type)) { + output.settings[j] = GetContentSetting( primary_url, secondary_url, ContentSettingsType(j), - ""); + std::string()); } } return output; @@ -350,30 +335,39 @@ void HostContentSettingsMap::GetSettingsForOneType( ContentSettingsType content_type, const std::string& resource_identifier, SettingsForOneType* settings) const { - DCHECK_NE(content_settings::RequiresResourceIdentifier(content_type), - resource_identifier.empty()); + DCHECK(content_settings::SupportsResourceIdentifier(content_type) || + resource_identifier.empty()); DCHECK(settings); settings->clear(); - for (size_t i = 0; i < content_settings_providers_.size(); ++i) { - // Get rules from the content settings provider. + for (ConstProviderIterator provider = content_settings_providers_.begin(); + provider != content_settings_providers_.end(); + ++provider) { Rules rules; - content_settings_providers_[i]->GetAllContentSettingsRules( - content_type, resource_identifier, &rules); - + provider->second->GetAllContentSettingsRules(content_type, + resource_identifier, + &rules); // Sort rules according to their primary-secondary pattern string pairs // using a map. std::map<StringPair, PatternSettingSourceTuple> settings_map; for (Rules::iterator rule = rules.begin(); rule != rules.end(); ++rule) { + // Filter out default settings. + if (rule->primary_pattern == ContentSettingsPattern::Wildcard() && + rule->secondary_pattern == ContentSettingsPattern::Wildcard() && + (provider->first == POLICY_PROVIDER || + provider->first == DEFAULT_PROVIDER)) { + continue; + } + StringPair sort_key(rule->primary_pattern.ToString(), rule->secondary_pattern.ToString()); settings_map[sort_key] = PatternSettingSourceTuple( rule->primary_pattern, rule->secondary_pattern, rule->content_setting, - kProviderNames[i]); + kProviderNames[provider->first]); } // TODO(markusheintz): Only the rules that are applied should be added. @@ -391,11 +385,13 @@ void HostContentSettingsMap::SetDefaultContentSetting( ContentSetting setting) { DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE); DCHECK(IsSettingAllowedForType(setting, content_type)); - for (DefaultProviderIterator provider = - default_content_settings_providers_.begin(); - provider != default_content_settings_providers_.end(); ++provider) { - (*provider)->UpdateDefaultSetting(content_type, setting); - } + + content_settings_providers_[DEFAULT_PROVIDER]->SetContentSetting( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + content_type, + std::string(), + setting); } void HostContentSettingsMap::SetContentSetting( @@ -406,12 +402,12 @@ void HostContentSettingsMap::SetContentSetting( ContentSetting setting) { DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE); DCHECK(IsSettingAllowedForType(setting, content_type)); - DCHECK_NE(content_settings::RequiresResourceIdentifier(content_type), - resource_identifier.empty()); + DCHECK(content_settings::SupportsResourceIdentifier(content_type) || + resource_identifier.empty()); for (ProviderIterator provider = content_settings_providers_.begin(); provider != content_settings_providers_.end(); ++provider) { - (*provider)->SetContentSetting( + provider->second->SetContentSetting( primary_pattern, secondary_pattern, content_type, @@ -450,7 +446,7 @@ void HostContentSettingsMap::ClearSettingsForOneType( for (ProviderIterator provider = content_settings_providers_.begin(); provider != content_settings_providers_.end(); ++provider) { - (*provider)->ClearAllContentSettingsRules(content_type); + provider->second->ClearAllContentSettingsRules(content_type); } } @@ -559,12 +555,13 @@ HostContentSettingsMap::~HostContentSettingsMap() { bool HostContentSettingsMap::IsDefaultContentSettingManaged( ContentSettingsType content_type) const { - for (ConstDefaultProviderIterator provider = - default_content_settings_providers_.begin(); - provider != default_content_settings_providers_.end(); ++provider) { - if ((*provider)->DefaultSettingIsManaged(content_type)) - return true; - } + Rules rules; + content_settings_providers_.find(POLICY_PROVIDER)->second-> + GetAllContentSettingsRules(content_type, std::string(), &rules); + ContentSetting default_setting = GetDefaultSetting(rules); + + if (default_setting != CONTENT_SETTING_DEFAULT) + return true; return false; } @@ -576,12 +573,7 @@ void HostContentSettingsMap::ShutdownOnUIThread() { for (ProviderIterator it = content_settings_providers_.begin(); it != content_settings_providers_.end(); ++it) { - (*it)->ShutdownOnUIThread(); - } - for (DefaultProviderIterator it = default_content_settings_providers_.begin(); - it != default_content_settings_providers_.end(); - ++it) { - (*it)->ShutdownOnUIThread(); + it->second->ShutdownOnUIThread(); } } diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h index 3a9724b..5146690 100644 --- a/chrome/browser/content_settings/host_content_settings_map.h +++ b/chrome/browser/content_settings/host_content_settings_map.h @@ -28,7 +28,6 @@ #include "content/common/notification_registrar.h" namespace content_settings { -class DefaultProviderInterface; class ProviderInterface; } // namespace content_settings @@ -43,6 +42,14 @@ class HostContentSettingsMap public NotificationObserver, public base::RefCountedThreadSafe<HostContentSettingsMap> { public: + enum ProviderType { + POLICY_PROVIDER = 0, + EXTENSION_PROVIDER = 1, + PREF_PROVIDER, + DEFAULT_PROVIDER, + NUM_PROVIDER_TYPES, + }; + // TODO(markusheintz): I sold my soul to the devil on order to add this tuple. // I really want my soul back, so I really will change this ASAP. typedef Tuple4<ContentSettingsPattern, @@ -203,34 +210,6 @@ class HostContentSettingsMap virtual ~HostContentSettingsMap(); - // Returns all non-default ContentSettings which apply to the given URLs. For - // content setting types that require an additional resource identifier, - // CONTENT_SETTING_DEFAULT is returned. - // - // This may be called on any thread. - ContentSettings GetNonDefaultContentSettings( - const GURL& primary_url, - const GURL& secondary_url) const; - - // Returns a single ContentSetting which applies to the given URLs or - // CONTENT_SETTING_DEFAULT, if no exception applies. Note that certain - // internal schemes are whitelisted. For ContentSettingsTypes that require an - // resource identifier to be specified, the |resource_identifier| must be - // non-empty. - // - // This may be called on any thread. - ContentSetting GetNonDefaultContentSetting( - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier) const; - - ContentSetting GetContentSettingInternal( - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier) const; - // Various migration methods (old cookie, popup and per-host data gets // migrated to the new format). void MigrateObsoleteCookiePref(); @@ -247,12 +226,8 @@ class HostContentSettingsMap // notifications from the preferences service that we triggered ourself. bool updating_preferences_; - // Default content setting providers. - std::vector<linked_ptr<content_settings::DefaultProviderInterface> > - default_content_settings_providers_; - // Content setting providers. - std::vector<linked_ptr<content_settings::ProviderInterface> > + std::map<ProviderType, linked_ptr<content_settings::ProviderInterface> > content_settings_providers_; // Used around accesses to the following objects to guarantee thread safety. diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index caa66ed..598c103 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc @@ -369,6 +369,10 @@ TEST_F(HostContentSettingsMapTest, ObserveExceptionPref) { ContentSettingsPattern::FromString("[*.]example.com"); GURL host("http://example.com"); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + host_content_settings_map->GetCookieContentSetting( + host, host, true)); + host_content_settings_map->SetContentSetting( pattern, ContentSettingsPattern::Wildcard(), @@ -787,33 +791,6 @@ TEST_F(HostContentSettingsMapTest, CanonicalizeExceptionsUnicodeAndPunycode) { prefs_as_json.c_str()); } -TEST_F(HostContentSettingsMapTest, NonDefaultSettings) { - TestingProfile profile; - HostContentSettingsMap* host_content_settings_map = - profile.GetHostContentSettingsMap(); - - GURL host("http://example.com/"); - ContentSettingsPattern pattern = - ContentSettingsPattern::FromString("[*.]example.com"); - - ContentSettings desired_settings(CONTENT_SETTING_DEFAULT); - ContentSettings settings = - host_content_settings_map->GetNonDefaultContentSettings(host, host); - EXPECT_TRUE(SettingsEqual(desired_settings, settings)); - - host_content_settings_map->SetContentSetting( - pattern, - ContentSettingsPattern::Wildcard(), - CONTENT_SETTINGS_TYPE_IMAGES, - "", - CONTENT_SETTING_BLOCK); - desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES] = - CONTENT_SETTING_BLOCK; - settings = - host_content_settings_map->GetNonDefaultContentSettings(host, host); - EXPECT_TRUE(SettingsEqual(desired_settings, settings)); -} - TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { // This feature is currently behind a flag. CommandLine* cmd = CommandLine::ForCurrentProcess(); @@ -830,6 +807,16 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { std::string resource1("someplugin"); std::string resource2("otherplugin"); + // If resource content settings are enabled GetContentSettings should return + // the default values for all plugins + ContentSetting default_plugin_setting = + host_content_settings_map->GetDefaultContentSetting( + CONTENT_SETTINGS_TYPE_PLUGINS); + ContentSettings settings = + host_content_settings_map->GetContentSettings(host, host); + EXPECT_EQ(default_plugin_setting, + settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]); + EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host, host, CONTENT_SETTINGS_TYPE_PLUGINS, resource1)); @@ -846,14 +833,6 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host, host, CONTENT_SETTINGS_TYPE_PLUGINS, resource2)); - - // If resource content settings are enabled GetContentSettings should return - // CONTENT_SETTING_DEFAULT for content types that require resource - // identifiers. - ContentSettings settings = - host_content_settings_map->GetContentSettings(host, host); - EXPECT_EQ(CONTENT_SETTING_DEFAULT, - settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]); } TEST_F(HostContentSettingsMapTest, ResourceIdentifierPrefs) { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index cc57bbd..7189f63 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -816,6 +816,8 @@ 'browser/component_updater/flash_component_installer.h', 'browser/component_updater/npapi_flash_component_installer.cc', 'browser/component_updater/pepper_flash_component_installer.cc', + 'browser/content_settings/content_settings_default_provider.cc', + 'browser/content_settings/content_settings_default_provider.h', 'browser/content_settings/content_settings_details.cc', 'browser/content_settings/content_settings_details.h', 'browser/content_settings/content_settings_extension_provider.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index b57e22a..0c58a34 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1239,6 +1239,7 @@ 'browser/component_updater/component_updater_service_unittest.cc', 'browser/component_updater/component_updater_interceptor.cc', 'browser/component_updater/component_updater_interceptor.h', + 'browser/content_settings/content_settings_default_provider_unittest.cc', 'browser/content_settings/content_settings_mock_observer.cc', 'browser/content_settings/content_settings_mock_observer.h', 'browser/content_settings/content_settings_mock_provider.cc', |