Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / settings_private / settings_private_event_router.cc
blob6a9582e54d9f7c80673ca8bd063f6531e5d8d538
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"
7 #include <vector>
9 #include "base/bind.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_);
27 if (event_router) {
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() {
40 DCHECK(!listening_);
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_);
48 if (event_router)
49 event_router->UnregisterObserver(this);
51 if (listening_) {
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);
59 listening_ = false;
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
71 // more listeners.
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(
97 pref_name.c_str(),
98 base::Bind(&SettingsPrivateEventRouter::OnPreferenceChanged,
99 base::Unretained(this), pref_name));
100 linked_ptr<chromeos::CrosSettings::ObserverSubscription> subscription(
101 observer.release());
102 cros_settings_subscription_map_.insert(
103 make_pair(pref_name, subscription));
104 #endif
105 } else {
106 FindRegistrarForPref(it.first)
107 ->Add(pref_name,
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);
117 else
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)) {
129 return;
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