1 // Copyright 2015 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.
5 #include "chrome/browser/extensions/api/settings_private/settings_private_event_router.h"
10 #include "base/bind_helpers.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/extensions/api/settings_private.h"
15 #include "content/public/browser/browser_context.h"
17 namespace extensions
{
19 SettingsPrivateEventRouter::SettingsPrivateEventRouter(
20 content::BrowserContext
* context
)
21 : context_(context
), listening_(false) {
22 // Register with the event router so we know when renderers are listening to
23 // our events. We first check and see if there *is* an event router, because
24 // some unit tests try to create all context services, but don't initialize
25 // the event router first.
26 EventRouter
* event_router
= EventRouter::Get(context_
);
28 event_router
->RegisterObserver(
29 this, api::settings_private::OnPrefsChanged::kEventName
);
30 StartOrStopListeningForPrefsChanges();
33 Profile
* profile
= Profile::FromBrowserContext(context_
);
34 prefs_util_
.reset(new PrefsUtil(profile
));
35 user_prefs_registrar_
.Init(profile
->GetPrefs());
36 local_state_registrar_
.Init(g_browser_process
->local_state());
39 SettingsPrivateEventRouter::~SettingsPrivateEventRouter() {
43 void SettingsPrivateEventRouter::Shutdown() {
44 // Unregister with the event router. We first check and see if there *is* an
45 // event router, because some unit tests try to shutdown all context services,
46 // but didn't initialize the event router first.
47 EventRouter
* event_router
= EventRouter::Get(context_
);
49 event_router
->UnregisterObserver(this);
52 cros_settings_subscription_map_
.clear();
53 const PrefsUtil::TypedPrefMap
& keys
= prefs_util_
->GetWhitelistedKeys();
54 for (const auto& it
: keys
) {
55 if (!prefs_util_
->IsCrosSetting(it
.first
))
56 FindRegistrarForPref(it
.first
)->Remove(it
.first
);
62 void SettingsPrivateEventRouter::OnListenerAdded(
63 const EventListenerInfo
& details
) {
64 // Start listening to events from the PrefChangeRegistrars.
65 StartOrStopListeningForPrefsChanges();
68 void SettingsPrivateEventRouter::OnListenerRemoved(
69 const EventListenerInfo
& details
) {
70 // Stop listening to events from the PrefChangeRegistrars if there are no
72 StartOrStopListeningForPrefsChanges();
75 PrefChangeRegistrar
* SettingsPrivateEventRouter::FindRegistrarForPref(
76 const std::string
& pref_name
) {
77 Profile
* profile
= Profile::FromBrowserContext(context_
);
78 if (prefs_util_
->FindServiceForPref(pref_name
) == profile
->GetPrefs()) {
79 return &user_prefs_registrar_
;
81 return &local_state_registrar_
;
84 void SettingsPrivateEventRouter::StartOrStopListeningForPrefsChanges() {
85 EventRouter
* event_router
= EventRouter::Get(context_
);
86 bool should_listen
= event_router
->HasEventListener(
87 api::settings_private::OnPrefsChanged::kEventName
);
89 if (should_listen
&& !listening_
) {
90 const PrefsUtil::TypedPrefMap
& keys
= prefs_util_
->GetWhitelistedKeys();
91 for (const auto& it
: keys
) {
92 std::string pref_name
= it
.first
;
93 if (prefs_util_
->IsCrosSetting(pref_name
)) {
94 #if defined(OS_CHROMEOS)
95 scoped_ptr
<chromeos::CrosSettings::ObserverSubscription
> observer
=
96 chromeos::CrosSettings::Get()->AddSettingsObserver(
98 base::Bind(&SettingsPrivateEventRouter::OnPreferenceChanged
,
99 base::Unretained(this), pref_name
));
100 linked_ptr
<chromeos::CrosSettings::ObserverSubscription
> subscription(
102 cros_settings_subscription_map_
.insert(
103 make_pair(pref_name
, subscription
));
106 FindRegistrarForPref(it
.first
)
108 base::Bind(&SettingsPrivateEventRouter::OnPreferenceChanged
,
109 base::Unretained(this)));
112 } else if (!should_listen
&& listening_
) {
113 const PrefsUtil::TypedPrefMap
& keys
= prefs_util_
->GetWhitelistedKeys();
114 for (const auto& it
: keys
) {
115 if (prefs_util_
->IsCrosSetting(it
.first
))
116 cros_settings_subscription_map_
.erase(it
.first
);
118 FindRegistrarForPref(it
.first
)->Remove(it
.first
);
121 listening_
= should_listen
;
124 void SettingsPrivateEventRouter::OnPreferenceChanged(
125 const std::string
& pref_name
) {
126 EventRouter
* event_router
= EventRouter::Get(context_
);
127 if (!event_router
->HasEventListener(
128 api::settings_private::OnPrefsChanged::kEventName
)) {
132 api::settings_private::PrefObject
* pref_object
=
133 prefs_util_
->GetPref(pref_name
).release();
135 std::vector
<linked_ptr
<api::settings_private::PrefObject
>> prefs
;
136 prefs
.push_back(linked_ptr
<api::settings_private::PrefObject
>(pref_object
));
138 scoped_ptr
<base::ListValue
> args(
139 api::settings_private::OnPrefsChanged::Create(prefs
));
141 scoped_ptr
<Event
> extension_event(new Event(
142 events::SETTINGS_PRIVATE_ON_PREFS_CHANGED
,
143 api::settings_private::OnPrefsChanged::kEventName
, args
.Pass()));
144 event_router
->BroadcastEvent(extension_event
.Pass());
147 SettingsPrivateEventRouter
* SettingsPrivateEventRouter::Create(
148 content::BrowserContext
* context
) {
149 return new SettingsPrivateEventRouter(context
);
152 } // namespace extensions