blob: a226685cc058faf37911b2eb5de50e6be1422b20 [file] [log] [blame]
[email protected]42c037e2012-06-26 22:23:321// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]acd78969c2010-12-08 09:49:112// 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]42c037e2012-06-26 22:23:327#include "base/logging.h"
[email protected]7286e3fc2011-07-19 22:13:248#include "base/stl_util.h"
[email protected]acd78969c2010-12-08 09:49:119#include "chrome/browser/prefs/pref_service.h"
[email protected]432115822011-07-10 15:52:2710#include "chrome/common/chrome_notification_types.h"
[email protected]6c2381d2011-10-19 02:52:5311#include "content/public/browser/notification_observer.h"
[email protected]ad50def52011-10-19 23:17:0712#include "content/public/browser/notification_service.h"
[email protected]acd78969c2010-12-08 09:49:1113
[email protected]361d37f62011-11-22 10:37:0214PrefNotifierImpl::PrefNotifierImpl()
15 : pref_service_(NULL) {
16}
17
[email protected]acd78969c2010-12-08 09:49:1118PrefNotifierImpl::PrefNotifierImpl(PrefService* service)
19 : pref_service_(service) {
20}
21
22PrefNotifierImpl::~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
39void PrefNotifierImpl::AddPrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:5340 content::NotificationObserver* obs) {
[email protected]acd78969c2010-12-08 09:49:1141 // 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]6c2381d2011-10-19 02:52:5354 content::NotificationObserver* existing_obs;
[email protected]acd78969c2010-12-08 09:49:1155 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
65void PrefNotifierImpl::RemovePrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:5366 content::NotificationObserver* obs) {
[email protected]acd78969c2010-12-08 09:49:1167 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
79void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) {
80 FireObservers(path);
81}
82
[email protected]845b43a82011-05-11 10:14:4383void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) {
[email protected]acd78969c2010-12-08 09:49:1184 DCHECK(CalledOnValidThread());
85
[email protected]ad50def52011-10-19 23:17:0786 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:2787 chrome::NOTIFICATION_PREF_INITIALIZATION_COMPLETED,
[email protected]6c2381d2011-10-19 02:52:5388 content::Source<PrefService>(pref_service_),
89 content::Details<bool>(&succeeded));
[email protected]acd78969c2010-12-08 09:49:1190}
91
92void 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]6c2381d2011-10-19 02:52:53105 content::NotificationObserver* observer;
[email protected]acd78969c2010-12-08 09:49:11106 while ((observer = it.GetNext()) != NULL) {
[email protected]432115822011-07-10 15:52:27107 observer->Observe(chrome::NOTIFICATION_PREF_CHANGED,
[email protected]6c2381d2011-10-19 02:52:53108 content::Source<PrefService>(pref_service_),
109 content::Details<const std::string>(&path));
[email protected]acd78969c2010-12-08 09:49:11110 }
111}
[email protected]361d37f62011-11-22 10:37:02112
113void PrefNotifierImpl::SetPrefService(PrefService* pref_service) {
114 DCHECK(pref_service_ == NULL);
115 pref_service_ = pref_service;
116}