diff options
author | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 15:10:17 +0000 |
---|---|---|
committer | mnissler@chromium.org <mnissler@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-09 15:10:17 +0000 |
commit | f2d1f61006eac0f8a051fa485b2cffb6b6fa74e0 (patch) | |
tree | f848fcb564eaff40eeebcf7044da9972f798bd2b /chrome/browser | |
parent | ba99ca24c0ba8f0e154dbd74d8a43a55736630e1 (diff) | |
download | chromium_src-f2d1f61006eac0f8a051fa485b2cffb6b6fa74e0.zip chromium_src-f2d1f61006eac0f8a051fa485b2cffb6b6fa74e0.tar.gz chromium_src-f2d1f61006eac0f8a051fa485b2cffb6b6fa74e0.tar.bz2 |
Sanitize PrefStore interface.
This reworks the PrefStore interface, specifically:
- Split up the interface into PrefStore, which only provides reading functionality, and the derived PersistentPrefStore for the actual user pref store
- Remove the hurt-me-plenty prefs() function from PrefStore, instead provide Get/Set/Remove operations
- Remove special handling of default and user pref store from PrefValueStore and put it into PrefService
- Pref change notification handling now almost exclusively handled through PrefValueStore
- Adjust all consumers of these interfaces (but keep ConfigurationPolicyPrefStore untouched, that's up next on the list)
BUG=64232
TEST=existing unit tests
Review URL: http://codereview.chromium.org/5646003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
43 files changed, 1140 insertions, 891 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index a0bec57..6327dfe 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -631,7 +631,7 @@ PrefService* InitializeLocalState(const CommandLine& parsed_command_line, FilePath parent_profile = parsed_command_line.GetSwitchValuePath(switches::kParentProfile); scoped_ptr<PrefService> parent_local_state( - PrefService::CreatePrefService(parent_profile, NULL)); + PrefService::CreatePrefService(parent_profile, NULL, NULL)); parent_local_state->RegisterStringPref(prefs::kApplicationLocale, std::string()); // Right now, we only inherit the locale setting from the parent profile. diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index e260184..9a1201e 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -637,7 +637,8 @@ void BrowserProcessImpl::CreateLocalState() { FilePath local_state_path; PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); - local_state_.reset(PrefService::CreatePrefService(local_state_path, NULL)); + local_state_.reset( + PrefService::CreatePrefService(local_state_path, NULL, NULL)); pref_change_registrar_.Init(local_state_.get()); diff --git a/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc b/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc index b1d7473..837e5f0 100644 --- a/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc +++ b/chrome/browser/chromeos/login/signed_settings_temp_storage_unittest.cc @@ -30,7 +30,7 @@ class SignedSettingsTempStorageTest : public ::testing::Test { FilePath temp_file; ASSERT_TRUE( file_util::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); - local_state_.reset(PrefService::CreatePrefService(temp_file, NULL)); + local_state_.reset(PrefService::CreatePrefService(temp_file, NULL, NULL)); ASSERT_TRUE(NULL != local_state_.get()); SignedSettingsTempStorage::RegisterPrefs(local_state_.get()); } diff --git a/chrome/browser/extensions/extension_pref_store.cc b/chrome/browser/extensions/extension_pref_store.cc new file mode 100644 index 0000000..b3aba44 --- /dev/null +++ b/chrome/browser/extensions/extension_pref_store.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_pref_store.h" + +ExtensionPrefStore::ExtensionPrefStore() + : initialization_complete_(false) { +} + +void ExtensionPrefStore::SetExtensionPref(const std::string& key, + Value* value) { + SetValue(key, value); +} + +void ExtensionPrefStore::RemoveExtensionPref(const std::string& key) { + RemoveValue(key); +} + +void ExtensionPrefStore::OnInitializationCompleted() { + DCHECK(!initialization_complete_); + initialization_complete_ = true; + NotifyInitializationCompleted(); +} + +bool ExtensionPrefStore::IsInitializationComplete() const { + return initialization_complete_; +} diff --git a/chrome/browser/extensions/extension_pref_store.h b/chrome/browser/extensions/extension_pref_store.h new file mode 100644 index 0000000..f2db809 --- /dev/null +++ b/chrome/browser/extensions/extension_pref_store.h @@ -0,0 +1,36 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_STORE_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_STORE_H_ +#pragma once + +#include "chrome/browser/prefs/value_map_pref_store.h" + +// A PrefStore implementation that holds preferences set by extensions. +class ExtensionPrefStore : public ValueMapPrefStore { + public: + ExtensionPrefStore(); + virtual ~ExtensionPrefStore() {} + + // Set an extension preference |value| for |key|. Takes ownership of |value|. + void SetExtensionPref(const std::string& key, Value* value); + + // Remove the extension preference value for |key|. + void RemoveExtensionPref(const std::string& key); + + // Tell the store it's now fully initialized. + void OnInitializationCompleted(); + + private: + // PrefStore overrides: + virtual bool IsInitializationComplete() const; + + bool initialization_complete_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionPrefStore); +}; + + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_STORE_H_ diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index cc1beb8..1f128ab 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/prefs/pref_notifier.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/url_pattern.h" @@ -140,9 +141,12 @@ static void ExtentToStringSet(const ExtensionExtent& host_extent, } // namespace -ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir) +ExtensionPrefs::ExtensionPrefs(PrefService* prefs, + const FilePath& root_dir, + ExtensionPrefStore* pref_store) : prefs_(prefs), - install_directory_(root_dir) { + install_directory_(root_dir), + pref_store_(pref_store) { // TODO(asargent) - Remove this in a couple of months. (See comment above // CleanupBadExtensionKeys). CleanupBadExtensionKeys(prefs_); @@ -1190,6 +1194,7 @@ void ExtensionPrefs::InitPrefStore() { // Store winning preference for each extension controlled preference. UpdatePrefStore(ext_controlled_prefs); + pref_store_->OnInitializationCompleted(); } const Value* ExtensionPrefs::GetWinningExtensionControlledPrefValue( @@ -1229,25 +1234,15 @@ void ExtensionPrefs::UpdatePrefStore( } void ExtensionPrefs::UpdatePrefStore(const std::string& pref_key) { - PrefStore* extension_pref_store = - pref_service()->GetExtensionPrefStore(); - if (extension_pref_store == NULL) - return; // Profile is being shut down, Pref Service is already gone. + if (pref_store_ == NULL) + return; const Value* winning_pref_value = GetWinningExtensionControlledPrefValue(pref_key); - Value* old_value = NULL; - extension_pref_store->prefs()->Get(pref_key, &old_value); - bool changed = !Value::Equals(winning_pref_value, old_value); - if (winning_pref_value) { - extension_pref_store->prefs()->Set(pref_key, - winning_pref_value->DeepCopy()); - } else { - extension_pref_store->prefs()->Remove(pref_key, NULL); - } - - if (changed) - pref_service()->pref_notifier()->OnPreferenceChanged(pref_key.c_str()); + if (winning_pref_value) + pref_store_->SetExtensionPref(pref_key, winning_pref_value->DeepCopy()); + else + pref_store_->RemoveExtensionPref(pref_key); } void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id, diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index b0f03f5..8c8be82 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -16,6 +16,8 @@ #include "chrome/common/extensions/extension.h" #include "googleurl/src/gurl.h" +class ExtensionPrefStore; + // Class for managing global and per-extension preferences. // // This class distinguishes the following kinds of preferences: @@ -57,7 +59,9 @@ class ExtensionPrefs { LAUNCH_WINDOW }; - explicit ExtensionPrefs(PrefService* prefs, const FilePath& root_dir); + explicit ExtensionPrefs(PrefService* prefs, + const FilePath& root_dir, + ExtensionPrefStore* extension_pref_store); ~ExtensionPrefs(); // Returns a copy of the Extensions prefs. @@ -387,6 +391,9 @@ class ExtensionPrefs { // Base extensions install directory. FilePath install_directory_; + // Used to manipulate extension preferences. + ExtensionPrefStore* pref_store_; + // The URLs of all of the toolstrips. URLList shelf_order_; diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index 83f4478..a1bf7e6 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -34,7 +34,7 @@ #include "chrome/browser/in_process_webkit/dom_storage_context.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/prefs/browser_prefs.h" -#include "chrome/browser/prefs/pref_value_store.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/scoped_pref_update.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" @@ -352,9 +352,9 @@ ExtensionsServiceTestBase::~ExtensionsServiceTestBase() { void ExtensionsServiceTestBase::InitializeExtensionsService( const FilePath& pref_file, const FilePath& extensions_install_dir) { ExtensionTestingProfile* profile = new ExtensionTestingProfile(); - // Create a preference service that only contains user defined - // preference values. - PrefService* prefs = PrefService::CreateUserPrefService(pref_file); + // Create a PrefService that only contains user defined preference values. + PrefService* prefs = + PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create(); Profile::RegisterUserPrefs(prefs); browser::RegisterUserPrefs(prefs); profile->SetPrefService(prefs); diff --git a/chrome/browser/extensions/test_extension_prefs.cc b/chrome/browser/extensions/test_extension_prefs.cc index d7f83fdb..5b0ee7b 100644 --- a/chrome/browser/extensions/test_extension_prefs.cc +++ b/chrome/browser/extensions/test_extension_prefs.cc @@ -6,26 +6,32 @@ #include "base/file_util.h" #include "base/message_loop.h" +#include "base/message_loop_proxy.h" #include "base/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/pref_value_store.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/json_pref_store.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { + // Mock ExtensionPrefs class with artificial clock to guarantee that no two // extensions get the same installation time stamp and we can reliably // assert the installation order in the tests below. class MockExtensionPrefs : public ExtensionPrefs { public: - MockExtensionPrefs(PrefService* prefs, const FilePath& root_dir_) - : ExtensionPrefs(prefs, root_dir_), - currentTime(base::Time::Now()) - {} + MockExtensionPrefs(PrefService* prefs, + const FilePath& root_dir_, + ExtensionPrefStore* pref_store) + : ExtensionPrefs(prefs, root_dir_, pref_store), + currentTime(base::Time::Now()) {} ~MockExtensionPrefs() {} protected: @@ -37,6 +43,8 @@ class MockExtensionPrefs : public ExtensionPrefs { } }; +} // namespace + TestExtensionPrefs::TestExtensionPrefs() : pref_service_(NULL) { EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); preferences_file_ = temp_dir_.path().AppendASCII("Preferences"); @@ -62,10 +70,14 @@ void TestExtensionPrefs::RecreateExtensionPrefs() { file_loop.RunAllPending(); } - // Create a |PrefService| instance that contains only user defined values. - pref_service_.reset(PrefService::CreateUserPrefService(preferences_file_)); + ExtensionPrefStore* pref_store = new ExtensionPrefStore; + PrefServiceMockBuilder builder; + builder.WithUserFilePrefs(preferences_file_); + builder.WithExtensionPrefs(pref_store); + pref_service_.reset(builder.Create()); ExtensionPrefs::RegisterUserPrefs(pref_service_.get()); - prefs_.reset(new MockExtensionPrefs(pref_service_.get(), temp_dir_.path())); + prefs_.reset(new MockExtensionPrefs(pref_service_.get(), temp_dir_.path(), + pref_store)); } scoped_refptr<Extension> TestExtensionPrefs::AddExtension(std::string name) { diff --git a/chrome/browser/metrics/metrics_service_uitest.cc b/chrome/browser/metrics/metrics_service_uitest.cc index 93889c5..4d67c13 100644 --- a/chrome/browser/metrics/metrics_service_uitest.cc +++ b/chrome/browser/metrics/metrics_service_uitest.cc @@ -13,14 +13,15 @@ #include "base/platform_thread.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/pref_value_store.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_pref_store.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" -#include "chrome/test/automation/tab_proxy.h" #include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/tab_proxy.h" #include "chrome/test/ui/ui_test.h" #include "net/base/net_util.h" @@ -51,10 +52,8 @@ class MetricsServiceTest : public UITest { // that was saved by the app as it closed. The caller takes ownership of the // returned PrefService object. PrefService* GetLocalState() { - FilePath local_state_path = user_data_dir() - .Append(chrome::kLocalStateFilename); - - return PrefService::CreateUserPrefService(local_state_path); + FilePath path = user_data_dir().Append(chrome::kLocalStateFilename); + return PrefServiceMockBuilder().WithUserFilePrefs(path).Create(); } }; diff --git a/chrome/browser/net/pref_proxy_config_service_unittest.cc b/chrome/browser/net/pref_proxy_config_service_unittest.cc index fd24dd6..cc602ec 100644 --- a/chrome/browser/net/pref_proxy_config_service_unittest.cc +++ b/chrome/browser/net/pref_proxy_config_service_unittest.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/file_path.h" #include "chrome/browser/net/chrome_url_request_context.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/testing_pref_service.h" @@ -65,12 +66,12 @@ class PrefProxyConfigServiceTestBase : public TESTBASE { : ui_thread_(BrowserThread::UI, &loop_), io_thread_(BrowserThread::IO, &loop_) {} - virtual void SetUp() { - ASSERT_TRUE(pref_service_.get()); - PrefProxyConfigService::RegisterUserPrefs(pref_service_.get()); + virtual void Init(PrefService* pref_service) { + ASSERT_TRUE(pref_service); + PrefProxyConfigService::RegisterUserPrefs(pref_service); fixed_config_.set_pac_url(GURL(kFixedPacUrl)); delegate_service_ = new TestProxyConfigService(fixed_config_); - proxy_config_tracker_ = new PrefProxyConfigTracker(pref_service_.get()); + proxy_config_tracker_ = new PrefProxyConfigTracker(pref_service); proxy_config_service_.reset( new PrefProxyConfigService(proxy_config_tracker_.get(), delegate_service_)); @@ -80,12 +81,10 @@ class PrefProxyConfigServiceTestBase : public TESTBASE { proxy_config_tracker_->DetachFromPrefService(); loop_.RunAllPending(); proxy_config_service_.reset(); - pref_service_.reset(); } MessageLoop loop_; TestProxyConfigService* delegate_service_; // weak - scoped_ptr<TestingPrefService> pref_service_; scoped_ptr<PrefProxyConfigService> proxy_config_service_; net::ProxyConfig fixed_config_; @@ -99,9 +98,11 @@ class PrefProxyConfigServiceTest : public PrefProxyConfigServiceTestBase<testing::Test> { protected: virtual void SetUp() { - pref_service_.reset(new TestingPrefService); - PrefProxyConfigServiceTestBase<testing::Test>::SetUp(); + pref_service_.reset(new TestingPrefService()); + Init(pref_service_.get()); } + + scoped_ptr<TestingPrefService> pref_service_; }; TEST_F(PrefProxyConfigServiceTest, BaseConfiguration) { @@ -240,13 +241,14 @@ class PrefProxyConfigServiceCommandLineTest else if (name) command_line_.AppendSwitch(name); } - pref_service_.reset(new TestingPrefService(NULL, NULL, &command_line_)); - PrefProxyConfigServiceTestBase< - testing::TestWithParam<CommandLineTestParams> >::SetUp(); + pref_service_.reset( + PrefServiceMockBuilder().WithCommandLine(&command_line_).Create()); + Init(pref_service_.get()); } private: CommandLine command_line_; + scoped_ptr<PrefService> pref_service_; }; TEST_P(PrefProxyConfigServiceCommandLineTest, CommandLine) { diff --git a/chrome/browser/policy/configuration_policy_pref_store.cc b/chrome/browser/policy/configuration_policy_pref_store.cc index 3ebbf2e..25df2d5 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.cc +++ b/chrome/browser/policy/configuration_policy_pref_store.cc @@ -322,19 +322,27 @@ ConfigurationPolicyPrefStore::ConfigurationPolicyPrefStore( proxy_disabled_(false), proxy_configuration_specified_(false), use_system_proxy_(false) { + if (!provider_->Provide(this)) + LOG(WARNING) << "Failed to get policy from provider."; + FinalizeDefaultSearchPolicySettings(); } ConfigurationPolicyPrefStore::~ConfigurationPolicyPrefStore() {} -PrefStore::PrefReadError ConfigurationPolicyPrefStore::ReadPrefs() { - proxy_disabled_ = false; - proxy_configuration_specified_ = false; - lower_priority_proxy_settings_overridden_ = false; +PrefStore::ReadResult ConfigurationPolicyPrefStore::GetValue( + const std::string& key, + Value** value) const { + Value* configured_value = NULL; + if (!prefs_->Get(key, &configured_value) || !configured_value) + return READ_NO_VALUE; - const bool success = (provider_ == NULL || provider_->Provide(this)); - FinalizeDefaultSearchPolicySettings(); - return success ? PrefStore::PREF_READ_ERROR_NONE : - PrefStore::PREF_READ_ERROR_OTHER; + // Check whether there's a default value, which indicates READ_USE_DEFAULT + // should be returned. + if (configured_value->IsType(Value::TYPE_NULL)) + return READ_USE_DEFAULT; + + *value = configured_value; + return READ_OK; } void ConfigurationPolicyPrefStore::Apply(ConfigurationPolicyType policy, @@ -466,7 +474,9 @@ bool ConfigurationPolicyPrefStore::ApplyProxyPolicy( GetProxyPreferenceSet(&proxy_preference_set); for (ProxyPreferenceSet::const_iterator i = proxy_preference_set.begin(); i != proxy_preference_set.end(); ++i) { - prefs_->Set(*i, PrefStore::CreateUseDefaultSentinelValue()); + // We use values of TYPE_NULL to mark preferences for which + // READ_USE_DEFAULT should be returned by GetValue(). + prefs_->Set(*i, Value::CreateNullValue()); } lower_priority_proxy_settings_overridden_ = true; } diff --git a/chrome/browser/policy/configuration_policy_pref_store.h b/chrome/browser/policy/configuration_policy_pref_store.h index 297d57d..2ce8c61 100644 --- a/chrome/browser/policy/configuration_policy_pref_store.h +++ b/chrome/browser/policy/configuration_policy_pref_store.h @@ -34,7 +34,8 @@ class ConfigurationPolicyPrefStore : public PrefStore, virtual ~ConfigurationPolicyPrefStore(); // PrefStore methods: - virtual PrefReadError ReadPrefs(); + virtual ReadResult GetValue(const std::string& key, Value** result) const; + virtual DictionaryValue* prefs() const { return prefs_.get(); } // ConfigurationPolicyStore methods: diff --git a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc index 2595f83..80c69e4 100644 --- a/chrome/browser/policy/configuration_policy_pref_store_unittest.cc +++ b/chrome/browser/policy/configuration_policy_pref_store_unittest.cc @@ -27,25 +27,35 @@ class TypeAndName { const char* pref_name_; }; +template<typename TESTBASE> +class ConfigurationPolicyPrefStoreTestBase : public TESTBASE { + protected: + ConfigurationPolicyPrefStoreTestBase() + : provider_(), + store_(&provider_) {} + + MockConfigurationPolicyProvider provider_; + ConfigurationPolicyPrefStore store_; +}; + // Test cases for list-valued policy settings. class ConfigurationPolicyPrefStoreListTest - : public testing::TestWithParam<TypeAndName> { + : public ConfigurationPolicyPrefStoreTestBase< + testing::TestWithParam<TypeAndName> > { }; TEST_P(ConfigurationPolicyPrefStoreListTest, GetDefault) { - ConfigurationPolicyPrefStore store(NULL); ListValue* list = NULL; - EXPECT_FALSE(store.prefs()->GetList(GetParam().pref_name(), &list)); + EXPECT_FALSE(store_.prefs()->GetList(GetParam().pref_name(), &list)); } TEST_P(ConfigurationPolicyPrefStoreListTest, SetValue) { - ConfigurationPolicyPrefStore store(NULL); ListValue* in_value = new ListValue(); in_value->Append(Value::CreateStringValue("test1")); in_value->Append(Value::CreateStringValue("test2,")); - store.Apply(GetParam().type(), in_value); + store_.Apply(GetParam().type(), in_value); ListValue* list = NULL; - EXPECT_TRUE(store.prefs()->GetList(GetParam().pref_name(), &list)); + EXPECT_TRUE(store_.prefs()->GetList(GetParam().pref_name(), &list)); ListValue::const_iterator current(list->begin()); const ListValue::const_iterator end(list->end()); ASSERT_TRUE(current != end); @@ -75,21 +85,20 @@ INSTANTIATE_TEST_CASE_P( // Test cases for string-valued policy settings. class ConfigurationPolicyPrefStoreStringTest - : public testing::TestWithParam<TypeAndName> { + : public ConfigurationPolicyPrefStoreTestBase< + testing::TestWithParam<TypeAndName> > { }; TEST_P(ConfigurationPolicyPrefStoreStringTest, GetDefault) { - ConfigurationPolicyPrefStore store(NULL); std::string result; - EXPECT_FALSE(store.prefs()->GetString(GetParam().pref_name(), &result)); + EXPECT_FALSE(store_.prefs()->GetString(GetParam().pref_name(), &result)); } TEST_P(ConfigurationPolicyPrefStoreStringTest, SetValue) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(GetParam().type(), + store_.Apply(GetParam().type(), Value::CreateStringValue("http://chromium.org")); std::string result; - EXPECT_TRUE(store.prefs()->GetString(GetParam().pref_name(), &result)); + EXPECT_TRUE(store_.prefs()->GetString(GetParam().pref_name(), &result)); EXPECT_EQ(result, "http://chromium.org"); } @@ -120,25 +129,24 @@ INSTANTIATE_TEST_CASE_P( // Test cases for boolean-valued policy settings. class ConfigurationPolicyPrefStoreBooleanTest - : public testing::TestWithParam<TypeAndName> { + : public ConfigurationPolicyPrefStoreTestBase< + testing::TestWithParam<TypeAndName> > { }; TEST_P(ConfigurationPolicyPrefStoreBooleanTest, GetDefault) { - ConfigurationPolicyPrefStore store(NULL); bool result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(GetParam().pref_name(), &result)); + EXPECT_FALSE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); } TEST_P(ConfigurationPolicyPrefStoreBooleanTest, SetValue) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(GetParam().type(), Value::CreateBooleanValue(false)); + store_.Apply(GetParam().type(), Value::CreateBooleanValue(false)); bool result = true; - EXPECT_TRUE(store.prefs()->GetBoolean(GetParam().pref_name(), &result)); + EXPECT_TRUE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); EXPECT_FALSE(result); - store.Apply(GetParam().type(), Value::CreateBooleanValue(true)); + store_.Apply(GetParam().type(), Value::CreateBooleanValue(true)); result = false; - EXPECT_TRUE(store.prefs()->GetBoolean(GetParam().pref_name(), &result)); + EXPECT_TRUE(store_.prefs()->GetBoolean(GetParam().pref_name(), &result)); EXPECT_TRUE(result); } @@ -190,20 +198,19 @@ INSTANTIATE_TEST_CASE_P( // Test cases for integer-valued policy settings. class ConfigurationPolicyPrefStoreIntegerTest - : public testing::TestWithParam<TypeAndName> { + : public ConfigurationPolicyPrefStoreTestBase< + testing::TestWithParam<TypeAndName> > { }; TEST_P(ConfigurationPolicyPrefStoreIntegerTest, GetDefault) { - ConfigurationPolicyPrefStore store(NULL); int result = 0; - EXPECT_FALSE(store.prefs()->GetInteger(GetParam().pref_name(), &result)); + EXPECT_FALSE(store_.prefs()->GetInteger(GetParam().pref_name(), &result)); } TEST_P(ConfigurationPolicyPrefStoreIntegerTest, SetValue) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(GetParam().type(), Value::CreateIntegerValue(2)); + store_.Apply(GetParam().type(), Value::CreateIntegerValue(2)); int result = 0; - EXPECT_TRUE(store.prefs()->GetInteger(GetParam().pref_name(), &result)); + EXPECT_TRUE(store_.prefs()->GetInteger(GetParam().pref_name(), &result)); EXPECT_EQ(result, 2); } @@ -232,7 +239,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, ManualOptions) { kPolicyManuallyConfiguredProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -259,7 +265,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxy) { kPolicyNoProxyServerMode)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -283,7 +288,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, NoProxyReversedApplyOrder) { Value::CreateStringValue("http://chromium.org/override")); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -305,7 +309,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, AutoDetect) { kPolicyAutoDetectProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -329,7 +332,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystem) { kPolicyUseSystemProxyMode)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -352,7 +354,6 @@ TEST_F(ConfigurationPolicyPrefStoreProxyTest, UseSystemReversedApplyOrder) { Value::CreateStringValue("http://chromium.org/override")); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); std::string string_result; EXPECT_FALSE(store.prefs()->GetString(prefs::kProxyBypassList, @@ -382,8 +383,6 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MinimallyDefined) { Value::CreateStringValue(search_url)); ConfigurationPolicyPrefStore store(provider.get()); - - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); const DictionaryValue* prefs = store.prefs(); std::string string_result; @@ -446,7 +445,6 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, FullyDefined) { Value::CreateStringValue(encodings)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); const DictionaryValue* prefs = store.prefs(); std::string result_search_url; @@ -510,7 +508,6 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, MissingUrl) { Value::CreateStringValue(encodings)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); const DictionaryValue* prefs = store.prefs(); std::string string_result; @@ -562,7 +559,6 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, Invalid) { Value::CreateStringValue(encodings)); ConfigurationPolicyPrefStore store(provider.get()); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); const DictionaryValue* const prefs = store.prefs(); std::string string_result; @@ -583,56 +579,52 @@ TEST_F(ConfigurationPolicyPrefStoreDefaultSearchTest, Invalid) { } // Test cases for the Sync policy setting. -class ConfigurationPolicyPrefStoreSyncTest : public testing::Test { +class ConfigurationPolicyPrefStoreSyncTest + : public ConfigurationPolicyPrefStoreTestBase<testing::Test> { }; TEST_F(ConfigurationPolicyPrefStoreSyncTest, Default) { - ConfigurationPolicyPrefStore store(NULL); bool result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result)); + EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); } TEST_F(ConfigurationPolicyPrefStoreSyncTest, Enabled) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(false)); + store_.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(false)); // Enabling Sync should not set the pref. bool result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result)); + EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); } TEST_F(ConfigurationPolicyPrefStoreSyncTest, Disabled) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(true)); + store_.Apply(kPolicySyncDisabled, Value::CreateBooleanValue(true)); // Sync should be flagged as managed. bool result = false; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kSyncManaged, &result)); + EXPECT_TRUE(store_.prefs()->GetBoolean(prefs::kSyncManaged, &result)); EXPECT_TRUE(result); } // Test cases for the AutoFill policy setting. -class ConfigurationPolicyPrefStoreAutoFillTest : public testing::Test { +class ConfigurationPolicyPrefStoreAutoFillTest + : public ConfigurationPolicyPrefStoreTestBase<testing::Test> { }; TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Default) { - ConfigurationPolicyPrefStore store(NULL); bool result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); + EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); } TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Enabled) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true)); + store_.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(true)); // Enabling AutoFill should not set the pref. bool result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); + EXPECT_FALSE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); } TEST_F(ConfigurationPolicyPrefStoreAutoFillTest, Disabled) { - ConfigurationPolicyPrefStore store(NULL); - store.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false)); + store_.Apply(kPolicyAutoFillEnabled, Value::CreateBooleanValue(false)); // Disabling AutoFill should switch the pref to managed. bool result = true; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); + EXPECT_TRUE(store_.prefs()->GetBoolean(prefs::kAutoFillEnabled, &result)); EXPECT_FALSE(result); } diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc index 2bebe5b..8fffb9c 100644 --- a/chrome/browser/prefs/command_line_pref_store.cc +++ b/chrome/browser/prefs/command_line_pref_store.cc @@ -34,24 +34,20 @@ const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry }; CommandLinePrefStore::CommandLinePrefStore(const CommandLine* command_line) - : command_line_(command_line), - prefs_(new DictionaryValue()) {} - -CommandLinePrefStore::~CommandLinePrefStore() {} - -PrefStore::PrefReadError CommandLinePrefStore::ReadPrefs() { + : command_line_(command_line) { ApplySimpleSwitches(); ValidateProxySwitches(); - return PrefStore::PREF_READ_ERROR_NONE; } +CommandLinePrefStore::~CommandLinePrefStore() {} + void CommandLinePrefStore::ApplySimpleSwitches() { // Look for each switch we know about and set its preference accordingly. for (size_t i = 0; i < arraysize(string_switch_map_); ++i) { if (command_line_->HasSwitch(string_switch_map_[i].switch_name)) { Value* value = Value::CreateStringValue(command_line_-> GetSwitchValueASCII(string_switch_map_[i].switch_name)); - prefs_->Set(string_switch_map_[i].preference_path, value); + SetValue(string_switch_map_[i].preference_path, value); } } @@ -59,7 +55,7 @@ void CommandLinePrefStore::ApplySimpleSwitches() { if (command_line_->HasSwitch(boolean_switch_map_[i].switch_name)) { Value* value = Value::CreateBooleanValue( boolean_switch_map_[i].set_value); - prefs_->Set(boolean_switch_map_[i].preference_path, value); + SetValue(boolean_switch_map_[i].preference_path, value); } } } diff --git a/chrome/browser/prefs/command_line_pref_store.h b/chrome/browser/prefs/command_line_pref_store.h index 2ea29ae..c3baf7a 100644 --- a/chrome/browser/prefs/command_line_pref_store.h +++ b/chrome/browser/prefs/command_line_pref_store.h @@ -9,21 +9,18 @@ #include "base/basictypes.h" #include "base/command_line.h" #include "base/scoped_ptr.h" -#include "chrome/common/pref_store.h" +#include "base/values.h" +#include "chrome/browser/prefs/value_map_pref_store.h" class DictionaryValue; // This PrefStore keeps track of preferences set by command-line switches, // such as proxy settings. -class CommandLinePrefStore : public PrefStore { +class CommandLinePrefStore : public ValueMapPrefStore { public: explicit CommandLinePrefStore(const CommandLine* command_line); virtual ~CommandLinePrefStore(); - // PrefStore methods: - virtual PrefReadError ReadPrefs(); - virtual DictionaryValue* prefs() const { return prefs_.get(); } - protected: // Logs a message and returns false if the proxy switches are // self-contradictory. Protected so it can be used in unit testing. @@ -51,8 +48,6 @@ class CommandLinePrefStore : public PrefStore { // Weak reference. const CommandLine* command_line_; - scoped_ptr<DictionaryValue> prefs_; - static const StringSwitchToPreferenceMapEntry string_switch_map_[]; DISALLOW_COPY_AND_ASSIGN(CommandLinePrefStore); diff --git a/chrome/browser/prefs/command_line_pref_store_unittest.cc b/chrome/browser/prefs/command_line_pref_store_unittest.cc index 064c7e6..031a7c9 100644 --- a/chrome/browser/prefs/command_line_pref_store_unittest.cc +++ b/chrome/browser/prefs/command_line_pref_store_unittest.cc @@ -34,10 +34,12 @@ TEST(CommandLinePrefStoreTest, SimpleStringPref) { CommandLine cl(CommandLine::NO_PROGRAM); cl.AppendSwitchASCII(switches::kLang, "hi-MOM"); CommandLinePrefStore store(&cl); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); + Value* actual = NULL; + EXPECT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kApplicationLocale, &actual)); std::string result; - EXPECT_TRUE(store.prefs()->GetString(prefs::kApplicationLocale, &result)); + EXPECT_TRUE(actual->GetAsString(&result)); EXPECT_EQ("hi-MOM", result); } @@ -46,10 +48,11 @@ TEST(CommandLinePrefStoreTest, SimpleBooleanPref) { CommandLine cl(CommandLine::NO_PROGRAM); cl.AppendSwitch(switches::kNoProxyServer); CommandLinePrefStore store(&cl); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); + Value* actual = NULL; + ASSERT_EQ(PrefStore::READ_OK, store.GetValue(prefs::kNoProxyServer, &actual)); bool result; - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &result)); + EXPECT_TRUE(actual->GetAsBoolean(&result)); EXPECT_TRUE(result); } @@ -59,15 +62,10 @@ TEST(CommandLinePrefStoreTest, NoPrefs) { cl.AppendSwitch(unknown_string); cl.AppendSwitchASCII(unknown_bool, "a value"); CommandLinePrefStore store(&cl); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); - bool bool_result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(unknown_bool, &bool_result)); - EXPECT_FALSE(bool_result); - - std::string string_result = ""; - EXPECT_FALSE(store.prefs()->GetString(unknown_string, &string_result)); - EXPECT_EQ("", string_result); + Value* actual = NULL; + EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_bool, &actual)); + EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_string, &actual)); } // Tests a complex command line with multiple known and unknown switches. @@ -79,21 +77,23 @@ TEST(CommandLinePrefStoreTest, MultipleSwitches) { cl.AppendSwitchASCII(switches::kProxyBypassList, "list"); cl.AppendSwitchASCII(unknown_bool, "a value"); CommandLinePrefStore store(&cl); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); + Value* actual = NULL; + EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_bool, &actual)); + ASSERT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kProxyAutoDetect, &actual)); bool bool_result = false; - EXPECT_FALSE(store.prefs()->GetBoolean(unknown_bool, &bool_result)); - EXPECT_FALSE(bool_result); - EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kProxyAutoDetect, &bool_result)); + EXPECT_TRUE(actual->GetAsBoolean(&bool_result)); EXPECT_TRUE(bool_result); + EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_string, &actual)); std::string string_result = ""; - EXPECT_FALSE(store.prefs()->GetString(unknown_string, &string_result)); - EXPECT_EQ("", string_result); - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyServer, &string_result)); + ASSERT_EQ(PrefStore::READ_OK, store.GetValue(prefs::kProxyServer, &actual)); + EXPECT_TRUE(actual->GetAsString(&string_result)); EXPECT_EQ("proxy", string_result); - EXPECT_TRUE(store.prefs()->GetString(prefs::kProxyBypassList, - &string_result)); + ASSERT_EQ(PrefStore::READ_OK, + store.GetValue(prefs::kProxyBypassList, &actual)); + EXPECT_TRUE(actual->GetAsString(&string_result)); EXPECT_EQ("list", string_result); } @@ -103,19 +103,16 @@ TEST(CommandLinePrefStoreTest, ProxySwitchValidation) { // No switches. TestCommandLinePrefStore store(&cl); - EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); EXPECT_TRUE(store.ProxySwitchesAreValid()); // Only no-proxy. cl.AppendSwitch(switches::kNoProxyServer); TestCommandLinePrefStore store2(&cl); - EXPECT_EQ(store2.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); EXPECT_TRUE(store2.ProxySwitchesAreValid()); // Another proxy switch too. cl.AppendSwitch(switches::kProxyAutoDetect); TestCommandLinePrefStore store3(&cl); - EXPECT_EQ(store3.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); EXPECT_FALSE(store3.ProxySwitchesAreValid()); // All proxy switches except no-proxy. @@ -125,6 +122,5 @@ TEST(CommandLinePrefStoreTest, ProxySwitchValidation) { cl2.AppendSwitchASCII(switches::kProxyPacUrl, "url"); cl2.AppendSwitchASCII(switches::kProxyBypassList, "list"); TestCommandLinePrefStore store4(&cl2); - EXPECT_EQ(store4.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE); EXPECT_TRUE(store4.ProxySwitchesAreValid()); } diff --git a/chrome/browser/prefs/default_pref_store.h b/chrome/browser/prefs/default_pref_store.h new file mode 100644 index 0000000..9e2e715 --- /dev/null +++ b/chrome/browser/prefs/default_pref_store.h @@ -0,0 +1,30 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREFS_DEFAULT_PREF_STORE_H_ +#define CHROME_BROWSER_PREFS_DEFAULT_PREF_STORE_H_ +#pragma once + +#include <map> + +#include "base/basictypes.h" +#include "chrome/browser/prefs/value_map_pref_store.h" + +// This PrefStore keeps track of default preference values set when a +// preference is registered with the PrefService. +class DefaultPrefStore : public ValueMapPrefStore { + public: + DefaultPrefStore() {} + virtual ~DefaultPrefStore() {} + + // Stores a new |value| for |key|. Assumes ownership of |value|. + void SetDefaultValue(const std::string& key, Value* value) { + SetValue(key, value); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultPrefStore); +}; + +#endif // CHROME_BROWSER_PREFS_DEFAULT_PREF_STORE_H_ diff --git a/chrome/browser/prefs/in_memory_pref_store.cc b/chrome/browser/prefs/in_memory_pref_store.cc deleted file mode 100644 index 1a2fcba..0000000 --- a/chrome/browser/prefs/in_memory_pref_store.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/prefs/in_memory_pref_store.h" - -#include "base/values.h" - -InMemoryPrefStore::InMemoryPrefStore() : prefs_(new DictionaryValue()) { -} - -InMemoryPrefStore::~InMemoryPrefStore() { -} - -DictionaryValue* InMemoryPrefStore::prefs() const { - return prefs_.get(); -} - -PrefStore::PrefReadError InMemoryPrefStore::ReadPrefs() { - return PrefStore::PREF_READ_ERROR_NONE; -} diff --git a/chrome/browser/prefs/in_memory_pref_store.h b/chrome/browser/prefs/in_memory_pref_store.h deleted file mode 100644 index 2558814..0000000 --- a/chrome/browser/prefs/in_memory_pref_store.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PREFS_IN_MEMORY_PREF_STORE_H_ -#define CHROME_BROWSER_PREFS_IN_MEMORY_PREF_STORE_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "chrome/common/pref_store.h" - -// This PrefStore keeps track of preference values in memory and can be used, -// e.g., for default preference values set when a preference is registered with -// the PrefService. -class InMemoryPrefStore : public PrefStore { - public: - InMemoryPrefStore(); - virtual ~InMemoryPrefStore(); - - // PrefStore methods: - virtual DictionaryValue* prefs() const; - virtual PrefStore::PrefReadError ReadPrefs(); - - private: - // The default preference values. - scoped_ptr<DictionaryValue> prefs_; - - DISALLOW_COPY_AND_ASSIGN(InMemoryPrefStore); -}; - -#endif // CHROME_BROWSER_PREFS_IN_MEMORY_PREF_STORE_H_ diff --git a/chrome/browser/prefs/pref_change_registrar_unittest.cc b/chrome/browser/prefs/pref_change_registrar_unittest.cc index 3310167..2e4cd0e 100644 --- a/chrome/browser/prefs/pref_change_registrar_unittest.cc +++ b/chrome/browser/prefs/pref_change_registrar_unittest.cc @@ -15,6 +15,8 @@ using testing::Mock; using testing::Eq; +namespace { + // A mock provider that allows us to capture pref observer changes. class MockPrefService : public TestingPrefService { public: @@ -25,6 +27,8 @@ class MockPrefService : public TestingPrefService { MOCK_METHOD2(RemovePrefObserver, void(const char*, NotificationObserver*)); }; +} // namespace + class PrefChangeRegistrarTest : public testing::Test { public: PrefChangeRegistrarTest() {} diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc index 524a858..4a3110c 100644 --- a/chrome/browser/prefs/pref_service.cc +++ b/chrome/browser/prefs/pref_service.cc @@ -23,7 +23,7 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/prefs/command_line_pref_store.h" -#include "chrome/browser/prefs/in_memory_pref_store.h" +#include "chrome/browser/prefs/default_pref_store.h" #include "chrome/browser/prefs/pref_notifier_impl.h" #include "chrome/browser/prefs/pref_value_store.h" #include "chrome/browser/profiles/profile.h" @@ -86,6 +86,7 @@ void NotifyReadError(PrefService* pref, int message_id) { // static PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, + PrefStore* extension_prefs, Profile* profile) { using policy::ConfigurationPolicyPrefStore; @@ -107,7 +108,6 @@ PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, ConfigurationPolicyPrefStore* device_management = ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( profile); - InMemoryPrefStore* extension = new InMemoryPrefStore(); CommandLinePrefStore* command_line = new CommandLinePrefStore(CommandLine::ForCurrentProcess()); JsonPrefStore* user = new JsonPrefStore( @@ -116,36 +116,26 @@ PrefService* PrefService::CreatePrefService(const FilePath& pref_filename, ConfigurationPolicyPrefStore* recommended = ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(); - return new PrefService(managed, device_management, extension, command_line, - user, recommended, profile); -} - -// static -PrefService* PrefService::CreateUserPrefService(const FilePath& pref_filename) { - JsonPrefStore* user = new JsonPrefStore( - pref_filename, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); - InMemoryPrefStore* extension = new InMemoryPrefStore(); - - return new PrefService(NULL, NULL, extension, NULL, user, NULL, NULL); + return new PrefService(managed, device_management, extension_prefs, + command_line, user, recommended, profile); } PrefService::PrefService(PrefStore* managed_platform_prefs, PrefStore* device_management_prefs, PrefStore* extension_prefs, PrefStore* command_line_prefs, - PrefStore* user_prefs, + PersistentPrefStore* user_prefs, PrefStore* recommended_prefs, - Profile* profile) { + Profile* profile) + : user_pref_store_(user_prefs) { pref_notifier_.reset(new PrefNotifierImpl(this)); - extension_store_ = extension_prefs; - default_store_ = new InMemoryPrefStore(); + default_store_ = new DefaultPrefStore(); pref_value_store_ = new PrefValueStore(managed_platform_prefs, device_management_prefs, - extension_store_, + extension_prefs, command_line_prefs, - user_prefs, + user_pref_store_, recommended_prefs, default_store_, pref_notifier_.get(), @@ -160,17 +150,18 @@ PrefService::~PrefService() { } void PrefService::InitFromStorage() { - PrefStore::PrefReadError error = LoadPersistentPrefs(); - if (error == PrefStore::PREF_READ_ERROR_NONE) + const PersistentPrefStore::PrefReadError error = + user_pref_store_->ReadPrefs(); + if (error == PersistentPrefStore::PREF_READ_ERROR_NONE) return; // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for // an example problem that this can cause. // Do some diagnosis and try to avoid losing data. int message_id = 0; - if (error <= PrefStore::PREF_READ_ERROR_JSON_TYPE) { + if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) { message_id = IDS_PREFERENCES_CORRUPT_ERROR; - } else if (error != PrefStore::PREF_READ_ERROR_NO_FILE) { + } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) { message_id = IDS_PREFERENCES_UNREADABLE_ERROR; } @@ -182,32 +173,20 @@ void PrefService::InitFromStorage() { } bool PrefService::ReloadPersistentPrefs() { - return (LoadPersistentPrefs() == PrefStore::PREF_READ_ERROR_NONE); -} - -PrefStore::PrefReadError PrefService::LoadPersistentPrefs() { - DCHECK(CalledOnValidThread()); - - PrefStore::PrefReadError pref_error = pref_value_store_->ReadPrefs(); - - for (PreferenceSet::iterator it = prefs_.begin(); - it != prefs_.end(); ++it) { - (*it)->pref_service_ = this; - } - - return pref_error; + return user_pref_store_->ReadPrefs() == + PersistentPrefStore::PREF_READ_ERROR_NONE; } bool PrefService::SavePersistentPrefs() { DCHECK(CalledOnValidThread()); - return pref_value_store_->WritePrefs(); + return user_pref_store_->WritePrefs(); } void PrefService::ScheduleSavePersistentPrefs() { DCHECK(CalledOnValidThread()); - pref_value_store_->ScheduleWritePrefs(); + user_pref_store_->ScheduleWritePrefs(); } void PrefService::RegisterBooleanPref(const char* path, @@ -361,17 +340,13 @@ const PrefService::Preference* PrefService::FindPreference( } bool PrefService::ReadOnly() const { - return pref_value_store_->ReadOnly(); + return user_pref_store_->ReadOnly(); } PrefNotifier* PrefService::pref_notifier() const { return pref_notifier_.get(); } -PrefStore* PrefService::GetExtensionPrefStore() { - return extension_store_; -} - bool PrefService::IsManagedPreference(const char* pref_name) const { const Preference* pref = FindPreference(pref_name); if (pref && pref->IsManaged()) { @@ -437,11 +412,10 @@ void PrefService::RegisterPreference(const char* path, Value* default_value) { // easier for callers to check for empty dict/list prefs. The PrefValueStore // accepts ownership of the value (null or default_value). if (Value::TYPE_LIST == orig_type || Value::TYPE_DICTIONARY == orig_type) { - default_store_->prefs()->Set(path, Value::CreateNullValue()); + default_store_->SetDefaultValue(path, Value::CreateNullValue()); } else { // Hand off ownership. - DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value)); - default_store_->prefs()->Set(path, scoped_value.release()); + default_store_->SetDefaultValue(path, scoped_value.release()); } pref_value_store_->RegisterPreferenceType(path, orig_type); @@ -456,7 +430,7 @@ void PrefService::ClearPref(const char* path) { NOTREACHED() << "Trying to clear an unregistered pref: " << path; return; } - pref_value_store_->RemoveUserPrefValue(path); + user_pref_store_->RemoveValue(path); } void PrefService::Set(const char* path, const Value& value) { @@ -473,13 +447,13 @@ void PrefService::Set(const char* path, const Value& value) { if (value.GetType() == Value::TYPE_NULL && (pref->GetType() == Value::TYPE_DICTIONARY || pref->GetType() == Value::TYPE_LIST)) { - pref_value_store_->RemoveUserPrefValue(path); + user_pref_store_->RemoveValue(path); } else if (pref->GetType() != value.GetType()) { NOTREACHED() << "Trying to set pref " << path << " of type " << pref->GetType() << " to value of type " << value.GetType(); } else { - pref_value_store_->SetUserPrefValue(path, value.DeepCopy()); + user_pref_store_->SetValue(path, value.DeepCopy()); } } @@ -555,10 +529,11 @@ DictionaryValue* PrefService::GetMutableDictionary(const char* path) { Value* tmp_value = NULL; // Look for an existing preference in the user store. If it doesn't // exist or isn't the correct type, create a new user preference. - if (!pref_value_store_->GetUserValue(path, &tmp_value) || + if (user_pref_store_->GetValue(path, &tmp_value) + != PersistentPrefStore::READ_OK || !tmp_value->IsType(Value::TYPE_DICTIONARY)) { dict = new DictionaryValue; - pref_value_store_->SetUserPrefValueSilently(path, dict); + user_pref_store_->SetValueSilently(path, dict); } else { dict = static_cast<DictionaryValue*>(tmp_value); } @@ -582,24 +557,17 @@ ListValue* PrefService::GetMutableList(const char* path) { Value* tmp_value = NULL; // Look for an existing preference in the user store. If it doesn't // exist or isn't the correct type, create a new user preference. - if (!pref_value_store_->GetUserValue(path, &tmp_value) || + if (user_pref_store_->GetValue(path, &tmp_value) + != PersistentPrefStore::READ_OK || !tmp_value->IsType(Value::TYPE_LIST)) { list = new ListValue; - pref_value_store_->SetUserPrefValueSilently(path, list); + user_pref_store_->SetValueSilently(path, list); } else { list = static_cast<ListValue*>(tmp_value); } return list; } -Value* PrefService::GetPrefCopy(const char* path) { - DCHECK(CalledOnValidThread()); - - const Preference* pref = FindPreference(path); - DCHECK(pref); - return pref->GetValue()->DeepCopy(); -} - void PrefService::SetUserPrefValue(const char* path, Value* new_value) { DCHECK(CalledOnValidThread()); @@ -608,10 +576,6 @@ void PrefService::SetUserPrefValue(const char* path, Value* new_value) { NOTREACHED() << "Trying to write an unregistered pref: " << path; return; } - if (pref->IsManaged()) { - NOTREACHED() << "Preference is managed: " << path; - return; - } if (pref->GetType() != new_value->GetType()) { NOTREACHED() << "Trying to set pref " << path << " of type " << pref->GetType() @@ -619,7 +583,7 @@ void PrefService::SetUserPrefValue(const char* path, Value* new_value) { return; } - pref_value_store_->SetUserPrefValue(path, new_value); + user_pref_store_->SetValue(path, new_value); } /////////////////////////////////////////////////////////////////////////////// @@ -651,8 +615,7 @@ const Value* PrefService::Preference::GetValue() const { } bool PrefService::Preference::IsManaged() const { - PrefValueStore* pref_value_store = - pref_service_->pref_value_store_; + PrefValueStore* pref_value_store = pref_service_->pref_value_store_; return pref_value_store->PrefValueInManagedPlatformStore(name_.c_str()) || pref_value_store->PrefValueInDeviceManagementStore(name_.c_str()); } diff --git a/chrome/browser/prefs/pref_service.h b/chrome/browser/prefs/pref_service.h index 18c70ed..04d7b91 100644 --- a/chrome/browser/prefs/pref_service.h +++ b/chrome/browser/prefs/pref_service.h @@ -15,14 +15,15 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/values.h" -#include "chrome/common/pref_store.h" class DefaultPrefStore; class FilePath; class NotificationObserver; +class PersistentPrefStore; class PrefChangeObserver; class PrefNotifier; class PrefNotifierImpl; +class PrefStore; class PrefValueStore; class Profile; @@ -101,16 +102,13 @@ class PrefService : public NonThreadSafe { // applicable PrefStores. The |pref_filename| points to the user preference // file. The |profile| is the one to which these preferences apply; it may be // NULL if we're dealing with the local state. This is the usual way to create - // a new PrefService. + // a new PrefService. |extension_pref_store| is used as the source for + // extension-controlled preferences and may be NULL. The PrefService takes + // ownership of |extension_pref_store|. static PrefService* CreatePrefService(const FilePath& pref_filename, + PrefStore* extension_pref_store, Profile* profile); - // Convenience factory method for use in unit tests. Creates a new - // PrefService that uses a PrefValueStore with user preferences at the given - // |pref_filename|, a default PrefStore, and no other PrefStores (i.e., no - // other types of preferences). - static PrefService* CreateUserPrefService(const FilePath& pref_filename); - virtual ~PrefService(); // Reloads the data from file. This should only be called when the importer @@ -223,9 +221,6 @@ class PrefService : public NonThreadSafe { // preference setter or use ScopedPrefUpdate. PrefNotifier* pref_notifier() const; - // Get the extension PrefStore. - PrefStore* GetExtensionPrefStore(); - protected: // Construct a new pref service, specifying the pref sources as explicit // PrefStore pointers. This constructor is what CreatePrefService() ends up @@ -234,7 +229,7 @@ class PrefService : public NonThreadSafe { PrefStore* device_management_prefs, PrefStore* extension_prefs, PrefStore* command_line_prefs, - PrefStore* user_prefs, + PersistentPrefStore* user_prefs, PrefStore* recommended_prefs, Profile* profile); @@ -244,7 +239,7 @@ class PrefService : public NonThreadSafe { scoped_ptr<PrefNotifierImpl> pref_notifier_; private: - friend class TestingPrefService; + friend class PrefServiceMockBuilder; // Registration of pref change observers must be done using the // PrefChangeRegistrar, which is declared as a friend here to grant it @@ -266,17 +261,10 @@ class PrefService : public NonThreadSafe { // false. This method takes ownership of |default_value|. void RegisterPreference(const char* path, Value* default_value); - // Returns a copy of the current pref value. The caller is responsible for - // deleting the returned object. - Value* GetPrefCopy(const char* pref_name); - // Sets the value for this pref path in the user pref store and informs the // PrefNotifier of the change. void SetUserPrefValue(const char* path, Value* new_value); - // Load from disk. Returns a non-zero error code on failure. - PrefStore::PrefReadError LoadPersistentPrefs(); - // Load preferences from storage, attempting to diagnose and handle errors. // This should only be called from the constructor. void InitFromStorage(); @@ -285,11 +273,11 @@ class PrefService : public NonThreadSafe { // and owned by this PrefService. Subclasses may access it for unit testing. scoped_refptr<PrefValueStore> pref_value_store_; - // The extension pref store registered with the PrefValueStore. - PrefStore* extension_store_; + // The persistent pref store used for actual user data. + PersistentPrefStore* user_pref_store_; // Points to the default pref store we passed to the PrefValueStore. - PrefStore* default_store_; + DefaultPrefStore* default_store_; // A set of all the registered Preference objects. PreferenceSet prefs_; diff --git a/chrome/browser/prefs/pref_service_mock_builder.cc b/chrome/browser/prefs/pref_service_mock_builder.cc new file mode 100644 index 0000000..3060948 --- /dev/null +++ b/chrome/browser/prefs/pref_service_mock_builder.cc @@ -0,0 +1,107 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/prefs/pref_service_mock_builder.h" + +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/policy/configuration_policy_pref_store.h" +#include "chrome/browser/prefs/command_line_pref_store.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/testing_pref_store.h" +#include "chrome/common/json_pref_store.h" + +PrefServiceMockBuilder::PrefServiceMockBuilder() + : user_prefs_(new TestingPrefStore), + profile_(NULL) { +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithManagedPlatformPrefs(PrefStore* store) { + managed_platform_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithDeviceManagementPrefs(PrefStore* store) { + device_management_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithExtensionPrefs(PrefStore* store) { + extension_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithCommandLinePrefs(PrefStore* store) { + command_line_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithUserPrefs(PersistentPrefStore* store) { + user_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithRecommendedPrefs(PrefStore* store) { + recommended_prefs_.reset(store); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithManagedPlatformProvider( + policy::ConfigurationPolicyProvider* provider) { + managed_platform_prefs_.reset( + new policy::ConfigurationPolicyPrefStore(provider)); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithDeviceManagementProvider( + policy::ConfigurationPolicyProvider* provider) { + device_management_prefs_.reset( + new policy::ConfigurationPolicyPrefStore(provider)); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithRecommendedProvider( + policy::ConfigurationPolicyProvider* provider) { + recommended_prefs_.reset( + new policy::ConfigurationPolicyPrefStore(provider)); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithCommandLine(CommandLine* command_line) { + command_line_prefs_.reset(new CommandLinePrefStore(command_line)); + return *this; +} + +PrefServiceMockBuilder& +PrefServiceMockBuilder::WithUserFilePrefs(const FilePath& prefs_file) { + user_prefs_.reset( + new JsonPrefStore(prefs_file, + BrowserThread::GetMessageLoopProxyForThread( + BrowserThread::FILE))); + return *this; +} + +PrefService* PrefServiceMockBuilder::Create() { + PrefService* pref_service = + new PrefService(managed_platform_prefs_.release(), + device_management_prefs_.release(), + extension_prefs_.release(), + command_line_prefs_.release(), + user_prefs_.release(), + recommended_prefs_.release(), + profile_); + user_prefs_.reset(new TestingPrefStore); + profile_ = NULL; + + return pref_service; +} diff --git a/chrome/browser/prefs/pref_service_mock_builder.h b/chrome/browser/prefs/pref_service_mock_builder.h new file mode 100644 index 0000000..c17040e --- /dev/null +++ b/chrome/browser/prefs/pref_service_mock_builder.h @@ -0,0 +1,69 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREFS_PREF_SERVICE_MOCK_BUILDER_H_ +#define CHROME_BROWSER_PREFS_PREF_SERVICE_MOCK_BUILDER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "chrome/common/persistent_pref_store.h" +#include "chrome/common/pref_store.h" + +class CommandLine; +class FilePath; +class PrefService; +class Profile; + +namespace policy { +class ConfigurationPolicyProvider; +} + +// A helper that allows convenient building of custom PrefServices in tests. +class PrefServiceMockBuilder { + public: + PrefServiceMockBuilder(); + + // Functions for setting the various parameters of the PrefService to build. + // These take ownership of the |store| parameter. + PrefServiceMockBuilder& WithManagedPlatformPrefs(PrefStore* store); + PrefServiceMockBuilder& WithDeviceManagementPrefs(PrefStore* store); + PrefServiceMockBuilder& WithExtensionPrefs(PrefStore* store); + PrefServiceMockBuilder& WithCommandLinePrefs(PrefStore* store); + PrefServiceMockBuilder& WithUserPrefs(PersistentPrefStore* store); + PrefServiceMockBuilder& WithRecommendedPrefs(PrefStore* store); + + // Set up policy pref stores using the given policy provider. + PrefServiceMockBuilder& WithManagedPlatformProvider( + policy::ConfigurationPolicyProvider* provider); + PrefServiceMockBuilder& WithDeviceManagementProvider( + policy::ConfigurationPolicyProvider* provider); + PrefServiceMockBuilder& WithRecommendedProvider( + policy::ConfigurationPolicyProvider* provider); + + // Specifies to use an actual command-line backed command-line pref store. + PrefServiceMockBuilder& WithCommandLine(CommandLine* command_line); + + // Specifies to use an actual file-backed user pref store. + PrefServiceMockBuilder& WithUserFilePrefs(const FilePath& prefs_file); + + // Sets the profile to pass to the PrefService. + PrefServiceMockBuilder& WithRecommendedPrefs(Profile* profile); + + // Creates the PrefService, invalidating the entire builder configuration. + PrefService* Create(); + + private: + scoped_ptr<PrefStore> managed_platform_prefs_; + scoped_ptr<PrefStore> device_management_prefs_; + scoped_ptr<PrefStore> extension_prefs_; + scoped_ptr<PrefStore> command_line_prefs_; + scoped_ptr<PersistentPrefStore> user_prefs_; + scoped_ptr<PrefStore> recommended_prefs_; + Profile* profile_; + + DISALLOW_COPY_AND_ASSIGN(PrefServiceMockBuilder); +}; + +#endif // CHROME_BROWSER_PREFS_PREF_SERVICE_MOCK_BUILDER_H_ diff --git a/chrome/browser/prefs/pref_service_unittest.cc b/chrome/browser/prefs/pref_service_unittest.cc index 6575bdf..8ada07a 100644 --- a/chrome/browser/prefs/pref_service_unittest.cc +++ b/chrome/browser/prefs/pref_service_unittest.cc @@ -12,10 +12,11 @@ #include "chrome/browser/policy/mock_configuration_policy_provider.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/prefs/command_line_pref_store.h" -#include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/browser/prefs/pref_observer_mock.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/browser/prefs/pref_value_store.h" +#include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" @@ -146,18 +147,6 @@ TEST(PrefServiceTest, Observers) { Mock::VerifyAndClearExpectations(&obs2); } -TEST(PrefServiceTest, ProxyFromCommandLineNotPolicy) { - CommandLine command_line(CommandLine::NO_PROGRAM); - command_line.AppendSwitch(switches::kProxyAutoDetect); - TestingPrefService prefs(NULL, NULL, &command_line); - browser::RegisterUserPrefs(&prefs); - EXPECT_TRUE(prefs.GetBoolean(prefs::kProxyAutoDetect)); - const PrefService::Preference* pref = - prefs.FindPreference(prefs::kProxyAutoDetect); - ASSERT_TRUE(pref); - EXPECT_FALSE(pref->IsManaged()); -} - TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) { CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kProxyBypassList, "123"); @@ -177,24 +166,28 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) { // First verify that command-line options are set correctly when // there is no policy in effect. - TestingPrefService prefs(NULL, NULL, &command_line); - browser::RegisterUserPrefs(&prefs); - EXPECT_FALSE(prefs.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ("789", prefs.GetString(prefs::kProxyServer)); - EXPECT_EQ("456", prefs.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ("123", prefs.GetString(prefs::kProxyBypassList)); + PrefServiceMockBuilder builder; + builder.WithCommandLine(&command_line); + scoped_ptr<PrefService> prefs(builder.Create()); + browser::RegisterUserPrefs(prefs.get()); + EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer)); + EXPECT_EQ("456", prefs->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ("123", prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the // manual proxy policy should have removed all traces of the command // line and replaced them with the policy versions. - TestingPrefService prefs2(provider.get(), NULL, &command_line); - browser::RegisterUserPrefs(&prefs2); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ("ghi", prefs2.GetString(prefs::kProxyServer)); - EXPECT_EQ("def", prefs2.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ("abc", prefs2.GetString(prefs::kProxyBypassList)); + builder.WithCommandLine(&command_line); + builder.WithManagedPlatformProvider(provider.get()); + scoped_ptr<PrefService> prefs2(builder.Create()); + browser::RegisterUserPrefs(prefs2.get()); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ("ghi", prefs2->GetString(prefs::kProxyServer)); + EXPECT_EQ("def", prefs2->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ("abc", prefs2->GetString(prefs::kProxyBypassList)); } TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) { @@ -210,25 +203,29 @@ TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) { // First verify that command-line options are set correctly when // there is no policy in effect. - TestingPrefService prefs(NULL, NULL, &command_line); - browser::RegisterUserPrefs(&prefs); - EXPECT_FALSE(prefs.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ("789", prefs.GetString(prefs::kProxyServer)); - EXPECT_EQ("456", prefs.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ("123", prefs.GetString(prefs::kProxyBypassList)); + PrefServiceMockBuilder builder; + builder.WithCommandLine(&command_line); + scoped_ptr<PrefService> prefs(builder.Create()); + browser::RegisterUserPrefs(prefs.get()); + EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer)); + EXPECT_EQ("456", prefs->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ("123", prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the // no proxy policy should have removed all traces of the command // line proxy settings, even though they were not the specific one // set in policy. - TestingPrefService prefs2(provider.get(), NULL, &command_line); - browser::RegisterUserPrefs(&prefs2); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyBypassList)); + builder.WithCommandLine(&command_line); + builder.WithManagedPlatformProvider(provider.get()); + scoped_ptr<PrefService> prefs2(builder.Create()); + browser::RegisterUserPrefs(prefs2.get()); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); } TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) { @@ -242,24 +239,28 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) { // First verify that command-line options are set correctly when // there is no policy in effect. - TestingPrefService prefs(NULL, NULL, &command_line); - browser::RegisterUserPrefs(&prefs); - EXPECT_FALSE(prefs.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_TRUE(prefs.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyServer)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyBypassList)); + PrefServiceMockBuilder builder; + builder.WithCommandLine(&command_line); + scoped_ptr<PrefService> prefs(builder.Create()); + browser::RegisterUserPrefs(prefs.get()); + EXPECT_FALSE(prefs->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_TRUE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyServer)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the // auto-detect should be overridden. The default pref store must be // in place with the appropriate default value for this to work. - TestingPrefService prefs2(provider.get(), NULL, &command_line); - browser::RegisterUserPrefs(&prefs2); - EXPECT_TRUE(prefs2.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyBypassList)); + builder.WithCommandLine(&command_line); + builder.WithManagedPlatformProvider(provider.get()); + scoped_ptr<PrefService> prefs2(builder.Create()); + browser::RegisterUserPrefs(prefs2.get()); + EXPECT_TRUE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); } TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) { @@ -273,24 +274,28 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) { // First verify that the auto-detect is set if there is no managed // PrefStore. - TestingPrefService prefs(NULL, NULL, &command_line); - browser::RegisterUserPrefs(&prefs); - EXPECT_TRUE(prefs.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_FALSE(prefs.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyServer)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ(std::string(), prefs.GetString(prefs::kProxyBypassList)); + PrefServiceMockBuilder builder; + builder.WithCommandLine(&command_line); + scoped_ptr<PrefService> prefs(builder.Create()); + browser::RegisterUserPrefs(prefs.get()); + EXPECT_TRUE(prefs->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_FALSE(prefs->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyServer)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs->GetString(prefs::kProxyBypassList)); // Try a second time time with the managed PrefStore in place, the // auto-detect should be overridden. The default pref store must be // in place with the appropriate default value for this to work. - TestingPrefService prefs2(provider.get(), NULL, &command_line); - browser::RegisterUserPrefs(&prefs2); - EXPECT_FALSE(prefs2.GetBoolean(prefs::kProxyAutoDetect)); - EXPECT_TRUE(prefs2.GetBoolean(prefs::kNoProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyServer)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyPacUrl)); - EXPECT_EQ(std::string(), prefs2.GetString(prefs::kProxyBypassList)); + builder.WithCommandLine(&command_line); + builder.WithManagedPlatformProvider(provider.get()); + scoped_ptr<PrefService> prefs2(builder.Create()); + browser::RegisterUserPrefs(prefs2.get()); + EXPECT_FALSE(prefs2->GetBoolean(prefs::kProxyAutoDetect)); + EXPECT_TRUE(prefs2->GetBoolean(prefs::kNoProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyServer)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl)); + EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyBypassList)); } class PrefServiceSetValueTest : public testing::Test { diff --git a/chrome/browser/prefs/pref_value_map.cc b/chrome/browser/prefs/pref_value_map.cc new file mode 100644 index 0000000..8d37f2b --- /dev/null +++ b/chrome/browser/prefs/pref_value_map.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/prefs/pref_value_map.h" + +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/stl_util-inl.h" +#include "base/values.h" + +PrefValueMap::~PrefValueMap() { + Clear(); +} + +bool PrefValueMap::GetValue(const std::string& key, Value** value) const { + const Map::const_iterator entry = prefs_.find(key); + if (entry != prefs_.end()) { + if (value) + *value = entry->second; + return true; + } + + return false; +} + +bool PrefValueMap::SetValue(const std::string& key, Value* value) { + DCHECK(value); + scoped_ptr<Value> value_ptr(value); + const Map::iterator entry = prefs_.find(key); + if (entry != prefs_.end()) { + if (Value::Equals(entry->second, value)) + return false; + delete entry->second; + entry->second = value_ptr.release(); + } else { + prefs_[key] = value_ptr.release(); + } + + return true; +} + +bool PrefValueMap::RemoveValue(const std::string& key) { + const Map::iterator entry = prefs_.find(key); + if (entry != prefs_.end()) { + delete entry->second; + prefs_.erase(entry); + return true; + } + + return false; +} + +void PrefValueMap::Clear() { + STLDeleteValues(&prefs_); + prefs_.clear(); +} diff --git a/chrome/browser/prefs/pref_value_map.h b/chrome/browser/prefs/pref_value_map.h new file mode 100644 index 0000000..26b6214 --- /dev/null +++ b/chrome/browser/prefs/pref_value_map.h @@ -0,0 +1,46 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREFS_PREF_VALUE_MAP_H_ +#define CHROME_BROWSER_PREFS_PREF_VALUE_MAP_H_ +#pragma once + +#include <map> +#include <string> + +#include "base/basictypes.h" + +class Value; + +// A generic string to value map used by the PrefStore implementations. +class PrefValueMap { + public: + PrefValueMap() {} + virtual ~PrefValueMap(); + + // Gets the value for |key| and stores it in |value|. Ownership remains with + // the map. Returns true if a value is present. If not, |value| is not + // touched. + bool GetValue(const std::string& key, Value** value) const; + + // Sets a new |value| for |key|. Takes ownership of |value|, which must be + // non-NULL. Returns true if the value changed. + bool SetValue(const std::string& key, Value* value); + + // Removes the value for |key| from the map. Returns true if a value was + // removed. + bool RemoveValue(const std::string& key); + + // Clears the map. + void Clear(); + + private: + typedef std::map<std::string, Value*> Map; + + Map prefs_; + + DISALLOW_COPY_AND_ASSIGN(PrefValueMap); +}; + +#endif // CHROME_BROWSER_PREFS_PREF_VALUE_MAP_H_ diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc index 3dcc813a..3ad6c44 100644 --- a/chrome/browser/prefs/pref_value_store.cc +++ b/chrome/browser/prefs/pref_value_store.cc @@ -52,9 +52,6 @@ PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, Profile* profile) : pref_notifier_(pref_notifier), profile_(profile) { - // NULL default pref store is usually bad, but may be OK for some unit tests. - if (!default_prefs) - LOG(WARNING) << "default pref store is null"; InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); InitPrefStore(EXTENSION_STORE, extension_prefs); @@ -85,11 +82,6 @@ bool PrefValueStore::GetValue(const std::string& name, return false; } -bool PrefValueStore::GetUserValue(const std::string& name, - Value** out_value) const { - return GetValueFromStore(name.c_str(), USER_STORE, out_value); -} - void PrefValueStore::RegisterPreferenceType(const std::string& name, Value::ValueType type) { pref_types_[name] = type; @@ -103,46 +95,6 @@ Value::ValueType PrefValueStore::GetRegisteredType( return found->second; } -bool PrefValueStore::WritePrefs() { - bool success = true; - for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { - PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); - if (store) - success = store->WritePrefs() && success; - } - return success; -} - -void PrefValueStore::ScheduleWritePrefs() { - for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { - PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); - if (store) - store->ScheduleWritePrefs(); - } -} - -PrefStore::PrefReadError PrefValueStore::ReadPrefs() { - PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE; - for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { - PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); - if (store) { - PrefStore::PrefReadError this_error = store->ReadPrefs(); - if (result == PrefStore::PREF_READ_ERROR_NONE) - result = this_error; - } - } - - if (HasPolicyConflictingUserProxySettings()) { - LOG(WARNING) << "user-requested proxy options have been overridden" - << " by a proxy configuration specified in a centrally" - << " administered policy."; - } - - // TODO(markusheintz): Return a better error status: maybe a struct with - // the error status of all PrefStores. - return result; -} - bool PrefValueStore::HasPrefPath(const char* path) const { Value* tmp_value = NULL; const std::string name(path); @@ -179,34 +131,6 @@ void PrefValueStore::NotifyPrefChanged( pref_notifier_->OnPreferenceChanged(path); } -void PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { - DCHECK(in_value); - Value* old_value = NULL; - GetPrefStore(USER_STORE)->prefs()->Get(name, &old_value); - bool value_changed = !old_value || !old_value->Equals(in_value); - GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); - - if (value_changed) - NotifyPrefChanged(name, USER_STORE); -} - -void PrefValueStore::SetUserPrefValueSilently(const char* name, - Value* in_value) { - DCHECK(in_value); - GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); -} - -bool PrefValueStore::ReadOnly() const { - return GetPrefStore(USER_STORE)->ReadOnly(); -} - -void PrefValueStore::RemoveUserPrefValue(const char* name) { - if (GetPrefStore(USER_STORE)) { - if (GetPrefStore(USER_STORE)->prefs()->Remove(name, NULL)) - NotifyPrefChanged(name, USER_STORE); - } -} - bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const { return PrefValueInStore(name, MANAGED_PLATFORM_STORE); } @@ -241,22 +165,6 @@ bool PrefValueStore::PrefValueUserModifiable(const char* name) const { effective_store == INVALID_STORE; } -bool PrefValueStore::HasPolicyConflictingUserProxySettings() const { - using policy::ConfigurationPolicyPrefStore; - ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs; - ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs); - ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i; - for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) { - if ((PrefValueInManagedPlatformStore(*i) || - PrefValueInDeviceManagementStore(*i)) && - PrefValueInStoreRange(*i, - COMMAND_LINE_STORE, - USER_STORE)) - return true; - } - return false; -} - // Returns true if the actual value is a valid type for the expected type when // found in the given store. bool PrefValueStore::IsValidType(Value::ValueType expected, @@ -316,25 +224,27 @@ bool PrefValueStore::GetValueFromStore(const char* name, // Only return true if we find a value and it is the correct type, so stale // values with the incorrect type will be ignored. const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type)); - if (store && store->prefs()->Get(name, out_value)) { - // If the value is the sentinel that redirects to the default store, - // re-fetch the value from the default store explicitly. Because the default - // values are not available when creating stores, the default value must be - // fetched dynamically for every redirect. - if (PrefStore::IsUseDefaultSentinelValue(*out_value)) { - store = GetPrefStore(DEFAULT_STORE); - if (!store || !store->prefs()->Get(name, out_value)) { - *out_value = NULL; - return false; - } - store_type = DEFAULT_STORE; - } - if (IsValidType(GetRegisteredType(name), - (*out_value)->GetType(), - store_type)) { - return true; + if (store) { + switch (store->GetValue(name, out_value)) { + case PrefStore::READ_USE_DEFAULT: + store = GetPrefStore(DEFAULT_STORE); + if (!store || store->GetValue(name, out_value) != PrefStore::READ_OK) { + *out_value = NULL; + return false; + } + // Fall through... + case PrefStore::READ_OK: + if (IsValidType(GetRegisteredType(name), + (*out_value)->GetType(), + store_type)) { + return true; + } + break; + case PrefStore::READ_NO_VALUE: + break; } } + // No valid value found for the given preference name: set the return false. *out_value = NULL; return false; @@ -342,37 +252,16 @@ bool PrefValueStore::GetValueFromStore(const char* name, void PrefValueStore::RefreshPolicyPrefsOnFileThread( BrowserThread::ID calling_thread_id, - PrefStore* new_managed_platform_pref_store, - PrefStore* new_device_management_pref_store, - PrefStore* new_recommended_pref_store) { + policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, + policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, + policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - scoped_ptr<PrefStore> managed_platform_pref_store( + scoped_ptr<policy::ConfigurationPolicyPrefStore> managed_platform_pref_store( new_managed_platform_pref_store); - scoped_ptr<PrefStore> device_management_pref_store( + scoped_ptr<policy::ConfigurationPolicyPrefStore> device_management_pref_store( new_device_management_pref_store); - scoped_ptr<PrefStore> recommended_pref_store(new_recommended_pref_store); - - PrefStore::PrefReadError read_error = - new_managed_platform_pref_store->ReadPrefs(); - if (read_error != PrefStore::PREF_READ_ERROR_NONE) { - LOG(ERROR) << "refresh of managed policy failed: PrefReadError = " - << read_error; - return; - } - - read_error = new_device_management_pref_store->ReadPrefs(); - if (read_error != PrefStore::PREF_READ_ERROR_NONE) { - LOG(ERROR) << "refresh of device management policy failed: " - << "PrefReadError = " << read_error; - return; - } - - read_error = new_recommended_pref_store->ReadPrefs(); - if (read_error != PrefStore::PREF_READ_ERROR_NONE) { - LOG(ERROR) << "refresh of recommended policy failed: PrefReadError = " - << read_error; - return; - } + scoped_ptr<policy::ConfigurationPolicyPrefStore> recommended_pref_store( + new_recommended_pref_store); BrowserThread::PostTask( calling_thread_id, FROM_HERE, @@ -392,12 +281,12 @@ void PrefValueStore::RefreshPolicyPrefs() { // created and the refreshed policy read into them. The new stores // are swapped with the old from a Task on the UI thread after the // load is complete. - PrefStore* new_managed_platform_pref_store( + ConfigurationPolicyPrefStore* new_managed_platform_pref_store( ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); - PrefStore* new_device_management_pref_store( + ConfigurationPolicyPrefStore* new_device_management_pref_store( ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( profile_)); - PrefStore* new_recommended_pref_store( + ConfigurationPolicyPrefStore* new_recommended_pref_store( ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); BrowserThread::ID current_thread_id; CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); @@ -412,27 +301,31 @@ void PrefValueStore::RefreshPolicyPrefs() { } void PrefValueStore::RefreshPolicyPrefsCompletion( - PrefStore* new_managed_platform_pref_store, - PrefStore* new_device_management_pref_store, - PrefStore* new_recommended_pref_store) { + policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, + policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, + policy::ConfigurationPolicyPrefStore* new_recommended_pref_store) { // Determine the paths of all the changed preferences values in the three // policy-related stores (managed platform, device management and // recommended). DictionaryValue* managed_platform_prefs_before( - GetPrefStore(MANAGED_PLATFORM_STORE)->prefs()); + static_cast<policy::ConfigurationPolicyPrefStore*>( + GetPrefStore(MANAGED_PLATFORM_STORE))->prefs()); DictionaryValue* managed_platform_prefs_after( new_managed_platform_pref_store->prefs()); DictionaryValue* device_management_prefs_before( - GetPrefStore(DEVICE_MANAGEMENT_STORE)->prefs()); + static_cast<policy::ConfigurationPolicyPrefStore*>( + GetPrefStore(DEVICE_MANAGEMENT_STORE))->prefs()); DictionaryValue* device_management_prefs_after( new_device_management_pref_store->prefs()); DictionaryValue* recommended_prefs_before( - GetPrefStore(RECOMMENDED_STORE)->prefs()); + static_cast<policy::ConfigurationPolicyPrefStore*>( + GetPrefStore(RECOMMENDED_STORE))->prefs()); DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); std::vector<std::string> changed_managed_platform_paths; - managed_platform_prefs_before->GetDifferingPaths(managed_platform_prefs_after, - &changed_managed_platform_paths); + managed_platform_prefs_before->GetDifferingPaths( + managed_platform_prefs_after, + &changed_managed_platform_paths); std::vector<std::string> changed_device_management_paths; device_management_prefs_before->GetDifferingPaths( @@ -440,8 +333,9 @@ void PrefValueStore::RefreshPolicyPrefsCompletion( &changed_device_management_paths); std::vector<std::string> changed_recommended_paths; - recommended_prefs_before->GetDifferingPaths(recommended_prefs_after, - &changed_recommended_paths); + recommended_prefs_before->GetDifferingPaths( + recommended_prefs_after, + &changed_recommended_paths); // Merge all three vectors of changed value paths together, filtering // duplicates in a post-processing step. diff --git a/chrome/browser/prefs/pref_value_store.h b/chrome/browser/prefs/pref_value_store.h index 1724bbc..fec16b4 100644 --- a/chrome/browser/prefs/pref_value_store.h +++ b/chrome/browser/prefs/pref_value_store.h @@ -26,6 +26,11 @@ class PrefNotifier; class PrefStore; class Profile; +// TODO(danno, mnissler): Remove after policy refresh cleanup. +namespace policy { +class ConfigurationPolicyPrefStore; +} + // The PrefValueStore manages various sources of values for Preferences // (e.g., configuration policies, extensions, and user settings). It returns // the value of a Preference from the source with the highest priority, and @@ -79,9 +84,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // Preference::GetValue() instead of calling this method directly. bool GetValue(const std::string& name, Value** out_value) const; - // Same as GetValue but only searches the user store. - bool GetUserValue(const std::string& name, Value** out_value) const; - // Adds a preference to the mapping of names to types. void RegisterPreferenceType(const std::string& name, Value::ValueType type); @@ -89,22 +91,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // Value::TYPE_NULL if the preference has never been registered. Value::ValueType GetRegisteredType(const std::string& name) const; - // Read preference values into the three PrefStores so that they are available - // through the GetValue method. Return the first error that occurs (but - // continue reading the remaining PrefStores). - PrefStore::PrefReadError ReadPrefs(); - - // Persists prefs (to disk or elsewhere). Returns true if writing values was - // successful. In practice, only the user prefs are expected to be written - // out. - // TODO(mnissler, danno): Handle writes through PrefService and remove. - bool WritePrefs(); - - // Calls the method ScheduleWritePrefs on the PrefStores. In practice, only - // the user prefs are expected to be written out. - // TODO(mnissler, danno): Handle writes through PrefService and remove. - void ScheduleWritePrefs(); - // Returns true if the PrefValueStore contains the given preference (i.e., // it's been registered), and a value with the correct type has been actively // set in some pref store. The application default specified when the pref was @@ -112,36 +98,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // store setting a value that happens to be equal to the default does. bool HasPrefPath(const char* name) const; - // Returns true if the PrefValueStore is read-only. Because the managed - // platform, device management and recommended PrefStores are always - // read-only, the PrefValueStore as a whole is read-only if the PrefStore - // containing the user preferences is read-only. - bool ReadOnly() const; - - // Alters the user-defined value of a preference. Even if the preference is - // managed this method allows the user-defined value of the preference to be - // set. However, GetValue calls will not return this value as long as the - // preference is overriden by a store of higher precedence. Note that the - // PrefValueStore takes the ownership of the value referenced by |in_value|. - // It is an error to call this when no user PrefStore has been set. Triggers - // notifications if the user-visible value changes. - // TODO(mnissler, danno): Handle writes in PrefService and notifications in - // the pref store implementation, so we can remove this call. - void SetUserPrefValue(const char* name, Value* in_value); - - // Like SetUserPrefValue, but silently puts the value without triggering - // notifications. - // TODO(mnissler, danno): Handle writes in PrefService and notifications in - // the pref store implementation, so we can remove this call. - void SetUserPrefValueSilently(const char* name, Value* in_value); - - // Removes a value from the user PrefStore. If a preference is overriden by a - // store of higher precedence, this function will have no immediately visible - // effect. Triggers notifications if the user-visible value changes. - // TODO(mnissler, danno): Handle writes in PrefService and notifications in - // the pref store implementation, so we can remove this call. - void RemoveUserPrefValue(const char* name); - // These methods return true if a preference with the given name is in the // indicated pref store, even if that value is currently being overridden by // a higher-priority source. @@ -161,11 +117,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // there is no higher-priority source controlling it. bool PrefValueUserModifiable(const char* name) const; - // Returns true if there are proxy preferences in user-modifiable - // preference stores (e.g. CommandLinePrefStore, ExtensionPrefStore) - // that conflict with proxy settings specified by proxy policy. - bool HasPolicyConflictingUserProxySettings() const; - private: // PrefStores must be listed here in order from highest to lowest priority. // MANAGED_PLATFORM contains all managed preference values that are @@ -196,7 +147,7 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // the PrefStore for changes, forwarding notifications to PrefValueStore. This // indirection is here for the sake of disambiguating notifications from the // individual PrefStores. - class PrefStoreKeeper : public PrefStore::ObserverInterface { + class PrefStoreKeeper : public PrefStore::Observer { public: PrefStoreKeeper(); virtual ~PrefStoreKeeper(); @@ -210,7 +161,7 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, const PrefStore* store() const { return pref_store_.get(); } private: - // PrefStore::ObserverInterface implementation. + // PrefStore::Observer implementation. virtual void OnPrefValueChanged(const std::string& key); virtual void OnInitializationCompleted(); @@ -228,11 +179,11 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, typedef std::map<std::string, Value::ValueType> PrefTypeMap; - friend class PrefValueStoreTest; - FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest, TestPolicyRefresh); - FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest, + friend class PrefValueStorePolicyRefreshTest; + FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh); + FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestRefreshPolicyPrefsCompletion); - FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest, + FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestConcurrentPolicyRefresh); // Returns true if the actual type is a valid type for the expected type when @@ -281,17 +232,17 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore>, // that initiated the policy refresh. RefreshPolicyPrefsCompletion takes // ownership of the |callback| object. void RefreshPolicyPrefsCompletion( - PrefStore* new_managed_platform_pref_store, - PrefStore* new_device_management_pref_store, - PrefStore* new_recommended_pref_store); + policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, + policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, + policy::ConfigurationPolicyPrefStore* new_recommended_pref_store); // Called during policy refresh to do the ReadPrefs on the FILE thread. // RefreshPolicyPrefsOnFileThread takes ownership of the |callback| object. void RefreshPolicyPrefsOnFileThread( BrowserThread::ID calling_thread_id, - PrefStore* new_managed_platform_pref_store, - PrefStore* new_device_management_pref_store, - PrefStore* new_recommended_pref_store); + policy::ConfigurationPolicyPrefStore* new_managed_platform_pref_store, + policy::ConfigurationPolicyPrefStore* new_device_management_pref_store, + policy::ConfigurationPolicyPrefStore* new_recommended_pref_store); // NotificationObserver methods: virtual void Observe(NotificationType type, diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc index 851a6bb..5649061 100644 --- a/chrome/browser/prefs/pref_value_store_unittest.cc +++ b/chrome/browser/prefs/pref_value_store_unittest.cc @@ -9,6 +9,7 @@ #include "base/values.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" +#include "chrome/browser/policy/dummy_configuration_policy_provider.h" #include "chrome/browser/prefs/pref_notifier.h" #include "chrome/browser/prefs/pref_value_store.h" #include "chrome/browser/prefs/testing_pref_store.h" @@ -23,23 +24,6 @@ using testing::Invoke; namespace { -// Records preference changes. -class PrefChangeRecorder { - public: - void Record(const std::string& pref_name) { - changed_prefs_.insert(pref_name); - } - - void Clear() { - changed_prefs_.clear(); - } - - const std::set<std::string>& changed_prefs() { return changed_prefs_; } - - private: - std::set<std::string> changed_prefs_; -}; - // Allows to capture pref notifications through gmock. class MockPrefNotifier : public PrefNotifier { public: @@ -151,91 +135,74 @@ class PrefValueStoreTest : public testing::Test { Value::TYPE_INTEGER); pref_value_store_->RegisterPreferenceType(prefs::kProxyAutoDetect, Value::TYPE_BOOLEAN); - - ui_thread_.reset(new BrowserThread(BrowserThread::UI, &loop_)); - file_thread_.reset(new BrowserThread(BrowserThread::FILE, &loop_)); } // Creates a new dictionary and stores some sample user preferences // in it. void CreateUserPrefs() { user_pref_store_ = new TestingPrefStore; - user_pref_store_->prefs()->SetBoolean(prefs::kDeleteCache, + user_pref_store_->SetBoolean(prefs::kDeleteCache, user_pref::kDeleteCacheValue); - user_pref_store_->prefs()->SetInteger(prefs::kStabilityLaunchCount, + user_pref_store_->SetInteger(prefs::kStabilityLaunchCount, user_pref::kStabilityLaunchCountValue); - user_pref_store_->prefs()->SetString(prefs::kCurrentThemeID, + user_pref_store_->SetString(prefs::kCurrentThemeID, user_pref::kCurrentThemeIDValue); - user_pref_store_->prefs()->SetString(prefs::kApplicationLocale, + user_pref_store_->SetString(prefs::kApplicationLocale, user_pref::kApplicationLocaleValue); - user_pref_store_->prefs()->SetString(prefs::kDefaultSearchProviderName, + user_pref_store_->SetString(prefs::kDefaultSearchProviderName, user_pref::kSearchProviderNameValue); - user_pref_store_->prefs()->SetString(prefs::kHomePage, + user_pref_store_->SetString(prefs::kHomePage, user_pref::kHomepageValue); } void CreateManagedPlatformPrefs() { managed_platform_pref_store_ = new TestingPrefStore; - managed_platform_pref_store_->prefs()->SetString( - prefs::kHomePage, + managed_platform_pref_store_->SetString(prefs::kHomePage, managed_platform_pref::kHomepageValue); - expected_differing_paths_.insert(prefs::kHomePage); } void CreateDeviceManagementPrefs() { device_management_pref_store_ = new TestingPrefStore; - device_management_pref_store_->prefs()->SetString( - prefs::kDefaultSearchProviderName, + device_management_pref_store_->SetString(prefs::kDefaultSearchProviderName, device_management_pref::kSearchProviderNameValue); - expected_differing_paths_.insert("default_search_provider"); - expected_differing_paths_.insert(prefs::kDefaultSearchProviderName); - device_management_pref_store_->prefs()->SetString(prefs::kHomePage, + device_management_pref_store_->SetString(prefs::kHomePage, device_management_pref::kHomepageValue); } void CreateExtensionPrefs() { extension_pref_store_ = new TestingPrefStore; - extension_pref_store_->prefs()->SetString(prefs::kCurrentThemeID, + extension_pref_store_->SetString(prefs::kCurrentThemeID, extension_pref::kCurrentThemeIDValue); - extension_pref_store_->prefs()->SetString(prefs::kHomePage, + extension_pref_store_->SetString(prefs::kHomePage, extension_pref::kHomepageValue); - extension_pref_store_->prefs()->SetString(prefs::kDefaultSearchProviderName, + extension_pref_store_->SetString(prefs::kDefaultSearchProviderName, extension_pref::kSearchProviderNameValue); } void CreateCommandLinePrefs() { command_line_pref_store_ = new TestingPrefStore; - command_line_pref_store_->prefs()->SetString(prefs::kCurrentThemeID, + command_line_pref_store_->SetString(prefs::kCurrentThemeID, command_line_pref::kCurrentThemeIDValue); - command_line_pref_store_->prefs()->SetString(prefs::kApplicationLocale, + command_line_pref_store_->SetString(prefs::kApplicationLocale, command_line_pref::kApplicationLocaleValue); - command_line_pref_store_->prefs()->SetString(prefs::kHomePage, + command_line_pref_store_->SetString(prefs::kHomePage, command_line_pref::kHomepageValue); - command_line_pref_store_->prefs()->SetString( - prefs::kDefaultSearchProviderName, + command_line_pref_store_->SetString(prefs::kDefaultSearchProviderName, command_line_pref::kSearchProviderNameValue); } void CreateRecommendedPrefs() { recommended_pref_store_ = new TestingPrefStore; - recommended_pref_store_->prefs()->SetInteger(prefs::kStabilityLaunchCount, + recommended_pref_store_->SetInteger(prefs::kStabilityLaunchCount, recommended_pref::kStabilityLaunchCountValue); - recommended_pref_store_->prefs()->SetBoolean( - prefs::kRecommendedPref, + recommended_pref_store_->SetBoolean(prefs::kRecommendedPref, recommended_pref::kRecommendedPrefValue); - - expected_differing_paths_.insert("this"); - expected_differing_paths_.insert("this.pref"); - expected_differing_paths_.insert(prefs::kRecommendedPref); - expected_differing_paths_.insert("user_experience_metrics"); - expected_differing_paths_.insert("user_experience_metrics.stability"); - expected_differing_paths_.insert(prefs::kStabilityLaunchCount); } void CreateDefaultPrefs() { default_pref_store_ = new TestingPrefStore; - default_pref_store_->prefs()->SetInteger(prefs::kDefaultPref, - default_pref::kDefaultValue); + default_pref_store_->SetInteger(prefs::kDefaultPref, + default_pref::kDefaultValue); } DictionaryValue* CreateSampleDictValue() { @@ -255,11 +222,6 @@ class PrefValueStoreTest : public testing::Test { return sample_list; } - virtual void TearDown() { - loop_.RunAllPending(); - } - - MessageLoop loop_; MockPrefNotifier pref_notifier_; scoped_refptr<PrefValueStore> pref_value_store_; @@ -271,31 +233,8 @@ class PrefValueStoreTest : public testing::Test { TestingPrefStore* user_pref_store_; TestingPrefStore* recommended_pref_store_; TestingPrefStore* default_pref_store_; - - // A vector of the preferences paths in the managed and recommended - // PrefStores that are set at the beginning of a test. Can be modified - // by the test to track changes that it makes to the preferences - // stored in the managed and recommended PrefStores. - std::set<std::string> expected_differing_paths_; - - private: - scoped_ptr<BrowserThread> ui_thread_; - scoped_ptr<BrowserThread> file_thread_; }; -TEST_F(PrefValueStoreTest, IsReadOnly) { - managed_platform_pref_store_->set_read_only(true); - extension_pref_store_->set_read_only(true); - command_line_pref_store_->set_read_only(true); - user_pref_store_->set_read_only(true); - recommended_pref_store_->set_read_only(true); - default_pref_store_->set_read_only(true); - EXPECT_TRUE(pref_value_store_->ReadOnly()); - - user_pref_store_->set_read_only(false); - EXPECT_FALSE(pref_value_store_->ReadOnly()); -} - TEST_F(PrefValueStoreTest, GetValue) { Value* value; @@ -368,8 +307,10 @@ TEST_F(PrefValueStoreTest, GetValue) { // Make sure that if a preference changes type, so the wrong type is stored in // the user pref file, it uses the correct fallback value instead. TEST_F(PrefValueStoreTest, GetValueChangedType) { + EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(AnyNumber()); + // Check falling back to a recommended value. - user_pref_store_->prefs()->SetString(prefs::kStabilityLaunchCount, + user_pref_store_->SetString(prefs::kStabilityLaunchCount, "not an integer"); Value* value = NULL; ASSERT_TRUE(pref_value_store_->GetValue(prefs::kStabilityLaunchCount, @@ -381,14 +322,14 @@ TEST_F(PrefValueStoreTest, GetValueChangedType) { EXPECT_EQ(recommended_pref::kStabilityLaunchCountValue, actual_int_value); // Check falling back multiple times, to a default string. - managed_platform_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - device_management_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - extension_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - command_line_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - user_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - recommended_pref_store_->prefs()->SetInteger(prefs::kHomePage, 1); - default_pref_store_->prefs()->SetString(prefs::kHomePage, - default_pref::kHomepageValue); + default_pref_store_->SetString(prefs::kHomePage, + default_pref::kHomepageValue); + managed_platform_pref_store_->SetInteger(prefs::kHomePage, 1); + device_management_pref_store_->SetInteger(prefs::kHomePage, 1); + extension_pref_store_->SetInteger(prefs::kHomePage, 1); + command_line_pref_store_->SetInteger(prefs::kHomePage, 1); + user_pref_store_->SetInteger(prefs::kHomePage, 1); + recommended_pref_store_->SetInteger(prefs::kHomePage, 1); value = NULL; ASSERT_TRUE(pref_value_store_->GetValue(prefs::kHomePage, &value)); @@ -419,18 +360,20 @@ TEST_F(PrefValueStoreTest, HasPrefPath) { TEST_F(PrefValueStoreTest, PrefChanges) { // Setup. + EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(AnyNumber()); const char managed_platform_pref_path[] = "managed_platform_pref"; pref_value_store_->RegisterPreferenceType(managed_platform_pref_path, Value::TYPE_STRING); - managed_platform_pref_store_->prefs()->SetString(managed_platform_pref_path, + managed_platform_pref_store_->SetString(managed_platform_pref_path, "managed value"); const char user_pref_path[] = "user_pref"; pref_value_store_->RegisterPreferenceType(user_pref_path, Value::TYPE_STRING); - user_pref_store_->prefs()->SetString(user_pref_path, "user value"); + user_pref_store_->SetString(user_pref_path, "user value"); const char default_pref_path[] = "default_pref"; pref_value_store_->RegisterPreferenceType(default_pref_path, Value::TYPE_STRING); - default_pref_store_->prefs()->SetString(default_pref_path, "default value"); + default_pref_store_->SetString(default_pref_path, "default value"); + Mock::VerifyAndClearExpectations(&pref_notifier_); // Check pref controlled by highest-priority store. EXPECT_CALL(pref_notifier_, OnPreferenceChanged(managed_platform_pref_path)); @@ -481,83 +424,6 @@ TEST_F(PrefValueStoreTest, OnInitializationCompleted) { Mock::VerifyAndClearExpectations(&pref_notifier_); } -TEST_F(PrefValueStoreTest, ReadPrefs) { - pref_value_store_->ReadPrefs(); - // The ReadPrefs method of the |TestingPrefStore| deletes the |pref_store|s - // internal dictionary and creates a new empty dictionary. Hence this - // dictionary does not contain any of the preloaded preferences. - // This shows that the ReadPrefs method of the |TestingPrefStore| was called. - EXPECT_FALSE(pref_value_store_->HasPrefPath(prefs::kDeleteCache)); -} - -TEST_F(PrefValueStoreTest, WritePrefs) { - user_pref_store_->set_prefs_written(false); - pref_value_store_->WritePrefs(); - ASSERT_TRUE(user_pref_store_->get_prefs_written()); -} - -TEST_F(PrefValueStoreTest, SetUserPrefValue) { - Value* new_value = NULL; - Value* actual_value = NULL; - - // Test that managed platform values can not be set. - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(0); - ASSERT_TRUE(pref_value_store_->PrefValueInManagedPlatformStore( - prefs::kHomePage)); - // The ownership is transfered to PrefValueStore. - new_value = Value::CreateStringValue("http://www.youtube.com"); - pref_value_store_->SetUserPrefValue(prefs::kHomePage, new_value); - Mock::VerifyAndClearExpectations(&pref_notifier_); - - ASSERT_TRUE(pref_value_store_->GetValue(prefs::kHomePage, &actual_value)); - std::string value_str; - actual_value->GetAsString(&value_str); - ASSERT_EQ(managed_platform_pref::kHomepageValue, value_str); - - // User preferences values can be set. - ASSERT_FALSE(pref_value_store_->PrefValueInManagedPlatformStore( - prefs::kStabilityLaunchCount)); - actual_value = NULL; - pref_value_store_->GetValue(prefs::kStabilityLaunchCount, &actual_value); - int int_value; - EXPECT_TRUE(actual_value->GetAsInteger(&int_value)); - EXPECT_EQ(user_pref::kStabilityLaunchCountValue, int_value); - - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(1); - new_value = Value::CreateIntegerValue(1); - pref_value_store_->SetUserPrefValue(prefs::kStabilityLaunchCount, new_value); - actual_value = NULL; - pref_value_store_->GetValue(prefs::kStabilityLaunchCount, &actual_value); - EXPECT_TRUE(new_value->Equals(actual_value)); - Mock::VerifyAndClearExpectations(&pref_notifier_); - - // Set and Get DictionaryValue. - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(1); - DictionaryValue* expected_dict_value = CreateSampleDictValue(); - pref_value_store_->SetUserPrefValue(prefs::kSampleDict, expected_dict_value); - Mock::VerifyAndClearExpectations(&pref_notifier_); - - actual_value = NULL; - std::string key(prefs::kSampleDict); - pref_value_store_->GetValue(key, &actual_value); - - ASSERT_EQ(expected_dict_value, actual_value); - ASSERT_TRUE(expected_dict_value->Equals(actual_value)); - - // Set and Get a ListValue. - EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(1); - ListValue* expected_list_value = CreateSampleListValue(); - pref_value_store_->SetUserPrefValue(prefs::kSampleList, expected_list_value); - Mock::VerifyAndClearExpectations(&pref_notifier_); - - actual_value = NULL; - key = prefs::kSampleList; - pref_value_store_->GetValue(key, &actual_value); - - ASSERT_EQ(expected_list_value, actual_value); - ASSERT_TRUE(expected_list_value->Equals(actual_value)); -} - TEST_F(PrefValueStoreTest, PrefValueInManagedPlatformStore) { // Test a managed platform preference. ASSERT_TRUE(pref_value_store_->HasPrefPath(prefs::kHomePage)); @@ -659,19 +525,6 @@ TEST_F(PrefValueStoreTest, PrefValueInExtensionStore) { prefs::kMissingPref)); } -TEST_F(PrefValueStoreTest, DetectProxyConfigurationConflict) { - // There should be no conflicting proxy prefs in the default - // preference stores created for the test. - ASSERT_FALSE(pref_value_store_->HasPolicyConflictingUserProxySettings()); - - // Create conflicting proxy settings in the managed and command-line - // preference stores. - command_line_pref_store_->prefs()->SetBoolean(prefs::kProxyAutoDetect, false); - managed_platform_pref_store_->prefs()->SetBoolean(prefs::kProxyAutoDetect, - true); - ASSERT_TRUE(pref_value_store_->HasPolicyConflictingUserProxySettings()); -} - TEST_F(PrefValueStoreTest, PrefValueInUserStore) { // Test a managed platform preference. ASSERT_TRUE(pref_value_store_->HasPrefPath(prefs::kHomePage)); @@ -767,7 +620,104 @@ TEST_F(PrefValueStoreTest, PrefValueFromDefaultStore) { pref_value_store_->PrefValueFromDefaultStore(prefs::kMissingPref)); } -TEST_F(PrefValueStoreTest, TestPolicyRefresh) { +// TODO(mnissler, danno): Clean this up when refactoring +// ConfigurationPolicyPrefStore. +class PrefValueStorePolicyRefreshTest : public testing::Test { + protected: + // Records preference changes. + class PrefChangeRecorder { + public: + void Record(const std::string& pref_name) { + changed_prefs_.insert(pref_name); + } + + void Clear() { + changed_prefs_.clear(); + } + + const std::set<std::string>& changed_prefs() { return changed_prefs_; } + + private: + std::set<std::string> changed_prefs_; + }; + + virtual void SetUp() { + using policy::ConfigurationPolicyPrefStore; + + ui_thread_.reset(new BrowserThread(BrowserThread::UI, &loop_)), + file_thread_.reset(new BrowserThread(BrowserThread::FILE, &loop_)), + policy_provider_.reset(new policy::DummyConfigurationPolicyProvider( + policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList())); + + ConfigurationPolicyPrefStore* managed_store = + NewConfigurationPolicyPrefStore(); + managed_store->prefs()->SetString(prefs::kHomePage, + managed_platform_pref::kHomepageValue); + expected_differing_paths_.insert(prefs::kHomePage); + + ConfigurationPolicyPrefStore* device_management_store = + NewConfigurationPolicyPrefStore(); + device_management_store->prefs()->SetString( + prefs::kDefaultSearchProviderName, + device_management_pref::kSearchProviderNameValue); + expected_differing_paths_.insert("default_search_provider"); + expected_differing_paths_.insert(prefs::kDefaultSearchProviderName); + + ConfigurationPolicyPrefStore* recommended_store = + NewConfigurationPolicyPrefStore(); + recommended_store->prefs()->SetInteger(prefs::kStabilityLaunchCount, + recommended_pref::kStabilityLaunchCountValue); + recommended_store->prefs()->SetBoolean(prefs::kRecommendedPref, + recommended_pref::kRecommendedPrefValue); + + expected_differing_paths_.insert("this"); + expected_differing_paths_.insert("this.pref"); + expected_differing_paths_.insert(prefs::kRecommendedPref); + expected_differing_paths_.insert("user_experience_metrics"); + expected_differing_paths_.insert("user_experience_metrics.stability"); + expected_differing_paths_.insert(prefs::kStabilityLaunchCount); + + pref_value_store_ = new PrefValueStore( + managed_store, + device_management_store, + NULL, + NULL, + new TestingPrefStore(), + recommended_store, + NULL, + &pref_notifier_, + NULL); + } + + virtual void TearDown() { + loop_.RunAllPending(); + pref_value_store_ = NULL; + file_thread_.reset(); + ui_thread_.reset(); + } + + // Creates a new ConfigurationPolicyPrefStore for testing. + policy::ConfigurationPolicyPrefStore* NewConfigurationPolicyPrefStore() { + return new policy::ConfigurationPolicyPrefStore(policy_provider_.get()); + } + + // A vector of the preferences paths in policy PrefStores that are set at the + // beginning of a test. Can be modified by the test to track changes that it + // makes to the preferences stored in the managed and recommended PrefStores. + std::set<std::string> expected_differing_paths_; + + MessageLoop loop_; + MockPrefNotifier pref_notifier_; + scoped_refptr<PrefValueStore> pref_value_store_; + + private: + scoped_ptr<BrowserThread> ui_thread_; + scoped_ptr<BrowserThread> file_thread_; + + scoped_ptr<policy::DummyConfigurationPolicyProvider> policy_provider_; +}; + +TEST_F(PrefValueStorePolicyRefreshTest, TestPolicyRefresh) { // pref_value_store_ is initialized by PrefValueStoreTest to have values in // the managed platform, device management and recommended stores. By // replacing them with dummy stores, all of the paths of the prefs originally @@ -782,7 +732,8 @@ TEST_F(PrefValueStoreTest, TestPolicyRefresh) { EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); } -TEST_F(PrefValueStoreTest, TestRefreshPolicyPrefsCompletion) { +TEST_F(PrefValueStorePolicyRefreshTest, TestRefreshPolicyPrefsCompletion) { + using policy::ConfigurationPolicyPrefStore; PrefChangeRecorder recorder; EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)) .WillRepeatedly(Invoke(&recorder, &PrefChangeRecorder::Record)); @@ -791,17 +742,16 @@ TEST_F(PrefValueStoreTest, TestRefreshPolicyPrefsCompletion) { // preferences in the recommended store. In addition to "homepage", the other // prefs that are set by default in the test class are removed by the // DummyStore. - scoped_ptr<TestingPrefStore> new_managed_platform_store( - new TestingPrefStore()); - DictionaryValue* dict = new DictionaryValue(); - dict->SetString("homepage", "some other changed homepage"); - new_managed_platform_store->set_prefs(dict); + scoped_ptr<ConfigurationPolicyPrefStore> new_managed_platform_store( + NewConfigurationPolicyPrefStore()); + new_managed_platform_store->prefs()->SetString("homepage", + "some other changed homepage"); recorder.Clear(); pref_value_store_->RefreshPolicyPrefsCompletion( new_managed_platform_store.release(), - new TestingPrefStore(), - new TestingPrefStore()); + NewConfigurationPolicyPrefStore(), + NewConfigurationPolicyPrefStore()); EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); // Test properties that have been removed from the managed platform store. @@ -811,47 +761,44 @@ TEST_F(PrefValueStoreTest, TestRefreshPolicyPrefsCompletion) { recorder.Clear(); pref_value_store_->RefreshPolicyPrefsCompletion( - new TestingPrefStore(), - new TestingPrefStore(), - new TestingPrefStore()); + NewConfigurationPolicyPrefStore(), + NewConfigurationPolicyPrefStore(), + NewConfigurationPolicyPrefStore()); EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); // Test properties that are added to the device management store. expected_differing_paths_.clear(); expected_differing_paths_.insert(prefs::kHomePage); - scoped_ptr<TestingPrefStore> new_device_management_store( - new TestingPrefStore()); - dict = new DictionaryValue(); - dict->SetString("homepage", "some other changed homepage"); - new_device_management_store->set_prefs(dict); + scoped_ptr<ConfigurationPolicyPrefStore> new_device_management_store( + NewConfigurationPolicyPrefStore()); + new_device_management_store->prefs()->SetString( + "homepage", "some other changed homepage"); recorder.Clear(); pref_value_store_->RefreshPolicyPrefsCompletion( - new TestingPrefStore(), + NewConfigurationPolicyPrefStore(), new_device_management_store.release(), - new TestingPrefStore()); + NewConfigurationPolicyPrefStore()); EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); // Test properties that are added to the recommended store. - scoped_ptr<TestingPrefStore> new_recommended_store(new TestingPrefStore()); - dict = new DictionaryValue(); - dict->SetString("homepage", "some other changed homepage 2"); - new_recommended_store->set_prefs(dict); + scoped_ptr<ConfigurationPolicyPrefStore> new_recommended_store( + NewConfigurationPolicyPrefStore()); + new_recommended_store->prefs()->SetString("homepage", + "some other changed homepage 2"); expected_differing_paths_.clear(); expected_differing_paths_.insert(prefs::kHomePage); recorder.Clear(); pref_value_store_->RefreshPolicyPrefsCompletion( - new TestingPrefStore(), - new TestingPrefStore(), + NewConfigurationPolicyPrefStore(), + NewConfigurationPolicyPrefStore(), new_recommended_store.release()); EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); // Test adding a multi-key path. - new_managed_platform_store.reset(new TestingPrefStore()); - dict = new DictionaryValue(); - dict->SetString("segment1.segment2", "value"); - new_managed_platform_store->set_prefs(dict); + new_managed_platform_store.reset(NewConfigurationPolicyPrefStore()); + new_managed_platform_store->prefs()->SetString("segment1.segment2", "value"); expected_differing_paths_.clear(); expected_differing_paths_.insert(prefs::kHomePage); expected_differing_paths_.insert("segment1"); @@ -860,12 +807,12 @@ TEST_F(PrefValueStoreTest, TestRefreshPolicyPrefsCompletion) { recorder.Clear(); pref_value_store_->RefreshPolicyPrefsCompletion( new_managed_platform_store.release(), - new TestingPrefStore(), - new TestingPrefStore()); + NewConfigurationPolicyPrefStore(), + NewConfigurationPolicyPrefStore()); EXPECT_EQ(expected_differing_paths_, recorder.changed_prefs()); } -TEST_F(PrefValueStoreTest, TestConcurrentPolicyRefresh) { +TEST_F(PrefValueStorePolicyRefreshTest, TestConcurrentPolicyRefresh) { PrefChangeRecorder recorder; EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)) .WillRepeatedly(Invoke(&recorder, &PrefChangeRecorder::Record)); diff --git a/chrome/browser/prefs/testing_pref_store.cc b/chrome/browser/prefs/testing_pref_store.cc index 5194737..39c20f2 100644 --- a/chrome/browser/prefs/testing_pref_store.cc +++ b/chrome/browser/prefs/testing_pref_store.cc @@ -7,14 +7,40 @@ #include "base/values.h" TestingPrefStore::TestingPrefStore() - : prefs_(new DictionaryValue()), - read_only_(true), + : read_only_(true), prefs_written_(false), init_complete_(false) { } -PrefStore::PrefReadError TestingPrefStore::ReadPrefs() { - prefs_.reset(new DictionaryValue()); - return PrefStore::PREF_READ_ERROR_NONE; +PrefStore::ReadResult TestingPrefStore::GetValue(const std::string& key, + Value** value) const { + return prefs_.GetValue(key, value) ? READ_OK : READ_NO_VALUE; +} + +void TestingPrefStore::AddObserver(PrefStore::Observer* observer) { + observers_.AddObserver(observer); +} + +void TestingPrefStore::RemoveObserver(PrefStore::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void TestingPrefStore::SetValue(const std::string& key, Value* value) { + if (prefs_.SetValue(key, value)) + NotifyPrefValueChanged(key); +} + +void TestingPrefStore::SetValueSilently(const std::string& key, Value* value) { + prefs_.SetValue(key, value); +} + +void TestingPrefStore::RemoveValue(const std::string& key) { + if (prefs_.RemoveValue(key)) + NotifyPrefValueChanged(key); +} + +PersistentPrefStore::PrefReadError TestingPrefStore::ReadPrefs() { + prefs_.Clear(); + return PersistentPrefStore::PREF_READ_ERROR_NONE; } bool TestingPrefStore::WritePrefs() { @@ -22,15 +48,53 @@ bool TestingPrefStore::WritePrefs() { return prefs_written_; } +void TestingPrefStore::SetInitializationCompleted() { + init_complete_ = true; + NotifyInitializationCompleted(); +} + void TestingPrefStore::NotifyPrefValueChanged(const std::string& key) { - PrefStoreBase::NotifyPrefValueChanged(key); + FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key)); } void TestingPrefStore::NotifyInitializationCompleted() { - PrefStoreBase::NotifyInitializationCompleted(); + FOR_EACH_OBSERVER(Observer, observers_, OnInitializationCompleted()); } -void TestingPrefStore::SetInitializationCompleted() { - init_complete_ = true; - NotifyInitializationCompleted(); +void TestingPrefStore::SetString(const std::string& key, + const std::string& value) { + SetValue(key, Value::CreateStringValue(value)); +} + +void TestingPrefStore::SetInteger(const std::string& key, int value) { + SetValue(key, Value::CreateIntegerValue(value)); +} + +void TestingPrefStore::SetBoolean(const std::string& key, bool value) { + SetValue(key, Value::CreateBooleanValue(value)); +} + +bool TestingPrefStore::GetString(const std::string& key, + std::string* value) const { + Value* stored_value; + if (!prefs_.GetValue(key, &stored_value) || !stored_value) + return false; + + return stored_value->GetAsString(value); +} + +bool TestingPrefStore::GetInteger(const std::string& key, int* value) const { + Value* stored_value; + if (!prefs_.GetValue(key, &stored_value) || !stored_value) + return false; + + return stored_value->GetAsInteger(value); +} + +bool TestingPrefStore::GetBoolean(const std::string& key, bool* value) const { + Value* stored_value; + if (!prefs_.GetValue(key, &stored_value) || !stored_value) + return false; + + return stored_value->GetAsBoolean(value); } diff --git a/chrome/browser/prefs/testing_pref_store.h b/chrome/browser/prefs/testing_pref_store.h index fe014f4..555ee69 100644 --- a/chrome/browser/prefs/testing_pref_store.h +++ b/chrome/browser/prefs/testing_pref_store.h @@ -7,46 +7,61 @@ #pragma once #include "base/basictypes.h" +#include "base/observer_list.h" #include "base/scoped_ptr.h" -#include "chrome/common/pref_store_base.h" +#include "chrome/browser/prefs/pref_value_map.h" +#include "chrome/common/persistent_pref_store.h" class DictionaryValue; -// |TestingPrefStore| is a stub implementation of the |PrefStore| interface. -// It allows to get and set the state of the |PrefStore| as well as triggering -// notifications. -class TestingPrefStore : public PrefStoreBase { +// |TestingPrefStore| is a preference store implementation that allows tests to +// explicitly manipulate the contents of the store, triggering notifications +// where appropriate. +class TestingPrefStore : public PersistentPrefStore { public: TestingPrefStore(); virtual ~TestingPrefStore() {} - virtual DictionaryValue* prefs() const { return prefs_.get(); } - - virtual PrefStore::PrefReadError ReadPrefs(); + // Overriden from PrefStore. + virtual ReadResult GetValue(const std::string& key, Value** result) const; + virtual void AddObserver(PrefStore::Observer* observer); + virtual void RemoveObserver(PrefStore::Observer* observer); + virtual bool IsInitializationComplete() const { return init_complete_; } + // PersistentPrefStore overrides: + virtual void SetValue(const std::string& key, Value* value); + virtual void SetValueSilently(const std::string& key, Value* value); + virtual void RemoveValue(const std::string& key); virtual bool ReadOnly() const { return read_only_; } - + virtual PersistentPrefStore::PrefReadError ReadPrefs(); virtual bool WritePrefs(); + virtual void ScheduleWritePrefs() {} + + // Marks the store as having completed initialization. + void SetInitializationCompleted(); + + // Used for tests to trigger notifications explicitly. + void NotifyPrefValueChanged(const std::string& key); + void NotifyInitializationCompleted(); + + // Some convenience getters/setters. + void SetString(const std::string& key, const std::string& value); + void SetInteger(const std::string& key, int value); + void SetBoolean(const std::string& key, bool value); + + bool GetString(const std::string& key, std::string* value) const; + bool GetInteger(const std::string& key, int* value) const; + bool GetBoolean(const std::string& key, bool* value) const; // Getter and Setter methods for setting and getting the state of the - // |DummyPrefStore|. + // |TestingPrefStore|. virtual void set_read_only(bool read_only) { read_only_ = read_only; } - virtual void set_prefs(DictionaryValue* prefs) { prefs_.reset(prefs); } virtual void set_prefs_written(bool status) { prefs_written_ = status; } virtual bool get_prefs_written() { return prefs_written_; } - // Publish these functions so testing code can call them. - virtual void NotifyPrefValueChanged(const std::string& key); - virtual void NotifyInitializationCompleted(); - - // Whether the store has completed all asynchronous initialization. - virtual bool IsInitializationComplete() { return init_complete_; } - - // Mark the store as having completed initialization. - void SetInitializationCompleted(); - private: - scoped_ptr<DictionaryValue> prefs_; + // Stores the preference values. + PrefValueMap prefs_; // Flag that indicates if the PrefStore is read-only bool read_only_; @@ -57,6 +72,8 @@ class TestingPrefStore : public PrefStoreBase { // Whether initialization has been completed. bool init_complete_; + ObserverList<PrefStore::Observer, true> observers_; + DISALLOW_COPY_AND_ASSIGN(TestingPrefStore); }; diff --git a/chrome/browser/prefs/value_map_pref_store.cc b/chrome/browser/prefs/value_map_pref_store.cc new file mode 100644 index 0000000..82574b2 --- /dev/null +++ b/chrome/browser/prefs/value_map_pref_store.cc @@ -0,0 +1,37 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/prefs/value_map_pref_store.h" + +#include <algorithm> + +#include "base/stl_util-inl.h" +#include "base/values.h" + +PrefStore::ReadResult ValueMapPrefStore::GetValue(const std::string& key, + Value** value) const { + return prefs_.GetValue(key, value) ? READ_OK : READ_NO_VALUE; +} + +void ValueMapPrefStore::AddObserver(PrefStore::Observer* observer) { + observers_.AddObserver(observer); +} + +void ValueMapPrefStore::RemoveObserver(PrefStore::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ValueMapPrefStore::SetValue(const std::string& key, Value* value) { + if (prefs_.SetValue(key, value)) + FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key)); +} + +void ValueMapPrefStore::RemoveValue(const std::string& key) { + if (prefs_.RemoveValue(key)) + FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key)); +} + +void ValueMapPrefStore::NotifyInitializationCompleted() { + FOR_EACH_OBSERVER(Observer, observers_, OnInitializationCompleted()); +} diff --git a/chrome/browser/prefs/value_map_pref_store.h b/chrome/browser/prefs/value_map_pref_store.h new file mode 100644 index 0000000..dbfba80 --- /dev/null +++ b/chrome/browser/prefs/value_map_pref_store.h @@ -0,0 +1,48 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PREFS_VALUE_MAP_PREF_STORE_H_ +#define CHROME_BROWSER_PREFS_VALUE_MAP_PREF_STORE_H_ +#pragma once + +#include <map> + +#include "base/basictypes.h" +#include "base/observer_list.h" +#include "chrome/browser/prefs/pref_value_map.h" +#include "chrome/common/pref_store.h" + +// A basic PrefStore implementation that uses a simple name-value map for +// storing the preference values. +class ValueMapPrefStore : public PrefStore { + public: + ValueMapPrefStore() {} + virtual ~ValueMapPrefStore() {} + + // PrefStore overrides: + virtual ReadResult GetValue(const std::string& key, Value** value) const; + virtual void AddObserver(PrefStore::Observer* observer); + virtual void RemoveObserver(PrefStore::Observer* observer); + + protected: + // Store a |value| for |key| in the store. Also generates an notification if + // the value changed. Assumes ownership of |value|, which must be non-NULL. + void SetValue(const std::string& key, Value* value); + + // Remove the value for |key| from the store. Sends a notification if there + // was a value to be removed. + void RemoveValue(const std::string& key); + + // Notify observers about the initialization completed event. + void NotifyInitializationCompleted(); + + private: + PrefValueMap prefs_; + + ObserverList<PrefStore::Observer, true> observers_; + + DISALLOW_COPY_AND_ASSIGN(ValueMapPrefStore); +}; + +#endif // CHROME_BROWSER_PREFS_VALUE_MAP_PREF_STORE_H_ diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 7913da1..20c8166 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -35,6 +35,7 @@ #include "chrome/browser/extensions/extension_info_map.h" #include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/extensions/extension_message_service.h" +#include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" @@ -277,12 +278,6 @@ ProfileImpl::ProfileImpl(const FilePath& path) pref_change_registrar_.Add(prefs::kEnableAutoSpellCorrect, this); pref_change_registrar_.Add(prefs::kClearSiteDataOnExit, this); - // Ensure that preferences set by extensions are restored in the profile - // as early as possible. The constructor takes care of that. - extension_prefs_.reset(new ExtensionPrefs( - GetPrefs(), - GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName))); - // Convert active labs into switches. Modifies the current command line. about_flags::ConvertFlagsToSwitches(prefs, CommandLine::ForCurrentProcess()); @@ -671,7 +666,9 @@ net::TransportSecurityState* PrefService* ProfileImpl::GetPrefs() { if (!prefs_.get()) { + ExtensionPrefStore* extension_pref_store = new ExtensionPrefStore; prefs_.reset(PrefService::CreatePrefService(GetPrefFilePath(), + extension_pref_store, GetOriginalProfile())); // The Profile class and ProfileManager class may read some prefs so @@ -688,6 +685,13 @@ PrefService* ProfileImpl::GetPrefs() { // Make sure we save to disk that the session has opened. prefs_->ScheduleSavePersistentPrefs(); + // Ensure that preferences set by extensions are restored in the profile + // as early as possible. The constructor takes care of that. + extension_prefs_.reset(new ExtensionPrefs( + prefs_.get(), + GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName), + extension_pref_store)); + DCHECK(!net_pref_observer_.get()); net_pref_observer_.reset(new NetPrefObserver(prefs_.get())); } diff --git a/chrome/browser/search_engines/keyword_editor_controller_unittest.cc b/chrome/browser/search_engines/keyword_editor_controller_unittest.cc index e29373e..df49cf0 100644 --- a/chrome/browser/search_engines/keyword_editor_controller_unittest.cc +++ b/chrome/browser/search_engines/keyword_editor_controller_unittest.cc @@ -68,19 +68,19 @@ class KeywordEditorControllerTest : public testing::Test, void SimulateDefaultSearchIsManaged(const std::string& url) { ASSERT_FALSE(url.empty()); TestingPrefService* service = profile_->GetTestingPrefService(); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderEnabled, Value::CreateBooleanValue(true)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderSearchURL, Value::CreateStringValue(url)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderName, Value::CreateStringValue("managed")); // Clear the IDs that are not specified via policy. - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderID, new StringValue("")); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderPrepopulateID, new StringValue("")); model_->Observe( NotificationType::PREF_CHANGED, diff --git a/chrome/browser/search_engines/search_provider_install_data_unittest.cc b/chrome/browser/search_engines/search_provider_install_data_unittest.cc index 0165578..28bcd47 100644 --- a/chrome/browser/search_engines/search_provider_install_data_unittest.cc +++ b/chrome/browser/search_engines/search_provider_install_data_unittest.cc @@ -190,19 +190,19 @@ class SearchProviderInstallDataTest : public testing::Test { void SimulateDefaultSearchIsManaged(const std::string& url) { ASSERT_FALSE(url.empty()); TestingPrefService* service = util_.profile()->GetTestingPrefService(); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderEnabled, Value::CreateBooleanValue(true)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderSearchURL, Value::CreateStringValue(url)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderName, Value::CreateStringValue("managed")); // Clear the IDs that are not specified via policy. - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderID, new StringValue("")); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderPrepopulateID, new StringValue("")); util_.model()->Observe( NotificationType::PREF_CHANGED, diff --git a/chrome/browser/search_engines/template_url_model.cc b/chrome/browser/search_engines/template_url_model.cc index 96fe656..917e57b 100644 --- a/chrome/browser/search_engines/template_url_model.cc +++ b/chrome/browser/search_engines/template_url_model.cc @@ -844,12 +844,12 @@ bool TemplateURLModel::LoadDefaultSearchProviderFromPrefs( std::vector<std::string> encodings_vector; base::SplitString(encodings, ';', &encodings_vector); (*default_provider)->set_input_encodings(encodings_vector); - if (!id_string.empty()) { + if (!id_string.empty() && !*is_managed) { int64 value; base::StringToInt64(id_string, &value); (*default_provider)->set_id(value); } - if (!prepopulate_id.empty()) { + if (!prepopulate_id.empty() && !*is_managed) { int value; base::StringToInt(prepopulate_id, &value); (*default_provider)->set_prepopulate_id(value); @@ -1258,4 +1258,3 @@ void TemplateURLModel::NotifyObservers() { FOR_EACH_OBSERVER(TemplateURLModelObserver, model_observers_, OnTemplateURLModelChanged()); } - diff --git a/chrome/browser/search_engines/template_url_model_test_util.cc b/chrome/browser/search_engines/template_url_model_test_util.cc index 52a6c91..e6ebc8d 100644 --- a/chrome/browser/search_engines/template_url_model_test_util.cc +++ b/chrome/browser/search_engines/template_url_model_test_util.cc @@ -167,9 +167,8 @@ void TemplateURLModelTestUtil::OnTemplateURLModelChanged() { changed_count_++; } -void TemplateURLModelTestUtil::VerifyObserverCount(int expected_changed_count) { - ASSERT_EQ(expected_changed_count, changed_count_); - changed_count_ = 0; +int TemplateURLModelTestUtil::GetObserverCount() { + return changed_count_; } void TemplateURLModelTestUtil::ResetObserverCount() { @@ -188,7 +187,8 @@ void TemplateURLModelTestUtil::VerifyLoad() { ASSERT_FALSE(model()->loaded()); model()->Load(); BlockTillServiceProcessesRequests(); - VerifyObserverCount(1); + EXPECT_EQ(1, GetObserverCount()); + ResetObserverCount(); } void TemplateURLModelTestUtil::ChangeModelToLoadState() { diff --git a/chrome/browser/search_engines/template_url_model_test_util.h b/chrome/browser/search_engines/template_url_model_test_util.h index 3921b44..058b64b 100644 --- a/chrome/browser/search_engines/template_url_model_test_util.h +++ b/chrome/browser/search_engines/template_url_model_test_util.h @@ -40,8 +40,8 @@ class TemplateURLModelTestUtil : public TemplateURLModelObserver { // TemplateURLModelObserver implemementation. virtual void OnTemplateURLModelChanged(); - // Checks that the observer count is what is expected. - void VerifyObserverCount(int expected_changed_count); + // Gets the observer count. + int GetObserverCount(); // Sets the observer count to 0. void ResetObserverCount(); diff --git a/chrome/browser/search_engines/template_url_model_unittest.cc b/chrome/browser/search_engines/template_url_model_unittest.cc index 15c4b12..f0465ae 100644 --- a/chrome/browser/search_engines/template_url_model_unittest.cc +++ b/chrome/browser/search_engines/template_url_model_unittest.cc @@ -194,58 +194,51 @@ class TemplateURLModelTest : public testing::Test { const char* encodings, const char* keyword) { TestingPrefService* service = profile()->GetTestingPrefService(); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderEnabled, Value::CreateBooleanValue(enabled)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderName, Value::CreateStringValue(name)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderSearchURL, Value::CreateStringValue(search_url)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderSuggestURL, Value::CreateStringValue(suggest_url)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderIconURL, Value::CreateStringValue(icon_url)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderEncodings, Value::CreateStringValue(encodings)); - service->SetManagedPrefWithoutNotification( + service->SetManagedPref( prefs::kDefaultSearchProviderKeyword, Value::CreateStringValue(keyword)); - // Clear the IDs that are not specified via policy. - service->SetManagedPrefWithoutNotification( - prefs::kDefaultSearchProviderID, new StringValue("")); - service->SetManagedPrefWithoutNotification( - prefs::kDefaultSearchProviderPrepopulateID, new StringValue("")); - NotifyManagedPrefsHaveChanged(); } // Remove all the managed preferences for the default search provider and // trigger notification. void RemoveManagedDefaultSearchPreferences() { TestingPrefService* service = profile()->GetTestingPrefService(); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( + prefs::kDefaultSearchProviderSearchURL); + service->RemoveManagedPref( prefs::kDefaultSearchProviderEnabled); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderName); - service->RemoveManagedPrefWithoutNotification( - prefs::kDefaultSearchProviderSearchURL); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderSuggestURL); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderIconURL); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderEncodings); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderKeyword); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderID); - service->RemoveManagedPrefWithoutNotification( + service->RemoveManagedPref( prefs::kDefaultSearchProviderPrepopulateID); - NotifyManagedPrefsHaveChanged(); } // Creates a TemplateURL with the same prepopluated id as a real prepopulated @@ -264,7 +257,12 @@ class TemplateURLModelTest : public testing::Test { // Helper methods to make calling TemplateURLModelTestUtil methods less // visually noisy in the test code. void VerifyObserverCount(int expected_changed_count) { - test_util_.VerifyObserverCount(expected_changed_count); + EXPECT_EQ(expected_changed_count, test_util_.GetObserverCount()); + test_util_.ResetObserverCount(); + } + void VerifyObserverFired() { + EXPECT_LE(1, test_util_.GetObserverCount()); + test_util_.ResetObserverCount(); } void BlockTillServiceProcessesRequests() { TemplateURLModelTestUtil::BlockTillServiceProcessesRequests(); @@ -1113,7 +1111,7 @@ TEST_F(TemplateURLModelTest, TestManagedDefaultSearch) { const char kEncodings[] = "UTF-16;UTF-32"; SetManagedDefaultSearchPreferences(true, kName, kSearchURL, "", kIconURL, kEncodings, ""); - VerifyObserverCount(1); + VerifyObserverFired(); EXPECT_TRUE(model()->is_default_search_managed()); EXPECT_EQ(2 + initial_count, model()->GetTemplateURLs().size()); @@ -1137,7 +1135,7 @@ TEST_F(TemplateURLModelTest, TestManagedDefaultSearch) { const char kNewSuggestURL[] = "http://other.com/suggest?t={searchTerms}"; SetManagedDefaultSearchPreferences(true, kNewName, kNewSearchURL, kNewSuggestURL, "", "", ""); - VerifyObserverCount(1); + VerifyObserverFired(); EXPECT_TRUE(model()->is_default_search_managed()); EXPECT_EQ(2 + initial_count, model()->GetTemplateURLs().size()); @@ -1153,7 +1151,7 @@ TEST_F(TemplateURLModelTest, TestManagedDefaultSearch) { // Remove all the managed prefs and check that we are no longer managed. RemoveManagedDefaultSearchPreferences(); - VerifyObserverCount(1); + VerifyObserverFired(); EXPECT_FALSE(model()->is_default_search_managed()); EXPECT_EQ(1 + initial_count, model()->GetTemplateURLs().size()); @@ -1166,7 +1164,7 @@ TEST_F(TemplateURLModelTest, TestManagedDefaultSearch) { // Disable the default search provider through policy. SetManagedDefaultSearchPreferences(false, "", "", "", "", "", ""); - VerifyObserverCount(1); + VerifyObserverFired(); EXPECT_TRUE(model()->is_default_search_managed()); EXPECT_TRUE(NULL == model()->GetDefaultSearchProvider()); EXPECT_EQ(1 + initial_count, model()->GetTemplateURLs().size()); @@ -1174,7 +1172,7 @@ TEST_F(TemplateURLModelTest, TestManagedDefaultSearch) { // Re-enable it. SetManagedDefaultSearchPreferences(true, kName, kSearchURL, "", kIconURL, kEncodings, ""); - VerifyObserverCount(1); + VerifyObserverFired(); EXPECT_TRUE(model()->is_default_search_managed()); EXPECT_EQ(2 + initial_count, model()->GetTemplateURLs().size()); diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm index ac00647..298711e 100644 --- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller_unittest.mm @@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/message_loop.h" #include "base/scoped_nsobject.h" +#include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extensions_service.h" @@ -26,8 +28,10 @@ class ExtensionTestingProfile : public TestingProfile { DCHECK(!GetExtensionsService()); manager_.reset(ExtensionProcessManager::Create(this)); + ExtensionPrefStore* pref_store = new ExtensionPrefStore; extension_prefs_.reset(new ExtensionPrefs(GetPrefs(), - GetExtensionsInstallDir())); + GetExtensionsInstallDir(), + pref_store)); service_ = new ExtensionsService(this, CommandLine::ForCurrentProcess(), GetExtensionsInstallDir(), |