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 | |
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
67 files changed, 1525 insertions, 1205 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(), diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 8cc41a9..177b175 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1132,6 +1132,8 @@ 'service/service_main.cc', 'service/service_process.cc', 'service/service_process.h', + 'service/service_process_prefs.cc', + 'service/service_process_prefs.h', 'service/service_utility_process_host.cc', 'service/service_utility_process_host.h', 'service/cloud_print/cloud_print_consts.cc', diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index a5bb572..d0368ad 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1113,6 +1113,8 @@ 'browser/extensions/extension_page_actions_module_constants.h', 'browser/extensions/extension_popup_api.cc', 'browser/extensions/extension_popup_api.h', + 'browser/extensions/extension_pref_store.h', + 'browser/extensions/extension_pref_store.cc', 'browser/extensions/extension_prefs.cc', 'browser/extensions/extension_prefs.h', 'browser/extensions/extension_process_manager.cc', @@ -1996,8 +1998,7 @@ 'browser/prefs/browser_prefs.h', 'browser/prefs/command_line_pref_store.cc', 'browser/prefs/command_line_pref_store.h', - 'browser/prefs/in_memory_pref_store.cc', - 'browser/prefs/in_memory_pref_store.h', + 'browser/prefs/default_pref_store.h', 'browser/prefs/pref_member.cc', 'browser/prefs/pref_member.h', 'browser/prefs/pref_notifier.h', @@ -2009,12 +2010,16 @@ 'browser/prefs/pref_service.h', 'browser/prefs/pref_set_observer.cc', 'browser/prefs/pref_set_observer.h', + 'browser/prefs/pref_value_map.cc', + 'browser/prefs/pref_value_map.h', 'browser/prefs/pref_value_store.cc', 'browser/prefs/pref_value_store.h', 'browser/prefs/scoped_pref_update.cc', 'browser/prefs/scoped_pref_update.h', 'browser/prefs/session_startup_pref.cc', 'browser/prefs/session_startup_pref.h', + 'browser/prefs/value_map_pref_store.cc', + 'browser/prefs/value_map_pref_store.h', 'browser/prerender/prerender_contents.cc', 'browser/prerender/prerender_contents.h', 'browser/prerender/prerender_interceptor.cc', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 2575f06..b3b26ec 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -286,10 +286,8 @@ 'common/plugin_messages.cc', 'common/plugin_messages.h', 'common/plugin_messages_internal.h', - 'common/pref_store.cc', + 'common/persistent_pref_store.h', 'common/pref_store.h', - 'common/pref_store_base.cc', - 'common/pref_store_base.h', 'common/render_messages.cc', 'common/render_messages.h', 'common/render_messages_internal.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index b1da7ad..41d3af9 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -64,6 +64,8 @@ 'browser/net/url_request_mock_net_error_job.cc', 'browser/net/url_request_mock_net_error_job.h', 'browser/prefs/pref_observer_mock.h', + 'browser/prefs/pref_service_mock_builder.cc', + 'browser/prefs/pref_service_mock_builder.h', 'browser/prefs/testing_pref_store.cc', 'browser/prefs/testing_pref_store.h', 'browser/renderer_host/mock_render_process_host.cc', diff --git a/chrome/common/json_pref_store.cc b/chrome/common/json_pref_store.cc index d68307f..bbf33d7 100644 --- a/chrome/common/json_pref_store.cc +++ b/chrome/common/json_pref_store.cc @@ -30,7 +30,46 @@ JsonPrefStore::~JsonPrefStore() { writer_.DoScheduledWrite(); } -PrefStore::PrefReadError JsonPrefStore::ReadPrefs() { +PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, + Value** result) const { + return prefs_->Get(key, result) ? READ_OK : READ_NO_VALUE; +} + +void JsonPrefStore::AddObserver(PrefStore::Observer* observer) { + observers_.AddObserver(observer); +} + +void JsonPrefStore::RemoveObserver(PrefStore::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void JsonPrefStore::SetValue(const std::string& key, Value* value) { + DCHECK(value); + scoped_ptr<Value> new_value(value); + Value* old_value = NULL; + prefs_->Get(key, &old_value); + if (!old_value || !value->Equals(old_value)) { + prefs_->Set(key, new_value.release()); + FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); + } +} + +void JsonPrefStore::SetValueSilently(const std::string& key, Value* value) { + DCHECK(value); + scoped_ptr<Value> new_value(value); + Value* old_value = NULL; + prefs_->Get(key, &old_value); + if (!old_value || !value->Equals(old_value)) + prefs_->Set(key, new_value.release()); +} + +void JsonPrefStore::RemoveValue(const std::string& key) { + if (prefs_->Remove(key, NULL)) { + FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); + } +} + +PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { if (path_.empty()) { read_only_ = true; return PREF_READ_ERROR_FILE_NOT_SPECIFIED; diff --git a/chrome/common/json_pref_store.h b/chrome/common/json_pref_store.h index 44f5c8c..a97985d 100644 --- a/chrome/common/json_pref_store.h +++ b/chrome/common/json_pref_store.h @@ -8,9 +8,12 @@ #include <string> +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/observer_list.h" #include "base/scoped_ptr.h" -#include "chrome/common/pref_store.h" #include "chrome/common/important_file_writer.h" +#include "chrome/common/persistent_pref_store.h" namespace base { class MessageLoopProxy; @@ -18,8 +21,10 @@ class MessageLoopProxy; class DictionaryValue; class FilePath; +class Value; -class JsonPrefStore : public PrefStore, +// A writable PrefStore implementation that is used for user preferences. +class JsonPrefStore : public PersistentPrefStore, public ImportantFileWriter::DataSerializer { public: // |file_message_loop_proxy| is the MessageLoopProxy for a thread on which @@ -28,21 +33,24 @@ class JsonPrefStore : public PrefStore, base::MessageLoopProxy* file_message_loop_proxy); virtual ~JsonPrefStore(); - // PrefStore methods: - virtual bool ReadOnly() const { return read_only_; } - - virtual DictionaryValue* prefs() const { return prefs_.get(); } + // PrefStore overrides: + virtual ReadResult GetValue(const std::string& key, Value** result) const; + virtual void AddObserver(PrefStore::Observer* observer); + virtual void RemoveObserver(PrefStore::Observer* observer); + // 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 PrefReadError ReadPrefs(); - virtual bool WritePrefs(); - virtual void ScheduleWritePrefs(); - // ImportantFileWriter::DataSerializer methods: - virtual bool SerializeData(std::string* data); - private: + // ImportantFileWriter::DataSerializer overrides: + bool SerializeData(std::string* output); + FilePath path_; scoped_ptr<DictionaryValue> prefs_; @@ -51,6 +59,10 @@ class JsonPrefStore : public PrefStore, // Helper for safely writing pref data. ImportantFileWriter writer_; + + ObserverList<PrefStore::Observer, true> observers_; + + DISALLOW_COPY_AND_ASSIGN(JsonPrefStore); }; #endif // CHROME_COMMON_JSON_PREF_STORE_H_ diff --git a/chrome/common/json_pref_store_unittest.cc b/chrome/common/json_pref_store_unittest.cc index e38aba2..326e32d 100644 --- a/chrome/common/json_pref_store_unittest.cc +++ b/chrome/common/json_pref_store_unittest.cc @@ -54,9 +54,9 @@ TEST_F(JsonPrefStoreTest, NonExistentFile) { FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); ASSERT_FALSE(file_util::PathExists(bogus_input_file)); JsonPrefStore pref_store(bogus_input_file, message_loop_proxy_.get()); - EXPECT_EQ(PrefStore::PREF_READ_ERROR_NO_FILE, pref_store.ReadPrefs()); + EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, + pref_store.ReadPrefs()); EXPECT_FALSE(pref_store.ReadOnly()); - EXPECT_TRUE(pref_store.prefs()->empty()); } // Test fallback behavior for an invalid file. @@ -65,9 +65,9 @@ TEST_F(JsonPrefStoreTest, InvalidFile) { FilePath invalid_file = test_dir_.AppendASCII("invalid.json"); ASSERT_TRUE(file_util::CopyFile(invalid_file_original, invalid_file)); JsonPrefStore pref_store(invalid_file, message_loop_proxy_.get()); - EXPECT_EQ(PrefStore::PREF_READ_ERROR_JSON_PARSE, pref_store.ReadPrefs()); + EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, + pref_store.ReadPrefs()); EXPECT_FALSE(pref_store.ReadOnly()); - EXPECT_TRUE(pref_store.prefs()->empty()); // The file should have been moved aside. EXPECT_FALSE(file_util::PathExists(invalid_file)); @@ -85,9 +85,8 @@ TEST_F(JsonPrefStoreTest, Basic) { FilePath input_file = test_dir_.AppendASCII("write.json"); ASSERT_TRUE(file_util::PathExists(input_file)); JsonPrefStore pref_store(input_file, message_loop_proxy_.get()); - ASSERT_EQ(PrefStore::PREF_READ_ERROR_NONE, pref_store.ReadPrefs()); + ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store.ReadPrefs()); ASSERT_FALSE(pref_store.ReadOnly()); - DictionaryValue* prefs = pref_store.prefs(); // The JSON file looks like this: // { @@ -105,38 +104,55 @@ TEST_F(JsonPrefStoreTest, Basic) { std::string cnn("http://www.cnn.com"); + Value* actual; + EXPECT_EQ(PrefStore::READ_OK, + pref_store.GetValue(prefs::kHomePage, &actual)); std::string string_value; - EXPECT_TRUE(prefs->GetString(prefs::kHomePage, &string_value)); + EXPECT_TRUE(actual->GetAsString(&string_value)); EXPECT_EQ(cnn, string_value); const char kSomeDirectory[] = "some_directory"; + EXPECT_EQ(PrefStore::READ_OK, pref_store.GetValue(kSomeDirectory, &actual)); FilePath::StringType path; - EXPECT_TRUE(prefs->GetString(kSomeDirectory, &path)); + EXPECT_TRUE(actual->GetAsString(&path)); EXPECT_EQ(FilePath::StringType(FILE_PATH_LITERAL("/usr/local/")), path); FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/")); - prefs->SetString(kSomeDirectory, some_path.value()); - EXPECT_TRUE(prefs->GetString(kSomeDirectory, &path)); + + pref_store.SetValue(kSomeDirectory, + Value::CreateStringValue(some_path.value())); + EXPECT_EQ(PrefStore::READ_OK, pref_store.GetValue(kSomeDirectory, &actual)); + EXPECT_TRUE(actual->GetAsString(&path)); EXPECT_EQ(some_path.value(), path); // Test reading some other data types from sub-dictionaries. - bool boolean; - EXPECT_TRUE(prefs->GetBoolean(kNewWindowsInTabs, &boolean)); + EXPECT_EQ(PrefStore::READ_OK, + pref_store.GetValue(kNewWindowsInTabs, &actual)); + bool boolean = false; + EXPECT_TRUE(actual->GetAsBoolean(&boolean)); EXPECT_TRUE(boolean); - prefs->SetBoolean(kNewWindowsInTabs, false); - EXPECT_TRUE(prefs->GetBoolean(kNewWindowsInTabs, &boolean)); + pref_store.SetValue(kNewWindowsInTabs, + Value::CreateBooleanValue(false)); + EXPECT_EQ(PrefStore::READ_OK, + pref_store.GetValue(kNewWindowsInTabs, &actual)); + EXPECT_TRUE(actual->GetAsBoolean(&boolean)); EXPECT_FALSE(boolean); - int integer; - EXPECT_TRUE(prefs->GetInteger(kMaxTabs, &integer)); + EXPECT_EQ(PrefStore::READ_OK, pref_store.GetValue(kMaxTabs, &actual)); + int integer = 0; + EXPECT_TRUE(actual->GetAsInteger(&integer)); EXPECT_EQ(20, integer); - prefs->SetInteger(kMaxTabs, 10); - EXPECT_TRUE(prefs->GetInteger(kMaxTabs, &integer)); + pref_store.SetValue(kMaxTabs, Value::CreateIntegerValue(10)); + EXPECT_EQ(PrefStore::READ_OK, pref_store.GetValue(kMaxTabs, &actual)); + EXPECT_TRUE(actual->GetAsInteger(&integer)); EXPECT_EQ(10, integer); - prefs->SetString(kLongIntPref, base::Int64ToString(214748364842LL)); - EXPECT_TRUE(prefs->GetString(kLongIntPref, &string_value)); + pref_store.SetValue(kLongIntPref, + Value::CreateStringValue( + base::Int64ToString(214748364842LL))); + EXPECT_EQ(PrefStore::READ_OK, pref_store.GetValue(kLongIntPref, &actual)); + EXPECT_TRUE(actual->GetAsString(&string_value)); int64 value; base::StringToInt64(string_value, &value); EXPECT_EQ(214748364842LL, value); diff --git a/chrome/common/persistent_pref_store.h b/chrome/common/persistent_pref_store.h new file mode 100644 index 0000000..9e2fb0a --- /dev/null +++ b/chrome/common/persistent_pref_store.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_COMMON_PERSISTENT_PREF_STORE_H_ +#define CHROME_COMMON_PERSISTENT_PREF_STORE_H_ +#pragma once + +#include <string> + +#include <chrome/common/pref_store.h> + +// This interface is complementary to the PrefStore interface, declaring +// additional functionatliy that adds support for setting values and persisting +// the data to some backing store. +class PersistentPrefStore : public PrefStore { + public: + virtual ~PersistentPrefStore() {} + + // Unique integer code for each type of error so we can report them + // distinctly in a histogram. + // NOTE: Don't change the order here as it will change the server's meaning + // of the histogram. + enum PrefReadError { + PREF_READ_ERROR_NONE = 0, + PREF_READ_ERROR_JSON_PARSE, + PREF_READ_ERROR_JSON_TYPE, + PREF_READ_ERROR_ACCESS_DENIED, + PREF_READ_ERROR_FILE_OTHER, + PREF_READ_ERROR_FILE_LOCKED, + PREF_READ_ERROR_NO_FILE, + PREF_READ_ERROR_JSON_REPEAT, + PREF_READ_ERROR_OTHER, + PREF_READ_ERROR_FILE_NOT_SPECIFIED + }; + + // Sets a |value| for |key| in the store. Assumes ownership of |value|, which + // must be non-NULL. + virtual void SetValue(const std::string& key, Value* value) = 0; + + // Same as SetValue, but doesn't generate notifications. This is used by + // GetMutableDictionary() and GetMutableList() in order to put empty entries + // into the user pref store. Using SetValue is not an option since existing + // tests rely on the number of notifications generated. + // + // TODO(mnissler, danno): Can we replace GetMutableDictionary() and + // GetMutableList() with something along the lines of ScopedPrefUpdate that + // updates the value in the end? + virtual void SetValueSilently(const std::string& key, Value* value) = 0; + + // Removes the value for |key|. + virtual void RemoveValue(const std::string& key) = 0; + + // Whether the store is in a pseudo-read-only mode where changes are not + // actually persisted to disk. This happens in some cases when there are + // read errors during startup. + virtual bool ReadOnly() const = 0; + + // Reads the preferences from disk. + virtual PrefReadError ReadPrefs() = 0; + + // Writes the preferences to disk immediately. + virtual bool WritePrefs() = 0; + + // Schedules an asynchronous write operation. + virtual void ScheduleWritePrefs() = 0; +}; + +#endif // CHROME_COMMON_PERSISTENT_PREF_STORE_H_ diff --git a/chrome/common/pref_store.cc b/chrome/common/pref_store.cc deleted file mode 100644 index cf85417..0000000 --- a/chrome/common/pref_store.cc +++ /dev/null @@ -1,14 +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/common/pref_store.h" -#include "base/values.h" - -Value* PrefStore::CreateUseDefaultSentinelValue() { - return Value::CreateNullValue(); -} - -bool PrefStore::IsUseDefaultSentinelValue(Value* value) { - return value->IsType(Value::TYPE_NULL); -} diff --git a/chrome/common/pref_store.h b/chrome/common/pref_store.h index 808ffbd2..745eff7 100644 --- a/chrome/common/pref_store.h +++ b/chrome/common/pref_store.h @@ -10,7 +10,6 @@ #include "base/basictypes.h" -class DictionaryValue; class Value; // This is an abstract interface for reading and writing from/to a persistent @@ -23,9 +22,9 @@ class Value; class PrefStore { public: // Observer interface for monitoring PrefStore. - class ObserverInterface { + class Observer { public: - virtual ~ObserverInterface() {} + virtual ~Observer() {} // Called when the value for the given |key| in the store changes. virtual void OnPrefValueChanged(const std::string& key) = 0; @@ -33,61 +32,30 @@ class PrefStore { virtual void OnInitializationCompleted() = 0; }; - // Unique integer code for each type of error so we can report them - // distinctly in a histogram. - // NOTE: Don't change the order here as it will change the server's meaning - // of the histogram. - enum PrefReadError { - PREF_READ_ERROR_NONE = 0, - PREF_READ_ERROR_JSON_PARSE, - PREF_READ_ERROR_JSON_TYPE, - PREF_READ_ERROR_ACCESS_DENIED, - PREF_READ_ERROR_FILE_OTHER, - PREF_READ_ERROR_FILE_LOCKED, - PREF_READ_ERROR_NO_FILE, - PREF_READ_ERROR_JSON_REPEAT, - PREF_READ_ERROR_OTHER, - PREF_READ_ERROR_FILE_NOT_SPECIFIED + // Return values for GetValue(). + enum ReadResult { + // Value found and returned. + READ_OK, + // No value present, but skip other pref stores and use default. + READ_USE_DEFAULT, + // No value present. + READ_NO_VALUE, }; - // To require that the default value be used for a preference, a - // PrefStore can set the value in its own prefs dictionary to the - // sentinel Value returned by this function. - // TODO(danno): Instead of having a sentinel value, pref stores - // should return a richer set of information from the property - // accessor methods to indicate that the default should be used. - static Value* CreateUseDefaultSentinelValue(); - - // Returns true if a value is the special sentinel value created by - // CreateUseDefaultSentinelValue. - static bool IsUseDefaultSentinelValue(Value* value); - PrefStore() {} virtual ~PrefStore() {} // Add and remove observers. - virtual void AddObserver(ObserverInterface* observer) {} - virtual void RemoveObserver(ObserverInterface* observer) {} + virtual void AddObserver(Observer* observer) {} + virtual void RemoveObserver(Observer* observer) {} // Whether the store has completed all asynchronous initialization. - virtual bool IsInitializationComplete() { return true; } - - // Whether the store is in a pseudo-read-only mode where changes are not - // actually persisted to disk. This happens in some cases when there are - // read errors during startup. - virtual bool ReadOnly() const { return true; } - - // TODO(danno): PrefValueStore shouldn't allow direct access to the - // DictionaryValue. Instead, it should have getters that return a - // richer set of information for a pref, including if the store - // wants to return the default value for a preference. - virtual DictionaryValue* prefs() const = 0; - - virtual PrefReadError ReadPrefs() = 0; - - virtual bool WritePrefs() { return true; } + virtual bool IsInitializationComplete() const { return true; } - virtual void ScheduleWritePrefs() { } + // Get the value for a given preference |key| and stores it in |result|. + // |result| is only modified if the return value is READ_OK. Ownership of the + // |result| value remains with the PrefStore. + virtual ReadResult GetValue(const std::string& key, Value** result) const = 0; DISALLOW_COPY_AND_ASSIGN(PrefStore); }; diff --git a/chrome/common/pref_store_base.cc b/chrome/common/pref_store_base.cc deleted file mode 100644 index 07f79ff..0000000 --- a/chrome/common/pref_store_base.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/common/pref_store_base.h" - -void PrefStoreBase::AddObserver(PrefStore::ObserverInterface* observer) { - observers_.AddObserver(observer); -} - -void PrefStoreBase::RemoveObserver(PrefStore::ObserverInterface* observer) { - observers_.RemoveObserver(observer); -} - -void PrefStoreBase::NotifyPrefValueChanged(const std::string& key) { - FOR_EACH_OBSERVER(ObserverInterface, observers_, OnPrefValueChanged(key)); -} - -void PrefStoreBase::NotifyInitializationCompleted() { - FOR_EACH_OBSERVER(ObserverInterface, observers_, OnInitializationCompleted()); -} diff --git a/chrome/common/pref_store_base.h b/chrome/common/pref_store_base.h deleted file mode 100644 index 3c9f37c..0000000 --- a/chrome/common/pref_store_base.h +++ /dev/null @@ -1,33 +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_COMMON_PREF_STORE_BASE_H_ -#define CHROME_COMMON_PREF_STORE_BASE_H_ -#pragma once - -#include "base/observer_list.h" -#include "chrome/common/pref_store.h" - -// Implements the observer-related bits of the PrefStore interface. This is -// provided as a convenience for PrefStore implementations to derive from. -class PrefStoreBase : public PrefStore { - public: - virtual ~PrefStoreBase() {} - - // Overriden from PrefStore. - virtual void AddObserver(ObserverInterface* observer); - virtual void RemoveObserver(ObserverInterface* observer); - - protected: - // Send a notification about a changed preference value. - virtual void NotifyPrefValueChanged(const std::string& key); - - // Notify observers about initialization being complete. - virtual void NotifyInitializationCompleted(); - - private: - ObserverList<ObserverInterface, true> observers_; -}; - -#endif // CHROME_COMMON_PREF_STORE_BASE_H_ diff --git a/chrome/service/cloud_print/cloud_print_proxy.cc b/chrome/service/cloud_print/cloud_print_proxy.cc index 4141b2d..d2fb73c 100644 --- a/chrome/service/cloud_print/cloud_print_proxy.cc +++ b/chrome/service/cloud_print/cloud_print_proxy.cc @@ -10,10 +10,10 @@ #include "base/values.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" -#include "chrome/common/json_pref_store.h" #include "chrome/service/cloud_print/cloud_print_consts.h" #include "chrome/service/cloud_print/print_system.h" #include "chrome/service/service_process.h" +#include "chrome/service/service_process_prefs.h" // This method is invoked on the IO thread to launch the browser process to // display a desktop notification that the Cloud Print token is invalid and @@ -48,7 +48,8 @@ CloudPrintProxy::~CloudPrintProxy() { Shutdown(); } -void CloudPrintProxy::Initialize(JsonPrefStore* service_prefs, Client* client) { +void CloudPrintProxy::Initialize(ServiceProcessPrefs* service_prefs, + Client* client) { DCHECK(CalledOnValidThread()); service_prefs_ = service_prefs; client_ = client; @@ -60,22 +61,22 @@ void CloudPrintProxy::EnableForUser(const std::string& lsid) { return; std::string proxy_id; - service_prefs_->prefs()->GetString(prefs::kCloudPrintProxyId, &proxy_id); + service_prefs_->GetString(prefs::kCloudPrintProxyId, &proxy_id); if (proxy_id.empty()) { proxy_id = cloud_print::PrintSystem::GenerateProxyId(); - service_prefs_->prefs()->SetString(prefs::kCloudPrintProxyId, proxy_id); + service_prefs_->SetString(prefs::kCloudPrintProxyId, proxy_id); service_prefs_->WritePrefs(); } // Getting print system specific settings from the preferences. DictionaryValue* print_system_settings = NULL; - service_prefs_->prefs()->GetDictionary(prefs::kCloudPrintPrintSystemSettings, - &print_system_settings); + service_prefs_->GetDictionary(prefs::kCloudPrintPrintSystemSettings, + &print_system_settings); // Check if there is an override for the cloud print server URL. std::string cloud_print_server_url_str; - service_prefs_->prefs()->GetString(prefs::kCloudPrintServiceURL, - &cloud_print_server_url_str); + service_prefs_->GetString(prefs::kCloudPrintServiceURL, + &cloud_print_server_url_str); if (cloud_print_server_url_str.empty()) { cloud_print_server_url_str = kDefaultCloudPrintServerUrl; } @@ -90,15 +91,15 @@ void CloudPrintProxy::EnableForUser(const std::string& lsid) { backend_->InitializeWithLsid(lsid, proxy_id); } else { std::string cloud_print_token; - service_prefs_->prefs()->GetString(prefs::kCloudPrintAuthToken, - &cloud_print_token); + service_prefs_->GetString(prefs::kCloudPrintAuthToken, + &cloud_print_token); DCHECK(!cloud_print_token.empty()); std::string cloud_print_xmpp_token; - service_prefs_->prefs()->GetString(prefs::kCloudPrintXMPPAuthToken, - &cloud_print_xmpp_token); + service_prefs_->GetString(prefs::kCloudPrintXMPPAuthToken, + &cloud_print_xmpp_token); DCHECK(!cloud_print_xmpp_token.empty()); - service_prefs_->prefs()->GetString(prefs::kCloudPrintEmail, - &cloud_print_email_); + service_prefs_->GetString(prefs::kCloudPrintEmail, + &cloud_print_email_); DCHECK(!cloud_print_email_.empty()); backend_->InitializeWithToken(cloud_print_token, cloud_print_xmpp_token, cloud_print_email_, proxy_id); @@ -125,13 +126,6 @@ bool CloudPrintProxy::IsEnabled(std::string* email) const { return enabled; } -void CloudPrintProxy::Shutdown() { - DCHECK(CalledOnValidThread()); - if (backend_.get()) - backend_->Shutdown(); - backend_.reset(); -} - // Notification methods from the backend. Called on UI thread. void CloudPrintProxy::OnPrinterListAvailable( const printing::PrinterList& printer_list) { @@ -147,11 +141,12 @@ void CloudPrintProxy::OnAuthenticated( const std::string& email) { DCHECK(CalledOnValidThread()); cloud_print_email_ = email; - service_prefs_->prefs()->SetString(prefs::kCloudPrintAuthToken, - cloud_print_token); - service_prefs_->prefs()->SetString(prefs::kCloudPrintXMPPAuthToken, - cloud_print_xmpp_token); - service_prefs_->prefs()->SetString(prefs::kCloudPrintEmail, email); + service_prefs_->SetString(prefs::kCloudPrintAuthToken, + cloud_print_token); + service_prefs_->SetString(prefs::kCloudPrintXMPPAuthToken, + cloud_print_xmpp_token); + service_prefs_->SetString(prefs::kCloudPrintEmail, + email); service_prefs_->WritePrefs(); } @@ -164,3 +159,10 @@ void CloudPrintProxy::OnAuthenticationFailed() { g_service_process->io_thread()->message_loop_proxy()->PostTask( FROM_HERE, NewRunnableFunction(&ShowTokenExpiredNotificationInBrowser)); } + +void CloudPrintProxy::Shutdown() { + DCHECK(CalledOnValidThread()); + if (backend_.get()) + backend_->Shutdown(); + backend_.reset(); +} diff --git a/chrome/service/cloud_print/cloud_print_proxy.h b/chrome/service/cloud_print/cloud_print_proxy.h index 36399ca..a5832f2 100644 --- a/chrome/service/cloud_print/cloud_print_proxy.h +++ b/chrome/service/cloud_print/cloud_print_proxy.h @@ -13,7 +13,7 @@ #include "base/scoped_ptr.h" #include "chrome/service/cloud_print/cloud_print_proxy_backend.h" -class JsonPrefStore; +class ServiceProcessPrefs; // CloudPrintProxy is the layer between the service process UI thread // and the cloud print proxy backend. @@ -31,7 +31,7 @@ class CloudPrintProxy : public CloudPrintProxyFrontend, // Initializes the object. This should be called every time an object of this // class is constructed. - void Initialize(JsonPrefStore* service_prefs, Client* client); + void Initialize(ServiceProcessPrefs* service_prefs, Client* client); // Enables/disables cloud printing for the user void EnableForUser(const std::string& lsid); @@ -60,7 +60,7 @@ class CloudPrintProxy : public CloudPrintProxyFrontend, scoped_ptr<CloudPrintProxyBackend> backend_; // This class does not own this. It is guaranteed to remain valid for the // lifetime of this class. - JsonPrefStore* service_prefs_; + ServiceProcessPrefs* service_prefs_; // This class does not own this. If non-NULL, It is guaranteed to remain // valid for the lifetime of this class. Client* client_; diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index e826c1f..aa91ca8 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc @@ -16,11 +16,11 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/json_pref_store.h" #include "chrome/common/pref_names.h" #include "chrome/common/service_process_util.h" #include "chrome/service/cloud_print/cloud_print_proxy.h" #include "chrome/service/service_ipc_server.h" +#include "chrome/service/service_process_prefs.h" #include "net/base/network_change_notifier.h" #if defined(ENABLE_REMOTING) @@ -95,11 +95,10 @@ bool ServiceProcess::Initialize(MessageLoop* message_loop, FilePath user_data_dir; PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); FilePath pref_path = user_data_dir.Append(chrome::kServiceStateFileName); - service_prefs_.reset(new JsonPrefStore(pref_path, - file_thread_->message_loop_proxy())); + service_prefs_.reset( + new ServiceProcessPrefs(pref_path, file_thread_->message_loop_proxy())); service_prefs_->ReadPrefs(); - DictionaryValue* values = service_prefs_->prefs(); bool remoting_host_enabled = false; // For development, we allow forcing the enabling of the host daemon via a @@ -107,7 +106,8 @@ bool ServiceProcess::Initialize(MessageLoop* message_loop, // // TODO(ajwong): When we've gotten the preference setting workflow more // stable, we should remove the command-line flag force-enable. - values->GetBoolean(prefs::kRemotingHostEnabled, &remoting_host_enabled); + service_prefs_->GetBoolean(prefs::kRemotingHostEnabled, + &remoting_host_enabled); remoting_host_enabled |= command_line.HasSwitch(switches::kEnableRemoting); #if defined(ENABLE_REMOTING) @@ -122,8 +122,8 @@ bool ServiceProcess::Initialize(MessageLoop* message_loop, command_line.HasSwitch(switches::kEnableCloudPrintProxy); if (!cloud_print_proxy_enabled) { // Then check if the cloud print proxy was previously enabled. - values->GetBoolean(prefs::kCloudPrintProxyEnabled, - &cloud_print_proxy_enabled); + service_prefs_->GetBoolean(prefs::kCloudPrintProxyEnabled, + &cloud_print_proxy_enabled); } if (cloud_print_proxy_enabled) { @@ -192,14 +192,14 @@ CloudPrintProxy* ServiceProcess::GetCloudPrintProxy() { void ServiceProcess::OnCloudPrintProxyEnabled() { // Save the preference that we have enabled the cloud print proxy. - service_prefs_->prefs()->SetBoolean(prefs::kCloudPrintProxyEnabled, true); + service_prefs_->SetBoolean(prefs::kCloudPrintProxyEnabled, true); service_prefs_->WritePrefs(); OnServiceEnabled(); } void ServiceProcess::OnCloudPrintProxyDisabled() { // Save the preference that we have disabled the cloud print proxy. - service_prefs_->prefs()->SetBoolean(prefs::kCloudPrintProxyEnabled, false); + service_prefs_->SetBoolean(prefs::kCloudPrintProxyEnabled, false); service_prefs_->WritePrefs(); OnServiceDisabled(); } @@ -311,7 +311,7 @@ void ServiceProcess::OnRemotingHostAdded() { talk_token_ = ""; // Save the preference that we have enabled the remoting host. - service_prefs_->prefs()->SetBoolean(prefs::kRemotingHostEnabled, true); + service_prefs_->SetBoolean(prefs::kRemotingHostEnabled, true); // Force writing prefs to the disk. service_prefs_->WritePrefs(); diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h index 91d51a0..230cf77 100644 --- a/chrome/service/service_process.h +++ b/chrome/service/service_process.h @@ -16,7 +16,7 @@ #include "chrome/service/cloud_print/cloud_print_proxy.h" #include "chrome/service/remoting/remoting_directory_service.h" -class JsonPrefStore; +class ServiceProcessPrefs; class ServiceIPCServer; namespace net { @@ -152,7 +152,7 @@ class ServiceProcess : public RemotingDirectoryService::Client, scoped_ptr<base::Thread> io_thread_; scoped_ptr<base::Thread> file_thread_; scoped_ptr<CloudPrintProxy> cloud_print_proxy_; - scoped_ptr<JsonPrefStore> service_prefs_; + scoped_ptr<ServiceProcessPrefs> service_prefs_; scoped_ptr<ServiceIPCServer> ipc_server_; #if defined(ENABLE_REMOTING) diff --git a/chrome/service/service_process_prefs.cc b/chrome/service/service_process_prefs.cc new file mode 100644 index 0000000..182b92f --- /dev/null +++ b/chrome/service/service_process_prefs.cc @@ -0,0 +1,54 @@ +// 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/service/service_process_prefs.h" + +#include "base/values.h" + +ServiceProcessPrefs::ServiceProcessPrefs( + const FilePath& pref_filename, + base::MessageLoopProxy* file_message_loop_proxy) + : prefs_(pref_filename, file_message_loop_proxy) { +} + +void ServiceProcessPrefs::ReadPrefs() { + prefs_.ReadPrefs(); +} + +void ServiceProcessPrefs::WritePrefs() { + prefs_.WritePrefs(); +} + +void ServiceProcessPrefs::GetString(const std::string& key, + std::string* result) { + Value* value; + if (prefs_.GetValue(key, &value) == PersistentPrefStore::READ_OK) + value->GetAsString(result); +} + +void ServiceProcessPrefs::SetString(const std::string& key, + const std::string& value) { + prefs_.SetValue(key, Value::CreateStringValue(value)); +} + +void ServiceProcessPrefs::GetBoolean(const std::string& key, bool* result) { + Value* value; + if (prefs_.GetValue(key, &value) == PersistentPrefStore::READ_OK) + value->GetAsBoolean(result); +} + +void ServiceProcessPrefs::SetBoolean(const std::string& key, bool value) { + prefs_.SetValue(key, Value::CreateBooleanValue(value)); +} + +void ServiceProcessPrefs::GetDictionary(const std::string& key, + DictionaryValue** result) { + Value* value; + if (prefs_.GetValue(key, &value) != PersistentPrefStore::READ_OK || + !value->IsType(Value::TYPE_DICTIONARY)) { + return; + } + + *result = static_cast<DictionaryValue*>(value); +} diff --git a/chrome/service/service_process_prefs.h b/chrome/service/service_process_prefs.h new file mode 100644 index 0000000..ce86b03 --- /dev/null +++ b/chrome/service/service_process_prefs.h @@ -0,0 +1,49 @@ +// 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_SERVICE_SERVICE_PROCESS_PREFS_H_ +#define CHROME_SERVICE_SERVICE_PROCESS_PREFS_H_ +#pragma once + +#include <string> + +#include "chrome/common/json_pref_store.h" + +// Manages persistent preferences for the service process. This is basically a +// thin wrapper around JsonPrefStore for more comfortable use. +class ServiceProcessPrefs { + public: + // |file_message_loop_proxy| is the MessageLoopProxy for a thread on which + // file I/O can be done. + ServiceProcessPrefs(const FilePath& pref_filename, + base::MessageLoopProxy* file_message_loop_proxy); + + // Read preferences from the backing file. + void ReadPrefs(); + + // Write the data to the backing file. + void WritePrefs(); + + // Get a string preference for |key| and store it in |result|. + void GetString(const std::string& key, std::string* result); + + // Set a string |value| for |key|. + void SetString(const std::string& key, const std::string& value); + + // Get a boolean preference for |key| and store it in |result|. + void GetBoolean(const std::string& key, bool* result); + + // Set a boolean |value| for |key|. + void SetBoolean(const std::string& key, bool value); + + // Get a dictionary preference for |key| and store it in |result|. + void GetDictionary(const std::string& key, DictionaryValue** result); + + private: + JsonPrefStore prefs_; + + DISALLOW_COPY_AND_ASSIGN(ServiceProcessPrefs); +}; + +#endif // CHROME_SERVICE_SERVICE_PROCESS_PREFS_H_ diff --git a/chrome/test/reliability/page_load_test.cc b/chrome/test/reliability/page_load_test.cc index 571c16a..fa06d56 100644 --- a/chrome/test/reliability/page_load_test.cc +++ b/chrome/test/reliability/page_load_test.cc @@ -50,6 +50,7 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/prefs/pref_service_mock_builder.h" #include "chrome/common/automation_messages.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" @@ -63,8 +64,8 @@ #include "chrome/test/automation/browser_proxy.h" #include "chrome/test/automation/tab_proxy.h" #include "chrome/test/automation/window_proxy.h" -#include "chrome/test/ui/ui_test.h" #include "chrome/test/reliability/page_load_test.h" +#include "chrome/test/ui/ui_test.h" #include "net/base/net_util.h" namespace { @@ -532,12 +533,8 @@ class PageLoadTest : 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); - - PrefService* local_state = PrefService::CreateUserPrefService( - local_state_path); - return local_state; + FilePath path = user_data_dir().Append(chrome::kLocalStateFilename); + return PrefServiceMockBuilder().WithUserFilePrefs(path).Create(); } void GetStabilityMetrics(NavigationMetrics* metrics) { diff --git a/chrome/test/testing_pref_service.cc b/chrome/test/testing_pref_service.cc index 9cc5321..66342bc 100644 --- a/chrome/test/testing_pref_service.cc +++ b/chrome/test/testing_pref_service.cc @@ -4,11 +4,11 @@ #include "chrome/test/testing_pref_service.h" +#include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/prefs/command_line_pref_store.h" -#include "chrome/browser/prefs/testing_pref_store.h" #include "chrome/browser/prefs/pref_notifier.h" #include "chrome/browser/prefs/pref_value_store.h" -#include "chrome/browser/policy/configuration_policy_pref_store.h" +#include "chrome/browser/prefs/testing_pref_store.h" // TODO(pamg): Instantiate no PrefStores by default. Allow callers to specify // which they want, and expand usage of this class to more unit tests. @@ -23,37 +23,7 @@ TestingPrefService::TestingPrefService() NULL) { } -TestingPrefService::TestingPrefService( - policy::ConfigurationPolicyProvider* managed_platform_provider, - policy::ConfigurationPolicyProvider* device_management_provider, - CommandLine* command_line) - : PrefService( - managed_platform_prefs_ = CreatePolicyPrefStoreFromProvider( - managed_platform_provider), - device_management_prefs_ = - CreatePolicyPrefStoreFromProvider(device_management_provider), - NULL, - CreateCommandLinePrefStore(command_line), - user_prefs_ = new TestingPrefStore(), - NULL, - NULL) { -} - -PrefStore* TestingPrefService::CreatePolicyPrefStoreFromProvider( - policy::ConfigurationPolicyProvider* provider) { - if (provider) - return new policy::ConfigurationPolicyPrefStore(provider); - return new TestingPrefStore(); -} - -PrefStore* TestingPrefService::CreateCommandLinePrefStore( - CommandLine* command_line) { - if (command_line) - return new CommandLinePrefStore(command_line); - return new TestingPrefStore(); -} - -const Value* TestingPrefService::GetManagedPref(const char* path) { +const Value* TestingPrefService::GetManagedPref(const char* path) const { return GetPref(managed_platform_prefs_, path); } @@ -65,17 +35,7 @@ void TestingPrefService::RemoveManagedPref(const char* path) { RemovePref(managed_platform_prefs_, path); } -void TestingPrefService::SetManagedPrefWithoutNotification(const char* path, - Value* value) { - managed_platform_prefs_->prefs()->Set(path, value); -} - -void TestingPrefService::RemoveManagedPrefWithoutNotification( - const char* path) { - managed_platform_prefs_->prefs()->Remove(path, NULL); -} - -const Value* TestingPrefService::GetUserPref(const char* path) { +const Value* TestingPrefService::GetUserPref(const char* path) const { return GetPref(user_prefs_, path); } @@ -87,21 +47,19 @@ void TestingPrefService::RemoveUserPref(const char* path) { RemovePref(user_prefs_, path); } -const Value* TestingPrefService::GetPref(PrefStore* pref_store, - const char* path) { - Value* result; - return pref_store->prefs()->Get(path, &result) ? result : NULL; +const Value* TestingPrefService::GetPref(TestingPrefStore* pref_store, + const char* path) const { + Value* res; + return pref_store->GetValue(path, &res) == PrefStore::READ_OK ? res : NULL; } -void TestingPrefService::SetPref(PrefStore* pref_store, +void TestingPrefService::SetPref(TestingPrefStore* pref_store, const char* path, Value* value) { - pref_store->prefs()->Set(path, value); - pref_notifier()->OnPreferenceChanged(path); + pref_store->SetValue(path, value); } -void TestingPrefService::RemovePref(PrefStore* pref_store, +void TestingPrefService::RemovePref(TestingPrefStore* pref_store, const char* path) { - pref_store->prefs()->Remove(path, NULL); - pref_notifier()->OnPreferenceChanged(path); + pref_store->RemoveValue(path); } diff --git a/chrome/test/testing_pref_service.h b/chrome/test/testing_pref_service.h index c5adc021..25349b6 100644 --- a/chrome/test/testing_pref_service.h +++ b/chrome/test/testing_pref_service.h @@ -8,11 +8,7 @@ #include "chrome/browser/prefs/pref_service.h" -class CommandLine; -namespace policy { -class ConfigurationPolicyProvider; -} -class PrefStore; +class TestingPrefStore; // A PrefService subclass for testing. It operates totally in memory and // provides additional API for manipulating preferences at the different levels @@ -21,23 +17,11 @@ class TestingPrefService : public PrefService { public: // Create an empty instance. TestingPrefService(); - - // Create an instance that has a managed PrefStore and a command- line - // PrefStore. |managed_platform_provider| contains the provider with which to - // initialize the managed platform PrefStore. If it is NULL, then a - // TestingPrefStore will be created. |device_management_provider| contains the - // provider with which to initialize the device management - // PrefStore. |command_line| contains the provider with which to initialize - // the command line PrefStore. If it is NULL then a TestingPrefStore will be - // created as the command line PrefStore. - TestingPrefService( - policy::ConfigurationPolicyProvider* managed_platform_provider, - policy::ConfigurationPolicyProvider* device_management_provider, - CommandLine* command_line); + virtual ~TestingPrefService() {} // Read the value of a preference from the managed layer. Returns NULL if the // preference is not defined at the managed layer. - const Value* GetManagedPref(const char* path); + const Value* GetManagedPref(const char* path) const; // Set a preference on the managed layer and fire observers if the preference // changed. Assumes ownership of |value|. @@ -47,48 +31,26 @@ class TestingPrefService : public PrefService { // preference has been defined previously. void RemoveManagedPref(const char* path); - // Set a preference on the managed layer. Assumes ownership of |value|. - // We don't fire observers for each change because in the real code, the - // notification is sent after all the prefs have been loaded. See - // ConfigurationPolicyPrefStore::ReadPrefs(). - void SetManagedPrefWithoutNotification(const char* path, Value* value); - - // Clear the preference on the managed layer. - // We don't fire observers for each change because in the real code, the - // notification is sent after all the prefs have been loaded. See - // ConfigurationPolicyPrefStore::ReadPrefs(). - void RemoveManagedPrefWithoutNotification(const char* path); - // Similar to the above, but for user preferences. - const Value* GetUserPref(const char* path); + const Value* GetUserPref(const char* path) const; void SetUserPref(const char* path, Value* value); void RemoveUserPref(const char* path); private: - // Creates a ConfigurationPolicyPrefStore based on the provided - // |provider| or a TestingPrefStore if |provider| is NULL. - PrefStore* CreatePolicyPrefStoreFromProvider( - policy::ConfigurationPolicyProvider* provider); - - // Creates a CommandLinePrefStore based on the supplied - // |command_line| or a TestingPrefStore if |command_line| is NULL. - PrefStore* CreateCommandLinePrefStore(CommandLine* command_line); - // Reads the value of the preference indicated by |path| from |pref_store|. // Returns NULL if the preference was not found. - const Value* GetPref(PrefStore* pref_store, const char* path); + const Value* GetPref(TestingPrefStore* pref_store, const char* path) const; // Sets the value for |path| in |pref_store|. - void SetPref(PrefStore* pref_store, const char* path, Value* value); + void SetPref(TestingPrefStore* pref_store, const char* path, Value* value); // Removes the preference identified by |path| from |pref_store|. - void RemovePref(PrefStore* pref_store, const char* path); + void RemovePref(TestingPrefStore* pref_store, const char* path); // Pointers to the pref stores our value store uses. - PrefStore* managed_platform_prefs_; // weak - PrefStore* device_management_prefs_; // weak - PrefStore* user_prefs_; // weak - PrefStore* default_prefs_; // weak + TestingPrefStore* managed_platform_prefs_; // weak + TestingPrefStore* device_management_prefs_; // weak + TestingPrefStore* user_prefs_; // weak DISALLOW_COPY_AND_ASSIGN(TestingPrefService); }; diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index d94fa06..5266771 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -17,6 +17,7 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/dom_ui/ntp_resource_cache.h" +#include "chrome/browser/extensions/extension_pref_store.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/favicon_service.h" #include "chrome/browser/geolocation/geolocation_content_settings_map.h" @@ -328,7 +329,10 @@ void TestingProfile::UseThemeProvider(BrowserThemeProvider* theme_provider) { scoped_refptr<ExtensionsService> TestingProfile::CreateExtensionsService( const CommandLine* command_line, const FilePath& install_directory) { - extension_prefs_.reset(new ExtensionPrefs(GetPrefs(),install_directory)); + extension_pref_store_.reset(new ExtensionPrefStore); + extension_prefs_.reset(new ExtensionPrefs(GetPrefs(), + install_directory, + extension_pref_store_.get())); extensions_service_ = new ExtensionsService(this, command_line, install_directory, diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index 70395bb..4f53925 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -25,6 +25,7 @@ class BookmarkModel; class BrowserThemeProvider; class CommandLine; class DesktopNotificationService; +class ExtensionPrefStore; class ExtensionPrefs; class FaviconService; class FindBarState; @@ -406,6 +407,9 @@ class TestingProfile : public Profile { FilePath last_selected_directory_; scoped_refptr<history::TopSites> top_sites_; // For history and thumbnails. + // Extension pref store, created for use by |extension_prefs_|. + scoped_ptr<ExtensionPrefStore> extension_pref_store_; + // The Extension Preferences. Only created if CreateExtensionsService is // invoked. scoped_ptr<ExtensionPrefs> extension_prefs_; diff --git a/chrome_frame/test/reliability/page_load_test.cc b/chrome_frame/test/reliability/page_load_test.cc index 4116464..3afdadf 100644 --- a/chrome_frame/test/reliability/page_load_test.cc +++ b/chrome_frame/test/reliability/page_load_test.cc @@ -36,6 +36,7 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/net/url_fixer_upper.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/automation_messages.h" #include "chrome/common/chrome_constants.h" @@ -45,14 +46,14 @@ #include "chrome/common/json_pref_store.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/pref_names.h" -#include "chrome_frame/test/chrome_frame_test_utils.h" -#include "chrome_frame/test/ie_event_sink.h" #include "chrome/test/automation/automation_proxy.h" #include "chrome/test/automation/browser_proxy.h" #include "chrome/test/automation/tab_proxy.h" #include "chrome/test/automation/window_proxy.h" -#include "chrome/test/ui/ui_test.h" #include "chrome/test/reliability/page_load_test.h" +#include "chrome/test/ui/ui_test.h" +#include "chrome_frame/test/chrome_frame_test_utils.h" +#include "chrome_frame/test/ie_event_sink.h" #include "chrome_frame/utils.h" #include "net/base/net_util.h" #include "testing/gmock/include/gmock/gmock.h" @@ -426,12 +427,9 @@ class PageLoadTest : public testing::Test { // that was saved by the app as it closed. The caller takes ownership of the // returned PrefService object. PrefService* GetLocalState() { - FilePath local_state_path; - chrome::GetChromeFrameUserDataDirectory(&local_state_path); - - PrefService* local_state = PrefService::CreateUserPrefService( - local_state_path); - return local_state; + FilePath path; + chrome::GetChromeFrameUserDataDirectory(&path); + return PrefServiceMockBuilder().WithUserFilePrefs(path).Create(); } void GetStabilityMetrics(NavigationMetrics* metrics) { |