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

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

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

Powered by Google App Engine
This is Rietveld 408576698