summaryrefslogtreecommitdiffstats
path: root/chrome/browser/prefs
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/prefs')
-rw-r--r--chrome/browser/prefs/browser_prefs.cc10
-rw-r--r--chrome/browser/prefs/command_line_pref_store.cc34
-rw-r--r--chrome/browser/prefs/command_line_pref_store.h14
-rw-r--r--chrome/browser/prefs/command_line_pref_store_unittest.cc70
-rw-r--r--chrome/browser/prefs/default_pref_store.cc21
-rw-r--r--chrome/browser/prefs/default_pref_store.h21
-rw-r--r--chrome/browser/prefs/dummy_pref_store.cc22
-rw-r--r--chrome/browser/prefs/dummy_pref_store.h49
-rw-r--r--chrome/browser/prefs/pref_change_registrar.cc1
-rw-r--r--chrome/browser/prefs/pref_change_registrar_unittest.cc16
-rw-r--r--chrome/browser/prefs/pref_member_unittest.cc5
-rw-r--r--chrome/browser/prefs/pref_notifier.cc137
-rw-r--r--chrome/browser/prefs/pref_notifier.h113
-rw-r--r--chrome/browser/prefs/pref_notifier_impl.cc105
-rw-r--r--chrome/browser/prefs/pref_notifier_impl.h58
-rw-r--r--chrome/browser/prefs/pref_notifier_impl_unittest.cc200
-rw-r--r--chrome/browser/prefs/pref_notifier_unittest.cc294
-rw-r--r--chrome/browser/prefs/pref_observer_mock.h60
-rw-r--r--chrome/browser/prefs/pref_service.cc138
-rw-r--r--chrome/browser/prefs/pref_service.h72
-rw-r--r--chrome/browser/prefs/pref_service_mock_builder.cc103
-rw-r--r--chrome/browser/prefs/pref_service_mock_builder.h68
-rw-r--r--chrome/browser/prefs/pref_service_unittest.cc328
-rw-r--r--chrome/browser/prefs/pref_set_observer.cc3
-rw-r--r--chrome/browser/prefs/pref_value_map.cc107
-rw-r--r--chrome/browser/prefs/pref_value_map.h64
-rw-r--r--chrome/browser/prefs/pref_value_map_unittest.cc76
-rw-r--r--chrome/browser/prefs/pref_value_store.cc475
-rw-r--r--chrome/browser/prefs/pref_value_store.h237
-rw-r--r--chrome/browser/prefs/pref_value_store_unittest.cc527
-rw-r--r--chrome/browser/prefs/proxy_prefs.cc45
-rw-r--r--chrome/browser/prefs/proxy_prefs.h45
-rw-r--r--chrome/browser/prefs/proxy_prefs_unittest.cc52
-rw-r--r--chrome/browser/prefs/scoped_pref_update.cc6
-rw-r--r--chrome/browser/prefs/session_startup_pref.cc2
-rw-r--r--chrome/browser/prefs/testing_pref_store.cc100
-rw-r--r--chrome/browser/prefs/testing_pref_store.h80
-rw-r--r--chrome/browser/prefs/value_map_pref_store.cc41
-rw-r--r--chrome/browser/prefs/value_map_pref_store.h48
39 files changed, 2105 insertions, 1742 deletions
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index ddc149b..1d21c1f 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -11,6 +11,9 @@
#include "chrome/browser/background_page_tracker.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/browser_shutdown.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/content_settings/policy_content_settings_provider.h"
+#include "chrome/browser/content_settings/pref_content_settings_provider.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/dom_ui/flags_ui.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
@@ -23,7 +26,6 @@
#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
#include "chrome/browser/geolocation/geolocation_prefs.h"
#include "chrome/browser/google/google_url_tracker.h"
-#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/host_zoom_map.h"
#include "chrome/browser/intranet_redirect_detector.h"
#include "chrome/browser/instant/instant_controller.h"
@@ -36,7 +38,7 @@
#include "chrome/browser/page_info_model.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/prefs/session_startup_pref.h"
-#include "chrome/browser/profile_impl.h"
+#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
@@ -90,7 +92,6 @@ void RegisterLocalState(PrefService* local_state) {
MetricsService::RegisterPrefs(local_state);
SafeBrowsingService::RegisterPrefs(local_state);
browser_shutdown::RegisterPrefs(local_state);
- chrome_browser_net::RegisterPrefs(local_state);
#if defined(TOOLKIT_VIEWS)
BrowserView::RegisterBrowserViewPrefs(local_state);
#endif
@@ -112,7 +113,6 @@ void RegisterLocalState(PrefService* local_state) {
void RegisterUserPrefs(PrefService* user_prefs) {
// User prefs
AutoFillManager::RegisterUserPrefs(user_prefs);
- BackgroundModeManager::RegisterUserPrefs(user_prefs);
SessionStartupPref::RegisterUserPrefs(user_prefs);
Browser::RegisterUserPrefs(user_prefs);
PasswordManager::RegisterUserPrefs(user_prefs);
@@ -128,6 +128,8 @@ void RegisterUserPrefs(PrefService* user_prefs) {
PluginsUI::RegisterUserPrefs(user_prefs);
ProfileImpl::RegisterUserPrefs(user_prefs);
HostContentSettingsMap::RegisterUserPrefs(user_prefs);
+ PolicyContentSettingsProvider::RegisterUserPrefs(user_prefs);
+ PrefContentSettingsProvider::RegisterUserPrefs(user_prefs);
HostZoomMap::RegisterUserPrefs(user_prefs);
DevToolsManager::RegisterUserPrefs(user_prefs);
PinnedTabCodec::RegisterUserPrefs(user_prefs);
diff --git a/chrome/browser/prefs/command_line_pref_store.cc b/chrome/browser/prefs/command_line_pref_store.cc
index cbb7ef7..4a386d6 100644
--- a/chrome/browser/prefs/command_line_pref_store.cc
+++ b/chrome/browser/prefs/command_line_pref_store.cc
@@ -7,6 +7,7 @@
#include "app/app_switches.h"
#include "base/logging.h"
#include "base/values.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -25,8 +26,6 @@ const CommandLinePrefStore::StringSwitchToPreferenceMapEntry
const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry
CommandLinePrefStore::boolean_switch_map_[] = {
- { switches::kNoProxyServer, prefs::kNoProxyServer, true },
- { switches::kProxyAutoDetect, prefs::kProxyAutoDetect, true },
{ switches::kDisableAuthNegotiateCnameLookup,
prefs::kDisableAuthNegotiateCnameLookup, true },
{ switches::kEnableAuthNegotiatePort, prefs::kEnableAuthNegotiatePort,
@@ -35,24 +34,21 @@ 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();
+ ApplyProxyMode();
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);
}
}
@@ -60,7 +56,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);
}
}
}
@@ -77,3 +73,19 @@ bool CommandLinePrefStore::ValidateProxySwitches() {
}
return true;
}
+
+void CommandLinePrefStore::ApplyProxyMode() {
+ if (command_line_->HasSwitch(switches::kNoProxyServer)) {
+ SetValue(prefs::kProxyMode,
+ Value::CreateIntegerValue(ProxyPrefs::MODE_DIRECT));
+ } else if (command_line_->HasSwitch(switches::kProxyPacUrl)) {
+ SetValue(prefs::kProxyMode,
+ Value::CreateIntegerValue(ProxyPrefs::MODE_PAC_SCRIPT));
+ } else if (command_line_->HasSwitch(switches::kProxyAutoDetect)) {
+ SetValue(prefs::kProxyMode,
+ Value::CreateIntegerValue(ProxyPrefs::MODE_AUTO_DETECT));
+ } else if (command_line_->HasSwitch(switches::kProxyServer)) {
+ SetValue(prefs::kProxyMode,
+ Value::CreateIntegerValue(ProxyPrefs::MODE_FIXED_SERVERS));
+ }
+}
diff --git a/chrome/browser/prefs/command_line_pref_store.h b/chrome/browser/prefs/command_line_pref_store.h
index 2ea29ae..75d8b10 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.
@@ -48,11 +45,12 @@ class CommandLinePrefStore : public PrefStore {
// corresponding preferences in this pref store.
void ApplySimpleSwitches();
+ // Determines the proxy mode preference from the given proxy switches.
+ void ApplyProxyMode();
+
// 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..1be9c0a 100644
--- a/chrome/browser/prefs/command_line_pref_store_unittest.cc
+++ b/chrome/browser/prefs/command_line_pref_store_unittest.cc
@@ -9,6 +9,7 @@
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/prefs/command_line_pref_store.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -22,6 +23,12 @@ class TestCommandLinePrefStore : public CommandLinePrefStore {
bool ProxySwitchesAreValid() {
return ValidateProxySwitches();
}
+
+ void VerifyIntPref(const std::string& path, int expected_value) {
+ Value* actual = NULL;
+ ASSERT_EQ(PrefStore::READ_OK, GetValue(path, &actual));
+ EXPECT_TRUE(FundamentalValue(expected_value).Equals(actual));
+ }
};
const char unknown_bool[] = "unknown_switch";
@@ -34,10 +41,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);
}
@@ -45,12 +54,9 @@ TEST(CommandLinePrefStoreTest, SimpleStringPref) {
TEST(CommandLinePrefStoreTest, SimpleBooleanPref) {
CommandLine cl(CommandLine::NO_PROGRAM);
cl.AppendSwitch(switches::kNoProxyServer);
- CommandLinePrefStore store(&cl);
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
+ TestCommandLinePrefStore store(&cl);
- bool result;
- EXPECT_TRUE(store.prefs()->GetBoolean(prefs::kNoProxyServer, &result));
- EXPECT_TRUE(result);
+ store.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_DIRECT);
}
// Tests a command line with no recognized prefs.
@@ -59,15 +65,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.
@@ -78,22 +79,20 @@ TEST(CommandLinePrefStoreTest, MultipleSwitches) {
cl.AppendSwitchASCII(switches::kProxyServer, "proxy");
cl.AppendSwitchASCII(switches::kProxyBypassList, "list");
cl.AppendSwitchASCII(unknown_bool, "a value");
- CommandLinePrefStore store(&cl);
- EXPECT_EQ(store.ReadPrefs(), PrefStore::PREF_READ_ERROR_NONE);
+ TestCommandLinePrefStore store(&cl);
- 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(bool_result);
+ Value* actual = NULL;
+ EXPECT_EQ(PrefStore::READ_NO_VALUE, store.GetValue(unknown_bool, &actual));
+ store.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_AUTO_DETECT);
+ 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 +102,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 +121,18 @@ 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());
}
+
+TEST(CommandLinePrefStoreTest, ManualProxyModeInference) {
+ CommandLine cl1(CommandLine::NO_PROGRAM);
+ cl1.AppendSwitch(unknown_string);
+ cl1.AppendSwitchASCII(switches::kProxyServer, "proxy");
+ TestCommandLinePrefStore store1(&cl1);
+ store1.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_FIXED_SERVERS);
+
+ CommandLine cl2(CommandLine::NO_PROGRAM);
+ cl2.AppendSwitchASCII(switches::kProxyPacUrl, "proxy");
+ TestCommandLinePrefStore store2(&cl2);
+ store2.VerifyIntPref(prefs::kProxyMode, ProxyPrefs::MODE_PAC_SCRIPT);
+}
diff --git a/chrome/browser/prefs/default_pref_store.cc b/chrome/browser/prefs/default_pref_store.cc
deleted file mode 100644
index a9e6861..0000000
--- a/chrome/browser/prefs/default_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/default_pref_store.h"
-
-#include "base/values.h"
-
-DefaultPrefStore::DefaultPrefStore() : prefs_(new DictionaryValue()) {
-}
-
-DefaultPrefStore::~DefaultPrefStore() {
-}
-
-DictionaryValue* DefaultPrefStore::prefs() const {
- return prefs_.get();
-}
-
-PrefStore::PrefReadError DefaultPrefStore::ReadPrefs() {
- return PrefStore::PREF_READ_ERROR_NONE;
-}
diff --git a/chrome/browser/prefs/default_pref_store.h b/chrome/browser/prefs/default_pref_store.h
index 6378aca..9e2e715 100644
--- a/chrome/browser/prefs/default_pref_store.h
+++ b/chrome/browser/prefs/default_pref_store.h
@@ -6,25 +6,24 @@
#define CHROME_BROWSER_PREFS_DEFAULT_PREF_STORE_H_
#pragma once
+#include <map>
+
#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "chrome/common/pref_store.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 PrefStore {
+class DefaultPrefStore : public ValueMapPrefStore {
public:
- DefaultPrefStore();
- virtual ~DefaultPrefStore();
+ DefaultPrefStore() {}
+ virtual ~DefaultPrefStore() {}
- // PrefStore methods:
- virtual DictionaryValue* prefs() const;
- virtual PrefStore::PrefReadError ReadPrefs();
+ // Stores a new |value| for |key|. Assumes ownership of |value|.
+ void SetDefaultValue(const std::string& key, Value* value) {
+ SetValue(key, value);
+ }
private:
- // The default preference values.
- scoped_ptr<DictionaryValue> prefs_;
-
DISALLOW_COPY_AND_ASSIGN(DefaultPrefStore);
};
diff --git a/chrome/browser/prefs/dummy_pref_store.cc b/chrome/browser/prefs/dummy_pref_store.cc
deleted file mode 100644
index 3a0a81a..0000000
--- a/chrome/browser/prefs/dummy_pref_store.cc
+++ /dev/null
@@ -1,22 +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/dummy_pref_store.h"
-
-#include "base/values.h"
-
-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/prefs/dummy_pref_store.h b/chrome/browser/prefs/dummy_pref_store.h
deleted file mode 100644
index 4a4e6ba..0000000
--- a/chrome/browser/prefs/dummy_pref_store.h
+++ /dev/null
@@ -1,49 +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_DUMMY_PREF_STORE_H_
-#define CHROME_BROWSER_PREFS_DUMMY_PREF_STORE_H_
-#pragma once
-
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "chrome/common/pref_store.h"
-
-class DictionaryValue;
-
-// |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() const { return prefs_.get(); }
-
- 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);
-};
-
-#endif // CHROME_BROWSER_PREFS_DUMMY_PREF_STORE_H_
diff --git a/chrome/browser/prefs/pref_change_registrar.cc b/chrome/browser/prefs/pref_change_registrar.cc
index 05372b1..5655a8e 100644
--- a/chrome/browser/prefs/pref_change_registrar.cc
+++ b/chrome/browser/prefs/pref_change_registrar.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/prefs/pref_change_registrar.h"
+#include "base/logging.h"
#include "chrome/browser/prefs/pref_service.h"
PrefChangeRegistrar::PrefChangeRegistrar() : service_(NULL) {}
diff --git a/chrome/browser/prefs/pref_change_registrar_unittest.cc b/chrome/browser/prefs/pref_change_registrar_unittest.cc
index 8096ee6..2e4cd0e 100644
--- a/chrome/browser/prefs/pref_change_registrar_unittest.cc
+++ b/chrome/browser/prefs/pref_change_registrar_unittest.cc
@@ -4,8 +4,9 @@
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_observer_mock.h"
#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -14,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:
@@ -24,12 +27,7 @@ class MockPrefService : public TestingPrefService {
MOCK_METHOD2(RemovePrefObserver, void(const char*, NotificationObserver*));
};
-// A mock observer used as a pref observer
-class MockObserver : public NotificationObserver {
- public:
- MOCK_METHOD3(Observe, void(NotificationType, const NotificationSource& source,
- const NotificationDetails& details));
-};
+} // namespace
class PrefChangeRegistrarTest : public testing::Test {
public:
@@ -44,12 +42,12 @@ class PrefChangeRegistrarTest : public testing::Test {
private:
scoped_ptr<MockPrefService> service_;
- scoped_ptr<MockObserver> observer_;
+ scoped_ptr<NotificationObserverMock> observer_;
};
void PrefChangeRegistrarTest::SetUp() {
service_.reset(new MockPrefService());
- observer_.reset(new MockObserver());
+ observer_.reset(new NotificationObserverMock());
}
TEST_F(PrefChangeRegistrarTest, AddAndRemove) {
diff --git a/chrome/browser/prefs/pref_member_unittest.cc b/chrome/browser/prefs/pref_member_unittest.cc
index f59f937..3f786afb 100644
--- a/chrome/browser/prefs/pref_member_unittest.cc
+++ b/chrome/browser/prefs/pref_member_unittest.cc
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/prefs/dummy_pref_store.h"
#include "chrome/browser/prefs/pref_member.h"
#include "chrome/browser/prefs/pref_value_store.h"
-#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
#include "chrome/test/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/prefs/pref_notifier.cc b/chrome/browser/prefs/pref_notifier.cc
deleted file mode 100644
index 151b128..0000000
--- a/chrome/browser/prefs/pref_notifier.cc
+++ /dev/null
@@ -1,137 +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/pref_notifier.h"
-
-#include "base/stl_util-inl.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/policy/configuration_policy_pref_store.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/pref_value_store.h"
-#include "chrome/common/notification_service.h"
-
-
-PrefNotifier::PrefNotifier(PrefService* service, PrefValueStore* value_store)
- : pref_service_(service),
- pref_value_store_(value_store) {
- registrar_.Add(this,
- NotificationType(NotificationType::POLICY_CHANGED),
- NotificationService::AllSources());
-}
-
-PrefNotifier::~PrefNotifier() {
- DCHECK(CalledOnValidThread());
-
- // Verify that there are no pref observers when we shut down.
- for (PrefObserverMap::iterator it = pref_observers_.begin();
- it != pref_observers_.end(); ++it) {
- NotificationObserverList::Iterator obs_iterator(*(it->second));
- if (obs_iterator.GetNext()) {
- LOG(WARNING) << "pref observer found at shutdown " << it->first;
- }
- }
-
- STLDeleteContainerPairSecondPointers(pref_observers_.begin(),
- pref_observers_.end());
- pref_observers_.clear();
-}
-
-void PrefNotifier::OnPreferenceSet(const char* pref_name,
- PrefNotifier::PrefStoreType new_store) {
- if (pref_value_store_->PrefHasChanged(pref_name, new_store))
- FireObservers(pref_name);
-}
-
-void PrefNotifier::OnUserPreferenceSet(const char* pref_name) {
- OnPreferenceSet(pref_name, PrefNotifier::USER_STORE);
-}
-
-void PrefNotifier::FireObservers(const char* path) {
- DCHECK(CalledOnValidThread());
-
- // Convert path to a std::string because the Details constructor requires a
- // class.
- std::string path_str(path);
- PrefObserverMap::iterator observer_iterator = pref_observers_.find(path_str);
- if (observer_iterator == pref_observers_.end())
- return;
-
- NotificationObserverList::Iterator it(*(observer_iterator->second));
- NotificationObserver* observer;
- while ((observer = it.GetNext()) != NULL) {
- observer->Observe(NotificationType::PREF_CHANGED,
- Source<PrefService>(pref_service_),
- Details<std::string>(&path_str));
- }
-}
-
-void PrefNotifier::AddPrefObserver(const char* path,
- NotificationObserver* obs) {
- // Get the pref observer list associated with the path.
- NotificationObserverList* observer_list = NULL;
- PrefObserverMap::iterator observer_iterator = pref_observers_.find(path);
- if (observer_iterator == pref_observers_.end()) {
- observer_list = new NotificationObserverList;
- pref_observers_[path] = observer_list;
- } else {
- observer_list = observer_iterator->second;
- }
-
- // Verify that this observer doesn't already exist.
- NotificationObserverList::Iterator it(*observer_list);
- NotificationObserver* existing_obs;
- while ((existing_obs = it.GetNext()) != NULL) {
- DCHECK(existing_obs != obs) << path << " observer already registered";
- if (existing_obs == obs)
- return;
- }
-
- // Ok, safe to add the pref observer.
- observer_list->AddObserver(obs);
-}
-
-void PrefNotifier::RemovePrefObserver(const char* path,
- NotificationObserver* obs) {
- DCHECK(CalledOnValidThread());
-
- PrefObserverMap::iterator observer_iterator = pref_observers_.find(path);
- if (observer_iterator == pref_observers_.end()) {
- return;
- }
-
- NotificationObserverList* observer_list = observer_iterator->second;
- observer_list->RemoveObserver(obs);
-}
-
-void PrefNotifier::FireObserversForRefreshedManagedPrefs(
- std::vector<std::string> changed_prefs_paths) {
- DCHECK(CalledOnValidThread());
- std::vector<std::string>::const_iterator current;
- for (current = changed_prefs_paths.begin();
- current != changed_prefs_paths.end();
- ++current) {
- FireObservers(current->c_str());
- }
-}
-
-void PrefNotifier::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- using policy::ConfigurationPolicyPrefStore;
-
- if (type == NotificationType::POLICY_CHANGED) {
- PrefValueStore::AfterRefreshCallback* callback =
- NewCallback(this,
- &PrefNotifier::FireObserversForRefreshedManagedPrefs);
- // The notification of the policy refresh can come from any thread,
- // but the manipulation of the PrefValueStore must happen on the UI
- // thread, thus the policy refresh must be explicitly started on it.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- pref_value_store_,
- &PrefValueStore::RefreshPolicyPrefs,
- callback));
- }
-}
diff --git a/chrome/browser/prefs/pref_notifier.h b/chrome/browser/prefs/pref_notifier.h
index 7334a51..f2d9c52 100644
--- a/chrome/browser/prefs/pref_notifier.h
+++ b/chrome/browser/prefs/pref_notifier.h
@@ -7,112 +7,21 @@
#pragma once
#include <string>
-#include <vector>
-#include "base/hash_tables.h"
-#include "base/non_thread_safe.h"
-#include "base/observer_list.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-
-class NotificationObserver;
-class PrefService;
-class PrefValueStore;
-class Value;
-
-// Registers observers for particular preferences and sends notifications when
-// preference values or sources (i.e., which preference layer controls the
-// preference) change.
-class PrefNotifier : public NonThreadSafe,
- public NotificationObserver {
+// Delegate interface used by PrefValueStore to notify its owner about changes
+// to the preference values.
+// TODO(mnissler, danno): Move this declaration to pref_value_store.h once we've
+// cleaned up all public uses of this interface.
+class PrefNotifier {
public:
- // PrefStores must be listed here in order from highest to lowest priority.
- // MANAGED_PLATFORM contains all managed preference values that are
- // provided by a platform-specific policy mechanism (e.g. Windows
- // Group Policy).
- // DEVICE_MANAGEMENT contains all managed preference values supplied
- // by the device management server (cloud policy).
- // EXTENSION contains preference values set by extensions.
- // COMMAND_LINE contains preference values set by command-line switches.
- // USER contains all user-set preference values.
- // RECOMMENDED contains all recommended (policy) preference values.
- // DEFAULT contains all application default preference values.
- // This enum is kept in pref_notifier.h rather than pref_value_store.h in
- // order to minimize additional headers needed by the *PrefStore files.
- enum PrefStoreType {
- // INVALID_STORE is not associated with an actual PrefStore but used as
- // an invalid marker, e.g. as a return value.
- INVALID_STORE = -1,
- MANAGED_PLATFORM_STORE = 0,
- DEVICE_MANAGEMENT_STORE,
- EXTENSION_STORE,
- COMMAND_LINE_STORE,
- USER_STORE,
- RECOMMENDED_STORE,
- DEFAULT_STORE,
- PREF_STORE_TYPE_MAX = DEFAULT_STORE
- };
-
- // The |service| with which this notifier is associated will be sent as the
- // source of any notifications.
- PrefNotifier(PrefService* service, PrefValueStore* value_store);
-
- virtual ~PrefNotifier();
-
- // For the given pref_name, fire any observer of the pref if the effective
- // value of the pref or the store controlling its value has changed, been
- // added, or been removed (but not if it's re-setting the same value it had
- // already). |new_store| should be the PrefStoreType of the store reporting
- // the change.
- void OnPreferenceSet(const char* pref_name,
- PrefNotifier::PrefStoreType new_store);
-
- // Convenience method to be called when a preference is set in the
- // USER_STORE. See OnPreferenceSet().
- void OnUserPreferenceSet(const char* pref_name);
-
- // For the given pref_name, fire any observer of the pref. Virtual so it can
- // be mocked for unit testing.
- virtual void FireObservers(const char* path);
-
- // If the pref at the given path changes, we call the observer's Observe
- // method with PREF_CHANGED.
- void AddPrefObserver(const char* path, NotificationObserver* obs);
- void RemovePrefObserver(const char* path, NotificationObserver* obs);
-
- protected:
- // A map from pref names to a list of observers. Observers get fired in the
- // order they are added. These should only be accessed externally for unit
- // testing.
- typedef ObserverList<NotificationObserver> NotificationObserverList;
- typedef base::hash_map<std::string, NotificationObserverList*>
- PrefObserverMap;
- const PrefObserverMap* pref_observers() { return &pref_observers_; }
-
- private:
- // Weak references.
- PrefService* pref_service_;
- PrefValueStore* pref_value_store_;
-
- NotificationRegistrar registrar_;
-
- PrefObserverMap pref_observers_;
-
- // Called after a policy refresh to notify relevant preference observers.
- // |changed_prefs_paths| is the vector of preference paths changed by the
- // policy update. It is passed by value and not reference because
- // this method is called asynchronously as a callback from another thread.
- // Copying the vector guarantees that the vector's lifecycle spans the
- // method's invocation.
- void FireObserversForRefreshedManagedPrefs(
- std::vector<std::string> changed_prefs_paths);
+ virtual ~PrefNotifier() {}
- // NotificationObserver methods:
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ // Sends out a change notification for the preference identified by
+ // |pref_name|.
+ virtual void OnPreferenceChanged(const std::string& pref_name) = 0;
- DISALLOW_COPY_AND_ASSIGN(PrefNotifier);
+ // Broadcasts the intialization completed notification.
+ virtual void OnInitializationCompleted() = 0;
};
#endif // CHROME_BROWSER_PREFS_PREF_NOTIFIER_H_
diff --git a/chrome/browser/prefs/pref_notifier_impl.cc b/chrome/browser/prefs/pref_notifier_impl.cc
new file mode 100644
index 0000000..d15f425
--- /dev/null
+++ b/chrome/browser/prefs/pref_notifier_impl.cc
@@ -0,0 +1,105 @@
+// 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_notifier_impl.h"
+
+#include "base/stl_util-inl.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_service.h"
+
+PrefNotifierImpl::PrefNotifierImpl(PrefService* service)
+ : pref_service_(service) {
+}
+
+PrefNotifierImpl::~PrefNotifierImpl() {
+ DCHECK(CalledOnValidThread());
+
+ // Verify that there are no pref observers when we shut down.
+ for (PrefObserverMap::iterator it = pref_observers_.begin();
+ it != pref_observers_.end(); ++it) {
+ NotificationObserverList::Iterator obs_iterator(*(it->second));
+ if (obs_iterator.GetNext()) {
+ LOG(WARNING) << "pref observer found at shutdown " << it->first;
+ }
+ }
+
+ STLDeleteContainerPairSecondPointers(pref_observers_.begin(),
+ pref_observers_.end());
+ pref_observers_.clear();
+}
+
+void PrefNotifierImpl::AddPrefObserver(const char* path,
+ NotificationObserver* obs) {
+ // Get the pref observer list associated with the path.
+ NotificationObserverList* observer_list = NULL;
+ const PrefObserverMap::iterator observer_iterator =
+ pref_observers_.find(path);
+ if (observer_iterator == pref_observers_.end()) {
+ observer_list = new NotificationObserverList;
+ pref_observers_[path] = observer_list;
+ } else {
+ observer_list = observer_iterator->second;
+ }
+
+ // Verify that this observer doesn't already exist.
+ NotificationObserverList::Iterator it(*observer_list);
+ NotificationObserver* existing_obs;
+ while ((existing_obs = it.GetNext()) != NULL) {
+ DCHECK(existing_obs != obs) << path << " observer already registered";
+ if (existing_obs == obs)
+ return;
+ }
+
+ // Ok, safe to add the pref observer.
+ observer_list->AddObserver(obs);
+}
+
+void PrefNotifierImpl::RemovePrefObserver(const char* path,
+ NotificationObserver* obs) {
+ DCHECK(CalledOnValidThread());
+
+ const PrefObserverMap::iterator observer_iterator =
+ pref_observers_.find(path);
+ if (observer_iterator == pref_observers_.end()) {
+ return;
+ }
+
+ NotificationObserverList* observer_list = observer_iterator->second;
+ observer_list->RemoveObserver(obs);
+}
+
+void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) {
+ FireObservers(path);
+}
+
+void PrefNotifierImpl::OnInitializationCompleted() {
+ DCHECK(CalledOnValidThread());
+
+ NotificationService::current()->Notify(
+ NotificationType::PREF_INITIALIZATION_COMPLETED,
+ Source<PrefService>(pref_service_),
+ NotificationService::NoDetails());
+}
+
+void PrefNotifierImpl::FireObservers(const std::string& path) {
+ DCHECK(CalledOnValidThread());
+
+ // Only send notifications for registered preferences.
+ if (!pref_service_->FindPreference(path.c_str()))
+ return;
+
+ const PrefObserverMap::iterator observer_iterator =
+ pref_observers_.find(path);
+ if (observer_iterator == pref_observers_.end())
+ return;
+
+ NotificationObserverList::Iterator it(*(observer_iterator->second));
+ NotificationObserver* observer;
+ while ((observer = it.GetNext()) != NULL) {
+ observer->Observe(NotificationType::PREF_CHANGED,
+ Source<PrefService>(pref_service_),
+ Details<const std::string>(&path));
+ }
+}
diff --git a/chrome/browser/prefs/pref_notifier_impl.h b/chrome/browser/prefs/pref_notifier_impl.h
new file mode 100644
index 0000000..1d61830
--- /dev/null
+++ b/chrome/browser/prefs/pref_notifier_impl.h
@@ -0,0 +1,58 @@
+// 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_NOTIFIER_IMPL_H_
+#define CHROME_BROWSER_PREFS_PREF_NOTIFIER_IMPL_H_
+#pragma once
+
+#include <string>
+
+#include "base/hash_tables.h"
+#include "base/non_thread_safe.h"
+#include "base/observer_list.h"
+#include "chrome/browser/prefs/pref_notifier.h"
+
+class PrefService;
+class NotificationObserver;
+
+// The PrefNotifier implementation used by the PrefService.
+class PrefNotifierImpl : public PrefNotifier,
+ public NonThreadSafe {
+ public:
+ explicit PrefNotifierImpl(PrefService* pref_service);
+ virtual ~PrefNotifierImpl();
+
+ // If the pref at the given path changes, we call the observer's Observe
+ // method with PREF_CHANGED.
+ void AddPrefObserver(const char* path, NotificationObserver* obs);
+ void RemovePrefObserver(const char* path, NotificationObserver* obs);
+
+ // PrefNotifier overrides.
+ virtual void OnPreferenceChanged(const std::string& pref_name);
+ virtual void OnInitializationCompleted();
+
+ protected:
+ // A map from pref names to a list of observers. Observers get fired in the
+ // order they are added. These should only be accessed externally for unit
+ // testing.
+ typedef ObserverList<NotificationObserver> NotificationObserverList;
+ typedef base::hash_map<std::string, NotificationObserverList*>
+ PrefObserverMap;
+
+ const PrefObserverMap* pref_observers() const { return &pref_observers_; }
+
+ private:
+ // For the given pref_name, fire any observer of the pref. Virtual so it can
+ // be mocked for unit testing.
+ virtual void FireObservers(const std::string& path);
+
+ // Weak reference; the notifier is owned by the PrefService.
+ PrefService* pref_service_;
+
+ PrefObserverMap pref_observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefNotifierImpl);
+};
+
+#endif // CHROME_BROWSER_PREFS_PREF_NOTIFIER_IMPL_H_
diff --git a/chrome/browser/prefs/pref_notifier_impl_unittest.cc b/chrome/browser/prefs/pref_notifier_impl_unittest.cc
new file mode 100644
index 0000000..a410884
--- /dev/null
+++ b/chrome/browser/prefs/pref_notifier_impl_unittest.cc
@@ -0,0 +1,200 @@
+// 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_notifier_impl.h"
+#include "chrome/browser/prefs/pref_observer_mock.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/pref_value_store.h"
+#include "chrome/common/notification_observer_mock.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/test/testing_pref_service.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Field;
+using testing::Invoke;
+using testing::Mock;
+using testing::Truly;
+
+namespace {
+
+const char kChangedPref[] = "changed_pref";
+const char kUnchangedPref[] = "unchanged_pref";
+
+bool DetailsAreChangedPref(const Details<std::string>& details) {
+ std::string* string_in = Details<std::string>(details).ptr();
+ return strcmp(string_in->c_str(), kChangedPref) == 0;
+}
+
+// Test PrefNotifier that allows tracking of observers and notifications.
+class MockPrefNotifier : public PrefNotifierImpl {
+ public:
+ explicit MockPrefNotifier(PrefService* pref_service)
+ : PrefNotifierImpl(pref_service) {}
+ virtual ~MockPrefNotifier() {}
+
+ MOCK_METHOD1(FireObservers, void(const std::string& path));
+
+ size_t CountObserver(const char* path, NotificationObserver* obs) {
+ PrefObserverMap::const_iterator observer_iterator =
+ pref_observers()->find(path);
+ if (observer_iterator == pref_observers()->end())
+ return false;
+
+ NotificationObserverList* observer_list = observer_iterator->second;
+ NotificationObserverList::Iterator it(*observer_list);
+ NotificationObserver* existing_obs;
+ size_t count = 0;
+ while ((existing_obs = it.GetNext()) != NULL) {
+ if (existing_obs == obs)
+ count++;
+ }
+
+ return count;
+ }
+};
+
+// Test fixture class.
+class PrefNotifierTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ pref_service_.RegisterBooleanPref(kChangedPref, true);
+ pref_service_.RegisterBooleanPref(kUnchangedPref, true);
+ }
+
+ TestingPrefService pref_service_;
+
+ PrefObserverMock obs1_;
+ PrefObserverMock obs2_;
+};
+
+TEST_F(PrefNotifierTest, OnPreferenceChanged) {
+ MockPrefNotifier notifier(&pref_service_);
+ EXPECT_CALL(notifier, FireObservers(kChangedPref)).Times(1);
+ notifier.OnPreferenceChanged(kChangedPref);
+}
+
+TEST_F(PrefNotifierTest, OnInitializationCompleted) {
+ MockPrefNotifier notifier(&pref_service_);
+ NotificationObserverMock observer;
+ NotificationRegistrar registrar;
+ registrar.Add(&observer, NotificationType::PREF_INITIALIZATION_COMPLETED,
+ Source<PrefService>(&pref_service_));
+ EXPECT_CALL(observer, Observe(
+ Field(&NotificationType::value,
+ NotificationType::PREF_INITIALIZATION_COMPLETED),
+ Source<PrefService>(&pref_service_),
+ NotificationService::NoDetails()));
+ notifier.OnInitializationCompleted();
+}
+
+TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) {
+ const char pref_name[] = "homepage";
+ const char pref_name2[] = "proxy";
+
+ MockPrefNotifier notifier(&pref_service_);
+ notifier.AddPrefObserver(pref_name, &obs1_);
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ // Re-adding the same observer for the same pref doesn't change anything.
+ // Skip this in debug mode, since it hits a DCHECK and death tests aren't
+ // thread-safe.
+#if defined(NDEBUG)
+ notifier.AddPrefObserver(pref_name, &obs1_);
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+#endif // NDEBUG
+
+ // Ensure that we can add the same observer to a different pref.
+ notifier.AddPrefObserver(pref_name2, &obs1_);
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ // Ensure that we can add another observer to the same pref.
+ notifier.AddPrefObserver(pref_name, &obs2_);
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ // Ensure that we can remove all observers, and that removing a non-existent
+ // observer is harmless.
+ notifier.RemovePrefObserver(pref_name, &obs1_);
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ notifier.RemovePrefObserver(pref_name, &obs2_);
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ notifier.RemovePrefObserver(pref_name, &obs1_);
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+
+ notifier.RemovePrefObserver(pref_name2, &obs1_);
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
+ ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
+}
+
+TEST_F(PrefNotifierTest, FireObservers) {
+ FundamentalValue value_true(true);
+ PrefNotifierImpl notifier(&pref_service_);
+ notifier.AddPrefObserver(kChangedPref, &obs1_);
+ notifier.AddPrefObserver(kUnchangedPref, &obs1_);
+
+ obs1_.Expect(&pref_service_, kChangedPref, &value_true);
+ EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
+ notifier.OnPreferenceChanged(kChangedPref);
+ Mock::VerifyAndClearExpectations(&obs1_);
+ Mock::VerifyAndClearExpectations(&obs2_);
+
+ notifier.AddPrefObserver(kChangedPref, &obs2_);
+ notifier.AddPrefObserver(kUnchangedPref, &obs2_);
+
+ obs1_.Expect(&pref_service_, kChangedPref, &value_true);
+ obs2_.Expect(&pref_service_, kChangedPref, &value_true);
+ notifier.OnPreferenceChanged(kChangedPref);
+ Mock::VerifyAndClearExpectations(&obs1_);
+ Mock::VerifyAndClearExpectations(&obs2_);
+
+ // Make sure removing an observer from one pref doesn't affect anything else.
+ notifier.RemovePrefObserver(kChangedPref, &obs1_);
+
+ EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
+ obs2_.Expect(&pref_service_, kChangedPref, &value_true);
+ notifier.OnPreferenceChanged(kChangedPref);
+ Mock::VerifyAndClearExpectations(&obs1_);
+ Mock::VerifyAndClearExpectations(&obs2_);
+
+ // Make sure removing an observer entirely doesn't affect anything else.
+ notifier.RemovePrefObserver(kUnchangedPref, &obs1_);
+
+ EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
+ obs2_.Expect(&pref_service_, kChangedPref, &value_true);
+ notifier.OnPreferenceChanged(kChangedPref);
+ Mock::VerifyAndClearExpectations(&obs1_);
+ Mock::VerifyAndClearExpectations(&obs2_);
+
+ notifier.RemovePrefObserver(kChangedPref, &obs2_);
+ notifier.RemovePrefObserver(kUnchangedPref, &obs2_);
+}
+
+} // namespace
diff --git a/chrome/browser/prefs/pref_notifier_unittest.cc b/chrome/browser/prefs/pref_notifier_unittest.cc
deleted file mode 100644
index 6792ada..0000000
--- a/chrome/browser/prefs/pref_notifier_unittest.cc
+++ /dev/null
@@ -1,294 +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/default_pref_store.h"
-#include "chrome/browser/prefs/pref_notifier.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/pref_value_store.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_type.h"
-#include "chrome/common/notification_service.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-
-namespace {
-
-const char kChangedPref[] = "changed_pref";
-const char kUnchangedPref[] = "unchanged_pref";
-
-bool DetailsAreChangedPref(const Details<std::string>& details) {
- std::string* string_in = Details<std::string>(details).ptr();
- return strcmp(string_in->c_str(), kChangedPref) == 0;
-}
-
-// Test PrefNotifier that allows tracking of observers and notifications.
-class MockPrefNotifier : public PrefNotifier {
- public:
- MockPrefNotifier(PrefService* prefs, PrefValueStore* value_store)
- : PrefNotifier(prefs, value_store) {}
-
- virtual ~MockPrefNotifier() {}
-
- MOCK_METHOD1(FireObservers, void(const char* path));
-
- void RealFireObservers(const char* path) {
- PrefNotifier::FireObservers(path);
- }
-
- size_t CountObserver(const char* path, NotificationObserver* obs) {
- PrefObserverMap::const_iterator observer_iterator =
- pref_observers()->find(path);
- if (observer_iterator == pref_observers()->end())
- return false;
-
- NotificationObserverList* observer_list = observer_iterator->second;
- NotificationObserverList::Iterator it(*observer_list);
- NotificationObserver* existing_obs;
- size_t count = 0;
- while ((existing_obs = it.GetNext()) != NULL) {
- if (existing_obs == obs)
- count++;
- }
-
- return count;
- }
-};
-
-// Mock PrefValueStore that has no unnecessary PrefStores and injects a simpler
-// PrefHasChanged().
-class MockPrefValueStore : public PrefValueStore {
- public:
- MockPrefValueStore()
- : PrefValueStore(NULL, NULL, NULL, NULL, NULL, NULL,
- new DefaultPrefStore(), NULL) {}
-
- virtual ~MockPrefValueStore() {}
-
- // This mock version returns true if the pref path starts with "changed".
- virtual bool PrefHasChanged(const char* path,
- PrefNotifier::PrefStoreType new_store) {
- std::string path_str(path);
- if (path_str.compare(0, 7, "changed") == 0)
- return true;
- return false;
- }
-};
-
-// Mock PrefService that allows the PrefNotifier to be injected.
-class MockPrefService : public PrefService {
- public:
- explicit MockPrefService(PrefValueStore* pref_value_store)
- : PrefService(pref_value_store) {}
-
- void SetPrefNotifier(PrefNotifier* notifier) {
- pref_notifier_.reset(notifier);
- }
-};
-
-// Mock PrefObserver that verifies notifications.
-class MockPrefObserver : public NotificationObserver {
- public:
- virtual ~MockPrefObserver() {}
-
- MOCK_METHOD3(Observe, void(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details));
-};
-
-// Test fixture class.
-class PrefNotifierTest : public testing::Test {
- protected:
- virtual void SetUp() {
- value_store_ = new MockPrefValueStore;
- pref_service_.reset(new MockPrefService(value_store_));
- notifier_ = new MockPrefNotifier(pref_service_.get(), value_store_);
- pref_service_->SetPrefNotifier(notifier_);
-
- pref_service_->RegisterBooleanPref(kChangedPref, true);
- pref_service_->RegisterBooleanPref(kUnchangedPref, true);
- }
-
- // The PrefService takes ownership of the PrefValueStore and PrefNotifier.
- PrefValueStore* value_store_;
- MockPrefNotifier* notifier_;
- scoped_ptr<MockPrefService> pref_service_;
-
- MockPrefObserver obs1_;
- MockPrefObserver obs2_;
-};
-
-TEST_F(PrefNotifierTest, OnPreferenceSet) {
- EXPECT_CALL(*notifier_, FireObservers(kChangedPref))
- .Times(PrefNotifier::PREF_STORE_TYPE_MAX + 1);
- EXPECT_CALL(*notifier_, FireObservers(kUnchangedPref)).Times(0);
-
- for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- notifier_->OnPreferenceSet(kChangedPref,
- static_cast<PrefNotifier::PrefStoreType>(i));
- notifier_->OnPreferenceSet(kUnchangedPref,
- static_cast<PrefNotifier::PrefStoreType>(i));
- }
-}
-
-TEST_F(PrefNotifierTest, OnUserPreferenceSet) {
- EXPECT_CALL(*notifier_, FireObservers(kChangedPref));
- EXPECT_CALL(*notifier_, FireObservers(kUnchangedPref)).Times(0);
- notifier_->OnUserPreferenceSet(kChangedPref);
- notifier_->OnUserPreferenceSet(kUnchangedPref);
-}
-
-TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) {
- const char pref_name[] = "homepage";
- const char pref_name2[] = "proxy";
-
- notifier_->AddPrefObserver(pref_name, &obs1_);
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- // Re-adding the same observer for the same pref doesn't change anything.
- // Skip this in debug mode, since it hits a DCHECK and death tests aren't
- // thread-safe.
-#if defined(NDEBUG)
- notifier_->AddPrefObserver(pref_name, &obs1_);
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-#endif // NDEBUG
-
- // Ensure that we can add the same observer to a different pref.
- notifier_->AddPrefObserver(pref_name2, &obs1_);
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- // Ensure that we can add another observer to the same pref.
- notifier_->AddPrefObserver(pref_name, &obs2_);
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- // Ensure that we can remove all observers, and that removing a non-existent
- // observer is harmless.
- notifier_->RemovePrefObserver(pref_name, &obs1_);
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- notifier_->RemovePrefObserver(pref_name, &obs2_);
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- notifier_->RemovePrefObserver(pref_name, &obs1_);
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-
- notifier_->RemovePrefObserver(pref_name2, &obs1_);
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier_->CountObserver(pref_name2, &obs2_));
-}
-
-TEST_F(PrefNotifierTest, FireObservers) {
- using testing::_;
- using testing::Field;
- using testing::Invoke;
- using testing::Mock;
- using testing::Truly;
-
- // Tell googlemock to pass calls to the mock's "back door" too.
- ON_CALL(*notifier_, FireObservers(_))
- .WillByDefault(Invoke(notifier_, &MockPrefNotifier::RealFireObservers));
- EXPECT_CALL(*notifier_, FireObservers(kChangedPref)).Times(4);
- EXPECT_CALL(*notifier_, FireObservers(kUnchangedPref)).Times(0);
-
- notifier_->AddPrefObserver(kChangedPref, &obs1_);
- notifier_->AddPrefObserver(kUnchangedPref, &obs1_);
-
- EXPECT_CALL(obs1_, Observe(
- Field(&NotificationType::value, NotificationType::PREF_CHANGED),
- Source<PrefService>(pref_service_.get()),
- Truly(DetailsAreChangedPref)));
- EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
- notifier_->OnUserPreferenceSet(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
- notifier_->OnUserPreferenceSet(kUnchangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- notifier_->AddPrefObserver(kChangedPref, &obs2_);
- notifier_->AddPrefObserver(kUnchangedPref, &obs2_);
-
- EXPECT_CALL(obs1_, Observe(
- Field(&NotificationType::value, NotificationType::PREF_CHANGED),
- Source<PrefService>(pref_service_.get()),
- Truly(DetailsAreChangedPref)));
- EXPECT_CALL(obs2_, Observe(
- Field(&NotificationType::value, NotificationType::PREF_CHANGED),
- Source<PrefService>(pref_service_.get()),
- Truly(DetailsAreChangedPref)));
- notifier_->OnUserPreferenceSet(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
- notifier_->OnUserPreferenceSet(kUnchangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- // Make sure removing an observer from one pref doesn't affect anything else.
- notifier_->RemovePrefObserver(kChangedPref, &obs1_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(
- Field(&NotificationType::value, NotificationType::PREF_CHANGED),
- Source<PrefService>(pref_service_.get()),
- Truly(DetailsAreChangedPref)));
- notifier_->OnUserPreferenceSet(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
- notifier_->OnUserPreferenceSet(kUnchangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- // Make sure removing an observer entirely doesn't affect anything else.
- notifier_->RemovePrefObserver(kUnchangedPref, &obs1_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(
- Field(&NotificationType::value, NotificationType::PREF_CHANGED),
- Source<PrefService>(pref_service_.get()),
- Truly(DetailsAreChangedPref)));
- notifier_->OnUserPreferenceSet(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
-
- EXPECT_CALL(obs1_, Observe(_, _, _)).Times(0);
- EXPECT_CALL(obs2_, Observe(_, _, _)).Times(0);
- notifier_->OnUserPreferenceSet(kUnchangedPref);
-
- notifier_->RemovePrefObserver(kChangedPref, &obs2_);
- notifier_->RemovePrefObserver(kUnchangedPref, &obs2_);
-}
-
-} // namespace
diff --git a/chrome/browser/prefs/pref_observer_mock.h b/chrome/browser/prefs/pref_observer_mock.h
new file mode 100644
index 0000000..f339841
--- /dev/null
+++ b/chrome/browser/prefs/pref_observer_mock.h
@@ -0,0 +1,60 @@
+// 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_OBSERVER_MOCK_H_
+#define CHROME_BROWSER_PREFS_PREF_OBSERVER_MOCK_H_
+#pragma once
+
+#include <string>
+
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::Pointee;
+using testing::Property;
+using testing::Truly;
+
+// Matcher that checks whether the current value of the preference named
+// |pref_name| in |prefs| matches |value|. If |value| is NULL, the matcher
+// checks that the value is not set.
+MATCHER_P3(PrefValueMatches, prefs, pref_name, value, "") {
+ const PrefService::Preference* pref =
+ prefs->FindPreference(pref_name.c_str());
+ if (!pref)
+ return false;
+
+ const Value* actual_value = pref->GetValue();
+ if (!actual_value)
+ return value == NULL;
+ if (!value)
+ return actual_value == NULL;
+ return value->Equals(actual_value);
+}
+
+// A mock for testing preference notifications and easy setup of expectations.
+class PrefObserverMock : public NotificationObserver {
+ public:
+ PrefObserverMock() {}
+ virtual ~PrefObserverMock() {}
+
+ MOCK_METHOD3(Observe, void(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details));
+
+ void Expect(const PrefService* prefs,
+ const std::string& pref_name,
+ const Value* value) {
+ EXPECT_CALL(*this, Observe(NotificationType(NotificationType::PREF_CHANGED),
+ Source<PrefService>(prefs),
+ Property(&Details<std::string>::ptr,
+ Pointee(pref_name))))
+ .With(PrefValueMatches(prefs, pref_name, value));
+ }
+};
+
+#endif // CHROME_BROWSER_PREFS_PREF_OBSERVER_MOCK_H_
diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc
index 8662f88..86149c5 100644
--- a/chrome/browser/prefs/pref_service.cc
+++ b/chrome/browser/prefs/pref_service.cc
@@ -23,10 +23,19 @@
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_thread.h"
+<<<<<<< HEAD
#include "chrome/browser/profile.h"
#ifndef ANDROID
// Notifications do not compile on Android and are the cause
// of most of the ANDROID guards in this file.
+=======
+#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/prefs/command_line_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/common/json_pref_store.h"
+>>>>>>> chromium.org at r10.0.621.0
#include "chrome/common/notification_service.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -90,8 +99,15 @@ void NotifyReadError(PrefService* pref, int message_id) {
// static
PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
+ PrefStore* extension_prefs,
Profile* profile) {
+<<<<<<< HEAD
#if defined(OS_LINUX) && !defined(ANDROID)
+=======
+ using policy::ConfigurationPolicyPrefStore;
+
+#if defined(OS_LINUX)
+>>>>>>> chromium.org at r10.0.621.0
// We'd like to see what fraction of our users have the preferences
// stored on a network file system, as we've had no end of troubles
// with NFS/AFS.
@@ -104,6 +120,7 @@ PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
}
#endif
+<<<<<<< HEAD
return new PrefService(
PrefValueStore::CreatePrefValueStore(pref_filename, profile, false));
}
@@ -119,6 +136,43 @@ PrefService::PrefService(PrefValueStore* pref_value_store)
#ifndef ANDROID
pref_notifier_.reset(new PrefNotifier(this, pref_value_store));
#endif
+=======
+ ConfigurationPolicyPrefStore* managed =
+ ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore();
+ ConfigurationPolicyPrefStore* device_management =
+ ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
+ profile);
+ CommandLinePrefStore* command_line =
+ new CommandLinePrefStore(CommandLine::ForCurrentProcess());
+ JsonPrefStore* user = new JsonPrefStore(
+ pref_filename,
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
+ ConfigurationPolicyPrefStore* recommended =
+ ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore();
+
+ return new PrefService(managed, device_management, extension_prefs,
+ command_line, user, recommended);
+}
+
+PrefService::PrefService(PrefStore* managed_platform_prefs,
+ PrefStore* device_management_prefs,
+ PrefStore* extension_prefs,
+ PrefStore* command_line_prefs,
+ PersistentPrefStore* user_prefs,
+ PrefStore* recommended_prefs)
+ : user_pref_store_(user_prefs) {
+ pref_notifier_.reset(new PrefNotifierImpl(this));
+ default_store_ = new DefaultPrefStore();
+ pref_value_store_ =
+ new PrefValueStore(managed_platform_prefs,
+ device_management_prefs,
+ extension_prefs,
+ command_line_prefs,
+ user_pref_store_,
+ recommended_prefs,
+ default_store_,
+ pref_notifier_.get());
+>>>>>>> chromium.org at r10.0.621.0
InitFromStorage();
}
@@ -129,18 +183,24 @@ PrefService::~PrefService() {
}
void PrefService::InitFromStorage() {
+<<<<<<< HEAD
#ifndef ANDROID
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)
+>>>>>>> chromium.org at r10.0.621.0
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;
}
@@ -153,32 +213,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,
@@ -331,6 +379,14 @@ const PrefService::Preference* PrefService::FindPreference(
return it == prefs_.end() ? NULL : *it;
}
+bool PrefService::ReadOnly() const {
+ return user_pref_store_->ReadOnly();
+}
+
+PrefNotifier* PrefService::pref_notifier() const {
+ return pref_notifier_.get();
+}
+
bool PrefService::IsManagedPreference(const char* pref_name) const {
const Preference* pref = FindPreference(pref_name);
if (pref && pref->IsManaged()) {
@@ -398,11 +454,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) {
- pref_value_store_->SetDefaultPrefValue(path, Value::CreateNullValue());
+ default_store_->SetDefaultValue(path, Value::CreateNullValue());
} else {
// Hand off ownership.
- DCHECK(!PrefStore::IsUseDefaultSentinelValue(default_value));
- pref_value_store_->SetDefaultPrefValue(path, scoped_value.release());
+ default_store_->SetDefaultValue(path, scoped_value.release());
}
pref_value_store_->RegisterPreferenceType(path, orig_type);
@@ -417,10 +472,14 @@ void PrefService::ClearPref(const char* path) {
NOTREACHED() << "Trying to clear an unregistered pref: " << path;
return;
}
+<<<<<<< HEAD
#ifndef ANDROID
if (pref_value_store_->RemoveUserPrefValue(path))
pref_notifier_->OnUserPreferenceSet(path);
#endif
+=======
+ user_pref_store_->RemoveValue(path);
+>>>>>>> chromium.org at r10.0.621.0
}
void PrefService::Set(const char* path, const Value& value) {
@@ -434,22 +493,24 @@ void PrefService::Set(const char* path, const Value& value) {
// Allow dictionary and list types to be set to null, which removes their
// user values.
- bool value_changed = false;
if (value.GetType() == Value::TYPE_NULL &&
(pref->GetType() == Value::TYPE_DICTIONARY ||
pref->GetType() == Value::TYPE_LIST)) {
- value_changed = 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 {
- value_changed = pref_value_store_->SetUserPrefValue(path, value.DeepCopy());
+ user_pref_store_->SetValue(path, value.DeepCopy());
}
+<<<<<<< HEAD
#ifndef ANDROID
if (value_changed)
pref_notifier_->OnUserPreferenceSet(path);
#endif
+=======
+>>>>>>> chromium.org at r10.0.621.0
}
void PrefService::SetBoolean(const char* path, bool value) {
@@ -524,10 +585,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_->SetUserPrefValue(path, dict);
+ user_pref_store_->SetValueSilently(path, dict);
} else {
dict = static_cast<DictionaryValue*>(tmp_value);
}
@@ -551,24 +613,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_->SetUserPrefValue(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());
@@ -577,10 +632,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()
@@ -588,10 +639,14 @@ void PrefService::SetUserPrefValue(const char* path, Value* new_value) {
return;
}
+<<<<<<< HEAD
#ifndef ANDROID
if (pref_value_store_->SetUserPrefValue(path, new_value))
pref_notifier_->OnUserPreferenceSet(path);
#endif
+=======
+ user_pref_store_->SetValue(path, new_value);
+>>>>>>> chromium.org at r10.0.621.0
}
///////////////////////////////////////////////////////////////////////////////
@@ -623,8 +678,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 44ae00b..40500b5 100644
--- a/chrome/browser/prefs/pref_service.h
+++ b/chrome/browser/prefs/pref_service.h
@@ -12,19 +12,23 @@
#include <string>
#include "base/non_thread_safe.h"
+#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
-#include "chrome/browser/prefs/pref_value_store.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;
namespace subtle {
- class PrefMemberBase;
+class PrefMemberBase;
};
class PrefService : public NonThreadSafe {
@@ -94,24 +98,17 @@ class PrefService : public NonThreadSafe {
DISALLOW_COPY_AND_ASSIGN(Preference);
};
- // Factory method that creates a new instance of a PrefService with
- // a PrefValueStore containing all platform-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.
+ // Factory method that creates a new instance of a PrefService with the
+ // 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. |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);
-
- // This constructor is primarily used by tests. The |pref_value_store|
- // provides preference values.
- explicit PrefService(PrefValueStore* pref_value_store);
-
virtual ~PrefService();
// Reloads the data from file. This should only be called when the importer
@@ -142,7 +139,7 @@ class PrefService : public NonThreadSafe {
void RegisterListPref(const char* path);
void RegisterDictionaryPref(const char* path);
- // These varients use a default value from the locale dll instead.
+ // These variants use a default value from the locale dll instead.
void RegisterLocalizedBooleanPref(const char* path,
int locale_default_message_id);
void RegisterLocalizedIntegerPref(const char* path,
@@ -218,23 +215,45 @@ class PrefService : public NonThreadSafe {
// preference is not registered.
const Preference* FindPreference(const char* pref_name) const;
+<<<<<<< HEAD
bool read_only() const { return pref_value_store_->ReadOnly(); }
#ifndef ANDROID
PrefNotifier* pref_notifier() const { return pref_notifier_.get(); }
#endif
+=======
+ bool ReadOnly() const;
+>>>>>>> chromium.org at r10.0.621.0
- PrefValueStore* pref_value_store() const { return pref_value_store_.get(); }
+ // TODO(mnissler): This should not be public. Change client code to call a
+ // preference setter or use ScopedPrefUpdate.
+ PrefNotifier* pref_notifier() const;
#ifndef ANDROID
protected:
+ // Construct a new pref service, specifying the pref sources as explicit
+ // PrefStore pointers. This constructor is what CreatePrefService() ends up
+ // calling. It's also used for unit tests.
+ PrefService(PrefStore* managed_platform_prefs,
+ PrefStore* device_management_prefs,
+ PrefStore* extension_prefs,
+ PrefStore* command_line_prefs,
+ PersistentPrefStore* user_prefs,
+ PrefStore* recommended_prefs);
+
// The PrefNotifier handles registering and notifying preference observers.
// It is created and owned by this PrefService. Subclasses may access it for
// unit testing.
+<<<<<<< HEAD
scoped_ptr<PrefNotifier> pref_notifier_;
#endif
+=======
+ scoped_ptr<PrefNotifierImpl> pref_notifier_;
+>>>>>>> chromium.org at r10.0.621.0
private:
+ friend class PrefServiceMockBuilder;
+
// Registration of pref change observers must be done using the
// PrefChangeRegistrar, which is declared as a friend here to grant it
// access to the otherwise protected members Add/RemovePrefObserver.
@@ -257,17 +276,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();
@@ -276,6 +288,12 @@ class PrefService : public NonThreadSafe {
// and owned by this PrefService. Subclasses may access it for unit testing.
scoped_refptr<PrefValueStore> pref_value_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.
+ 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..005b700
--- /dev/null
+++ b/chrome/browser/prefs/pref_service_mock_builder.cc
@@ -0,0 +1,103 @@
+// 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) {
+}
+
+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());
+ user_prefs_.reset(new TestingPrefStore);
+ 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..b8e3275
--- /dev/null
+++ b/chrome/browser/prefs/pref_service_mock_builder.h
@@ -0,0 +1,68 @@
+// 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_;
+
+ 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 e7c737c..1a79708 100644
--- a/chrome/browser/prefs/pref_service_unittest.cc
+++ b/chrome/browser/prefs/pref_service_unittest.cc
@@ -12,15 +12,14 @@
#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/default_pref_store.h"
-#include "chrome/browser/prefs/dummy_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/proxy_prefs.h"
+#include "chrome/browser/prefs/testing_pref_store.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/notification_observer_mock.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -28,49 +27,6 @@
using testing::_;
using testing::Mock;
-using testing::Pointee;
-using testing::Property;
-
-namespace {
-
-class TestPrefObserver : public NotificationObserver {
- public:
- TestPrefObserver(const PrefService* prefs,
- const std::string& pref_name,
- const std::string& new_pref_value)
- : observer_fired_(false),
- prefs_(prefs),
- pref_name_(pref_name),
- new_pref_value_(new_pref_value) {}
- virtual ~TestPrefObserver() {}
-
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- EXPECT_EQ(type.value, NotificationType::PREF_CHANGED);
- const PrefService* prefs_in = Source<PrefService>(source).ptr();
- EXPECT_EQ(prefs_in, prefs_);
- const std::string* pref_name_in = Details<std::string>(details).ptr();
- EXPECT_EQ(*pref_name_in, pref_name_);
- EXPECT_EQ(new_pref_value_, prefs_in->GetString("homepage"));
- observer_fired_ = true;
- }
-
- bool observer_fired() { return observer_fired_; }
-
- void Reset(const std::string& new_pref_value) {
- observer_fired_ = false;
- new_pref_value_ = new_pref_value;
- }
-
- private:
- bool observer_fired_;
- const PrefService* prefs_;
- const std::string pref_name_;
- std::string new_pref_value_;
-};
-
-} // namespace
// TODO(port): port this test to POSIX.
#if defined(OS_WIN)
@@ -103,33 +59,34 @@ TEST(PrefServiceTest, NoObserverFire) {
const char pref_name[] = "homepage";
prefs.RegisterStringPref(pref_name, std::string());
- const std::string new_pref_value("http://www.google.com/");
- TestPrefObserver obs(&prefs, pref_name, new_pref_value);
-
+ const char new_pref_value[] = "http://www.google.com/";
+ PrefObserverMock obs;
PrefChangeRegistrar registrar;
registrar.Init(&prefs);
registrar.Add(pref_name, &obs);
- // This should fire the checks in TestPrefObserver::Observe.
- prefs.SetString(pref_name, new_pref_value);
- // Make sure the observer was actually fired.
- EXPECT_TRUE(obs.observer_fired());
+ // This should fire the checks in PrefObserverMock::Observe.
+ const StringValue expected_value(new_pref_value);
+ obs.Expect(&prefs, pref_name, &expected_value);
+ prefs.SetString(pref_name, new_pref_value);
+ Mock::VerifyAndClearExpectations(&obs);
// Setting the pref to the same value should not set the pref value a second
// time.
- obs.Reset(new_pref_value);
+ EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
prefs.SetString(pref_name, new_pref_value);
- EXPECT_FALSE(obs.observer_fired());
+ Mock::VerifyAndClearExpectations(&obs);
// Clearing the pref should cause the pref to fire.
- obs.Reset(std::string());
+ const StringValue expected_default_value("");
+ obs.Expect(&prefs, pref_name, &expected_default_value);
prefs.ClearPref(pref_name);
- EXPECT_TRUE(obs.observer_fired());
+ Mock::VerifyAndClearExpectations(&obs);
// Clearing the pref again should not cause the pref to fire.
- obs.Reset(std::string());
+ EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
prefs.ClearPref(pref_name);
- EXPECT_FALSE(obs.observer_fired());
+ Mock::VerifyAndClearExpectations(&obs);
}
TEST(PrefServiceTest, HasPrefPath) {
@@ -157,120 +114,114 @@ TEST(PrefServiceTest, Observers) {
prefs.SetUserPref(pref_name, Value::CreateStringValue("http://www.cnn.com"));
prefs.RegisterStringPref(pref_name, std::string());
- const std::string new_pref_value("http://www.google.com/");
- TestPrefObserver obs(&prefs, pref_name, new_pref_value);
+ const char new_pref_value[] = "http://www.google.com/";
+ const StringValue expected_new_pref_value(new_pref_value);
+ PrefObserverMock obs;
PrefChangeRegistrar registrar;
registrar.Init(&prefs);
registrar.Add(pref_name, &obs);
- // This should fire the checks in TestPrefObserver::Observe.
- prefs.SetString(pref_name, new_pref_value);
- // Make sure the tests were actually run.
- EXPECT_TRUE(obs.observer_fired());
+ // This should fire the checks in PrefObserverMock::Observe.
+ obs.Expect(&prefs, pref_name, &expected_new_pref_value);
+ prefs.SetString(pref_name, new_pref_value);
+ Mock::VerifyAndClearExpectations(&obs);
// Now try adding a second pref observer.
- const std::string new_pref_value2("http://www.youtube.com/");
- obs.Reset(new_pref_value2);
- TestPrefObserver obs2(&prefs, pref_name, new_pref_value2);
+ const char new_pref_value2[] = "http://www.youtube.com/";
+ const StringValue expected_new_pref_value2(new_pref_value2);
+ PrefObserverMock obs2;
+ obs.Expect(&prefs, pref_name, &expected_new_pref_value2);
+ obs2.Expect(&prefs, pref_name, &expected_new_pref_value2);
registrar.Add(pref_name, &obs2);
// This should fire the checks in obs and obs2.
prefs.SetString(pref_name, new_pref_value2);
- EXPECT_TRUE(obs.observer_fired());
- EXPECT_TRUE(obs2.observer_fired());
+ Mock::VerifyAndClearExpectations(&obs);
+ Mock::VerifyAndClearExpectations(&obs2);
// Make sure obs2 still works after removing obs.
registrar.Remove(pref_name, &obs);
- obs.Reset(std::string());
- obs2.Reset(new_pref_value);
+ EXPECT_CALL(obs, Observe(_, _, _)).Times(0);
+ obs2.Expect(&prefs, pref_name, &expected_new_pref_value);
// This should only fire the observer in obs2.
prefs.SetString(pref_name, new_pref_value);
- EXPECT_FALSE(obs.observer_fired());
- EXPECT_TRUE(obs2.observer_fired());
-}
-
-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());
+ Mock::VerifyAndClearExpectations(&obs);
+ Mock::VerifyAndClearExpectations(&obs2);
}
TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineOptions) {
CommandLine command_line(CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kProxyBypassList, "123");
- command_line.AppendSwitchASCII(switches::kProxyPacUrl, "456");
command_line.AppendSwitchASCII(switches::kProxyServer, "789");
scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
new policy::MockConfigurationPolicyProvider());
Value* mode_value = Value::CreateIntegerValue(
policy::kPolicyManuallyConfiguredProxyMode);
- provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value);
+ provider->AddPolicy(policy::kPolicyProxyMode, mode_value);
provider->AddPolicy(policy::kPolicyProxyBypassList,
Value::CreateStringValue("abc"));
- provider->AddPolicy(policy::kPolicyProxyPacUrl,
- Value::CreateStringValue("def"));
provider->AddPolicy(policy::kPolicyProxyServer,
Value::CreateStringValue("ghi"));
// 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_EQ(ProxyPrefs::MODE_FIXED_SERVERS,
+ prefs->GetInteger(prefs::kProxyMode));
+ EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer));
+ EXPECT_EQ(std::string(), 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_EQ(ProxyPrefs::MODE_FIXED_SERVERS,
+ prefs2->GetInteger(prefs::kProxyMode));
+ EXPECT_EQ("ghi", prefs2->GetString(prefs::kProxyServer));
+ EXPECT_EQ(std::string(), prefs2->GetString(prefs::kProxyPacUrl));
+ EXPECT_EQ("abc", prefs2->GetString(prefs::kProxyBypassList));
}
TEST(PrefServiceTest, ProxyPolicyOverridesUnrelatedCommandLineOptions) {
CommandLine command_line(CommandLine::NO_PROGRAM);
command_line.AppendSwitchASCII(switches::kProxyBypassList, "123");
- command_line.AppendSwitchASCII(switches::kProxyPacUrl, "456");
command_line.AppendSwitchASCII(switches::kProxyServer, "789");
scoped_ptr<policy::MockConfigurationPolicyProvider> provider(
new policy::MockConfigurationPolicyProvider());
Value* mode_value = Value::CreateIntegerValue(
- policy::kPolicyUseSystemProxyMode);
- provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value);
+ policy::kPolicyAutoDetectProxyMode);
+ provider->AddPolicy(policy::kPolicyProxyMode, mode_value);
// 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_EQ(ProxyPrefs::MODE_FIXED_SERVERS,
+ prefs->GetInteger(prefs::kProxyMode));
+ EXPECT_EQ("789", prefs->GetString(prefs::kProxyServer));
+ 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_EQ(ProxyPrefs::MODE_AUTO_DETECT,
+ prefs2->GetInteger(prefs::kProxyMode));
+ 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) {
@@ -280,28 +231,31 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineNoProxy) {
new policy::MockConfigurationPolicyProvider());
Value* mode_value = Value::CreateIntegerValue(
policy::kPolicyAutoDetectProxyMode);
- provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value);
+ provider->AddPolicy(policy::kPolicyProxyMode, mode_value);
// 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_EQ(ProxyPrefs::MODE_DIRECT, prefs->GetInteger(prefs::kProxyMode));
+ 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_EQ(ProxyPrefs::MODE_AUTO_DETECT,
+ prefs2->GetInteger(prefs::kProxyMode));
+ 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) {
@@ -311,28 +265,30 @@ TEST(PrefServiceTest, ProxyPolicyOverridesCommandLineAutoDetect) {
new policy::MockConfigurationPolicyProvider());
Value* mode_value = Value::CreateIntegerValue(
policy::kPolicyNoProxyServerMode);
- provider->AddPolicy(policy::kPolicyProxyServerMode, mode_value);
+ provider->AddPolicy(policy::kPolicyProxyMode, mode_value);
// 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_EQ(ProxyPrefs::MODE_AUTO_DETECT, prefs->GetInteger(prefs::kProxyMode));
+ 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_EQ(ProxyPrefs::MODE_DIRECT, prefs2->GetInteger(prefs::kProxyMode));
+ 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 {
@@ -341,24 +297,11 @@ class PrefServiceSetValueTest : public testing::Test {
static const char kValue[];
PrefServiceSetValueTest()
- : name_string_(kName),
- null_value_(Value::CreateNullValue()) {}
-
- void SetExpectNoNotification() {
- EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
- }
-
- void SetExpectPrefChanged() {
- EXPECT_CALL(observer_,
- Observe(NotificationType(NotificationType::PREF_CHANGED), _,
- Property(&Details<std::string>::ptr,
- Pointee(name_string_))));
- }
+ : null_value_(Value::CreateNullValue()) {}
TestingPrefService prefs_;
- std::string name_string_;
scoped_ptr<Value> null_value_;
- NotificationObserverMock observer_;
+ PrefObserverMock observer_;
};
const char PrefServiceSetValueTest::kName[] = "name";
@@ -366,8 +309,7 @@ const char PrefServiceSetValueTest::kValue[] = "value";
TEST_F(PrefServiceSetValueTest, SetStringValue) {
const char default_string[] = "default";
- const scoped_ptr<Value> default_value(
- Value::CreateStringValue(default_string));
+ const StringValue default_value(default_string);
prefs_.RegisterStringPref(kName, default_string);
PrefChangeRegistrar registrar;
@@ -375,18 +317,18 @@ TEST_F(PrefServiceSetValueTest, SetStringValue) {
registrar.Add(kName, &observer_);
// Changing the controlling store from default to user triggers notification.
- SetExpectPrefChanged();
- prefs_.Set(kName, *default_value);
+ observer_.Expect(&prefs_, kName, &default_value);
+ prefs_.Set(kName, default_value);
Mock::VerifyAndClearExpectations(&observer_);
- SetExpectNoNotification();
- prefs_.Set(kName, *default_value);
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
+ prefs_.Set(kName, default_value);
Mock::VerifyAndClearExpectations(&observer_);
- const scoped_ptr<Value> new_value(Value::CreateStringValue(kValue));
- SetExpectPrefChanged();
- prefs_.Set(kName, *new_value);
- EXPECT_EQ(kValue, prefs_.GetString(kName));
+ StringValue new_value(kValue);
+ observer_.Expect(&prefs_, kName, &new_value);
+ prefs_.Set(kName, new_value);
+ Mock::VerifyAndClearExpectations(&observer_);
}
TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
@@ -397,30 +339,23 @@ TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
// Dictionary values are special: setting one to NULL is the same as clearing
// the user value, allowing the NULL default to take (or keep) control.
- SetExpectNoNotification();
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
prefs_.Set(kName, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
DictionaryValue new_value;
new_value.SetString(kName, kValue);
- SetExpectPrefChanged();
+ observer_.Expect(&prefs_, kName, &new_value);
prefs_.Set(kName, new_value);
Mock::VerifyAndClearExpectations(&observer_);
- DictionaryValue* dict = prefs_.GetMutableDictionary(kName);
- EXPECT_EQ(1U, dict->size());
- std::string out_value;
- dict->GetString(kName, &out_value);
- EXPECT_EQ(kValue, out_value);
- SetExpectNoNotification();
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
prefs_.Set(kName, new_value);
Mock::VerifyAndClearExpectations(&observer_);
- SetExpectPrefChanged();
+ observer_.Expect(&prefs_, kName, null_value_.get());
prefs_.Set(kName, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
- dict = prefs_.GetMutableDictionary(kName);
- EXPECT_EQ(0U, dict->size());
}
TEST_F(PrefServiceSetValueTest, SetListValue) {
@@ -431,28 +366,21 @@ TEST_F(PrefServiceSetValueTest, SetListValue) {
// List values are special: setting one to NULL is the same as clearing the
// user value, allowing the NULL default to take (or keep) control.
- SetExpectNoNotification();
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
prefs_.Set(kName, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
ListValue new_value;
new_value.Append(Value::CreateStringValue(kValue));
- SetExpectPrefChanged();
+ observer_.Expect(&prefs_, kName, &new_value);
prefs_.Set(kName, new_value);
Mock::VerifyAndClearExpectations(&observer_);
- const ListValue* list = prefs_.GetMutableList(kName);
- ASSERT_EQ(1U, list->GetSize());
- std::string out_value;
- list->GetString(0, &out_value);
- EXPECT_EQ(kValue, out_value);
- SetExpectNoNotification();
+ EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
prefs_.Set(kName, new_value);
Mock::VerifyAndClearExpectations(&observer_);
- SetExpectPrefChanged();
+ observer_.Expect(&prefs_, kName, null_value_.get());
prefs_.Set(kName, *null_value_);
Mock::VerifyAndClearExpectations(&observer_);
- list = prefs_.GetMutableList(kName);
- EXPECT_EQ(0U, list->GetSize());
}
diff --git a/chrome/browser/prefs/pref_set_observer.cc b/chrome/browser/prefs/pref_set_observer.cc
index a073eb2..133b219 100644
--- a/chrome/browser/prefs/pref_set_observer.cc
+++ b/chrome/browser/prefs/pref_set_observer.cc
@@ -47,8 +47,7 @@ PrefSetObserver* PrefSetObserver::CreateProxyPrefSetObserver(
PrefService* pref_service,
NotificationObserver* observer) {
PrefSetObserver* pref_set = new PrefSetObserver(pref_service, observer);
- pref_set->AddPref(prefs::kNoProxyServer);
- pref_set->AddPref(prefs::kProxyAutoDetect);
+ pref_set->AddPref(prefs::kProxyMode);
pref_set->AddPref(prefs::kProxyServer);
pref_set->AddPref(prefs::kProxyPacUrl);
pref_set->AddPref(prefs::kProxyBypassList);
diff --git a/chrome/browser/prefs/pref_value_map.cc b/chrome/browser/prefs/pref_value_map.cc
new file mode 100644
index 0000000..6e7bf79
--- /dev/null
+++ b/chrome/browser/prefs/pref_value_map.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_value_map.h"
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/stl_util-inl.h"
+#include "base/values.h"
+
+PrefValueMap::PrefValueMap() {}
+
+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();
+}
+
+bool PrefValueMap::GetBoolean(const std::string& key,
+ bool* value) const {
+ Value* stored_value = NULL;
+ return GetValue(key, &stored_value) && stored_value->GetAsBoolean(value);
+}
+
+bool PrefValueMap::GetString(const std::string& key,
+ std::string* value) const {
+ Value* stored_value = NULL;
+ return GetValue(key, &stored_value) && stored_value->GetAsString(value);
+}
+
+void PrefValueMap::SetString(const std::string& key,
+ const std::string& value) {
+ SetValue(key, Value::CreateStringValue(value));
+}
+
+void PrefValueMap::GetDifferingKeys(
+ const PrefValueMap* other,
+ std::vector<std::string>* differing_keys) const {
+ differing_keys->clear();
+
+ // Walk over the maps in lockstep, adding everything that is different.
+ Map::const_iterator this_pref(prefs_.begin());
+ Map::const_iterator other_pref(other->prefs_.begin());
+ while (this_pref != prefs_.end() && other_pref != other->prefs_.end()) {
+ const int diff = this_pref->first.compare(other_pref->first);
+ if (diff == 0) {
+ if (!this_pref->second->Equals(other_pref->second))
+ differing_keys->push_back(this_pref->first);
+ ++this_pref;
+ ++other_pref;
+ } else if (diff < 0) {
+ differing_keys->push_back(this_pref->first);
+ ++this_pref;
+ } else if (diff > 0) {
+ differing_keys->push_back(other_pref->first);
+ ++other_pref;
+ }
+ }
+
+ // Add the remaining entries.
+ for ( ; this_pref != prefs_.end(); ++this_pref)
+ differing_keys->push_back(this_pref->first);
+ for ( ; other_pref != other->prefs_.end(); ++other_pref)
+ differing_keys->push_back(other_pref->first);
+}
diff --git a/chrome/browser/prefs/pref_value_map.h b/chrome/browser/prefs/pref_value_map.h
new file mode 100644
index 0000000..0e99920
--- /dev/null
+++ b/chrome/browser/prefs/pref_value_map.h
@@ -0,0 +1,64 @@
+// 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 <vector>
+
+#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();
+
+ // Gets a boolean value for |key| and stores it in |value|. Returns true if
+ // the value was found and of the proper type.
+ bool GetBoolean(const std::string& key, bool* value) const;
+
+ // Gets a string value for |key| and stores it in |value|. Returns true if
+ // the value was found and of the proper type.
+ bool GetString(const std::string& key, std::string* value) const;
+
+ // Sets the value for |key| to the string |value|.
+ void SetString(const std::string& key, const std::string& value);
+
+ // Compares this value map against |other| and stores all key names that have
+ // different values in |differing_keys|. This includes keys that are present
+ // only in one of the maps.
+ void GetDifferingKeys(const PrefValueMap* other,
+ std::vector<std::string>* differing_keys) const;
+
+ 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_map_unittest.cc b/chrome/browser/prefs/pref_value_map_unittest.cc
new file mode 100644
index 0000000..5e248b0
--- /dev/null
+++ b/chrome/browser/prefs/pref_value_map_unittest.cc
@@ -0,0 +1,76 @@
+// 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 "base/values.h"
+#include "chrome/browser/prefs/pref_value_map.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class PrefValueMapTest : public testing::Test {
+};
+
+TEST_F(PrefValueMapTest, SetValue) {
+ PrefValueMap map;
+ Value* result = NULL;
+ EXPECT_FALSE(map.GetValue("key", &result));
+ EXPECT_FALSE(result);
+
+ EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test")));
+ EXPECT_FALSE(map.SetValue("key", Value::CreateStringValue("test")));
+ EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("hi mom!")));
+
+ EXPECT_TRUE(map.GetValue("key", &result));
+ EXPECT_TRUE(StringValue("hi mom!").Equals(result));
+}
+
+TEST_F(PrefValueMapTest, RemoveValue) {
+ PrefValueMap map;
+ EXPECT_FALSE(map.RemoveValue("key"));
+
+ EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test")));
+ EXPECT_TRUE(map.GetValue("key", NULL));
+
+ EXPECT_TRUE(map.RemoveValue("key"));
+ EXPECT_FALSE(map.GetValue("key", NULL));
+
+ EXPECT_FALSE(map.RemoveValue("key"));
+}
+
+TEST_F(PrefValueMapTest, Clear) {
+ PrefValueMap map;
+ EXPECT_TRUE(map.SetValue("key", Value::CreateStringValue("test")));
+ EXPECT_TRUE(map.GetValue("key", NULL));
+
+ map.Clear();
+
+ EXPECT_FALSE(map.GetValue("key", NULL));
+}
+
+TEST_F(PrefValueMapTest, GetDifferingKeys) {
+ PrefValueMap reference;
+ EXPECT_TRUE(reference.SetValue("b", Value::CreateStringValue("test")));
+ EXPECT_TRUE(reference.SetValue("c", Value::CreateStringValue("test")));
+ EXPECT_TRUE(reference.SetValue("e", Value::CreateStringValue("test")));
+
+ PrefValueMap check;
+ std::vector<std::string> differing_paths;
+ std::vector<std::string> expected_differing_paths;
+
+ reference.GetDifferingKeys(&check, &differing_paths);
+ expected_differing_paths.push_back("b");
+ expected_differing_paths.push_back("c");
+ expected_differing_paths.push_back("e");
+ EXPECT_EQ(expected_differing_paths, differing_paths);
+
+ EXPECT_TRUE(check.SetValue("a", Value::CreateStringValue("test")));
+ EXPECT_TRUE(check.SetValue("c", Value::CreateStringValue("test")));
+ EXPECT_TRUE(check.SetValue("d", Value::CreateStringValue("test")));
+
+ reference.GetDifferingKeys(&check, &differing_paths);
+ expected_differing_paths.clear();
+ expected_differing_paths.push_back("a");
+ expected_differing_paths.push_back("b");
+ expected_differing_paths.push_back("d");
+ expected_differing_paths.push_back("e");
+ EXPECT_EQ(expected_differing_paths, differing_paths);
+}
diff --git a/chrome/browser/prefs/pref_value_store.cc b/chrome/browser/prefs/pref_value_store.cc
index ee23b3b..431e55f 100644
--- a/chrome/browser/prefs/pref_value_store.cc
+++ b/chrome/browser/prefs/pref_value_store.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/prefs/pref_value_store.h"
+<<<<<<< HEAD
#ifndef ANDROID
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_pref_store.h"
@@ -15,26 +16,34 @@
#include "chrome/common/json_pref_store.h"
#include "chrome/common/notification_service.h"
#endif
+=======
+#include "chrome/browser/prefs/pref_notifier.h"
+>>>>>>> chromium.org at r10.0.621.0
-namespace {
+PrefValueStore::PrefStoreKeeper::PrefStoreKeeper()
+ : pref_value_store_(NULL),
+ type_(PrefValueStore::INVALID_STORE) {
+}
-// Returns true if the actual value is a valid type for the expected type when
-// found in the given store.
-bool IsValidType(Value::ValueType expected, Value::ValueType actual,
- PrefNotifier::PrefStoreType store) {
- if (expected == actual)
- return true;
+PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() {
+ if (pref_store_.get())
+ pref_store_->RemoveObserver(this);
+}
- // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only
- // in the default pref store.
- if (store == PrefNotifier::DEFAULT_STORE &&
- actual == Value::TYPE_NULL &&
- (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) {
- return true;
- }
- return false;
+void PrefValueStore::PrefStoreKeeper::Initialize(
+ PrefValueStore* store,
+ PrefStore* pref_store,
+ PrefValueStore::PrefStoreType type) {
+ if (pref_store_.get())
+ pref_store_->RemoveObserver(this);
+ type_ = type;
+ pref_value_store_ = store;
+ pref_store_.reset(pref_store);
+ if (pref_store_.get())
+ pref_store_->AddObserver(this);
}
+<<<<<<< HEAD
} // namespace
// static
@@ -73,6 +82,35 @@ PrefValueStore* PrefValueStore::CreatePrefValueStore(
command_line, user, recommended, default_store,
profile);
#endif
+=======
+void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged(
+ const std::string& key) {
+ pref_value_store_->OnPrefValueChanged(type_, key);
+}
+
+void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() {
+ pref_value_store_->OnInitializationCompleted(type_);
+}
+
+PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs,
+ PrefStore* device_management_prefs,
+ PrefStore* extension_prefs,
+ PrefStore* command_line_prefs,
+ PrefStore* user_prefs,
+ PrefStore* recommended_prefs,
+ PrefStore* default_prefs,
+ PrefNotifier* pref_notifier)
+ : pref_notifier_(pref_notifier) {
+ InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs);
+ InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs);
+ InitPrefStore(EXTENSION_STORE, extension_prefs);
+ InitPrefStore(COMMAND_LINE_STORE, command_line_prefs);
+ InitPrefStore(USER_STORE, user_prefs);
+ InitPrefStore(RECOMMENDED_STORE, recommended_prefs);
+ InitPrefStore(DEFAULT_STORE, default_prefs);
+
+ CheckInitializationCompleted();
+>>>>>>> chromium.org at r10.0.621.0
}
PrefValueStore::~PrefValueStore() {}
@@ -81,20 +119,14 @@ bool PrefValueStore::GetValue(const std::string& 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.
- for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- if (GetValueFromStore(name.c_str(),
- static_cast<PrefNotifier::PrefStoreType>(i),
+ for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
+ if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i),
out_value))
return true;
}
return false;
}
-bool PrefValueStore::GetUserValue(const std::string& name,
- Value** out_value) const {
- return GetValueFromStore(name.c_str(), PrefNotifier::USER_STORE, out_value);
-}
-
void PrefValueStore::RegisterPreferenceType(const std::string& name,
Value::ValueType type) {
pref_types_[name] = type;
@@ -108,43 +140,6 @@ Value::ValueType PrefValueStore::GetRegisteredType(
return found->second;
}
-bool PrefValueStore::WritePrefs() {
- bool success = true;
- for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- if (pref_stores_[i].get())
- success = pref_stores_[i]->WritePrefs() && success;
- }
- return success;
-}
-
-void PrefValueStore::ScheduleWritePrefs() {
- for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- if (pref_stores_[i].get())
- pref_stores_[i]->ScheduleWritePrefs();
- }
-}
-
-PrefStore::PrefReadError PrefValueStore::ReadPrefs() {
- PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE;
- for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- if (pref_stores_[i].get()) {
- PrefStore::PrefReadError this_error = pref_stores_[i]->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);
@@ -154,158 +149,112 @@ bool PrefValueStore::HasPrefPath(const char* path) const {
return rv && !PrefValueFromDefaultStore(path);
}
-bool PrefValueStore::PrefHasChanged(const char* path,
- PrefNotifier::PrefStoreType new_store) {
- DCHECK(new_store != PrefNotifier::INVALID_STORE);
- // Replying that the pref has changed may cause problems, but it's the safer
- // choice.
- if (new_store == PrefNotifier::INVALID_STORE)
- return true;
-
- PrefNotifier::PrefStoreType controller = ControllingPrefStoreForPref(path);
- DCHECK(controller != PrefNotifier::INVALID_STORE);
- if (controller == PrefNotifier::INVALID_STORE)
- return true;
-
- // If the pref is controlled by a higher-priority store, its effective value
- // cannot have changed.
- if (controller < new_store)
- return false;
-
- // Otherwise, we take the pref store's word that something changed.
- return true;
-}
-
-// Note the |DictionaryValue| referenced by the |PrefStore| USER_STORE
-// (returned by the method prefs()) takes the ownership of the Value referenced
-// by in_value.
-bool PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) {
- Value* old_value = NULL;
- pref_stores_[PrefNotifier::USER_STORE]->prefs()->Get(name, &old_value);
- bool value_changed = !(old_value && old_value->Equals(in_value));
+void PrefValueStore::NotifyPrefChanged(
+ const char* path,
+ PrefValueStore::PrefStoreType new_store) {
+ DCHECK(new_store != INVALID_STORE);
- pref_stores_[PrefNotifier::USER_STORE]->prefs()->Set(name, in_value);
- return value_changed;
-}
-
-// Note the |DictionaryValue| referenced by the |PrefStore| DEFAULT_STORE
-// (returned by the method prefs()) takes the ownership of the Value referenced
-// by in_value.
-void PrefValueStore::SetDefaultPrefValue(const char* name, Value* in_value) {
- pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Set(name, in_value);
-}
-
-bool PrefValueStore::ReadOnly() {
- return pref_stores_[PrefNotifier::USER_STORE]->ReadOnly();
-}
+ // If this pref is not registered, just discard the notification.
+ if (!pref_types_.count(path))
+ return;
-bool PrefValueStore::RemoveUserPrefValue(const char* name) {
- if (pref_stores_[PrefNotifier::USER_STORE].get()) {
- return pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL);
+ bool changed = true;
+ // Replying that the pref has changed in case the new store is invalid may
+ // cause problems, but it's the safer choice.
+ if (new_store != INVALID_STORE) {
+ PrefStoreType controller = ControllingPrefStoreForPref(path);
+ DCHECK(controller != INVALID_STORE);
+ // If the pref is controlled by a higher-priority store, its effective value
+ // cannot have changed.
+ if (controller != INVALID_STORE &&
+ controller < new_store) {
+ changed = false;
+ }
}
- return false;
+
+ if (changed)
+ pref_notifier_->OnPreferenceChanged(path);
}
bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const {
- return PrefValueInStore(name, PrefNotifier::MANAGED_PLATFORM_STORE);
+ return PrefValueInStore(name, MANAGED_PLATFORM_STORE);
}
bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const {
- return PrefValueInStore(name, PrefNotifier::DEVICE_MANAGEMENT_STORE);
+ return PrefValueInStore(name, DEVICE_MANAGEMENT_STORE);
}
bool PrefValueStore::PrefValueInExtensionStore(const char* name) const {
- return PrefValueInStore(name, PrefNotifier::EXTENSION_STORE);
+ return PrefValueInStore(name, EXTENSION_STORE);
}
bool PrefValueStore::PrefValueInUserStore(const char* name) const {
- return PrefValueInStore(name, PrefNotifier::USER_STORE);
-}
-
-bool PrefValueStore::PrefValueInStoreRange(
- const char* name,
- PrefNotifier::PrefStoreType first_checked_store,
- PrefNotifier::PrefStoreType last_checked_store) {
- if (first_checked_store > last_checked_store) {
- NOTREACHED();
- return false;
- }
-
- for (size_t i = first_checked_store;
- i <= static_cast<size_t>(last_checked_store); ++i) {
- if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i)))
- return true;
- }
- return false;
+ return PrefValueInStore(name, USER_STORE);
}
bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const {
- return ControllingPrefStoreForPref(name) == PrefNotifier::EXTENSION_STORE;
+ return ControllingPrefStoreForPref(name) == EXTENSION_STORE;
}
bool PrefValueStore::PrefValueFromUserStore(const char* name) const {
- return ControllingPrefStoreForPref(name) == PrefNotifier::USER_STORE;
+ return ControllingPrefStoreForPref(name) == USER_STORE;
}
bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const {
- return ControllingPrefStoreForPref(name) == PrefNotifier::DEFAULT_STORE;
+ return ControllingPrefStoreForPref(name) == DEFAULT_STORE;
}
bool PrefValueStore::PrefValueUserModifiable(const char* name) const {
- PrefNotifier::PrefStoreType effective_store =
- ControllingPrefStoreForPref(name);
- return effective_store >= PrefNotifier::USER_STORE ||
- effective_store == PrefNotifier::INVALID_STORE;
+ PrefStoreType effective_store = ControllingPrefStoreForPref(name);
+ return effective_store >= USER_STORE ||
+ effective_store == INVALID_STORE;
}
-PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
- const char* name) const {
- for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) {
- if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i)))
- return static_cast<PrefNotifier::PrefStoreType>(i);
+// 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,
+ Value::ValueType actual,
+ PrefValueStore::PrefStoreType store) {
+ if (expected == actual)
+ return true;
+
+ // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only
+ // in the default pref store.
+ if (store == DEFAULT_STORE &&
+ actual == Value::TYPE_NULL &&
+ (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) {
+ return true;
}
- return PrefNotifier::INVALID_STORE;
+ return false;
}
bool PrefValueStore::PrefValueInStore(
const char* name,
- PrefNotifier::PrefStoreType store) const {
+ PrefValueStore::PrefStoreType store) const {
// Declare a temp Value* and call GetValueFromStore,
// ignoring the output value.
Value* tmp_value = NULL;
return GetValueFromStore(name, store, &tmp_value);
}
-bool PrefValueStore::GetValueFromStore(
+bool PrefValueStore::PrefValueInStoreRange(
const char* name,
- PrefNotifier::PrefStoreType store,
- Value** out_value) const {
- // Only return true if we find a value and it is the correct type, so stale
- // values with the incorrect type will be ignored.
- if (pref_stores_[store].get() &&
- pref_stores_[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)) {
- DCHECK(pref_stores_[PrefNotifier::DEFAULT_STORE].get());
- if (!pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Get(name,
- out_value)) {
- *out_value = NULL;
- return false;
- }
- store = PrefNotifier::DEFAULT_STORE;
- }
- if (IsValidType(GetRegisteredType(name), (*out_value)->GetType(), store))
+ PrefValueStore::PrefStoreType first_checked_store,
+ PrefValueStore::PrefStoreType last_checked_store) const {
+ if (first_checked_store > last_checked_store) {
+ NOTREACHED();
+ return false;
+ }
+
+ for (size_t i = first_checked_store;
+ i <= static_cast<size_t>(last_checked_store); ++i) {
+ if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
return true;
}
- // No valid value found for the given preference name: set the return false.
- *out_value = NULL;
return false;
}
+<<<<<<< HEAD
#ifndef ANDROID
void PrefValueStore::RefreshPolicyPrefsOnFileThread(
BrowserThread::ID calling_thread_id,
@@ -334,130 +283,61 @@ void PrefValueStore::RefreshPolicyPrefsOnFileThread(
LOG(ERROR) << "refresh of device management policy failed: "
<< "PrefReadError = " << read_error;
return;
+=======
+PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref(
+ const char* name) const {
+ for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
+ if (PrefValueInStore(name, static_cast<PrefStoreType>(i)))
+ return static_cast<PrefStoreType>(i);
+>>>>>>> chromium.org at r10.0.621.0
}
+ return INVALID_STORE;
+}
- 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;
+bool PrefValueStore::GetValueFromStore(const char* name,
+ PrefValueStore::PrefStoreType store_type,
+ Value** out_value) const {
+ // 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) {
+ 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;
+ }
}
- BrowserThread::PostTask(
- calling_thread_id, FROM_HERE,
- NewRunnableMethod(this,
- &PrefValueStore::RefreshPolicyPrefsCompletion,
- managed_platform_pref_store.release(),
- device_management_pref_store.release(),
- recommended_pref_store.release(),
- callback.release()));
+ // No valid value found for the given preference name: set the return false.
+ *out_value = NULL;
+ return false;
}
-void PrefValueStore::RefreshPolicyPrefsCompletion(
- PrefStore* new_managed_platform_pref_store,
- PrefStore* new_device_management_pref_store,
- PrefStore* new_recommended_pref_store,
- AfterRefreshCallback* callback_pointer) {
- scoped_ptr<AfterRefreshCallback> callback(callback_pointer);
-
- // 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(
- pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE]->prefs());
- DictionaryValue* managed_platform_prefs_after(
- new_managed_platform_pref_store->prefs());
- DictionaryValue* device_management_prefs_before(
- pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE]->prefs());
- DictionaryValue* device_management_prefs_after(
- new_device_management_pref_store->prefs());
- DictionaryValue* recommended_prefs_before(
- pref_stores_[PrefNotifier::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);
-
- std::vector<std::string> changed_device_management_paths;
- device_management_prefs_before->GetDifferingPaths(
- device_management_prefs_after,
- &changed_device_management_paths);
-
- std::vector<std::string> 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.
- std::vector<std::string> all_changed_managed_platform_paths(
- changed_managed_platform_paths.size() +
- changed_device_management_paths.size());
-
- std::vector<std::string>::iterator last_insert =
- std::merge(changed_managed_platform_paths.begin(),
- changed_managed_platform_paths.end(),
- changed_device_management_paths.begin(),
- changed_device_management_paths.end(),
- all_changed_managed_platform_paths.begin());
- all_changed_managed_platform_paths.resize(
- last_insert - all_changed_managed_platform_paths.begin());
-
- std::vector<std::string> changed_paths(
- all_changed_managed_platform_paths.size() +
- changed_recommended_paths.size());
- last_insert = std::merge(all_changed_managed_platform_paths.begin(),
- all_changed_managed_platform_paths.end(),
- changed_recommended_paths.begin(),
- changed_recommended_paths.end(),
- changed_paths.begin());
- changed_paths.resize(last_insert - changed_paths.begin());
-
- last_insert = unique(changed_paths.begin(), changed_paths.end());
- changed_paths.resize(last_insert - changed_paths.begin());
-
- // Replace the old stores with the new and send notification of the changed
- // preferences.
- pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset(
- new_managed_platform_pref_store);
- pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset(
- new_device_management_pref_store);
- pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(
- new_recommended_pref_store);
- callback->Run(changed_paths);
+void PrefValueStore::OnPrefValueChanged(PrefValueStore::PrefStoreType type,
+ const std::string& key) {
+ NotifyPrefChanged(key.c_str(), type);
}
-void PrefValueStore::RefreshPolicyPrefs(
- AfterRefreshCallback* callback) {
- using policy::ConfigurationPolicyPrefStore;
- // Because loading of policy information must happen on the FILE
- // thread, it's not possible to just replace the contents of the
- // managed and recommended stores in place due to possible
- // concurrent access from the UI thread. Instead, new stores are
- // 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::CreateManagedPlatformPolicyPrefStore());
- PrefStore* new_device_management_pref_store(
- ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore(
- profile_));
- PrefStore* new_recommended_pref_store(
- ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore());
- BrowserThread::ID current_thread_id;
- CHECK(BrowserThread::GetCurrentThreadIdentifier(&current_thread_id));
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this,
- &PrefValueStore::RefreshPolicyPrefsOnFileThread,
- current_thread_id,
- new_managed_platform_pref_store,
- new_device_management_pref_store,
- new_recommended_pref_store,
- callback));
+void PrefValueStore::OnInitializationCompleted(
+ PrefValueStore::PrefStoreType type) {
+ CheckInitializationCompleted();
}
#endif // ANDROID
+<<<<<<< HEAD
bool PrefValueStore::HasPolicyConflictingUserProxySettings() {
#if !defined(ANDROID)
using policy::ConfigurationPolicyPrefStore;
@@ -474,27 +354,18 @@ bool PrefValueStore::HasPolicyConflictingUserProxySettings() {
}
#endif
return false;
-}
-
-PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs,
- PrefStore* device_management_prefs,
- PrefStore* extension_prefs,
- PrefStore* command_line_prefs,
- PrefStore* user_prefs,
- PrefStore* recommended_prefs,
- PrefStore* default_prefs,
- Profile* profile)
- : 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";
- pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset(
- managed_platform_prefs);
- pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset(
- device_management_prefs);
- pref_stores_[PrefNotifier::EXTENSION_STORE].reset(extension_prefs);
- pref_stores_[PrefNotifier::COMMAND_LINE_STORE].reset(command_line_prefs);
- pref_stores_[PrefNotifier::USER_STORE].reset(user_prefs);
- pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(recommended_prefs);
- pref_stores_[PrefNotifier::DEFAULT_STORE].reset(default_prefs);
+=======
+void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type,
+ PrefStore* pref_store) {
+ pref_stores_[type].Initialize(this, pref_store, type);
+>>>>>>> chromium.org at r10.0.621.0
+}
+
+void PrefValueStore::CheckInitializationCompleted() {
+ for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) {
+ PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i));
+ if (store && !store->IsInitializationComplete())
+ return;
+ }
+ pref_notifier_->OnInitializationCompleted();
}
diff --git a/chrome/browser/prefs/pref_value_store.h b/chrome/browser/prefs/pref_value_store.h
index a82944d..2b8c539 100644
--- a/chrome/browser/prefs/pref_value_store.h
+++ b/chrome/browser/prefs/pref_value_store.h
@@ -11,18 +11,21 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#ifndef ANDROID
#include "chrome/browser/browser_thread.h"
+<<<<<<< HEAD
#endif
#include "chrome/browser/prefs/pref_notifier.h"
+=======
+>>>>>>> chromium.org at r10.0.621.0
#include "chrome/common/pref_store.h"
class FilePath;
+class PrefNotifier;
class PrefStore;
class Profile;
@@ -30,13 +33,12 @@ class Profile;
// (e.g., configuration policies, extensions, and user settings). It returns
// the value of a Preference from the source with the highest priority, and
// allows setting user-defined values for preferences that are not managed.
-// See PrefNotifier for a list of the available preference sources (PrefStores)
-// and their descriptions.
//
// Unless otherwise explicitly noted, all of the methods of this class must
// be called on the UI thread.
class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
public:
+<<<<<<< HEAD
// Returns a new PrefValueStore with all 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
@@ -53,6 +55,38 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
virtual
#endif
~PrefValueStore();
+=======
+ // In decreasing order of precedence:
+ // |managed_platform_prefs| contains all managed platform (non-cloud policy)
+ // preference values.
+ // |device_management_prefs| contains all device management (cloud policy)
+ // preference values.
+ // |extension_prefs| contains preference values set by extensions.
+ // |command_line_prefs| contains preference values set by command-line
+ // switches.
+ // |user_prefs| contains all user-set preference values.
+ // |recommended_prefs| contains all recommended (policy) preference values.
+ // |default_prefs| contains application-default preference values. It must
+ // be non-null if any preferences are to be registered.
+ //
+ // |pref_notifier| facilitates broadcasting preference change notifications
+ // to the world.
+ //
+ // The |profile| parameter is used to construct a replacement device
+ // management pref store. This is done after policy refresh when we swap out
+ // the policy pref stores for new ones, so the |profile| pointer needs to be
+ // kept around for then. It is safe to pass a NULL pointer for local state
+ // preferences.
+ PrefValueStore(PrefStore* managed_platform_prefs,
+ PrefStore* device_management_prefs,
+ PrefStore* extension_prefs,
+ PrefStore* command_line_prefs,
+ PrefStore* user_prefs,
+ PrefStore* recommended_prefs,
+ PrefStore* default_prefs,
+ PrefNotifier* pref_notifier);
+ virtual ~PrefValueStore();
+>>>>>>> chromium.org at r10.0.621.0
// Gets the value for the given preference name that has a valid value type;
// that is, the same type the preference was registered with, or NULL for
@@ -61,9 +95,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 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);
@@ -71,20 +102,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.
- bool WritePrefs();
-
- // Calls the method ScheduleWritePrefs on the PrefStores. In practice, only
- // the user prefs are expected to be written out.
- 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
@@ -92,38 +109,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;
- // Called by the PrefNotifier when the value of the preference at |path| has
- // changed, been added, or been removed in one of the PrefStores. The
- // |new_store| is the PrefStoreType of the caller. Returns true if the
- // effective value of the preference has changed, or if the store controlling
- // the pref has changed. Virtual so it can be mocked for a unit test.
- virtual bool PrefHasChanged(const char* path,
- PrefNotifier::PrefStoreType new_store);
-
- // 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();
-
- // 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|. It is an error to call this when no
- // user PrefStore has been set. Returns true if the user-set value of the
- // preference was newly added or changed.
- bool SetUserPrefValue(const char* name, Value* in_value);
-
- // Removes a value from the user PrefStore. If a preference is managed
- // this function should have no visible effect. Returns true if there was a
- // user-set value to be removed.
- bool RemoveUserPrefValue(const char* name);
-
- // Sets a value in the DefaultPrefStore, which takes ownership of the Value.
- void SetDefaultPrefValue(const char* name, Value* in_value);
-
// 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.
@@ -132,14 +117,6 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
bool PrefValueInExtensionStore(const char* name) const;
bool PrefValueInUserStore(const char* name) const;
- // Returns true if a preference has an explicit value in any of the
- // stores in the range specified by |first_checked_store| and
- // |last_checked_store|, even if that value is currently being
- // overridden by a higher-priority store.
- bool PrefValueInStoreRange(const char* name,
- PrefNotifier::PrefStoreType first_checked_store,
- PrefNotifier::PrefStoreType last_checked_store);
-
// These methods return true if a preference with the given name is actually
// being controlled by the indicated pref store and not being overridden by
// a higher-priority source.
@@ -151,6 +128,7 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
// there is no higher-priority source controlling it.
bool PrefValueUserModifiable(const char* name) const;
+<<<<<<< HEAD
// Returns the pref store type identifying the source that controls the
// Preference identified by |name|. If none of the sources has a value,
// PrefNotifier::INVALID_STORE is returned. In practice, the default PrefStore
@@ -215,24 +193,109 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
PrefStore* default_prefs,
Profile* profile);
+=======
+>>>>>>> chromium.org at r10.0.621.0
private:
+ // PrefStores must be listed here in order from highest to lowest priority.
+ // MANAGED_PLATFORM contains all managed preference values that are
+ // provided by a platform-specific policy mechanism (e.g. Windows
+ // Group Policy).
+ // DEVICE_MANAGEMENT contains all managed preference values supplied
+ // by the device management server (cloud policy).
+ // EXTENSION contains preference values set by extensions.
+ // COMMAND_LINE contains preference values set by command-line switches.
+ // USER contains all user-set preference values.
+ // RECOMMENDED contains all recommended (policy) preference values.
+ // DEFAULT contains all application default preference values.
+ enum PrefStoreType {
+ // INVALID_STORE is not associated with an actual PrefStore but used as
+ // an invalid marker, e.g. as a return value.
+ INVALID_STORE = -1,
+ MANAGED_PLATFORM_STORE = 0,
+ DEVICE_MANAGEMENT_STORE,
+ EXTENSION_STORE,
+ COMMAND_LINE_STORE,
+ USER_STORE,
+ RECOMMENDED_STORE,
+ DEFAULT_STORE,
+ PREF_STORE_TYPE_MAX = DEFAULT_STORE
+ };
+
+ // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors
+ // 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::Observer {
+ public:
+ PrefStoreKeeper();
+ virtual ~PrefStoreKeeper();
+
+ // Takes ownership of |pref_store|.
+ void Initialize(PrefValueStore* store,
+ PrefStore* pref_store,
+ PrefStoreType type);
+
+ PrefStore* store() { return pref_store_.get(); }
+ const PrefStore* store() const { return pref_store_.get(); }
+
+ private:
+ // PrefStore::Observer implementation.
+ virtual void OnPrefValueChanged(const std::string& key);
+ virtual void OnInitializationCompleted();
+
+ // PrefValueStore this keeper is part of.
+ PrefValueStore* pref_value_store_;
+
+ // The PrefStore managed by this keeper.
+ scoped_ptr<PrefStore> pref_store_;
+
+ // Type of the pref store.
+ PrefStoreType type_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper);
+ };
+
typedef std::map<std::string, Value::ValueType> PrefTypeMap;
- friend class PrefValueStoreTest;
- FRIEND_TEST_ALL_PREFIXES(PrefValueStoreTest,
+ friend class PrefValueStorePolicyRefreshTest;
+ FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh);
+ FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
TestRefreshPolicyPrefsCompletion);
+ FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest,
+ TestConcurrentPolicyRefresh);
+
+ // Returns true if the actual type is a valid type for the expected type when
+ // found in the given store.
+ static bool IsValidType(Value::ValueType expected,
+ Value::ValueType actual,
+ PrefStoreType store);
// Returns true if the preference with the given name has a value in the
// given PrefStoreType, of the same value type as the preference was
// registered with.
- bool PrefValueInStore(const char* name,
- PrefNotifier::PrefStoreType store) const;
+ bool PrefValueInStore(const char* name, PrefStoreType store) const;
+
+ // Returns true if a preference has an explicit value in any of the
+ // stores in the range specified by |first_checked_store| and
+ // |last_checked_store|, even if that value is currently being
+ // overridden by a higher-priority store.
+ bool PrefValueInStoreRange(const char* name,
+ PrefStoreType first_checked_store,
+ PrefStoreType last_checked_store) const;
+
+ // Returns the pref store type identifying the source that controls the
+ // Preference identified by |name|. If none of the sources has a value,
+ // INVALID_STORE is returned. In practice, the default PrefStore
+ // should always have a value for any registered preferencem, so INVALID_STORE
+ // indicates an error.
+ PrefStoreType ControllingPrefStoreForPref(const char* name) const;
// Get a value from the specified store type.
bool GetValueFromStore(const char* name,
- PrefNotifier::PrefStoreType store,
+ PrefStoreType store,
Value** out_value) const;
+<<<<<<< HEAD
#ifndef ANDROID
// Called during policy refresh after ReadPrefs completes on the thread
// that initiated the policy refresh. RefreshPolicyPrefsCompletion takes
@@ -254,15 +317,49 @@ class PrefValueStore : public base::RefCountedThreadSafe<PrefValueStore> {
#endif
scoped_ptr<PrefStore> pref_stores_[PrefNotifier::PREF_STORE_TYPE_MAX + 1];
+=======
+ // Called upon changes in individual pref stores in order to determine whether
+ // the user-visible pref value has changed. Triggers the change notification
+ // if the effective value of the preference has changed, or if the store
+ // controlling the pref has changed.
+ void NotifyPrefChanged(const char* path, PrefStoreType new_store);
+
+ // Called from the PrefStoreKeeper implementation when a pref value for |key|
+ // changed in the pref store for |type|.
+ void OnPrefValueChanged(PrefStoreType type, const std::string& key);
+
+ // Handle the event that the store for |type| has completed initialization.
+ void OnInitializationCompleted(PrefStoreType type);
+
+ // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take
+ // ownership of the passed |pref_store|.
+ void InitPrefStore(PrefStoreType type, PrefStore* pref_store);
+
+ // Checks whether initialization is completed and tells the notifier if that
+ // is the case.
+ void CheckInitializationCompleted();
+
+ // Get the PrefStore pointer for the given type. May return NULL if there is
+ // no PrefStore for that type.
+ PrefStore* GetPrefStore(PrefStoreType type) {
+ return pref_stores_[type].store();
+ }
+ const PrefStore* GetPrefStore(PrefStoreType type) const {
+ return pref_stores_[type].store();
+ }
+
+ // Keeps the PrefStore references in order of precedence.
+ PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1];
+
+ // Used for generating PREF_CHANGED and PREF_INITIALIZATION_COMPLETED
+ // notifications. This is a weak reference, since the notifier is owned by the
+ // corresponding PrefService.
+ PrefNotifier* pref_notifier_;
+>>>>>>> chromium.org at r10.0.621.0
// A mapping of preference names to their registered types.
PrefTypeMap pref_types_;
- // The associated profile, in case this value store is associated with a
- // profile pref service. Used for recreating the device management pref store
- // upon policy refresh.
- Profile* profile_;
-
DISALLOW_COPY_AND_ASSIGN(PrefValueStore);
};
diff --git a/chrome/browser/prefs/pref_value_store_unittest.cc b/chrome/browser/prefs/pref_value_store_unittest.cc
index cbf7ccc..5c0fa53 100644
--- a/chrome/browser/prefs/pref_value_store_unittest.cc
+++ b/chrome/browser/prefs/pref_value_store_unittest.cc
@@ -2,26 +2,33 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <set>
+#include <string>
+
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
-#include "chrome/browser/prefs/dummy_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"
#include "chrome/common/pref_names.h"
-#include "chrome/test/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
+using testing::AnyNumber;
using testing::Mock;
+using testing::Invoke;
namespace {
-class MockPolicyRefreshCallback {
+// Allows to capture pref notifications through gmock.
+class MockPrefNotifier : public PrefNotifier {
public:
- MockPolicyRefreshCallback() {}
- MOCK_METHOD1(DoCallback, void(const std::vector<std::string>));
+ MOCK_METHOD1(OnPreferenceChanged, void(const std::string&));
+ MOCK_METHOD0(OnInitializationCompleted, void());
};
} // namespace
@@ -83,44 +90,25 @@ const std::string kSearchProviderNameValue = "AreYouFeelingExtraLucky";
class PrefValueStoreTest : public testing::Test {
protected:
virtual void SetUp() {
- // Create dummy user preferences.
- managed_platform_prefs_= CreateManagedPlatformPrefs();
- device_management_prefs_ = CreateDeviceManagementPrefs();
- extension_prefs_ = CreateExtensionPrefs();
- command_line_prefs_ = CreateCommandLinePrefs();
- user_prefs_ = CreateUserPrefs();
- recommended_prefs_ = CreateRecommendedPrefs();
- default_prefs_ = CreateDefaultPrefs();
-
- std::sort(expected_differing_paths_.begin(),
- expected_differing_paths_.end());
-
- // Create |DummyPrefStore|s.
- managed_platform_pref_store_ = new DummyPrefStore();
- managed_platform_pref_store_->set_prefs(managed_platform_prefs_);
- device_management_pref_store_ = new DummyPrefStore();
- device_management_pref_store_->set_prefs(device_management_prefs_);
- extension_pref_store_ = new DummyPrefStore();
- extension_pref_store_->set_prefs(extension_prefs_);
- command_line_pref_store_ = new DummyPrefStore();
- command_line_pref_store_->set_prefs(command_line_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_);
- default_pref_store_ = new DummyPrefStore();
- default_pref_store_->set_prefs(default_prefs_);
-
- // Create a new pref-value-store.
- pref_value_store_ = new TestingPrefService::TestingPrefValueStore(
+ // Create TestingPrefStores.
+ CreateManagedPlatformPrefs();
+ CreateDeviceManagementPrefs();
+ CreateExtensionPrefs();
+ CreateCommandLinePrefs();
+ CreateUserPrefs();
+ CreateRecommendedPrefs();
+ CreateDefaultPrefs();
+
+ // Create a fresh PrefValueStore.
+ pref_value_store_ = new PrefValueStore(
managed_platform_pref_store_,
device_management_pref_store_,
extension_pref_store_,
command_line_pref_store_,
user_pref_store_,
recommended_pref_store_,
- default_pref_store_);
+ default_pref_store_,
+ &pref_notifier_);
// Register prefs with the PrefValueStore.
pref_value_store_->RegisterPreferenceType(prefs::kApplicationLocale,
@@ -144,99 +132,76 @@ class PrefValueStoreTest : public testing::Test {
Value::TYPE_LIST);
pref_value_store_->RegisterPreferenceType(prefs::kDefaultPref,
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_));
+ pref_value_store_->RegisterPreferenceType(prefs::kProxyMode,
+ Value::TYPE_INTEGER);
}
// Creates a new dictionary and stores some sample user preferences
// in it.
- DictionaryValue* CreateUserPrefs() {
- DictionaryValue* user_prefs = new DictionaryValue();
- user_prefs->SetBoolean(prefs::kDeleteCache, user_pref::kDeleteCacheValue);
- user_prefs->SetInteger(prefs::kStabilityLaunchCount,
- user_pref::kStabilityLaunchCountValue);
- user_prefs->SetString(prefs::kCurrentThemeID,
+ void CreateUserPrefs() {
+ user_pref_store_ = new TestingPrefStore;
+ user_pref_store_->SetBoolean(prefs::kDeleteCache,
+ user_pref::kDeleteCacheValue);
+ user_pref_store_->SetInteger(prefs::kStabilityLaunchCount,
+ user_pref::kStabilityLaunchCountValue);
+ user_pref_store_->SetString(prefs::kCurrentThemeID,
user_pref::kCurrentThemeIDValue);
- user_prefs->SetString(prefs::kApplicationLocale,
+ user_pref_store_->SetString(prefs::kApplicationLocale,
user_pref::kApplicationLocaleValue);
- user_prefs->SetString(prefs::kDefaultSearchProviderName,
+ user_pref_store_->SetString(prefs::kDefaultSearchProviderName,
user_pref::kSearchProviderNameValue);
- user_prefs->SetString(prefs::kHomePage, user_pref::kHomepageValue);
- return user_prefs;
+ user_pref_store_->SetString(prefs::kHomePage,
+ user_pref::kHomepageValue);
}
- DictionaryValue* CreateManagedPlatformPrefs() {
- DictionaryValue* managed_platform_prefs = new DictionaryValue();
- managed_platform_prefs->SetString(
- prefs::kHomePage,
+ void CreateManagedPlatformPrefs() {
+ managed_platform_pref_store_ = new TestingPrefStore;
+ managed_platform_pref_store_->SetString(prefs::kHomePage,
managed_platform_pref::kHomepageValue);
- expected_differing_paths_.push_back(prefs::kHomePage);
- return managed_platform_prefs;
}
- DictionaryValue* CreateDeviceManagementPrefs() {
- DictionaryValue* device_management_prefs = new DictionaryValue();
- device_management_prefs->SetString(
- prefs::kDefaultSearchProviderName,
+ void CreateDeviceManagementPrefs() {
+ device_management_pref_store_ = new TestingPrefStore;
+ device_management_pref_store_->SetString(prefs::kDefaultSearchProviderName,
device_management_pref::kSearchProviderNameValue);
- expected_differing_paths_.push_back("default_search_provider");
- expected_differing_paths_.push_back(prefs::kDefaultSearchProviderName);
- device_management_prefs->SetString(prefs::kHomePage,
- device_management_pref::kHomepageValue);
- return device_management_prefs;
+ device_management_pref_store_->SetString(prefs::kHomePage,
+ device_management_pref::kHomepageValue);
}
- DictionaryValue* CreateExtensionPrefs() {
- DictionaryValue* extension_prefs = new DictionaryValue();
- extension_prefs->SetString(prefs::kCurrentThemeID,
+ void CreateExtensionPrefs() {
+ extension_pref_store_ = new TestingPrefStore;
+ extension_pref_store_->SetString(prefs::kCurrentThemeID,
extension_pref::kCurrentThemeIDValue);
- extension_prefs->SetString(prefs::kHomePage,
+ extension_pref_store_->SetString(prefs::kHomePage,
extension_pref::kHomepageValue);
- extension_prefs->SetString(prefs::kDefaultSearchProviderName,
- extension_pref::kSearchProviderNameValue);
- return extension_prefs;
+ extension_pref_store_->SetString(prefs::kDefaultSearchProviderName,
+ extension_pref::kSearchProviderNameValue);
}
- DictionaryValue* CreateCommandLinePrefs() {
- DictionaryValue* command_line_prefs = new DictionaryValue();
- command_line_prefs->SetString(prefs::kCurrentThemeID,
+ void CreateCommandLinePrefs() {
+ command_line_pref_store_ = new TestingPrefStore;
+ command_line_pref_store_->SetString(prefs::kCurrentThemeID,
command_line_pref::kCurrentThemeIDValue);
- command_line_prefs->SetString(prefs::kApplicationLocale,
+ command_line_pref_store_->SetString(prefs::kApplicationLocale,
command_line_pref::kApplicationLocaleValue);
- command_line_prefs->SetString(prefs::kHomePage,
+ command_line_pref_store_->SetString(prefs::kHomePage,
command_line_pref::kHomepageValue);
- command_line_prefs->SetString(
- prefs::kDefaultSearchProviderName,
+ command_line_pref_store_->SetString(prefs::kDefaultSearchProviderName,
command_line_pref::kSearchProviderNameValue);
- return command_line_prefs;
}
- DictionaryValue* CreateRecommendedPrefs() {
- DictionaryValue* recommended_prefs = new DictionaryValue();
- recommended_prefs->SetInteger(prefs::kStabilityLaunchCount,
+ void CreateRecommendedPrefs() {
+ recommended_pref_store_ = new TestingPrefStore;
+ recommended_pref_store_->SetInteger(prefs::kStabilityLaunchCount,
recommended_pref::kStabilityLaunchCountValue);
- recommended_prefs->SetBoolean(
- prefs::kRecommendedPref,
+ recommended_pref_store_->SetBoolean(prefs::kRecommendedPref,
recommended_pref::kRecommendedPrefValue);
-
- // Expected differing paths must be added in lexicographic order
- // to work properly
- expected_differing_paths_.push_back("this");
- expected_differing_paths_.push_back("this.pref");
- expected_differing_paths_.push_back(prefs::kRecommendedPref);
- expected_differing_paths_.push_back("user_experience_metrics");
- expected_differing_paths_.push_back("user_experience_metrics.stability");
- expected_differing_paths_.push_back(prefs::kStabilityLaunchCount);
- return recommended_prefs;
}
- DictionaryValue* CreateDefaultPrefs() {
- DictionaryValue* default_prefs = new DictionaryValue();
- default_prefs->SetInteger(prefs::kDefaultPref, default_pref::kDefaultValue);
- return default_prefs;
+ void CreateDefaultPrefs() {
+ default_pref_store_ = new TestingPrefStore;
+ default_pref_store_->SetInteger(prefs::kDefaultPref,
+ default_pref::kDefaultValue);
}
DictionaryValue* CreateSampleDictValue() {
@@ -256,56 +221,19 @@ class PrefValueStoreTest : public testing::Test {
return sample_list;
}
- virtual void TearDown() {
- loop_.RunAllPending();
- }
-
- MessageLoop loop_;
-
- scoped_refptr<TestingPrefService::TestingPrefValueStore> pref_value_store_;
+ MockPrefNotifier pref_notifier_;
+ scoped_refptr<PrefValueStore> pref_value_store_;
// |PrefStore|s are owned by the |PrefValueStore|.
- DummyPrefStore* managed_platform_pref_store_;
- DummyPrefStore* device_management_pref_store_;
- DummyPrefStore* extension_pref_store_;
- DummyPrefStore* command_line_pref_store_;
- DummyPrefStore* user_pref_store_;
- DummyPrefStore* recommended_pref_store_;
- DummyPrefStore* 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::vector<std::string> expected_differing_paths_;
-
- // Preferences are owned by the individual |DummyPrefStores|.
- DictionaryValue* managed_platform_prefs_;
- DictionaryValue* device_management_prefs_;
- DictionaryValue* extension_prefs_;
- DictionaryValue* command_line_prefs_;
- DictionaryValue* user_prefs_;
- DictionaryValue* recommended_prefs_;
- DictionaryValue* default_prefs_;
-
- private:
- scoped_ptr<BrowserThread> ui_thread_;
- scoped_ptr<BrowserThread> file_thread_;
+ TestingPrefStore* managed_platform_pref_store_;
+ TestingPrefStore* device_management_pref_store_;
+ TestingPrefStore* extension_pref_store_;
+ TestingPrefStore* command_line_pref_store_;
+ TestingPrefStore* user_pref_store_;
+ TestingPrefStore* recommended_pref_store_;
+ TestingPrefStore* default_pref_store_;
};
-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;
@@ -378,8 +306,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,
@@ -391,14 +321,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));
@@ -427,109 +357,70 @@ TEST_F(PrefValueStoreTest, HasPrefPath) {
EXPECT_FALSE(pref_value_store_->HasPrefPath(prefs::kMissingPref));
}
-TEST_F(PrefValueStoreTest, PrefHasChanged) {
+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_TRUE(pref_value_store_->PrefHasChanged(managed_platform_pref_path,
- static_cast<PrefNotifier::PrefStoreType>(0)));
- EXPECT_FALSE(pref_value_store_->PrefHasChanged(managed_platform_pref_path,
- PrefNotifier::USER_STORE));
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(managed_platform_pref_path));
+ managed_platform_pref_store_->NotifyPrefValueChanged(
+ managed_platform_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
- // Check pref controlled by user store.
- EXPECT_TRUE(pref_value_store_->PrefHasChanged(user_pref_path,
- static_cast<PrefNotifier::PrefStoreType>(0)));
- EXPECT_TRUE(pref_value_store_->PrefHasChanged(user_pref_path,
- PrefNotifier::USER_STORE));
- EXPECT_FALSE(pref_value_store_->PrefHasChanged(user_pref_path,
- PrefNotifier::PREF_STORE_TYPE_MAX));
-
- // Check pref controlled by default-pref store.
- EXPECT_TRUE(pref_value_store_->PrefHasChanged(default_pref_path,
- PrefNotifier::USER_STORE));
- EXPECT_TRUE(pref_value_store_->PrefHasChanged(default_pref_path,
- PrefNotifier::DEFAULT_STORE));
-}
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(0);
+ user_pref_store_->NotifyPrefValueChanged(managed_platform_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
-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));
-}
+ // Check pref controlled by user store.
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(user_pref_path));
+ managed_platform_pref_store_->NotifyPrefValueChanged(user_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
-TEST_F(PrefValueStoreTest, WritePrefs) {
- user_pref_store_->set_prefs_written(false);
- pref_value_store_->WritePrefs();
- ASSERT_TRUE(user_pref_store_->get_prefs_written());
-}
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(user_pref_path));
+ user_pref_store_->NotifyPrefValueChanged(user_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
-TEST_F(PrefValueStoreTest, SetUserPrefValue) {
- Value* new_value = NULL;
- Value* actual_value = NULL;
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(_)).Times(0);
+ default_pref_store_->NotifyPrefValueChanged(user_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
- // Test that managed platform values can not be set.
- ASSERT_TRUE(pref_value_store_->PrefValueInManagedPlatformStore(
- prefs::kHomePage));
- // The Ownership is tranfered to |PrefValueStore|.
- new_value = Value::CreateStringValue("http://www.youtube.com");
- pref_value_store_->SetUserPrefValue(prefs::kHomePage, new_value);
+ // Check pref controlled by default-pref store.
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(default_pref_path));
+ user_pref_store_->NotifyPrefValueChanged(default_pref_path);
+ 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);
+ EXPECT_CALL(pref_notifier_, OnPreferenceChanged(default_pref_path));
+ default_pref_store_->NotifyPrefValueChanged(default_pref_path);
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
+}
- // 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);
-
- 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));
-
- // Set and Get |DictionaryValue|
- DictionaryValue* expected_dict_value = CreateSampleDictValue();
- pref_value_store_->SetUserPrefValue(prefs::kSampleDict, expected_dict_value);
-
- 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|
- 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, OnInitializationCompleted) {
+ EXPECT_CALL(pref_notifier_, OnInitializationCompleted()).Times(0);
+ managed_platform_pref_store_->SetInitializationCompleted();
+ device_management_pref_store_->SetInitializationCompleted();
+ extension_pref_store_->SetInitializationCompleted();
+ command_line_pref_store_->SetInitializationCompleted();
+ recommended_pref_store_->SetInitializationCompleted();
+ default_pref_store_->SetInitializationCompleted();
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
+
+ // The notification should only be triggered after the last store is done.
+ EXPECT_CALL(pref_notifier_, OnInitializationCompleted()).Times(1);
+ user_pref_store_->SetInitializationCompleted();
+ Mock::VerifyAndClearExpectations(&pref_notifier_);
}
TEST_F(PrefValueStoreTest, PrefValueInManagedPlatformStore) {
@@ -633,18 +524,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_prefs_->SetBoolean(prefs::kProxyAutoDetect, false);
- managed_platform_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));
@@ -739,147 +618,3 @@ TEST_F(PrefValueStoreTest, PrefValueFromDefaultStore) {
EXPECT_FALSE(
pref_value_store_->PrefValueFromDefaultStore(prefs::kMissingPref));
}
-
-TEST_F(PrefValueStoreTest, 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
- // in the managed platform, device management and recommended stores should
- // change.
- MockPolicyRefreshCallback callback;
- EXPECT_CALL(callback, DoCallback(_)).Times(0);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- pref_value_store_.get(),
- &PrefValueStore::RefreshPolicyPrefs,
- NewCallback(&callback,
- &MockPolicyRefreshCallback::DoCallback)));
- Mock::VerifyAndClearExpectations(&callback);
- EXPECT_CALL(callback, DoCallback(expected_differing_paths_)).Times(1);
- loop_.RunAllPending();
-}
-
-TEST_F(PrefValueStoreTest, TestRefreshPolicyPrefsCompletion) {
- // Test changed preferences in the managed platform store and removed
- // 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<DummyPrefStore> new_managed_platform_store(new DummyPrefStore());
- DictionaryValue* dict = new DictionaryValue();
- dict->SetString("homepage", "some other changed homepage");
- new_managed_platform_store->set_prefs(dict);
- MockPolicyRefreshCallback callback;
- EXPECT_CALL(callback, DoCallback(expected_differing_paths_)).Times(1);
- pref_value_store_->RefreshPolicyPrefsCompletion(
- new_managed_platform_store.release(),
- new DummyPrefStore(),
- new DummyPrefStore(),
- NewCallback(&callback,
- &MockPolicyRefreshCallback::DoCallback));
-
- // Test properties that have been removed from the managed platform store.
- // Homepage is still set in managed prefs.
- expected_differing_paths_.clear();
- expected_differing_paths_.push_back(std::string("homepage"));
- MockPolicyRefreshCallback callback2;
- EXPECT_CALL(callback2, DoCallback(expected_differing_paths_)).Times(1);
- pref_value_store_->RefreshPolicyPrefsCompletion(
- new DummyPrefStore(),
- new DummyPrefStore(),
- new DummyPrefStore(),
- NewCallback(&callback2,
- &MockPolicyRefreshCallback::DoCallback));
-
- // Test properties that are added to the device management store.
- expected_differing_paths_.clear();
- expected_differing_paths_.push_back(std::string("homepage"));
- scoped_ptr<DummyPrefStore> new_device_management_store(
- new DummyPrefStore());
- dict = new DictionaryValue();
- dict->SetString("homepage", "some other changed homepage");
- new_device_management_store->set_prefs(dict);
- MockPolicyRefreshCallback callback3;
- EXPECT_CALL(callback3, DoCallback(expected_differing_paths_)).Times(1);
- pref_value_store_->RefreshPolicyPrefsCompletion(
- new DummyPrefStore(),
- new_device_management_store.release(),
- new DummyPrefStore(),
- NewCallback(&callback3,
- &MockPolicyRefreshCallback::DoCallback));
-
- // Test properties that are added to the recommended store.
- scoped_ptr<DummyPrefStore> new_recommended_store(new DummyPrefStore());
- dict = new DictionaryValue();
- dict->SetString("homepage", "some other changed homepage 2");
- new_recommended_store->set_prefs(dict);
- expected_differing_paths_.clear();
- expected_differing_paths_.push_back(std::string("homepage"));
- MockPolicyRefreshCallback callback4;
- EXPECT_CALL(callback4, DoCallback(expected_differing_paths_)).Times(1);
- pref_value_store_->RefreshPolicyPrefsCompletion(
- new DummyPrefStore(),
- new DummyPrefStore(),
- new_recommended_store.release(),
- NewCallback(&callback4,
- &MockPolicyRefreshCallback::DoCallback));
-
- // Test adding a multi-key path.
- new_managed_platform_store.reset(new DummyPrefStore());
- dict = new DictionaryValue();
- dict->SetString("segment1.segment2", "value");
- new_managed_platform_store->set_prefs(dict);
- expected_differing_paths_.clear();
- expected_differing_paths_.push_back(std::string("homepage"));
- expected_differing_paths_.push_back(std::string("segment1"));
- expected_differing_paths_.push_back(std::string("segment1.segment2"));
- MockPolicyRefreshCallback callback5;
- EXPECT_CALL(callback5, DoCallback(expected_differing_paths_)).Times(1);
- pref_value_store_->RefreshPolicyPrefsCompletion(
- new_managed_platform_store.release(),
- new DummyPrefStore(),
- new DummyPrefStore(),
- NewCallback(&callback5,
- &MockPolicyRefreshCallback::DoCallback));
-}
-
-TEST_F(PrefValueStoreTest, TestConcurrentPolicyRefresh) {
- MockPolicyRefreshCallback callback1;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- pref_value_store_.get(),
- &PrefValueStore::RefreshPolicyPrefs,
- NewCallback(&callback1,
- &MockPolicyRefreshCallback::DoCallback)));
- EXPECT_CALL(callback1, DoCallback(_)).Times(0);
-
- MockPolicyRefreshCallback callback2;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- pref_value_store_.get(),
- &PrefValueStore::RefreshPolicyPrefs,
- NewCallback(&callback2,
- &MockPolicyRefreshCallback::DoCallback)));
- EXPECT_CALL(callback2, DoCallback(_)).Times(0);
-
- MockPolicyRefreshCallback callback3;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- pref_value_store_.get(),
- &PrefValueStore::RefreshPolicyPrefs,
- NewCallback(&callback3,
- &MockPolicyRefreshCallback::DoCallback)));
- EXPECT_CALL(callback3, DoCallback(_)).Times(0);
- Mock::VerifyAndClearExpectations(&callback1);
- Mock::VerifyAndClearExpectations(&callback2);
- Mock::VerifyAndClearExpectations(&callback3);
-
- EXPECT_CALL(callback1, DoCallback(expected_differing_paths_)).Times(1);
- std::vector<std::string> no_differing_paths;
- EXPECT_CALL(callback2, DoCallback(no_differing_paths)).Times(1);
- EXPECT_CALL(callback3, DoCallback(no_differing_paths)).Times(1);
- loop_.RunAllPending();
-}
diff --git a/chrome/browser/prefs/proxy_prefs.cc b/chrome/browser/prefs/proxy_prefs.cc
new file mode 100644
index 0000000..7eb504c
--- /dev/null
+++ b/chrome/browser/prefs/proxy_prefs.cc
@@ -0,0 +1,45 @@
+// 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/proxy_prefs.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+namespace {
+
+// These names are exposed to the proxy extension API. They must be in sync
+// with the constants of ProxyPrefs.
+const char* kProxyModeNames[] = { "direct",
+ "auto_detect",
+ "pac_script",
+ "fixed_servers",
+ "system" };
+
+} // namespace
+
+namespace ProxyPrefs {
+
+COMPILE_ASSERT(arraysize(kProxyModeNames) == kModeCount,
+ kProxyModeNames_must_have_size_of_NUM_MODES);
+
+bool IntToProxyMode(int in_value, ProxyMode* out_value) {
+ DCHECK(out_value);
+ if (in_value < 0 || in_value >= kModeCount)
+ return false;
+ *out_value = static_cast<ProxyMode>(in_value);
+ return true;
+}
+
+// static
+bool StringToProxyMode(const std::string& in_value, ProxyMode* out_value) {
+ DCHECK(out_value);
+ for (int i = 0; i < kModeCount; i++) {
+ if (in_value == kProxyModeNames[i])
+ return IntToProxyMode(i, out_value);
+ }
+ return false;
+}
+
+} // namespace
diff --git a/chrome/browser/prefs/proxy_prefs.h b/chrome/browser/prefs/proxy_prefs.h
new file mode 100644
index 0000000..bbeb44d
--- /dev/null
+++ b/chrome/browser/prefs/proxy_prefs.h
@@ -0,0 +1,45 @@
+// 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_PROXY_PREFS_H_
+#define CHROME_BROWSER_PREFS_PROXY_PREFS_H_
+#pragma once
+
+#include <string>
+
+namespace ProxyPrefs {
+
+// Possible types of specifying proxy settings. Do not change the order of
+// the constants, because numeric values are exposed to users.
+// If you add an enum constant, you should also add a string to
+// kProxyModeNames in the .cc file.
+enum ProxyMode {
+ // Direct connection to the network, other proxy preferences are ignored.
+ MODE_DIRECT = 0,
+
+ // Try to retrieve a PAC script from http://wpad/wpad.dat or fall back to
+ // direct connection.
+ MODE_AUTO_DETECT = 1,
+
+ // Try to retrieve a PAC script from kProxyPacURL or fall back to direct
+ // connection.
+ MODE_PAC_SCRIPT = 2,
+
+ // Use the settings specified in kProxyServer and kProxyBypassList.
+ MODE_FIXED_SERVERS = 3,
+
+ // The system's proxy settings are used, other proxy preferences are
+ // ignored.
+ MODE_SYSTEM = 4,
+
+ kModeCount
+};
+
+bool IntToProxyMode(int in_value, ProxyMode* out_value);
+bool StringToProxyMode(const std::string& in_value,
+ ProxyMode* out_value);
+
+} // namespace ProxyPrefs
+
+#endif // CHROME_BROWSER_PREFS_PROXY_PREFS_H_
diff --git a/chrome/browser/prefs/proxy_prefs_unittest.cc b/chrome/browser/prefs/proxy_prefs_unittest.cc
new file mode 100644
index 0000000..72aa0f1
--- /dev/null
+++ b/chrome/browser/prefs/proxy_prefs_unittest.cc
@@ -0,0 +1,52 @@
+// 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 <string>
+
+#include "base/logging.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(ProxyPrefsTest, StringToProxyMode) {
+ ProxyPrefs::ProxyMode mode;
+ EXPECT_TRUE(ProxyPrefs::StringToProxyMode("direct", &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode);
+ EXPECT_TRUE(ProxyPrefs::StringToProxyMode("auto_detect", &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode);
+ EXPECT_TRUE(ProxyPrefs::StringToProxyMode("pac_script", &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode);
+ EXPECT_TRUE(ProxyPrefs::StringToProxyMode("system", &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, mode);
+ EXPECT_TRUE(ProxyPrefs::StringToProxyMode("fixed_servers", &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, mode);
+
+ EXPECT_FALSE(ProxyPrefs::StringToProxyMode("monkey", &mode));
+}
+
+TEST(ProxyPrefsTest, IntToProxyMode) {
+ ASSERT_EQ(ProxyPrefs::MODE_DIRECT, 0);
+ ASSERT_EQ(ProxyPrefs::MODE_AUTO_DETECT, 1);
+ ASSERT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, 2);
+ ASSERT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, 3);
+ ASSERT_EQ(ProxyPrefs::MODE_SYSTEM, 4);
+ // Update the following as necessary, don't change the previous ones.
+ ASSERT_EQ(ProxyPrefs::kModeCount, 5);
+
+ ProxyPrefs::ProxyMode mode;
+ EXPECT_TRUE(ProxyPrefs::IntToProxyMode(0, &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode);
+ EXPECT_TRUE(ProxyPrefs::IntToProxyMode(1, &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode);
+ EXPECT_TRUE(ProxyPrefs::IntToProxyMode(2, &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode);
+ EXPECT_TRUE(ProxyPrefs::IntToProxyMode(3, &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS, mode);
+ EXPECT_TRUE(ProxyPrefs::IntToProxyMode(4, &mode));
+ EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, mode);
+
+ EXPECT_FALSE(ProxyPrefs::IntToProxyMode(-1, &mode));
+ EXPECT_FALSE(ProxyPrefs::IntToProxyMode(ProxyPrefs::kModeCount, &mode));
+}
diff --git a/chrome/browser/prefs/scoped_pref_update.cc b/chrome/browser/prefs/scoped_pref_update.cc
index bc77b28..024d71b 100644
--- a/chrome/browser/prefs/scoped_pref_update.cc
+++ b/chrome/browser/prefs/scoped_pref_update.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/prefs/scoped_pref_update.h"
+#include "chrome/browser/prefs/pref_notifier.h"
#include "chrome/browser/prefs/pref_service.h"
ScopedPrefUpdate::ScopedPrefUpdate(PrefService* service, const char* path)
@@ -11,5 +12,8 @@ ScopedPrefUpdate::ScopedPrefUpdate(PrefService* service, const char* path)
path_(path) {}
ScopedPrefUpdate::~ScopedPrefUpdate() {
- service_->pref_notifier()->FireObservers(path_.c_str());
+ // TODO(mnissler, danno): This sends a notification unconditionally, which is
+ // wrong. We should rather tell the PrefService that the user pref got
+ // updated.
+ service_->pref_notifier()->OnPreferenceChanged(path_.c_str());
}
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index 188bb4c..b339e1d 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -12,7 +12,7 @@
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_pref_update.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
namespace {
diff --git a/chrome/browser/prefs/testing_pref_store.cc b/chrome/browser/prefs/testing_pref_store.cc
new file mode 100644
index 0000000..39c20f2
--- /dev/null
+++ b/chrome/browser/prefs/testing_pref_store.cc
@@ -0,0 +1,100 @@
+// 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/testing_pref_store.h"
+
+#include "base/values.h"
+
+TestingPrefStore::TestingPrefStore()
+ : read_only_(true),
+ prefs_written_(false),
+ init_complete_(false) { }
+
+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() {
+ prefs_written_ = true;
+ return prefs_written_;
+}
+
+void TestingPrefStore::SetInitializationCompleted() {
+ init_complete_ = true;
+ NotifyInitializationCompleted();
+}
+
+void TestingPrefStore::NotifyPrefValueChanged(const std::string& key) {
+ FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
+}
+
+void TestingPrefStore::NotifyInitializationCompleted() {
+ FOR_EACH_OBSERVER(Observer, observers_, OnInitializationCompleted());
+}
+
+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
new file mode 100644
index 0000000..555ee69
--- /dev/null
+++ b/chrome/browser/prefs/testing_pref_store.h
@@ -0,0 +1,80 @@
+// 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_TESTING_PREF_STORE_H_
+#define CHROME_BROWSER_PREFS_TESTING_PREF_STORE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/observer_list.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/prefs/pref_value_map.h"
+#include "chrome/common/persistent_pref_store.h"
+
+class DictionaryValue;
+
+// |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() {}
+
+ // 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
+ // |TestingPrefStore|.
+ virtual void set_read_only(bool read_only) { read_only_ = read_only; }
+ virtual void set_prefs_written(bool status) { prefs_written_ = status; }
+ virtual bool get_prefs_written() { return prefs_written_; }
+
+ private:
+ // Stores the preference values.
+ PrefValueMap 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_;
+
+ // Whether initialization has been completed.
+ bool init_complete_;
+
+ ObserverList<PrefStore::Observer, true> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestingPrefStore);
+};
+
+#endif // CHROME_BROWSER_PREFS_TESTING_PREF_STORE_H_
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..705c958
--- /dev/null
+++ b/chrome/browser/prefs/value_map_pref_store.cc
@@ -0,0 +1,41 @@
+// 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"
+
+ValueMapPrefStore::ValueMapPrefStore() {}
+
+ValueMapPrefStore::~ValueMapPrefStore() {}
+
+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..20bf290
--- /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_