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

Side by Side Diff: chrome/browser/extensions/api/settings_private/settings_private_delegate.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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/settings_private/settings_private_delega te.h" 5 #include "chrome/browser/extensions/api/settings_private/settings_private_delega te.h"
6 6
7 #include "base/json/json_reader.h" 7 #include "base/json/json_reader.h"
8 #include "base/prefs/pref_service.h" 8 #include "base/prefs/pref_service.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/api/settings_private/prefs_util.h"
12 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
12 #include "components/url_fixer/url_fixer.h" 14 #include "components/url_fixer/url_fixer.h"
13 #include "extensions/browser/extension_registry.h" 15 #include "extensions/browser/extension_registry.h"
14 #include "extensions/common/extension.h" 16 #include "extensions/common/extension.h"
15 #include "url/gurl.h" 17 #include "url/gurl.h"
16 18
17 namespace extensions { 19 namespace extensions {
18 20
19 namespace settings_private = api::settings_private; 21 namespace settings_private = api::settings_private;
20 22
21 namespace {
22
23 // NOTE: Consider moving this function to a separate file, e.g. in
24 // chrome/browser/prefs.
25 bool IsPrefUserModifiable(Profile* profile,
26 PrefService* pref_service,
27 const std::string& pref_name) {
28 if (pref_name != prefs::kBrowserGuestModeEnabled &&
29 pref_name != prefs::kBrowserAddPersonEnabled) {
30 return true;
31 }
32
33 const PrefService::Preference* pref =
34 pref_service->FindPreference(pref_name.c_str());
35 if (!pref || !pref->IsUserModifiable() || profile->IsSupervised())
36 return false;
37
38 return true;
39 }
40
41 const TypedPrefMap& GetWhitelistedKeys() {
42 static TypedPrefMap* s_whitelist = nullptr;
43 if (s_whitelist)
44 return *s_whitelist;
45 s_whitelist = new TypedPrefMap();
46 (*s_whitelist)["download.default_directory"] =
47 settings_private::PrefType::PREF_TYPE_STRING;
48 (*s_whitelist)["download.prompt_for_download"] =
49 settings_private::PrefType::PREF_TYPE_BOOLEAN;
50 (*s_whitelist)["homepage"] =
51 settings_private::PrefType::PREF_TYPE_URL;
52 return *s_whitelist;
53 }
54
55 #if defined(OS_CHROMEOS)
56 const TypedPrefMap& GetWhitelistedCrosKeys() {
57 static TypedPrefMap* s_whitelist = nullptr;
58 if (s_whitelist)
59 return *s_whitelist;
60 s_whitelist = new TypedPrefMap();
61 (*s_whitelist)["settings.accessibility"] =
62 settings_private::PrefType::PREF_TYPE_BOOLEAN;
63 (*s_whitelist)["settings.a11y.autoclick"] =
64 settings_private::PrefType::PREF_TYPE_BOOLEAN;
65 (*s_whitelist)["settings.a11y.autoclick_delay_ms"] =
66 settings_private::PrefType::PREF_TYPE_BOOLEAN;
67 (*s_whitelist)["settings.a11y.enable_menu"] =
68 settings_private::PrefType::PREF_TYPE_BOOLEAN;
69 (*s_whitelist)["settings.a11y.high_contrast_enabled"] =
70 settings_private::PrefType::PREF_TYPE_BOOLEAN;
71 (*s_whitelist)["settings.a11y.large_cursor_enabled"] =
72 settings_private::PrefType::PREF_TYPE_BOOLEAN;
73 (*s_whitelist)["settings.a11y.screen_magnifier"] =
74 settings_private::PrefType::PREF_TYPE_BOOLEAN;
75 (*s_whitelist)["settings.a11y.sticky_keys_enabled"] =
76 settings_private::PrefType::PREF_TYPE_BOOLEAN;
77 (*s_whitelist)["settings.a11y.virtual_keyboard"] =
78 settings_private::PrefType::PREF_TYPE_BOOLEAN;
79 (*s_whitelist)["settings.touchpad.enable_tap_dragging"] =
80 settings_private::PrefType::PREF_TYPE_BOOLEAN;
81 return *s_whitelist;
82 }
83 #endif
84
85 bool IsPrefTypeURL(const std::string& pref_name) {
86 settings_private::PrefType pref_type =
87 settings_private::PrefType::PREF_TYPE_NONE;
88
89 const TypedPrefMap keys = GetWhitelistedKeys();
90 const auto& iter = keys.find(pref_name);
91 if (iter != keys.end()) {
92 pref_type = iter->second;
93 }
94
95 #if defined(OS_CHROMEOS)
96 const TypedPrefMap cros_keys = GetWhitelistedCrosKeys();
97 const auto& cros_iter = cros_keys.find(pref_name);
98 if (cros_iter != cros_keys.end()) {
99 pref_type = cros_iter->second;
100 }
101 #endif
102
103 return pref_type == settings_private::PrefType::PREF_TYPE_URL;
104 }
105
106 } // namespace
107
108 SettingsPrivateDelegate::SettingsPrivateDelegate(Profile* profile) 23 SettingsPrivateDelegate::SettingsPrivateDelegate(Profile* profile)
109 : profile_(profile) { 24 : profile_(profile) {
110 } 25 }
111 26
112 SettingsPrivateDelegate::~SettingsPrivateDelegate() { 27 SettingsPrivateDelegate::~SettingsPrivateDelegate() {
113 } 28 }
114 29
115 scoped_ptr<base::Value> SettingsPrivateDelegate::GetPref( 30 scoped_ptr<base::Value> SettingsPrivateDelegate::GetPref(
116 const std::string& name) { 31 const std::string& name) {
117 PrefService* pref_service = profile_->GetPrefs(); 32 return prefs_util::GetPref(profile_, name)->ToValue();
118 const PrefService::Preference* pref = pref_service->FindPreference(name);
119 if (!pref)
120 return make_scoped_ptr(base::Value::CreateNullValue());
121
122 api::settings_private::PrefObject* pref_object =
123 new api::settings_private::PrefObject();
124 pref_object->key = pref->name();
125 switch (pref->GetType()) {
126 case base::Value::Type::TYPE_BOOLEAN:
127 pref_object->type = api::settings_private::PrefType::PREF_TYPE_BOOLEAN;
128 break;
129 case base::Value::Type::TYPE_INTEGER:
130 case base::Value::Type::TYPE_DOUBLE:
131 pref_object->type = api::settings_private::PrefType::PREF_TYPE_NUMBER;
132 break;
133 case base::Value::Type::TYPE_STRING:
134 pref_object->type = IsPrefTypeURL(name)
135 ? api::settings_private::PrefType::PREF_TYPE_URL
136 : api::settings_private::PrefType::PREF_TYPE_STRING;
137 break;
138 case base::Value::Type::TYPE_LIST:
139 pref_object->type = api::settings_private::PrefType::PREF_TYPE_LIST;
140 break;
141 default:
142 break;
143 }
144
145 pref_object->value.reset(pref->GetValue()->DeepCopy());
146
147 if (pref->IsManaged()) {
148 if (pref->IsManagedByCustodian()) {
149 pref_object->policy_source =
150 api::settings_private::PolicySource::POLICY_SOURCE_DEVICE;
151 } else {
152 pref_object->policy_source =
153 api::settings_private::PolicySource::POLICY_SOURCE_USER;
154 }
155 pref_object->policy_enforcement =
156 pref->IsRecommended() ? api::settings_private::PolicyEnforcement::
157 POLICY_ENFORCEMENT_RECOMMENDED
158 : api::settings_private::PolicyEnforcement::
159 POLICY_ENFORCEMENT_ENFORCED;
160 } else if (!IsPrefUserModifiable(profile_, pref_service, name)) {
161 pref_object->policy_source =
162 api::settings_private::PolicySource::POLICY_SOURCE_USER;
163 pref_object->policy_enforcement =
164 api::settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED;
165 }
166
167 return pref_object->ToValue();
168 } 33 }
169 34
170 scoped_ptr<base::Value> SettingsPrivateDelegate::GetAllPrefs() { 35 scoped_ptr<base::Value> SettingsPrivateDelegate::GetAllPrefs() {
171 scoped_ptr<base::ListValue> prefs(new base::ListValue()); 36 scoped_ptr<base::ListValue> prefs(new base::ListValue());
172 37
173 const TypedPrefMap& keys = GetWhitelistedKeys(); 38 const TypedPrefMap& keys = prefs_util::GetWhitelistedKeys();
174 for (const auto& it : keys) { 39 for (const auto& it : keys) {
175 prefs->Append(GetPref(it.first).release()); 40 prefs->Append(GetPref(it.first).release());
176 } 41 }
177 42
178 #if defined(OS_CHROMEOS)
179 const TypedPrefMap cros_keys = GetWhitelistedCrosKeys();
180 for (const auto& it : cros_keys) {
181 prefs->Append(GetPref(it.first).release());
182 }
183 #endif
184
185 return prefs.Pass(); 43 return prefs.Pass();
186 } 44 }
187 45
188 PrefService* SettingsPrivateDelegate::FindServiceForPref(
189 const std::string& pref_name) {
190 PrefService* user_prefs = profile_->GetPrefs();
191
192 // Proxy is a peculiar case: on ChromeOS, settings exist in both user
193 // prefs and local state, but chrome://settings should affect only user prefs.
194 // Elsewhere the proxy settings are stored in local state.
195 // See http://crbug.com/157147
196
197 if (pref_name == prefs::kProxy) {
198 #if defined(OS_CHROMEOS)
199 return user_prefs;
200 #else
201 return g_browser_process->local_state();
202 #endif
203 }
204
205 // Find which PrefService contains the given pref. Pref names should not
206 // be duplicated across services, however if they are, prefer the user's
207 // prefs.
208 if (user_prefs->FindPreference(pref_name))
209 return user_prefs;
210
211 if (g_browser_process->local_state()->FindPreference(pref_name))
212 return g_browser_process->local_state();
213
214 return user_prefs;
215 }
216
217 bool SettingsPrivateDelegate::SetPref(const std::string& pref_name, 46 bool SettingsPrivateDelegate::SetPref(const std::string& pref_name,
218 const base::Value* value) { 47 const base::Value* value) {
219 PrefService* pref_service = FindServiceForPref(pref_name); 48 PrefService* pref_service =
49 prefs_util::FindServiceForPref(profile_, pref_name);
220 50
221 if (!IsPrefUserModifiable(profile_, pref_service, pref_name)) 51 if (!prefs_util::IsPrefUserModifiable(profile_, pref_name))
222 return false; 52 return false;
223 53
224 const PrefService::Preference* pref = 54 const PrefService::Preference* pref =
225 pref_service->FindPreference(pref_name.c_str()); 55 pref_service->FindPreference(pref_name.c_str());
226 if (!pref) 56 if (!pref)
227 return false; 57 return false;
228 58
229 DCHECK_EQ(pref->GetType(), value->GetType()); 59 DCHECK_EQ(pref->GetType(), value->GetType());
230 60
231 scoped_ptr<base::Value> temp_value; 61 scoped_ptr<base::Value> temp_value;
232 62
233 switch (pref->GetType()) { 63 switch (pref->GetType()) {
234 case base::Value::TYPE_INTEGER: { 64 case base::Value::TYPE_INTEGER: {
235 // In JS all numbers are doubles. 65 // In JS all numbers are doubles.
236 double double_value; 66 double double_value;
237 if (!value->GetAsDouble(&double_value)) 67 if (!value->GetAsDouble(&double_value))
238 return false; 68 return false;
239 69
240 int int_value = static_cast<int>(double_value); 70 int int_value = static_cast<int>(double_value);
241 temp_value.reset(new base::FundamentalValue(int_value)); 71 temp_value.reset(new base::FundamentalValue(int_value));
242 value = temp_value.get(); 72 value = temp_value.get();
243 break; 73 break;
244 } 74 }
245 case base::Value::TYPE_STRING: { 75 case base::Value::TYPE_STRING: {
246 std::string original; 76 std::string original;
247 if (!value->GetAsString(&original)) 77 if (!value->GetAsString(&original))
248 return false; 78 return false;
249 79
250 if (IsPrefTypeURL(pref_name)) { 80 if (prefs_util::IsPrefTypeURL(pref_name)) {
251 GURL fixed = url_fixer::FixupURL(original, std::string()); 81 GURL fixed = url_fixer::FixupURL(original, std::string());
252 temp_value.reset(new base::StringValue(fixed.spec())); 82 temp_value.reset(new base::StringValue(fixed.spec()));
253 value = temp_value.get(); 83 value = temp_value.get();
254 } 84 }
255 break; 85 break;
256 } 86 }
257 case base::Value::TYPE_LIST: { 87 case base::Value::TYPE_LIST: {
258 // In case we have a List pref we got a JSON string. 88 // In case we have a List pref we got a JSON string.
259 std::string json_string; 89 std::string json_string;
260 if (!value->GetAsString(&json_string)) 90 if (!value->GetAsString(&json_string))
(...skipping 13 matching lines...) Expand all
274 return false; 104 return false;
275 } 105 }
276 106
277 // TODO(orenb): Process setting metrics here (like "ProcessUserMetric" in 107 // TODO(orenb): Process setting metrics here (like "ProcessUserMetric" in
278 // CoreOptionsHandler). 108 // CoreOptionsHandler).
279 pref_service->Set(pref_name.c_str(), *value); 109 pref_service->Set(pref_name.c_str(), *value);
280 return true; 110 return true;
281 } 111 }
282 112
283 } // namespace extensions 113 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698