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. 4 5 #include "base/prefs/pref_notifier_impl.h" 6 7 #include "base/logging.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/stl_util.h" 10 PrefNotifierImpl()11PrefNotifierImpl::PrefNotifierImpl() 12 : pref_service_(NULL) { 13 } 14 PrefNotifierImpl(PrefService * service)15PrefNotifierImpl::PrefNotifierImpl(PrefService* service) 16 : pref_service_(service) { 17 } 18 ~PrefNotifierImpl()19PrefNotifierImpl::~PrefNotifierImpl() { 20 DCHECK(thread_checker_.CalledOnValidThread()); 21 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; 28 } 29 } 30 31 // Same for initialization observers. 32 if (!init_observers_.empty()) 33 LOG(WARNING) << "Init observer found at shutdown."; 34 35 STLDeleteContainerPairSecondPointers(pref_observers_.begin(), 36 pref_observers_.end()); 37 pref_observers_.clear(); 38 init_observers_.clear(); 39 } 40 AddPrefObserver(const char * path,PrefObserver * obs)41void PrefNotifierImpl::AddPrefObserver(const char* path, 42 PrefObserver* obs) { 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; 50 } else { 51 observer_list = observer_iterator->second; 52 } 53 54 // Add the pref observer. ObserverList will DCHECK if it already is 55 // in the list. 56 observer_list->AddObserver(obs); 57 } 58 RemovePrefObserver(const char * path,PrefObserver * obs)59void PrefNotifierImpl::RemovePrefObserver(const char* path, 60 PrefObserver* obs) { 61 DCHECK(thread_checker_.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 PrefObserverList* observer_list = observer_iterator->second; 70 observer_list->RemoveObserver(obs); 71 } 72 AddInitObserver(base::Callback<void (bool)> obs)73void PrefNotifierImpl::AddInitObserver(base::Callback<void(bool)> obs) { 74 init_observers_.push_back(obs); 75 } 76 OnPreferenceChanged(const std::string & path)77void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) { 78 FireObservers(path); 79 } 80 OnInitializationCompleted(bool succeeded)81void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) { 82 DCHECK(thread_checker_.CalledOnValidThread()); 83 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(); 89 90 for (PrefInitObserverList::iterator it = observers.begin(); 91 it != observers.end(); 92 ++it) { 93 it->Run(succeeded); 94 } 95 } 96 FireObservers(const std::string & path)97void PrefNotifierImpl::FireObservers(const std::string& path) { 98 DCHECK(thread_checker_.CalledOnValidThread()); 99 100 // Only send notifications for registered preferences. 101 if (!pref_service_->FindPreference(path.c_str())) 102 return; 103 104 const PrefObserverMap::iterator observer_iterator = 105 pref_observers_.find(path); 106 if (observer_iterator == pref_observers_.end()) 107 return; 108 109 FOR_EACH_OBSERVER(PrefObserver, 110 *(observer_iterator->second), 111 OnPreferenceChanged(pref_service_, path)); 112 } 113 SetPrefService(PrefService * pref_service)114void PrefNotifierImpl::SetPrefService(PrefService* pref_service) { 115 DCHECK(pref_service_ == NULL); 116 pref_service_ = pref_service; 117 } 118