| 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));
|
| + }
|
| +}
|
|
|