diff options
24 files changed, 710 insertions, 121 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index fdb68b4..bc78554 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -48,6 +48,7 @@ #include "chrome/browser/net/websocket_experiment/websocket_experiment_runner.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/browser/process_singleton.h" #include "chrome/browser/profile.h" #include "chrome/browser/profile_manager.h" @@ -438,16 +439,14 @@ PrefService* InitializeLocalState(const CommandLine& parsed_command_line, parsed_command_line.HasSwitch(switches::kParentProfile)) { FilePath parent_profile = parsed_command_line.GetSwitchValuePath(switches::kParentProfile); - PrefService parent_local_state( - new JsonPrefStore( - parent_profile, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); - parent_local_state.RegisterStringPref(prefs::kApplicationLocale, - std::wstring()); + scoped_ptr<PrefService> parent_local_state( + PrefService::CreatePrefService(parent_profile)); + parent_local_state->RegisterStringPref(prefs::kApplicationLocale, + std::wstring()); // Right now, we only inherit the locale setting from the parent profile. local_state->SetString( prefs::kApplicationLocale, - parent_local_state.GetString(prefs::kApplicationLocale)); + parent_local_state->GetString(prefs::kApplicationLocale)); } return local_state; diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index e6f99a1..ffa2277 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -408,11 +408,8 @@ void BrowserProcessImpl::CreateLocalState() { FilePath local_state_path; PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); - local_state_.reset(new PrefService( - new JsonPrefStore( - local_state_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); -} + local_state_.reset(PrefService::CreatePrefService(local_state_path)); + } void BrowserProcessImpl::CreateIconManager() { DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); diff --git a/chrome/browser/dom_ui/new_tab_ui_uitest.cc b/chrome/browser/dom_ui/new_tab_ui_uitest.cc index daf6ce7..7bd8357 100644 --- a/chrome/browser/dom_ui/new_tab_ui_uitest.cc +++ b/chrome/browser/dom_ui/new_tab_ui_uitest.cc @@ -9,6 +9,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/new_tab_ui.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/json_pref_store.h" #include "chrome/common/pref_names.h" #include "chrome/test/automation/browser_proxy.h" @@ -76,10 +77,14 @@ TEST_F(NewTabUITest, ChromeInternalLoadsNTP) { } TEST_F(NewTabUITest, UpdateUserPrefsVersion) { - PrefService prefs( + // PrefService with JSON user-pref file only, no enforced or advised prefs. + PrefService prefs(new PrefValueStore( + NULL, /* no enforced prefs */ new JsonPrefStore( FilePath(), - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + /* user prefs */ + NULL /* no advised prefs */)); // Does the migration NewTabUI::RegisterUserPrefs(&prefs); diff --git a/chrome/browser/dom_ui/shown_sections_handler_unittest.cc b/chrome/browser/dom_ui/shown_sections_handler_unittest.cc index 48530d2..9dc5c872 100644 --- a/chrome/browser/dom_ui/shown_sections_handler_unittest.cc +++ b/chrome/browser/dom_ui/shown_sections_handler_unittest.cc @@ -8,6 +8,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/json_pref_store.h" #include "chrome/common/pref_names.h" #include "testing/gtest/include/gtest/gtest.h" @@ -16,10 +17,14 @@ class ShownSectionsHandlerTest : public testing::Test { }; TEST_F(ShownSectionsHandlerTest, MigrateUserPrefs) { - PrefService pref( - new JsonPrefStore( - FilePath(), - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); + // Create a preference value that has only user defined + // preference values. + PrefService pref(new PrefValueStore( + NULL, /* no managed preference values */ + new JsonPrefStore( /* user defined preference values */ + FilePath(), + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no suggested preference values */)); // Set an *old* value pref.RegisterIntegerPref(prefs::kNTPShownSections, 0); @@ -37,10 +42,12 @@ TEST_F(ShownSectionsHandlerTest, MigrateUserPrefs) { } TEST_F(ShownSectionsHandlerTest, MigrateUserPrefs1To2) { - PrefService pref( + PrefService pref(new PrefValueStore( + NULL, new JsonPrefStore( - FilePath(), - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); + FilePath(), + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL)); // Set an *old* value pref.RegisterIntegerPref(prefs::kNTPShownSections, 0); @@ -53,3 +60,4 @@ TEST_F(ShownSectionsHandlerTest, MigrateUserPrefs1To2) { EXPECT_TRUE(shown_sections & THUMB); EXPECT_FALSE(shown_sections & LIST); } + diff --git a/chrome/browser/dummy_pref_store.cc b/chrome/browser/dummy_pref_store.cc index bd728d4..7b3cd0a 100644 --- a/chrome/browser/dummy_pref_store.cc +++ b/chrome/browser/dummy_pref_store.cc @@ -4,11 +4,18 @@ #include "chrome/browser/dummy_pref_store.h" -#include "base/values.h" - -DummyPrefStore::DummyPrefStore() : prefs_(new DictionaryValue()) { } +DummyPrefStore::DummyPrefStore() + : prefs_(new DictionaryValue()), + read_only_(true), + prefs_written_(false) { } PrefStore::PrefReadError DummyPrefStore::ReadPrefs() { prefs_.reset(new DictionaryValue()); return PrefStore::PREF_READ_ERROR_NONE; } + +bool DummyPrefStore::WritePrefs() { + prefs_written_ = true; + return prefs_written_; +} + diff --git a/chrome/browser/dummy_pref_store.h b/chrome/browser/dummy_pref_store.h index a3c1ee4..8103763 100644 --- a/chrome/browser/dummy_pref_store.h +++ b/chrome/browser/dummy_pref_store.h @@ -1,25 +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_DUMMY_PREF_STORE_H_ #define CHROME_BROWSER_DUMMY_PREF_STORE_H_ #include "base/basictypes.h" #include "base/scoped_ptr.h" +#include "base/values.h" #include "chrome/common/pref_store.h" + +// |DummyPrefStore| is a stub implementation of the |PrefStore| interface. +// It allows to get and set the state of the |PrefStore|. class DummyPrefStore : public PrefStore { public: DummyPrefStore(); + virtual ~DummyPrefStore() {} + virtual DictionaryValue* prefs() { return prefs_.get(); } - void SetPrefs(DictionaryValue* prefs) { prefs_.reset(prefs); } virtual PrefStore::PrefReadError ReadPrefs(); + virtual bool ReadOnly() { return read_only_; } + + virtual bool WritePrefs(); + + // Getter and Setter methods for setting and getting the state of the + // |DummyPrefStore|. + 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_; } + private: scoped_ptr<DictionaryValue> prefs_; + // Flag that indicates if the PrefStore is read-only + bool read_only_; + + // Flag that indicates if the method WritePrefs was called. + bool prefs_written_; + DISALLOW_COPY_AND_ASSIGN(DummyPrefStore); }; diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index a9b8042..a819ef8 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -25,6 +25,7 @@ #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/external_extension_provider.h" #include "chrome/browser/extensions/external_pref_extension_provider.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_resource.h" @@ -250,10 +251,14 @@ void ExtensionsServiceTestBase::InitializeExtensionsService( switches::kEnableApps); ExtensionTestingProfile* profile = new ExtensionTestingProfile(); - prefs_.reset(new PrefService( - new JsonPrefStore( + // Create a preference service that only contains user defined + // preference values. + prefs_.reset(new PrefService(new PrefValueStore( + NULL, /* No managed preference values */ + new JsonPrefStore( /* user defined preference values */ pref_file, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* No suggested preference values */ ))); Profile::RegisterUserPrefs(prefs_.get()); browser::RegisterUserPrefs(prefs_.get()); diff --git a/chrome/browser/extensions/test_extension_prefs.cc b/chrome/browser/extensions/test_extension_prefs.cc index 716539f..945fb0b 100644 --- a/chrome/browser/extensions/test_extension_prefs.cc +++ b/chrome/browser/extensions/test_extension_prefs.cc @@ -4,12 +4,16 @@ #include "chrome/browser/extensions/test_extension_prefs.h" + #include "base/file_util.h" #include "base/logging.h" #include "base/message_loop.h" +#include "base/scoped_ptr.h" +#include "base/values.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/json_pref_store.h" @@ -37,11 +41,13 @@ void TestExtensionPrefs::RecreateExtensionPrefs() { file_loop.RunAllPending(); } - pref_service_.reset(new PrefService( - new JsonPrefStore( - preferences_file_, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); - + // Create a |PrefService| instance that contains only user defined values. + pref_service_.reset(new PrefService(new PrefValueStore( + NULL, /* no managed preference values*/ + new JsonPrefStore( /* user defined preferemnce values*/ + preferences_file_, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no suggested preference values*/))); ExtensionPrefs::RegisterUserPrefs(pref_service_.get()); prefs_.reset(new ExtensionPrefs(pref_service_.get(), temp_dir_.path())); } diff --git a/chrome/browser/metrics/metrics_service_uitest.cc b/chrome/browser/metrics/metrics_service_uitest.cc index 05c1b8d..6f8b6a3 100644 --- a/chrome/browser/metrics/metrics_service_uitest.cc +++ b/chrome/browser/metrics/metrics_service_uitest.cc @@ -13,6 +13,7 @@ #include "base/platform_thread.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_pref_store.h" @@ -53,10 +54,12 @@ class MetricsServiceTest : public UITest { FilePath local_state_path = user_data_dir() .Append(chrome::kLocalStateFilename); - return new PrefService( + return new PrefService(new PrefValueStore( + NULL, new JsonPrefStore( local_state_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL)); } }; diff --git a/chrome/browser/pref_member_unittest.cc b/chrome/browser/pref_member_unittest.cc index 4a137e5..c301ef6 100644 --- a/chrome/browser/pref_member_unittest.cc +++ b/chrome/browser/pref_member_unittest.cc @@ -6,6 +6,7 @@ #include "chrome/browser/dummy_pref_store.h" #include "chrome/browser/pref_member.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/notification_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -52,7 +53,7 @@ class PrefMemberTestClass : public NotificationObserver { } // anonymous namespace TEST(PrefMemberTest, BasicGetAndSet) { - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); RegisterTestPrefs(&prefs); // Test bool @@ -142,7 +143,7 @@ TEST(PrefMemberTest, BasicGetAndSet) { TEST(PrefMemberTest, TwoPrefs) { // Make sure two RealPrefMembers stay in sync. - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); RegisterTestPrefs(&prefs); RealPrefMember pref1; @@ -162,7 +163,7 @@ TEST(PrefMemberTest, TwoPrefs) { } TEST(PrefMemberTest, Observer) { - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); RegisterTestPrefs(&prefs); PrefMemberTestClass test_obj(&prefs); diff --git a/chrome/browser/pref_service.cc b/chrome/browser/pref_service.cc index bfc3ceb..5bbb712 100644 --- a/chrome/browser/pref_service.cc +++ b/chrome/browser/pref_service.cc @@ -17,6 +17,7 @@ #include "base/utf_string_conversions.h" #include "build/build_config.h" #include "chrome/browser/chrome_thread.h" +#include "chrome/common/json_pref_store.h" #include "chrome/common/notification_service.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -74,7 +75,20 @@ void NotifyReadError(PrefService* pref, int message_id) { } // namespace -PrefService::PrefService(PrefStore* storage) : store_(storage) { +PrefService* PrefService::CreatePrefService(const FilePath& pref_filename) { + // Create a PrefValueStore that has user defined preference values + // read from a local json text file. + PrefValueStore* value_store = new PrefValueStore( + NULL, /* no managed preference values */ + new JsonPrefStore( /* user defined preference values */ + pref_filename, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no recommended preference values */); + return new PrefService(value_store); +} + +PrefService::PrefService(PrefValueStore* pref_value_store) + : pref_value_store_(pref_value_store) { InitFromStorage(); } @@ -126,13 +140,11 @@ bool PrefService::ReloadPersistentPrefs() { PrefStore::PrefReadError PrefService::LoadPersistentPrefs() { DCHECK(CalledOnValidThread()); - PrefStore::PrefReadError pref_error = store_->ReadPrefs(); - - persistent_ = store_->prefs(); + PrefStore::PrefReadError pref_error = pref_value_store_->ReadPrefs(); for (PreferenceSet::iterator it = prefs_.begin(); it != prefs_.end(); ++it) { - (*it)->root_pref_ = persistent_; + (*it)->pref_value_store_ = pref_value_store_.get(); } return pref_error; @@ -141,86 +153,86 @@ PrefStore::PrefReadError PrefService::LoadPersistentPrefs() { bool PrefService::SavePersistentPrefs() { DCHECK(CalledOnValidThread()); - return store_->WritePrefs(); + return pref_value_store_->WritePrefs(); } void PrefService::ScheduleSavePersistentPrefs() { DCHECK(CalledOnValidThread()); - store_->ScheduleWritePrefs(); + pref_value_store_->ScheduleWritePrefs(); } void PrefService::RegisterBooleanPref(const wchar_t* path, bool default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateBooleanValue(default_value)); RegisterPreference(pref); } void PrefService::RegisterIntegerPref(const wchar_t* path, int default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateIntegerValue(default_value)); RegisterPreference(pref); } void PrefService::RegisterRealPref(const wchar_t* path, double default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateRealValue(default_value)); RegisterPreference(pref); } void PrefService::RegisterStringPref(const wchar_t* path, const std::wstring& default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateStringValue(default_value)); RegisterPreference(pref); } void PrefService::RegisterFilePathPref(const wchar_t* path, const FilePath& default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateStringValue(default_value.value())); RegisterPreference(pref); } void PrefService::RegisterListPref(const wchar_t* path) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, new ListValue); RegisterPreference(pref); } void PrefService::RegisterDictionaryPref(const wchar_t* path) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, new DictionaryValue()); RegisterPreference(pref); } void PrefService::RegisterLocalizedBooleanPref(const wchar_t* path, int locale_default_message_id) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id)); RegisterPreference(pref); } void PrefService::RegisterLocalizedIntegerPref(const wchar_t* path, int locale_default_message_id) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id)); RegisterPreference(pref); } void PrefService::RegisterLocalizedRealPref(const wchar_t* path, int locale_default_message_id) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, CreateLocaleDefaultValue(Value::TYPE_REAL, locale_default_message_id)); RegisterPreference(pref); } void PrefService::RegisterLocalizedStringPref(const wchar_t* path, int locale_default_message_id) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id)); RegisterPreference(pref); } @@ -305,8 +317,7 @@ FilePath PrefService::GetFilePath(const wchar_t* path) const { } bool PrefService::HasPrefPath(const wchar_t* path) const { - Value* value = NULL; - return persistent_->Get(path, &value); + return pref_value_store_->HasPrefPath(path); } const PrefService::Preference* PrefService::FindPreference( @@ -412,8 +423,8 @@ void PrefService::ClearPref(const wchar_t* path) { return; } Value* value; - bool has_old_value = persistent_->Get(path, &value); - persistent_->Remove(path, NULL); + bool has_old_value = pref_value_store_->GetValue(path, &value); + pref_value_store_->RemoveUserPrefValue(path); if (has_old_value) FireObservers(path); @@ -434,7 +445,7 @@ void PrefService::Set(const wchar_t* path, const Value& value) { pref->type() == Value::TYPE_LIST)) { scoped_ptr<Value> old_value(GetPrefCopy(path)); if (!old_value->Equals(&value)) { - persistent_->Remove(path, NULL); + pref_value_store_->RemoveUserPrefValue(path); FireObservers(path); } return; @@ -445,7 +456,7 @@ void PrefService::Set(const wchar_t* path, const Value& value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->Set(path, value.DeepCopy()); + pref_value_store_->SetUserPrefValue(path, value.DeepCopy()); FireObserversIfChanged(path, old_value.get()); } @@ -468,7 +479,8 @@ void PrefService::SetBoolean(const wchar_t* path, bool value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->SetBoolean(path, value); + Value* new_value = Value::CreateBooleanValue(value); + pref_value_store_->SetUserPrefValue(path, new_value); FireObserversIfChanged(path, old_value.get()); } @@ -491,7 +503,8 @@ void PrefService::SetInteger(const wchar_t* path, int value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->SetInteger(path, value); + Value* new_value = Value::CreateIntegerValue(value); + pref_value_store_->SetUserPrefValue(path, new_value); FireObserversIfChanged(path, old_value.get()); } @@ -514,7 +527,8 @@ void PrefService::SetReal(const wchar_t* path, double value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->SetReal(path, value); + Value* new_value = Value::CreateRealValue(value); + pref_value_store_->SetUserPrefValue(path, new_value); FireObserversIfChanged(path, old_value.get()); } @@ -537,7 +551,8 @@ void PrefService::SetString(const wchar_t* path, const std::wstring& value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->SetString(path, value); + Value* new_value = Value::CreateStringValue(value); + pref_value_store_->SetUserPrefValue(path, new_value); FireObserversIfChanged(path, old_value.get()); } @@ -564,9 +579,11 @@ void PrefService::SetFilePath(const wchar_t* path, const FilePath& value) { // Value::SetString only knows about UTF8 strings, so convert the path from // the system native value to UTF8. std::string path_utf8 = WideToUTF8(base::SysNativeMBToWide(value.value())); - persistent_->SetString(path, path_utf8); + Value* new_value = Value::CreateStringValue(path_utf8); + pref_value_store_->SetUserPrefValue(path, new_value); #else - persistent_->SetString(path, value.value()); + Value* new_value = Value::CreateStringValue(value.value()); + pref_value_store_->SetUserPrefValue(path, new_value); #endif FireObserversIfChanged(path, old_value.get()); @@ -590,7 +607,8 @@ void PrefService::SetInt64(const wchar_t* path, int64 value) { } scoped_ptr<Value> old_value(GetPrefCopy(path)); - persistent_->SetString(path, Int64ToWString(value)); + Value* new_value = Value::CreateStringValue(Int64ToWString(value)); + pref_value_store_->SetUserPrefValue(path, new_value); FireObserversIfChanged(path, old_value.get()); } @@ -610,7 +628,7 @@ int64 PrefService::GetInt64(const wchar_t* path) const { } void PrefService::RegisterInt64Pref(const wchar_t* path, int64 default_value) { - Preference* pref = new Preference(persistent_, path, + Preference* pref = new Preference(pref_value_store_.get(), path, Value::CreateStringValue(Int64ToWString(default_value))); RegisterPreference(pref); } @@ -629,9 +647,12 @@ DictionaryValue* PrefService::GetMutableDictionary(const wchar_t* path) { } DictionaryValue* dict = NULL; - if (!persistent_->GetDictionary(path, &dict)) { + Value* tmp_value = NULL; + if (!pref_value_store_->GetValue(path, &tmp_value)) { dict = new DictionaryValue; - persistent_->Set(path, dict); + pref_value_store_->SetUserPrefValue(path, dict); + } else { + dict = static_cast<DictionaryValue*>(tmp_value); } return dict; } @@ -650,9 +671,12 @@ ListValue* PrefService::GetMutableList(const wchar_t* path) { } ListValue* list = NULL; - if (!persistent_->GetList(path, &list)) { + Value* tmp_value = NULL; + if (!pref_value_store_->GetValue(path, &tmp_value)) { list = new ListValue; - persistent_->Set(path, list); + pref_value_store_->SetUserPrefValue(path, list); + } else { + list = static_cast<ListValue*>(tmp_value); } return list; } @@ -668,7 +692,7 @@ Value* PrefService::GetPrefCopy(const wchar_t* path) { void PrefService::FireObserversIfChanged(const wchar_t* path, const Value* old_value) { Value* new_value = NULL; - persistent_->Get(path, &new_value); + pref_value_store_->GetValue(path, &new_value); if (!old_value->Equals(new_value)) FireObservers(path); } @@ -695,13 +719,13 @@ void PrefService::FireObservers(const wchar_t* path) { /////////////////////////////////////////////////////////////////////////////// // PrefService::Preference -PrefService::Preference::Preference(DictionaryValue* root_pref, +PrefService::Preference::Preference(PrefValueStore* pref_value_store, const wchar_t* name, Value* default_value) : type_(Value::TYPE_NULL), name_(name), default_value_(default_value), - root_pref_(root_pref) { + pref_value_store_(pref_value_store) { DCHECK(name); if (default_value) { @@ -717,11 +741,11 @@ PrefService::Preference::Preference(DictionaryValue* root_pref, } const Value* PrefService::Preference::GetValue() const { - DCHECK(NULL != root_pref_) << + DCHECK(NULL != pref_value_store_) << "Must register pref before getting its value"; Value* temp_value = NULL; - if (root_pref_->Get(name_.c_str(), &temp_value) && + if (pref_value_store_->GetValue(name_, &temp_value) && temp_value->GetType() == type_) { return temp_value; } @@ -734,3 +758,8 @@ bool PrefService::Preference::IsDefaultValue() const { DCHECK(default_value_.get()); return default_value_->Equals(GetValue()); } + +bool PrefService::Preference::IsManaged() const { + return pref_value_store_->PrefValueIsManaged(name_.c_str()); +} + diff --git a/chrome/browser/pref_service.h b/chrome/browser/pref_service.h index c79edd7..5247e83 100644 --- a/chrome/browser/pref_service.h +++ b/chrome/browser/pref_service.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -15,6 +15,7 @@ #include "base/observer_list.h" #include "base/scoped_ptr.h" #include "base/values.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/pref_store.h" class NotificationObserver; @@ -33,7 +34,7 @@ class PrefService : public NonThreadSafe { // dictionary (a branch), or list. You shouldn't need to construct this on // your own, use the PrefService::Register*Pref methods instead. // |default_value| will be owned by the Preference object. - Preference(DictionaryValue* root_pref, + Preference(PrefValueStore* pref_value_store, const wchar_t* name, Value* default_value); ~Preference() {} @@ -53,7 +54,7 @@ class PrefService : public NonThreadSafe { // Returns true if the Preference is managed, i.e. not changeable // by the user. - bool IsManaged() const { return false; } + bool IsManaged() const; private: friend class PrefService; @@ -62,14 +63,17 @@ class PrefService : public NonThreadSafe { std::wstring name_; scoped_ptr<Value> default_value_; - // A reference to the pref service's persistent prefs. - DictionaryValue* root_pref_; + // A reference to the pref service's pref_value_store_. + PrefValueStore* pref_value_store_; DISALLOW_COPY_AND_ASSIGN(Preference); }; - // The |PrefStore| manages reading and writing the preferences. - explicit PrefService(PrefStore* store); + // Factory method that creates a new instance of a |PrefService|. + static PrefService* CreatePrefService(const FilePath& pref_filename); + + // The |PrefValueStore| provides preference values. + explicit PrefService(PrefValueStore* pref_value_store); ~PrefService(); // Reloads the data from file. This should only be called when the importer @@ -177,7 +181,7 @@ class PrefService : public NonThreadSafe { // preference is not registered. const Preference* FindPreference(const wchar_t* pref_name) const; - bool read_only() const { return store_->ReadOnly(); } + bool read_only() const { return pref_value_store_->ReadOnly(); } private: // Add a preference to the PreferenceMap. If the pref already exists, return @@ -203,10 +207,13 @@ class PrefService : public NonThreadSafe { // This should only be called from the constructor. void InitFromStorage(); - scoped_ptr<PrefStore> store_; - - // The user-defined preference values. Owned by the |PrefStore|. - DictionaryValue* persistent_; + // The value of a Preference can be: + // managed, user defined, recommended or default. + // The PrefValueStore manages enforced, user defined and recommended values + // for Preferences. It returns the value of a Preference with the + // highest priority, and allows to set user defined values for preferences + // that are not managed. + scoped_ptr<PrefValueStore> pref_value_store_; // A set of all the registered Preference objects. PreferenceSet prefs_; diff --git a/chrome/browser/pref_service_unittest.cc b/chrome/browser/pref_service_unittest.cc index fc801d6..49ac729 100644 --- a/chrome/browser/pref_service_unittest.cc +++ b/chrome/browser/pref_service_unittest.cc @@ -9,6 +9,7 @@ #include "base/values.h" #include "chrome/browser/dummy_pref_store.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/notification_observer_mock.h" #include "chrome/common/notification_service.h" @@ -62,7 +63,7 @@ class TestPrefObserver : public NotificationObserver { // TODO(port): port this test to POSIX. #if defined(OS_WIN) TEST(PrefServiceTest, LocalizedPrefs) { - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); const wchar_t kBoolean[] = L"boolean"; const wchar_t kInteger[] = L"integer"; const wchar_t kString[] = L"string"; @@ -85,7 +86,7 @@ TEST(PrefServiceTest, LocalizedPrefs) { #endif TEST(PrefServiceTest, NoObserverFire) { - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); const wchar_t pref_name[] = L"homepage"; prefs.RegisterStringPref(pref_name, L""); @@ -120,7 +121,7 @@ TEST(PrefServiceTest, NoObserverFire) { } TEST(PrefServiceTest, HasPrefPath) { - PrefService prefs(new DummyPrefStore()); + PrefService prefs(new PrefValueStore(NULL, new DummyPrefStore(), NULL)); const wchar_t path[] = L"fake.path"; @@ -143,8 +144,8 @@ TEST(PrefServiceTest, Observers) { DictionaryValue* dict = new DictionaryValue(); dict->SetString(pref_name, std::wstring(L"http://www.cnn.com")); DummyPrefStore* pref_store = new DummyPrefStore(); - pref_store->SetPrefs(dict); - PrefService prefs(pref_store); + pref_store->set_prefs(dict); + PrefService prefs(new PrefValueStore(NULL, pref_store, NULL)); prefs.RegisterStringPref(pref_name, L""); const std::wstring new_pref_value(L"http://www.google.com/"); @@ -185,7 +186,7 @@ class PrefServiceSetValueTest : public testing::Test { static const wchar_t value_[]; PrefServiceSetValueTest() - : prefs_(new DummyPrefStore()), + : prefs_(new PrefValueStore(NULL, new DummyPrefStore(), NULL)), name_string_(name_), null_value_(Value::CreateNullValue()) {} diff --git a/chrome/browser/pref_value_store.cc b/chrome/browser/pref_value_store.cc new file mode 100644 index 0000000..d408272 --- /dev/null +++ b/chrome/browser/pref_value_store.cc @@ -0,0 +1,116 @@ +// 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/pref_value_store.h" + +PrefValueStore::PrefValueStore(PrefStore* managed_prefs, + PrefStore* user_prefs, + PrefStore* recommended_prefs) + : managed_prefs_(managed_prefs), + user_prefs_(user_prefs), + recommended_prefs_(recommended_prefs) { +} + +PrefValueStore::~PrefValueStore() { } + +bool PrefValueStore::GetValue( + const std::wstring& name, Value** out_value) const { + // Check the |PrefStore|s in order of their priority from highest to lowest + // to find the value of the preference described by the given preference name. + if (managed_prefs_.get() && + managed_prefs_->prefs()->Get(name.c_str(), out_value) ) { + return true; + } else if (user_prefs_.get() && + user_prefs_->prefs()->Get(name.c_str(), out_value) ) { + return true; + } else if (recommended_prefs_.get() && + recommended_prefs_->prefs()->Get(name.c_str(), out_value)) { + return true; + } + // No value found for the given preference name, set the return false. + *out_value = NULL; + return false; +} + +bool PrefValueStore::WritePrefs() { + // Managed and recommended preferences are not set by the user. + // Hence they will not be written out. + return user_prefs_->WritePrefs(); +} + +void PrefValueStore::ScheduleWritePrefs() { + // Managed and recommended preferences are not set by the user. + // Hence they will not be written out. + user_prefs_->ScheduleWritePrefs(); +} + +PrefStore::PrefReadError PrefValueStore::ReadPrefs() { + PrefStore::PrefReadError managed_pref_error = PrefStore::PREF_READ_ERROR_NONE; + PrefStore::PrefReadError user_pref_error = PrefStore::PREF_READ_ERROR_NONE; + PrefStore::PrefReadError recommended_pref_error = + PrefStore::PREF_READ_ERROR_NONE; + + // Read managed preferences. + if (managed_prefs_.get()) { + managed_pref_error = managed_prefs_->ReadPrefs(); + } + + // Read preferences set by the user. + if (user_prefs_.get()) { + user_pref_error = user_prefs_->ReadPrefs(); + } + + // Read recommended preferences. + if (recommended_prefs_.get()) { + recommended_pref_error = recommended_prefs_->ReadPrefs(); + } + + // TODO(markusheintz): Return a better error status maybe a struct with + // the error status of all PrefStores. + + // Return the first pref store error that occured. + if (managed_pref_error != PrefStore::PREF_READ_ERROR_NONE) { + return managed_pref_error; + } + if (user_pref_error != PrefStore::PREF_READ_ERROR_NONE) { + return user_pref_error; + } + return recommended_pref_error; +} + +bool PrefValueStore::HasPrefPath(const wchar_t* path) const { + Value* tmp_value = NULL; + const std::wstring name(path); + bool rv = GetValue(name, &tmp_value); + return rv; +} + +// The value of a Preference is managed if the PrefStore for managed +// preferences contains a value for the given preference |name|. +bool PrefValueStore::PrefValueIsManaged(const wchar_t* name) { + if (managed_prefs_.get() == NULL) { + // No managed PreferenceStore set, hence there are no managed + // preferences. + return false; + } + Value* tmp_value; + return managed_prefs_->prefs()->Get(name, &tmp_value); +} + +// Note the |DictionaryValue| referenced by the |PrefStore| user_prefs_ +// (returned by the method Prefs()) takes the ownership of the Value referenced +// by in_value. +void PrefValueStore::SetUserPrefValue(const wchar_t* name, Value* in_value) { + user_prefs_->prefs()->Set(name, in_value); +} + +bool PrefValueStore::ReadOnly() { + return user_prefs_->ReadOnly(); +} + +void PrefValueStore::RemoveUserPrefValue(const wchar_t* name) { + if (user_prefs_.get()) { + user_prefs_->prefs()->Remove(name, NULL); + } +} diff --git a/chrome/browser/pref_value_store.h b/chrome/browser/pref_value_store.h new file mode 100644 index 0000000..a3d92d5 --- /dev/null +++ b/chrome/browser/pref_value_store.h @@ -0,0 +1,91 @@ +// 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_PREF_VALUE_STORE_H_ +#define CHROME_BROWSER_PREF_VALUE_STORE_H_ + +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/string16.h" +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "chrome/common/pref_store.h" + +class PrefStore; + +// The class PrefValueStore provides values for preferences. Each Preference +// has a unique name. This name is used to retrieve the value of a Preference. +// The value of a preference can be either managed, user-defined or recommended. +// Managed preference values are set (managed) by a third person (like an +// admin for example). They have the highest priority and can not be +// altered by the user. +// User-defined values are chosen by the user. If there is already +// a managed value for a preference the user-defined value is ignored and +// the managed value is used (returned). +// Otherwise user-defined values have a higher precedence than recommended +// values. Recommended preference values are set by a third person +// (like an admin). +class PrefValueStore { + public: + // |managed_prefs| contains all managed preference values. They have the + // highest priority and precede user-defined preference values. |user_prefs| + // contains all user-defined preference values. User-defined values precede + // recommended values. |recommended_prefs| contains all recommended + // preference values. + PrefValueStore(PrefStore* managed_prefs, + PrefStore* user_prefs, + PrefStore* recommended_prefs); + + ~PrefValueStore(); + + // Get the preference value for the given preference name. + // Return true if a value for the given preference name was found. + bool GetValue(const std::wstring& name, Value** out_value) const; + + // Read preference values into the three PrefStores so that they are available + // through the GetValue method. + PrefStore::PrefReadError ReadPrefs(); + + // Write user settable preference values. Return true if writing values was + // successfull. + bool WritePrefs(); + + // Calls the method ScheduleWritePrefs on the PrefStores. + void ScheduleWritePrefs(); + + // Returns true if the PrefValueStore contains the given preference. + bool HasPrefPath(const wchar_t* name) const; + + // Returns true if the PrefValueStore is read-only. + // Because the managed 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(); + + // 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. But GetValue calls will not return this value as long as the + // preference is managed. Instead GetValue will return the managed value + // of the preference. Note that the PrefValueStore takes the ownership of + // the value referenced by |in_value|. + void SetUserPrefValue(const wchar_t* name, Value* in_value); + + // Removes a value from the PrefValueStore. If a preference is managed + // or recommended this function should have no effect. + void RemoveUserPrefValue(const wchar_t* name); + + // Returns true if the preference with the given name is managed. + // A preference is managed if a managed value is available for that + // preference. + bool PrefValueIsManaged(const wchar_t* name); + + private: + scoped_ptr<PrefStore> managed_prefs_; + scoped_ptr<PrefStore> user_prefs_; + scoped_ptr<PrefStore> recommended_prefs_; + + DISALLOW_COPY_AND_ASSIGN(PrefValueStore); +}; + +#endif // CHROME_BROWSER_PREF_VALUE_STORE_H_ diff --git a/chrome/browser/pref_value_store_unittest.cc b/chrome/browser/pref_value_store_unittest.cc new file mode 100644 index 0000000..5fbab74 --- /dev/null +++ b/chrome/browser/pref_value_store_unittest.cc @@ -0,0 +1,268 @@ +// 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 "app/test/data/resource.h" +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/dummy_pref_store.h" +#include "chrome/browser/pref_value_store.h" + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Mock; + +// Names of the preferences used in this test program. +namespace prefs { + const wchar_t kDeleteCache[] = L"browser.clear_data.cache"; + const wchar_t kMaxTabs[] = L"tabs.max_tabs"; + const wchar_t kHomepage[] = L"homepage"; + const wchar_t kMissingPref[] = L"this.pref.does_not_exist"; + const wchar_t kRecommendedPref[] = L"this.pref.recommended_value_only"; + const wchar_t kSampleDict[] = L"sample.dict"; + const wchar_t kSampleList[] = L"sample.list"; +} + +// Expected values of all preferences used in this test programm. +namespace expected { + const int kMaxTabsValue = 31; + const bool kDeleteCacheValue = true; + const std::wstring kHomepageValue = L"http://www.google.com"; +} + +namespace enforced { + const std::wstring kHomepageValue = L"http://www.topeka.com"; +} + +namespace recommended { + const int kMaxTabsValue = 10; + const bool kRecommendedPrefValue = true; +} + +class PrefValueStoreTest : public testing::Test { + protected: + scoped_ptr<PrefValueStore> pref_value_store_; + + // |PrefStore|s are owned by the |PrefValueStore|. + DummyPrefStore* enforced_pref_store_; + DummyPrefStore* recommended_pref_store_; + DummyPrefStore* user_pref_store_; + + // Preferences are owned by the individual |DummyPrefStores|. + DictionaryValue* enforced_prefs_; + DictionaryValue* user_prefs_; + DictionaryValue* recommended_prefs_; + + virtual void SetUp() { + // Create dummy user preferences. + enforced_prefs_= CreateEnforcedPrefs(); + user_prefs_ = CreateUserPrefs(); + recommended_prefs_ = CreateRecommendedPrefs(); + + // Create |DummyPrefStore|s. + enforced_pref_store_ = new DummyPrefStore(); + enforced_pref_store_->set_prefs(enforced_prefs_); + user_pref_store_ = new DummyPrefStore(); + user_pref_store_->set_read_only(false); + user_pref_store_->set_prefs(user_prefs_); + recommended_pref_store_ = new DummyPrefStore(); + recommended_pref_store_->set_prefs(recommended_prefs_); + + // Create a new pref-value-store. + pref_value_store_.reset(new PrefValueStore(enforced_pref_store_, + user_pref_store_, + recommended_pref_store_)); + } + + // Creates a new dictionary and stores some sample user preferences + // in it. + DictionaryValue* CreateUserPrefs() { + DictionaryValue* user_prefs = new DictionaryValue(); + user_prefs->SetBoolean(prefs::kDeleteCache, expected::kDeleteCacheValue); + user_prefs->SetInteger(prefs::kMaxTabs, expected::kMaxTabsValue); + user_prefs->SetString(prefs::kHomepage, expected::kHomepageValue); + return user_prefs; + } + + DictionaryValue* CreateEnforcedPrefs() { + DictionaryValue* enforced_prefs = new DictionaryValue(); + enforced_prefs->SetString(prefs::kHomepage, enforced::kHomepageValue); + return enforced_prefs; + } + + DictionaryValue* CreateRecommendedPrefs() { + DictionaryValue* recommended_prefs = new DictionaryValue(); + recommended_prefs->SetInteger(prefs::kMaxTabs, recommended::kMaxTabsValue); + recommended_prefs->SetBoolean( + prefs::kRecommendedPref, + recommended::kRecommendedPrefValue); + return recommended_prefs; } + + DictionaryValue* CreateSampleDictValue() { + DictionaryValue* sample_dict = new DictionaryValue(); + sample_dict->SetBoolean(L"issample", true); + sample_dict->SetInteger(L"value", 4); + sample_dict->SetString(L"descr", L"Sample Test Dictionary"); + return sample_dict; + } + + ListValue* CreateSampleListValue() { + ListValue* sample_list = new ListValue(); + sample_list->Set(0, Value::CreateIntegerValue(0)); + sample_list->Set(1, Value::CreateIntegerValue(1)); + sample_list->Set(2, Value::CreateIntegerValue(2)); + sample_list->Set(3, Value::CreateIntegerValue(3)); + return sample_list; + } + + virtual void TearDown() {} +}; + + +TEST_F(PrefValueStoreTest, IsReadOnly) { + enforced_pref_store_->set_read_only(true); + user_pref_store_->set_read_only(true); + recommended_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; + + // Test getting an enforced value overwriting a user defined value. + value = NULL; + ASSERT_TRUE(pref_value_store_->GetValue(prefs::kHomepage, &value)); + std::wstring actual_str_value; + EXPECT_TRUE(value->GetAsString(&actual_str_value)); + EXPECT_EQ(enforced::kHomepageValue, actual_str_value); + + // Test getting a user set value. + value = NULL; + ASSERT_TRUE(pref_value_store_->GetValue(prefs::kDeleteCache, &value)); + bool actual_bool_value = false; + EXPECT_TRUE(value->GetAsBoolean(&actual_bool_value)); + EXPECT_EQ(expected::kDeleteCacheValue, actual_bool_value); + + // Test getting a user set value overwriting a recommended value. + value = NULL; + ASSERT_TRUE(pref_value_store_->GetValue(prefs::kMaxTabs, &value)); + int actual_int_value = -1; + EXPECT_TRUE(value->GetAsInteger(&actual_int_value)); + EXPECT_EQ(expected::kMaxTabsValue, actual_int_value); + + // Test getting a recommended value. + value = NULL; + ASSERT_TRUE(pref_value_store_->GetValue(prefs::kRecommendedPref, &value)); + actual_bool_value = false; + EXPECT_TRUE(value->GetAsBoolean(&actual_bool_value)); + EXPECT_EQ(recommended::kRecommendedPrefValue, actual_bool_value); + + // Test getting a preference value that the |PrefValueStore| + // does not contain. + FundamentalValue tmp_dummy_value(true); + Value* v_null = &tmp_dummy_value; + ASSERT_FALSE(pref_value_store_->GetValue(prefs::kMissingPref, &v_null)); + ASSERT_TRUE(v_null == NULL); +} + +TEST_F(PrefValueStoreTest, HasPrefPath) { + // Enforced preference + EXPECT_TRUE(pref_value_store_->HasPrefPath(prefs::kHomepage)); + // User preference + EXPECT_TRUE(pref_value_store_->HasPrefPath(prefs::kDeleteCache)); + // Recommended preference + EXPECT_TRUE(pref_value_store_->HasPrefPath(prefs::kRecommendedPref)); + // Unknown preference + EXPECT_FALSE(pref_value_store_->HasPrefPath(prefs::kMissingPref)); +} + +TEST_F(PrefValueStoreTest, ReadPrefs) { + pref_value_store_->ReadPrefs(); + // The ReadPrefs method of the |DummyPrefStore| 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 |DummyPrefStore| 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 enforced values can not be set. + ASSERT_TRUE(pref_value_store_->PrefValueIsManaged(prefs::kHomepage)); + // The Ownership is tranfered to |PrefValueStore|. + new_value = Value::CreateStringValue(L"http://www.youtube.com"); + pref_value_store_->SetUserPrefValue(prefs::kHomepage, new_value); + + ASSERT_TRUE(pref_value_store_->GetValue(prefs::kHomepage, &actual_value)); + std::wstring value_str; + actual_value->GetAsString(&value_str); + ASSERT_EQ(enforced::kHomepageValue, value_str); + + // User preferences values can be set + ASSERT_FALSE(pref_value_store_->PrefValueIsManaged(prefs::kMaxTabs)); + actual_value = NULL; + pref_value_store_->GetValue(prefs::kMaxTabs, &actual_value); + int int_value; + EXPECT_TRUE(actual_value->GetAsInteger(&int_value)); + EXPECT_EQ(expected::kMaxTabsValue, int_value); + + new_value = Value::CreateIntegerValue(1); + pref_value_store_->SetUserPrefValue(prefs::kMaxTabs, new_value); + actual_value = NULL; + pref_value_store_->GetValue(prefs::kMaxTabs, &actual_value); + EXPECT_TRUE(new_value->Equals(actual_value)); + + // Set and Get |DictionaryValue| + DictionaryValue* expected_dict_value = CreateSampleDictValue(); + pref_value_store_->SetUserPrefValue(prefs::kSampleDict, expected_dict_value); + + actual_value = NULL; + std::wstring 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| + ListValue* expected_list_value = CreateSampleListValue(); + pref_value_store_->SetUserPrefValue(prefs::kSampleList, expected_list_value); + + 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, PrefValueIsManaged) { + // Test an enforced preference. + ASSERT_TRUE(pref_value_store_->HasPrefPath(prefs::kHomepage)); + EXPECT_TRUE(pref_value_store_->PrefValueIsManaged(prefs::kHomepage)); + + // Test a user preference. + ASSERT_TRUE(pref_value_store_->HasPrefPath(prefs::kMaxTabs)); + EXPECT_FALSE(pref_value_store_->PrefValueIsManaged(prefs::kMaxTabs)); + + // Test a preference from the recommended pref store. + ASSERT_TRUE(pref_value_store_->HasPrefPath(prefs::kRecommendedPref)); + EXPECT_FALSE(pref_value_store_->PrefValueIsManaged(prefs::kRecommendedPref)); + + // Test a preference for which the PrefValueStore does not contain a value. + ASSERT_FALSE(pref_value_store_->HasPrefPath(prefs::kMissingPref)); + EXPECT_FALSE(pref_value_store_->PrefValueIsManaged(prefs::kMissingPref)); +} + diff --git a/chrome/browser/privacy_blacklist/blacklist_unittest.cc b/chrome/browser/privacy_blacklist/blacklist_unittest.cc index 049c32d..f010eef 100644 --- a/chrome/browser/privacy_blacklist/blacklist_unittest.cc +++ b/chrome/browser/privacy_blacklist/blacklist_unittest.cc @@ -11,6 +11,7 @@ #include "chrome/browser/browser_prefs.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/browser/profile.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_pref_store.h" @@ -24,10 +25,15 @@ class BlacklistTest : public testing::Test { source_path = source_path.AppendASCII("profiles") .AppendASCII("blacklist_prefs").AppendASCII("Preferences"); - prefs_.reset(new PrefService( - new JsonPrefStore( - source_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); + // Create a preference service that only contains user defined + // preference values. + prefs_.reset(new PrefService(new PrefValueStore( + NULL, /* No managed preference values */ + new JsonPrefStore( /* user defined preference values */ + source_path, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* No suggested preference values */))); + Profile::RegisterUserPrefs(prefs_.get()); browser::RegisterAllPrefs(prefs_.get(), prefs_.get()); } diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 89e5545..c0be2f9 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -45,6 +45,7 @@ #include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/password_manager/password_store_default.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/browser/privacy_blacklist/blacklist.h" #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" #include "chrome/browser/profile_manager.h" @@ -994,10 +995,7 @@ net::TransportSecurityState* PrefService* ProfileImpl::GetPrefs() { if (!prefs_.get()) { - prefs_.reset(new PrefService( - new JsonPrefStore( - GetPrefFilePath(), - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); + prefs_.reset(PrefService::CreatePrefService(GetPrefFilePath())); // The Profile class and ProfileManager class may read some prefs so // register known prefs as soon as possible. diff --git a/chrome/browser/tab_contents/web_contents_unittest.cc b/chrome/browser/tab_contents/web_contents_unittest.cc index 682aac6..75d75ea 100644 --- a/chrome/browser/tab_contents/web_contents_unittest.cc +++ b/chrome/browser/tab_contents/web_contents_unittest.cc @@ -5,6 +5,7 @@ #include "app/message_box_flags.h" #include "base/logging.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/test/test_render_view_host.h" @@ -51,11 +52,14 @@ class TabContentsTestingProfile : public TestingProfile { source_path = source_path.AppendASCII("profiles") .AppendASCII("chrome_prefs").AppendASCII("Preferences"); - prefs_.reset(new PrefService( - new JsonPrefStore( - source_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); - + // Create a preference service that only contains user defined + // preference values. + prefs_.reset(new PrefService(new PrefValueStore( + NULL, /* No managed preference values */ + new JsonPrefStore( /* user defined preference values */ + source_path, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* No suggested preference values */))); Profile::RegisterUserPrefs(prefs_.get()); browser::RegisterAllPrefs(prefs_.get(), prefs_.get()); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b8cdca3..7196ad4 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1827,6 +1827,9 @@ 'browser/pref_member.h', 'browser/pref_service.cc', 'browser/pref_service.h', + 'browser/pref_store.h', + 'browser/pref_value_store.cc', + 'browser/pref_value_store.h', 'browser/printing/print_dialog_gtk.cc', 'browser/printing/print_dialog_gtk.h', 'browser/printing/print_dialog_cloud.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 787ffa3..6c8ccd0 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -84,6 +84,8 @@ #'browser/net/url_request_mock_http_job.h', 'browser/net/url_request_mock_net_error_job.cc', 'browser/net/url_request_mock_net_error_job.h', + 'browser/pref_value_store.cc', + 'browser/pref_value_store.h', 'browser/renderer_host/mock_render_process_host.cc', 'browser/renderer_host/mock_render_process_host.h', 'browser/renderer_host/test/test_backing_store.cc', @@ -832,6 +834,7 @@ 'browser/in_process_webkit/dom_storage_dispatcher_host_unittest.cc', 'browser/in_process_webkit/webkit_context_unittest.cc', 'browser/in_process_webkit/webkit_thread_unittest.cc', + 'browser/pref_value_store_unittest.cc', 'browser/keychain_mock_mac.cc', 'browser/keychain_mock_mac.h', 'browser/login_prompt_unittest.cc', diff --git a/chrome/test/reliability/page_load_test.cc b/chrome/test/reliability/page_load_test.cc index 5d509de..b9fafd0 100644 --- a/chrome/test/reliability/page_load_test.cc +++ b/chrome/test/reliability/page_load_test.cc @@ -528,10 +528,12 @@ class PageLoadTest : public UITest { FilePath local_state_path = user_data_dir() .Append(chrome::kLocalStateFilename); - PrefService* local_state(new PrefService( - new JsonPrefStore( + PrefService* local_state(new PrefService(new PrefValueStore( + NULL, /* no menaged preference values */ + new JsonPrefStore( /* user defined preference values */ local_state_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no advised preference values */))); return local_state; } diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index 70e3085..dac0025 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -21,6 +21,7 @@ #include "chrome/browser/history/history.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/json_pref_store.h" @@ -149,10 +150,13 @@ class TestingProfile : public Profile { if (!prefs_.get()) { FilePath prefs_filename = path_.Append(FILE_PATH_LITERAL("TestPreferences")); - prefs_.reset(new PrefService( - new JsonPrefStore( - prefs_filename, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)))); + + prefs_.reset(new PrefService(new PrefValueStore( + NULL, /* no managed preference values */ + new JsonPrefStore( /* user defined preference values */ + prefs_filename, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no suggested preference values */))); Profile::RegisterUserPrefs(prefs_.get()); browser::RegisterAllPrefs(prefs_.get(), prefs_.get()); } diff --git a/chrome_frame/test/reliability/page_load_test.cc b/chrome_frame/test/reliability/page_load_test.cc index 70a6ee4..badbcd3 100644 --- a/chrome_frame/test/reliability/page_load_test.cc +++ b/chrome_frame/test/reliability/page_load_test.cc @@ -38,6 +38,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/pref_service.h" +#include "chrome/browser/pref_value_store.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths_internal.h" @@ -469,10 +470,12 @@ class PageLoadTest : public testing::Test { FilePath local_state_path; chrome::GetChromeFrameUserDataDirectory(&local_state_path); - PrefService* local_state = new PrefService( - new JsonPrefStore( - local_state_path, - ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE))); + PrefService* local_state = new PrefService(new PrefValueStore( + NULL, /* no managed preference values */ + new JsonPrefStore(/* user defined preference values */ + local_state_path, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)), + NULL /* no sugessted preference values */)); return local_state; } |