[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 | |||||
5 | #include "chrome/browser/prefs/pref_notifier_impl.h" | ||||
6 | |||||
[email protected] | 42c037e | 2012-06-26 22:23:32 | [diff] [blame^] | 7 | #include "base/logging.h" |
[email protected] | 7286e3fc | 2011-07-19 22:13:24 | [diff] [blame] | 8 | #include "base/stl_util.h" |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 9 | #include "chrome/browser/prefs/pref_service.h" |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 10 | #include "chrome/common/chrome_notification_types.h" |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 11 | #include "content/public/browser/notification_observer.h" |
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 12 | #include "content/public/browser/notification_service.h" |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 13 | |
[email protected] | 361d37f6 | 2011-11-22 10:37:02 | [diff] [blame] | 14 | PrefNotifierImpl::PrefNotifierImpl() |
15 | : pref_service_(NULL) { | ||||
16 | } | ||||
17 | |||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 18 | PrefNotifierImpl::PrefNotifierImpl(PrefService* service) |
19 | : pref_service_(service) { | ||||
20 | } | ||||
21 | |||||
22 | PrefNotifierImpl::~PrefNotifierImpl() { | ||||
23 | DCHECK(CalledOnValidThread()); | ||||
24 | |||||
25 | // Verify that there are no pref observers when we shut down. | ||||
26 | for (PrefObserverMap::iterator it = pref_observers_.begin(); | ||||
27 | it != pref_observers_.end(); ++it) { | ||||
28 | NotificationObserverList::Iterator obs_iterator(*(it->second)); | ||||
29 | if (obs_iterator.GetNext()) { | ||||
30 | LOG(WARNING) << "pref observer found at shutdown " << it->first; | ||||
31 | } | ||||
32 | } | ||||
33 | |||||
34 | STLDeleteContainerPairSecondPointers(pref_observers_.begin(), | ||||
35 | pref_observers_.end()); | ||||
36 | pref_observers_.clear(); | ||||
37 | } | ||||
38 | |||||
39 | void PrefNotifierImpl::AddPrefObserver(const char* path, | ||||
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 40 | content::NotificationObserver* obs) { |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 41 | // Get the pref observer list associated with the path. |
42 | NotificationObserverList* observer_list = NULL; | ||||
43 | const PrefObserverMap::iterator observer_iterator = | ||||
44 | pref_observers_.find(path); | ||||
45 | if (observer_iterator == pref_observers_.end()) { | ||||
46 | observer_list = new NotificationObserverList; | ||||
47 | pref_observers_[path] = observer_list; | ||||
48 | } else { | ||||
49 | observer_list = observer_iterator->second; | ||||
50 | } | ||||
51 | |||||
52 | // Verify that this observer doesn't already exist. | ||||
53 | NotificationObserverList::Iterator it(*observer_list); | ||||
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 54 | content::NotificationObserver* existing_obs; |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 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); | ||||
63 | } | ||||
64 | |||||
65 | void PrefNotifierImpl::RemovePrefObserver(const char* path, | ||||
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 66 | content::NotificationObserver* obs) { |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 67 | DCHECK(CalledOnValidThread()); |
68 | |||||
69 | const PrefObserverMap::iterator observer_iterator = | ||||
70 | pref_observers_.find(path); | ||||
71 | if (observer_iterator == pref_observers_.end()) { | ||||
72 | return; | ||||
73 | } | ||||
74 | |||||
75 | NotificationObserverList* observer_list = observer_iterator->second; | ||||
76 | observer_list->RemoveObserver(obs); | ||||
77 | } | ||||
78 | |||||
79 | void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) { | ||||
80 | FireObservers(path); | ||||
81 | } | ||||
82 | |||||
[email protected] | 845b43a8 | 2011-05-11 10:14:43 | [diff] [blame] | 83 | void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) { |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 84 | DCHECK(CalledOnValidThread()); |
85 | |||||
[email protected] | ad50def5 | 2011-10-19 23:17:07 | [diff] [blame] | 86 | content::NotificationService::current()->Notify( |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 87 | chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 88 | content::Source<PrefService>(pref_service_), |
89 | content::Details<bool>(&succeeded)); | ||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 90 | } |
91 | |||||
92 | void PrefNotifierImpl::FireObservers(const std::string& path) { | ||||
93 | DCHECK(CalledOnValidThread()); | ||||
94 | |||||
95 | // Only send notifications for registered preferences. | ||||
96 | if (!pref_service_->FindPreference(path.c_str())) | ||||
97 | return; | ||||
98 | |||||
99 | const PrefObserverMap::iterator observer_iterator = | ||||
100 | pref_observers_.find(path); | ||||
101 | if (observer_iterator == pref_observers_.end()) | ||||
102 | return; | ||||
103 | |||||
104 | NotificationObserverList::Iterator it(*(observer_iterator->second)); | ||||
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 105 | content::NotificationObserver* observer; |
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 106 | while ((observer = it.GetNext()) != NULL) { |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 107 | observer->Observe(chrome::NOTIFICATION_PREF_CHANGED, |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 108 | content::Source<PrefService>(pref_service_), |
109 | content::Details<const std::string>(&path)); | ||||
[email protected] | acd78969c | 2010-12-08 09:49:11 | [diff] [blame] | 110 | } |
111 | } | ||||
[email protected] | 361d37f6 | 2011-11-22 10:37:02 | [diff] [blame] | 112 | |
113 | void PrefNotifierImpl::SetPrefService(PrefService* pref_service) { | ||||
114 | DCHECK(pref_service_ == NULL); | ||||
115 | pref_service_ = pref_service; | ||||
116 | } |