[email protected] | 42c037e | 2012-06-26 22:23:32 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
4 | |||||
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 5 | #include "components/prefs/pref_notifier_impl.h" |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 6 | |
[email protected] | 42c037e | 2012-06-26 22:23:32 | [diff] [blame] | 7 | #include "base/logging.h" |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 8 | #include "base/memory/ptr_util.h" |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 9 | #include "components/prefs/pref_service.h" |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 10 | |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 11 | PrefNotifierImpl::PrefNotifierImpl() : pref_service_(nullptr) {} |
[email protected] | 361d37f6 | 2011-11-22 10:37:02 | [diff] [blame] | 12 | |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 13 | PrefNotifierImpl::PrefNotifierImpl(PrefService* service) |
14 | : pref_service_(service) { | ||||
15 | } | ||||
16 | |||||
17 | PrefNotifierImpl::~PrefNotifierImpl() { | ||||
[email protected] | 5b7238f | 2013-04-22 15:56:40 | [diff] [blame] | 18 | DCHECK(thread_checker_.CalledOnValidThread()); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 19 | |
20 | // Verify that there are no pref observers when we shut down. | ||||
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 21 | for (const auto& observer_list : pref_observers_) { |
dcheng | 018341c | 2016-10-14 21:53:56 | [diff] [blame] | 22 | if (observer_list.second->begin() != observer_list.second->end()) |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 23 | LOG(WARNING) << "Pref observer found at shutdown."; |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 24 | } |
25 | |||||
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 26 | // Same for initialization observers. |
27 | if (!init_observers_.empty()) | ||||
28 | LOG(WARNING) << "Init observer found at shutdown."; | ||||
29 | |||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 30 | pref_observers_.clear(); |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 31 | init_observers_.clear(); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 32 | } |
33 | |||||
georgesak | 7da6e9d | 2014-12-03 01:10:29 | [diff] [blame] | 34 | void PrefNotifierImpl::AddPrefObserver(const std::string& path, |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 35 | PrefObserver* obs) { |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 36 | // Get the pref observer list associated with the path. |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 37 | PrefObserverList* observer_list = nullptr; |
38 | auto observer_iterator = pref_observers_.find(path); | ||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 39 | if (observer_iterator == pref_observers_.end()) { |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 40 | observer_list = new PrefObserverList; |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 41 | pref_observers_[path] = base::WrapUnique(observer_list); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 42 | } else { |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 43 | observer_list = observer_iterator->second.get(); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 44 | } |
45 | |||||
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 46 | // Add the pref observer. ObserverList will DCHECK if it already is |
47 | // in the list. | ||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 48 | observer_list->AddObserver(obs); |
49 | } | ||||
50 | |||||
georgesak | 7da6e9d | 2014-12-03 01:10:29 | [diff] [blame] | 51 | void PrefNotifierImpl::RemovePrefObserver(const std::string& path, |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 52 | PrefObserver* obs) { |
[email protected] | 5b7238f | 2013-04-22 15:56:40 | [diff] [blame] | 53 | DCHECK(thread_checker_.CalledOnValidThread()); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 54 | |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 55 | auto observer_iterator = pref_observers_.find(path); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 56 | if (observer_iterator == pref_observers_.end()) { |
57 | return; | ||||
58 | } | ||||
59 | |||||
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 60 | PrefObserverList* observer_list = observer_iterator->second.get(); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 61 | observer_list->RemoveObserver(obs); |
62 | } | ||||
63 | |||||
Brett Wilson | 21cf626a | 2017-09-07 00:30:20 | [diff] [blame] | 64 | void PrefNotifierImpl::AddPrefObserverAllPrefs(PrefObserver* observer) { |
65 | DCHECK(thread_checker_.CalledOnValidThread()); | ||||
66 | all_prefs_pref_observers_.AddObserver(observer); | ||||
67 | } | ||||
68 | |||||
69 | void PrefNotifierImpl::RemovePrefObserverAllPrefs(PrefObserver* observer) { | ||||
70 | DCHECK(thread_checker_.CalledOnValidThread()); | ||||
71 | all_prefs_pref_observers_.RemoveObserver(observer); | ||||
72 | } | ||||
73 | |||||
Kenichi Ishibashi | f958ad6 | 2017-12-19 02:43:14 | [diff] [blame^] | 74 | void PrefNotifierImpl::AddInitObserver(base::OnceCallback<void(bool)> obs) { |
75 | init_observers_.push_back(std::move(obs)); | ||||
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 76 | } |
77 | |||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 78 | void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) { |
79 | FireObservers(path); | ||||
80 | } | ||||
81 | |||||
[email protected] | 845b43a8 | 2011-05-11 10:14:43 | [diff] [blame] | 82 | void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) { |
[email protected] | 5b7238f | 2013-04-22 15:56:40 | [diff] [blame] | 83 | DCHECK(thread_checker_.CalledOnValidThread()); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 84 | |
Kenichi Ishibashi | f958ad6 | 2017-12-19 02:43:14 | [diff] [blame^] | 85 | // We must move init_observers_ to a local variable before we run |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 86 | // observers, or we can end up in this method re-entrantly before |
87 | // clearing the observers list. | ||||
Kenichi Ishibashi | f958ad6 | 2017-12-19 02:43:14 | [diff] [blame^] | 88 | PrefInitObserverList observers; |
89 | std::swap(observers, init_observers_); | ||||
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 90 | |
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 91 | for (auto& observer : observers) |
Kenichi Ishibashi | f958ad6 | 2017-12-19 02:43:14 | [diff] [blame^] | 92 | std::move(observer).Run(succeeded); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 93 | } |
94 | |||||
95 | void PrefNotifierImpl::FireObservers(const std::string& path) { | ||||
[email protected] | 5b7238f | 2013-04-22 15:56:40 | [diff] [blame] | 96 | DCHECK(thread_checker_.CalledOnValidThread()); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 97 | |
98 | // Only send notifications for registered preferences. | ||||
georgesak | 7da6e9d | 2014-12-03 01:10:29 | [diff] [blame] | 99 | if (!pref_service_->FindPreference(path)) |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 100 | return; |
101 | |||||
Brett Wilson | 21cf626a | 2017-09-07 00:30:20 | [diff] [blame] | 102 | // Fire observers for any preference change. |
103 | for (auto& observer : all_prefs_pref_observers_) | ||||
104 | observer.OnPreferenceChanged(pref_service_, path); | ||||
105 | |||||
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 106 | auto observer_iterator = pref_observers_.find(path); |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 107 | if (observer_iterator == pref_observers_.end()) |
108 | return; | ||||
109 | |||||
ericwilligers | 42b92c1 | 2016-10-24 20:21:13 | [diff] [blame] | 110 | for (PrefObserver& observer : *(observer_iterator->second)) |
111 | observer.OnPreferenceChanged(pref_service_, path); | ||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 112 | } |
[email protected] | 361d37f6 | 2011-11-22 10:37:02 | [diff] [blame] | 113 | |
114 | void PrefNotifierImpl::SetPrefService(PrefService* pref_service) { | ||||
avi | a92d13b | 2016-09-21 07:48:40 | [diff] [blame] | 115 | DCHECK(pref_service_ == nullptr); |
[email protected] | 361d37f6 | 2011-11-22 10:37:02 | [diff] [blame] | 116 | pref_service_ = pref_service; |
117 | } |