• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/prefs/pref_notifier_impl.h"
6 
7 #include "base/stl_util-inl.h"
8 #include "chrome/browser/prefs/pref_service.h"
9 #include "content/common/notification_observer.h"
10 #include "content/common/notification_service.h"
11 
PrefNotifierImpl(PrefService * service)12 PrefNotifierImpl::PrefNotifierImpl(PrefService* service)
13     : pref_service_(service) {
14 }
15 
~PrefNotifierImpl()16 PrefNotifierImpl::~PrefNotifierImpl() {
17   DCHECK(CalledOnValidThread());
18 
19   // Verify that there are no pref observers when we shut down.
20   for (PrefObserverMap::iterator it = pref_observers_.begin();
21        it != pref_observers_.end(); ++it) {
22     NotificationObserverList::Iterator obs_iterator(*(it->second));
23     if (obs_iterator.GetNext()) {
24       LOG(WARNING) << "pref observer found at shutdown " << it->first;
25     }
26   }
27 
28   STLDeleteContainerPairSecondPointers(pref_observers_.begin(),
29                                        pref_observers_.end());
30   pref_observers_.clear();
31 }
32 
AddPrefObserver(const char * path,NotificationObserver * obs)33 void PrefNotifierImpl::AddPrefObserver(const char* path,
34                                        NotificationObserver* obs) {
35   // Get the pref observer list associated with the path.
36   NotificationObserverList* observer_list = NULL;
37   const PrefObserverMap::iterator observer_iterator =
38       pref_observers_.find(path);
39   if (observer_iterator == pref_observers_.end()) {
40     observer_list = new NotificationObserverList;
41     pref_observers_[path] = observer_list;
42   } else {
43     observer_list = observer_iterator->second;
44   }
45 
46   // Verify that this observer doesn't already exist.
47   NotificationObserverList::Iterator it(*observer_list);
48   NotificationObserver* existing_obs;
49   while ((existing_obs = it.GetNext()) != NULL) {
50     DCHECK(existing_obs != obs) << path << " observer already registered";
51     if (existing_obs == obs)
52       return;
53   }
54 
55   // Ok, safe to add the pref observer.
56   observer_list->AddObserver(obs);
57 }
58 
RemovePrefObserver(const char * path,NotificationObserver * obs)59 void PrefNotifierImpl::RemovePrefObserver(const char* path,
60                                           NotificationObserver* obs) {
61   DCHECK(CalledOnValidThread());
62 
63   const PrefObserverMap::iterator observer_iterator =
64       pref_observers_.find(path);
65   if (observer_iterator == pref_observers_.end()) {
66     return;
67   }
68 
69   NotificationObserverList* observer_list = observer_iterator->second;
70   observer_list->RemoveObserver(obs);
71 }
72 
OnPreferenceChanged(const std::string & path)73 void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) {
74   FireObservers(path);
75 }
76 
OnInitializationCompleted()77 void PrefNotifierImpl::OnInitializationCompleted() {
78   DCHECK(CalledOnValidThread());
79 
80   NotificationService::current()->Notify(
81       NotificationType::PREF_INITIALIZATION_COMPLETED,
82       Source<PrefService>(pref_service_),
83       NotificationService::NoDetails());
84 }
85 
FireObservers(const std::string & path)86 void PrefNotifierImpl::FireObservers(const std::string& path) {
87   DCHECK(CalledOnValidThread());
88 
89   // Only send notifications for registered preferences.
90   if (!pref_service_->FindPreference(path.c_str()))
91     return;
92 
93   const PrefObserverMap::iterator observer_iterator =
94       pref_observers_.find(path);
95   if (observer_iterator == pref_observers_.end())
96     return;
97 
98   NotificationObserverList::Iterator it(*(observer_iterator->second));
99   NotificationObserver* observer;
100   while ((observer = it.GetNext()) != NULL) {
101     observer->Observe(NotificationType::PREF_CHANGED,
102                       Source<PrefService>(pref_service_),
103                       Details<const std::string>(&path));
104   }
105 }
106