Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: chrome/browser/extensions/api/settings_private/settings_private_event_router.cc

Issue 1061613002: chrome.settingsPrivate: Implement onPrefsChanged event handling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a direct memory leak Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/extensions/api/settings_private/settings_private_event_ router.h"
6
7 #include <vector>
8
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/extensions/api/settings_private/prefs_util.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/extensions/api/settings_private.h"
16 #include "content/public/browser/browser_context.h"
17
18 namespace extensions {
19
20 SettingsPrivateEventRouter::SettingsPrivateEventRouter(
21 content::BrowserContext* context)
22 : context_(context), listening_(false) {
23 // Register with the event router so we know when renderers are listening to
24 // our events. We first check and see if there *is* an event router, because
25 // some unit tests try to create all context services, but don't initialize
26 // the event router first.
27 EventRouter* event_router = EventRouter::Get(context_);
28 if (event_router) {
29 event_router->RegisterObserver(
30 this, api::settings_private::OnPrefsChanged::kEventName);
31 StartOrStopListeningForPrefsChanges();
32 }
33
34 Profile* profile = Profile::FromBrowserContext(context_);
35 user_prefs_registrar_.Init(profile->GetPrefs());
36 local_state_registrar_.Init(g_browser_process->local_state());
37 }
38
39 SettingsPrivateEventRouter::~SettingsPrivateEventRouter() {
40 DCHECK(!listening_);
41 }
42
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);
50
51 if (listening_) {
52 const prefs_util::TypedPrefMap& keys = prefs_util::GetWhitelistedKeys();
53 for (const auto& it : keys) {
54 FindRegistrarForPref(it.first)->Remove(it.first);
55 }
56 }
57 listening_ = false;
58 }
59
60 void SettingsPrivateEventRouter::OnListenerAdded(
61 const EventListenerInfo& details) {
62 // Start listening to events from the PrefChangeRegistrars.
63 StartOrStopListeningForPrefsChanges();
64 }
65
66 void SettingsPrivateEventRouter::OnListenerRemoved(
67 const EventListenerInfo& details) {
68 // Stop listening to events from the PrefChangeRegistrars if there are no
69 // more listeners.
70 StartOrStopListeningForPrefsChanges();
71 }
72
73 PrefChangeRegistrar* SettingsPrivateEventRouter::FindRegistrarForPref(
74 const std::string& pref_name) {
75 Profile* profile = Profile::FromBrowserContext(context_);
76 if (prefs_util::FindServiceForPref(profile, pref_name) ==
77 profile->GetPrefs()) {
78 return &user_prefs_registrar_;
79 }
80 return &local_state_registrar_;
81 }
82
83 void SettingsPrivateEventRouter::StartOrStopListeningForPrefsChanges() {
84 EventRouter* event_router = EventRouter::Get(context_);
85 bool should_listen = event_router->HasEventListener(
86 api::settings_private::OnPrefsChanged::kEventName);
87
88 if (should_listen && !listening_) {
89 const prefs_util::TypedPrefMap& keys = prefs_util::GetWhitelistedKeys();
90 for (const auto& it : keys) {
91 FindRegistrarForPref(it.first)->Add(
92 it.first,
93 base::Bind(&SettingsPrivateEventRouter::OnPreferenceChanged,
94 base::Unretained(this), user_prefs_registrar_.prefs()));
95 }
96 } else if (!should_listen && listening_) {
97 const prefs_util::TypedPrefMap& keys = prefs_util::GetWhitelistedKeys();
98 for (const auto& it : keys) {
99 FindRegistrarForPref(it.first)->Remove(it.first);
100 }
101 }
102 listening_ = should_listen;
103 }
104
105 void SettingsPrivateEventRouter::OnPreferenceChanged(
106 PrefService* service,
107 const std::string& pref_name) {
108 EventRouter* event_router = EventRouter::Get(context_);
109 if (!event_router->HasEventListener(
110 api::settings_private::OnPrefsChanged::kEventName)) {
111 return;
112 }
113
114 Profile* profile = Profile::FromBrowserContext(context_);
115 api::settings_private::PrefObject* pref_object =
116 prefs_util::GetPref(profile, pref_name).release();
117
118 std::vector<linked_ptr<api::settings_private::PrefObject>> prefs;
119 prefs.push_back(linked_ptr<api::settings_private::PrefObject>(pref_object));
120
121 scoped_ptr<base::ListValue> args(
122 api::settings_private::OnPrefsChanged::Create(prefs));
123
124 scoped_ptr<Event> extension_event(new Event(
125 api::settings_private::OnPrefsChanged::kEventName, args.Pass()));
126 event_router->BroadcastEvent(extension_event.Pass());
127 }
128
129 SettingsPrivateEventRouter* SettingsPrivateEventRouter::Create(
130 content::BrowserContext* context) {
131 return new SettingsPrivateEventRouter(context);
132 }
133
134 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698