| Index: chrome/browser/prefs/pref_notifier_impl.cc
 | 
| diff --git a/chrome/browser/prefs/pref_notifier_impl.cc b/chrome/browser/prefs/pref_notifier_impl.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..d15f425c5ae15253e6614710f0de4cfab4e9cbfa
 | 
| --- /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));
 | 
| +  }
 | 
| +}
 | 
| 
 |