Refactor PrefService, pulling the PREF_CHANGED notification infrastructure out so
it can be accessed by both the PrefService, for user preferences, and the individal
PrefStores, for preferences set "from below" (e.g., by configuration policy changes).

BUG=50722
TEST=covered by unit tests
Review URL: http://codereview.chromium.org/3052045

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56493 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/pref_value_store_unittest.cc b/chrome/browser/pref_value_store_unittest.cc
index 0effd04..c159945 100644
--- a/chrome/browser/pref_value_store_unittest.cc
+++ b/chrome/browser/pref_value_store_unittest.cc
@@ -15,6 +15,16 @@
 using testing::_;
 using testing::Mock;
 
+namespace {
+
+class MockPolicyRefreshCallback {
+ public:
+  MockPolicyRefreshCallback() {}
+  MOCK_METHOD1(DoCallback, void(const std::vector<std::string>));
+};
+
+}  // namespace
+
 // Names of the preferences used in this test program.
 namespace prefs {
   const char kCurrentThemeID[] = "extensions.theme.id";
@@ -31,7 +41,7 @@
   const char kApplicationLocale[] = "intl.app_locale";
 }
 
-// Potentailly expected values of all preferences used in this test program.
+// Potentially expected values of all preferences used in this test program.
 // The "user" namespace is defined globally in an ARM system header, so we need
 // something different here.
 namespace user_pref {
@@ -281,6 +291,25 @@
   EXPECT_FALSE(pref_value_store_->HasPrefPath(prefs::kMissingPref));
 }
 
+TEST_F(PrefValueStoreTest, PrefHasChanged) {
+  ASSERT_TRUE(pref_value_store_->PrefValueInManagedStore(prefs::kHomepage));
+
+  // Pretend we used to have a different enforced value set.
+  scoped_ptr<Value> value(Value::CreateStringValue("http://www.youtube.com"));
+  EXPECT_TRUE(pref_value_store_->PrefHasChanged(prefs::kHomepage, value.get()));
+
+  // Pretend we used to have the same enforced value set.
+  value.reset(Value::CreateStringValue(enforced_pref::kHomepageValue));
+  EXPECT_FALSE(pref_value_store_->PrefHasChanged(prefs::kHomepage,
+      value.get()));
+
+  // Really set a new value in a lower-priority store.
+  Value* new_value = Value::CreateStringValue("http://www.chromium.org");
+  pref_value_store_->SetUserPrefValue(prefs::kHomepage, new_value);
+  EXPECT_FALSE(pref_value_store_->PrefHasChanged(prefs::kHomepage,
+      value.get()));
+}
+
 TEST_F(PrefValueStoreTest, ReadPrefs) {
   pref_value_store_->ReadPrefs();
   // The ReadPrefs method of the |DummyPrefStore| deletes the |pref_store|s
@@ -456,12 +485,6 @@
   EXPECT_FALSE(pref_value_store_->PrefValueFromUserStore(prefs::kMissingPref));
 }
 
-class MockPolicyRefreshCallback {
- public:
-  MockPolicyRefreshCallback() {}
-  MOCK_METHOD1(DoCallback, void(const std::vector<std::string>));
-};
-
 TEST_F(PrefValueStoreTest, TestPolicyRefresh) {
   // pref_value_store_ is initialized by PrefValueStoreTest to have values
   // in both it's managed and recommended store. By replacing them with