Remove content::NotificationObserver dependency from most Prefs code.

Instead of using content::NotificationObserver, introduce specific
type-safe observer classes and update users to use them.  In a very
large number of cases this was the users' only reason for being a
content::NotificationObserver and they would have a lot of
boiler-plate code such as a DCHECK on the notification type and
unpacking of the generic NotificationDetails types, so this change
removes a bunch of boilerplate and introduces more type safety.

This is part of enabling more of the Prefs code to live in
base/prefs/.

[email protected],[email protected]
BUG=155525


Review URL: https://chromiumcodereview.appspot.com/11345008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165414 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/prefs/pref_notifier_impl.cc b/chrome/browser/prefs/pref_notifier_impl.cc
index a226685c..9bdf322 100644
--- a/chrome/browser/prefs/pref_notifier_impl.cc
+++ b/chrome/browser/prefs/pref_notifier_impl.cc
@@ -7,9 +7,6 @@
 #include "base/logging.h"
 #include "base/stl_util.h"
 #include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_service.h"
 
 PrefNotifierImpl::PrefNotifierImpl()
     : pref_service_(NULL) {
@@ -25,45 +22,42 @@
   // 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));
+    PrefObserverList::Iterator obs_iterator(*(it->second));
     if (obs_iterator.GetNext()) {
       LOG(WARNING) << "pref observer found at shutdown " << it->first;
     }
   }
 
+  // Same for initialization observers.
+  if (!init_observers_.empty())
+    LOG(WARNING) << "Init observer found at shutdown.";
+
   STLDeleteContainerPairSecondPointers(pref_observers_.begin(),
                                        pref_observers_.end());
   pref_observers_.clear();
+  init_observers_.clear();
 }
 
 void PrefNotifierImpl::AddPrefObserver(const char* path,
-                                       content::NotificationObserver* obs) {
+                                       PrefObserver* obs) {
   // Get the pref observer list associated with the path.
-  NotificationObserverList* observer_list = NULL;
+  PrefObserverList* observer_list = NULL;
   const PrefObserverMap::iterator observer_iterator =
       pref_observers_.find(path);
   if (observer_iterator == pref_observers_.end()) {
-    observer_list = new NotificationObserverList;
+    observer_list = new PrefObserverList;
     pref_observers_[path] = observer_list;
   } else {
     observer_list = observer_iterator->second;
   }
 
-  // Verify that this observer doesn't already exist.
-  NotificationObserverList::Iterator it(*observer_list);
-  content::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.
+  // Add the pref observer. ObserverList will DCHECK if it already is
+  // in the list.
   observer_list->AddObserver(obs);
 }
 
 void PrefNotifierImpl::RemovePrefObserver(const char* path,
-                                          content::NotificationObserver* obs) {
+                                          PrefObserver* obs) {
   DCHECK(CalledOnValidThread());
 
   const PrefObserverMap::iterator observer_iterator =
@@ -72,10 +66,14 @@
     return;
   }
 
-  NotificationObserverList* observer_list = observer_iterator->second;
+  PrefObserverList* observer_list = observer_iterator->second;
   observer_list->RemoveObserver(obs);
 }
 
+void PrefNotifierImpl::AddInitObserver(base::Callback<void(bool)> obs) {
+  init_observers_.push_back(obs);
+}
+
 void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) {
   FireObservers(path);
 }
@@ -83,10 +81,17 @@
 void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) {
   DCHECK(CalledOnValidThread());
 
-  content::NotificationService::current()->Notify(
-      chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED,
-      content::Source<PrefService>(pref_service_),
-      content::Details<bool>(&succeeded));
+  // We must make a copy of init_observers_ and clear it before we run
+  // observers, or we can end up in this method re-entrantly before
+  // clearing the observers list.
+  PrefInitObserverList observers(init_observers_);
+  init_observers_.clear();
+
+  for (PrefInitObserverList::iterator it = observers.begin();
+       it != observers.end();
+       ++it) {
+    it->Run(succeeded);
+  }
 }
 
 void PrefNotifierImpl::FireObservers(const std::string& path) {
@@ -101,13 +106,9 @@
   if (observer_iterator == pref_observers_.end())
     return;
 
-  NotificationObserverList::Iterator it(*(observer_iterator->second));
-  content::NotificationObserver* observer;
-  while ((observer = it.GetNext()) != NULL) {
-    observer->Observe(chrome::NOTIFICATION_PREF_CHANGED,
-                      content::Source<PrefService>(pref_service_),
-                      content::Details<const std::string>(&path));
-  }
+  FOR_EACH_OBSERVER(PrefObserver,
+                    *(observer_iterator->second),
+                    OnPreferenceChanged(pref_service_, path));
 }
 
 void PrefNotifierImpl::SetPrefService(PrefService* pref_service) {