Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: chrome/browser/prefs/pref_notifier_impl.cc

Issue 11345008: Remove content::NotificationObserver dependency from most Prefs code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge to head for commit Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prefs/pref_notifier_impl.h" 5 #include "chrome/browser/prefs/pref_notifier_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "chrome/browser/prefs/pref_service.h" 9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/common/chrome_notification_types.h"
11 #include "content/public/browser/notification_observer.h"
12 #include "content/public/browser/notification_service.h"
13 10
14 PrefNotifierImpl::PrefNotifierImpl() 11 PrefNotifierImpl::PrefNotifierImpl()
15 : pref_service_(NULL) { 12 : pref_service_(NULL) {
16 } 13 }
17 14
18 PrefNotifierImpl::PrefNotifierImpl(PrefService* service) 15 PrefNotifierImpl::PrefNotifierImpl(PrefService* service)
19 : pref_service_(service) { 16 : pref_service_(service) {
20 } 17 }
21 18
22 PrefNotifierImpl::~PrefNotifierImpl() { 19 PrefNotifierImpl::~PrefNotifierImpl() {
23 DCHECK(CalledOnValidThread()); 20 DCHECK(CalledOnValidThread());
24 21
25 // Verify that there are no pref observers when we shut down. 22 // Verify that there are no pref observers when we shut down.
26 for (PrefObserverMap::iterator it = pref_observers_.begin(); 23 for (PrefObserverMap::iterator it = pref_observers_.begin();
27 it != pref_observers_.end(); ++it) { 24 it != pref_observers_.end(); ++it) {
28 NotificationObserverList::Iterator obs_iterator(*(it->second)); 25 PrefObserverList::Iterator obs_iterator(*(it->second));
29 if (obs_iterator.GetNext()) { 26 if (obs_iterator.GetNext()) {
30 LOG(WARNING) << "pref observer found at shutdown " << it->first; 27 LOG(WARNING) << "pref observer found at shutdown " << it->first;
31 } 28 }
32 } 29 }
33 30
31 // Same for initialization observers.
32 if (!init_observers_.empty())
33 LOG(WARNING) << "Init observer found at shutdown.";
34
34 STLDeleteContainerPairSecondPointers(pref_observers_.begin(), 35 STLDeleteContainerPairSecondPointers(pref_observers_.begin(),
35 pref_observers_.end()); 36 pref_observers_.end());
36 pref_observers_.clear(); 37 pref_observers_.clear();
38 init_observers_.clear();
37 } 39 }
38 40
39 void PrefNotifierImpl::AddPrefObserver(const char* path, 41 void PrefNotifierImpl::AddPrefObserver(const char* path,
40 content::NotificationObserver* obs) { 42 PrefObserver* obs) {
41 // Get the pref observer list associated with the path. 43 // Get the pref observer list associated with the path.
42 NotificationObserverList* observer_list = NULL; 44 PrefObserverList* observer_list = NULL;
43 const PrefObserverMap::iterator observer_iterator = 45 const PrefObserverMap::iterator observer_iterator =
44 pref_observers_.find(path); 46 pref_observers_.find(path);
45 if (observer_iterator == pref_observers_.end()) { 47 if (observer_iterator == pref_observers_.end()) {
46 observer_list = new NotificationObserverList; 48 observer_list = new PrefObserverList;
47 pref_observers_[path] = observer_list; 49 pref_observers_[path] = observer_list;
48 } else { 50 } else {
49 observer_list = observer_iterator->second; 51 observer_list = observer_iterator->second;
50 } 52 }
51 53
52 // Verify that this observer doesn't already exist. 54 // Add the pref observer. ObserverList will DCHECK if it already is
53 NotificationObserverList::Iterator it(*observer_list); 55 // in the list.
54 content::NotificationObserver* existing_obs;
55 while ((existing_obs = it.GetNext()) != NULL) {
56 DCHECK(existing_obs != obs) << path << " observer already registered";
57 if (existing_obs == obs)
58 return;
59 }
60
61 // Ok, safe to add the pref observer.
62 observer_list->AddObserver(obs); 56 observer_list->AddObserver(obs);
63 } 57 }
64 58
65 void PrefNotifierImpl::RemovePrefObserver(const char* path, 59 void PrefNotifierImpl::RemovePrefObserver(const char* path,
66 content::NotificationObserver* obs) { 60 PrefObserver* obs) {
67 DCHECK(CalledOnValidThread()); 61 DCHECK(CalledOnValidThread());
68 62
69 const PrefObserverMap::iterator observer_iterator = 63 const PrefObserverMap::iterator observer_iterator =
70 pref_observers_.find(path); 64 pref_observers_.find(path);
71 if (observer_iterator == pref_observers_.end()) { 65 if (observer_iterator == pref_observers_.end()) {
72 return; 66 return;
73 } 67 }
74 68
75 NotificationObserverList* observer_list = observer_iterator->second; 69 PrefObserverList* observer_list = observer_iterator->second;
76 observer_list->RemoveObserver(obs); 70 observer_list->RemoveObserver(obs);
77 } 71 }
78 72
73 void PrefNotifierImpl::AddInitObserver(base::Callback<void(bool)> obs) {
74 init_observers_.push_back(obs);
75 }
76
79 void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) { 77 void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) {
80 FireObservers(path); 78 FireObservers(path);
81 } 79 }
82 80
83 void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) { 81 void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) {
84 DCHECK(CalledOnValidThread()); 82 DCHECK(CalledOnValidThread());
85 83
86 content::NotificationService::current()->Notify( 84 // We must make a copy of init_observers_ and clear it before we run
87 chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED, 85 // observers, or we can end up in this method re-entrantly before
88 content::Source<PrefService>(pref_service_), 86 // clearing the observers list.
89 content::Details<bool>(&succeeded)); 87 PrefInitObserverList observers(init_observers_);
88 init_observers_.clear();
89
90 for (PrefInitObserverList::iterator it = observers.begin();
91 it != observers.end();
92 ++it) {
93 it->Run(succeeded);
94 }
90 } 95 }
91 96
92 void PrefNotifierImpl::FireObservers(const std::string& path) { 97 void PrefNotifierImpl::FireObservers(const std::string& path) {
93 DCHECK(CalledOnValidThread()); 98 DCHECK(CalledOnValidThread());
94 99
95 // Only send notifications for registered preferences. 100 // Only send notifications for registered preferences.
96 if (!pref_service_->FindPreference(path.c_str())) 101 if (!pref_service_->FindPreference(path.c_str()))
97 return; 102 return;
98 103
99 const PrefObserverMap::iterator observer_iterator = 104 const PrefObserverMap::iterator observer_iterator =
100 pref_observers_.find(path); 105 pref_observers_.find(path);
101 if (observer_iterator == pref_observers_.end()) 106 if (observer_iterator == pref_observers_.end())
102 return; 107 return;
103 108
104 NotificationObserverList::Iterator it(*(observer_iterator->second)); 109 FOR_EACH_OBSERVER(PrefObserver,
105 content::NotificationObserver* observer; 110 *(observer_iterator->second),
106 while ((observer = it.GetNext()) != NULL) { 111 OnPreferenceChanged(pref_service_, path));
107 observer->Observe(chrome::NOTIFICATION_PREF_CHANGED,
108 content::Source<PrefService>(pref_service_),
109 content::Details<const std::string>(&path));
110 }
111 } 112 }
112 113
113 void PrefNotifierImpl::SetPrefService(PrefService* pref_service) { 114 void PrefNotifierImpl::SetPrefService(PrefService* pref_service) {
114 DCHECK(pref_service_ == NULL); 115 DCHECK(pref_service_ == NULL);
115 pref_service_ = pref_service; 116 pref_service_ = pref_service;
116 } 117 }
OLDNEW
« no previous file with comments | « chrome/browser/prefs/pref_notifier_impl.h ('k') | chrome/browser/prefs/pref_notifier_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698