1 // Copyright (c) 2012 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.
5 #include "base/prefs/pref_notifier_impl.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/stl_util.h"
11 PrefNotifierImpl::PrefNotifierImpl()
12 : pref_service_(NULL
) {
15 PrefNotifierImpl::PrefNotifierImpl(PrefService
* service
)
16 : pref_service_(service
) {
19 PrefNotifierImpl::~PrefNotifierImpl() {
20 DCHECK(thread_checker_
.CalledOnValidThread());
22 // Verify that there are no pref observers when we shut down.
23 for (PrefObserverMap::iterator it
= pref_observers_
.begin();
24 it
!= pref_observers_
.end(); ++it
) {
25 PrefObserverList::Iterator
obs_iterator(*(it
->second
));
26 if (obs_iterator
.GetNext()) {
27 LOG(WARNING
) << "pref observer found at shutdown " << it
->first
;
31 // Same for initialization observers.
32 if (!init_observers_
.empty())
33 LOG(WARNING
) << "Init observer found at shutdown.";
35 STLDeleteContainerPairSecondPointers(pref_observers_
.begin(),
36 pref_observers_
.end());
37 pref_observers_
.clear();
38 init_observers_
.clear();
41 void PrefNotifierImpl::AddPrefObserver(const char* path
,
43 // Get the pref observer list associated with the path.
44 PrefObserverList
* observer_list
= NULL
;
45 const PrefObserverMap::iterator observer_iterator
=
46 pref_observers_
.find(path
);
47 if (observer_iterator
== pref_observers_
.end()) {
48 observer_list
= new PrefObserverList
;
49 pref_observers_
[path
] = observer_list
;
51 observer_list
= observer_iterator
->second
;
54 // Add the pref observer. ObserverList will DCHECK if it already is
56 observer_list
->AddObserver(obs
);
59 void PrefNotifierImpl::RemovePrefObserver(const char* path
,
61 DCHECK(thread_checker_
.CalledOnValidThread());
63 const PrefObserverMap::iterator observer_iterator
=
64 pref_observers_
.find(path
);
65 if (observer_iterator
== pref_observers_
.end()) {
69 PrefObserverList
* observer_list
= observer_iterator
->second
;
70 observer_list
->RemoveObserver(obs
);
73 void PrefNotifierImpl::AddInitObserver(base::Callback
<void(bool)> obs
) {
74 init_observers_
.push_back(obs
);
77 void PrefNotifierImpl::OnPreferenceChanged(const std::string
& path
) {
81 void PrefNotifierImpl::OnInitializationCompleted(bool succeeded
) {
82 DCHECK(thread_checker_
.CalledOnValidThread());
84 // We must make a copy of init_observers_ and clear it before we run
85 // observers, or we can end up in this method re-entrantly before
86 // clearing the observers list.
87 PrefInitObserverList
observers(init_observers_
);
88 init_observers_
.clear();
90 for (PrefInitObserverList::iterator it
= observers
.begin();
91 it
!= observers
.end();
97 void PrefNotifierImpl::FireObservers(const std::string
& path
) {
98 DCHECK(thread_checker_
.CalledOnValidThread());
100 // Only send notifications for registered preferences.
101 if (!pref_service_
->FindPreference(path
.c_str()))
104 const PrefObserverMap::iterator observer_iterator
=
105 pref_observers_
.find(path
);
106 if (observer_iterator
== pref_observers_
.end())
109 FOR_EACH_OBSERVER(PrefObserver
,
110 *(observer_iterator
->second
),
111 OnPreferenceChanged(pref_service_
, path
));
114 void PrefNotifierImpl::SetPrefService(PrefService
* pref_service
) {
115 DCHECK(pref_service_
== NULL
);
116 pref_service_
= pref_service
;