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

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

Issue 1163593005: Update chrome.settingsPrivate to support CrOS-only settings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix issues preventing compilation on non-CrOS builds. Created 5 years, 6 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 "base/json/json_reader.h"
5 #include "base/prefs/pref_service.h" 6 #include "base/prefs/pref_service.h"
6 #include "chrome/browser/browser_process.h" 7 #include "chrome/browser/browser_process.h"
7 #include "chrome/browser/extensions/api/settings_private/prefs_util.h" 8 #include "chrome/browser/extensions/api/settings_private/prefs_util.h"
9 #include "chrome/browser/extensions/chrome_extension_function.h"
8 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/common/pref_names.h" 11 #include "chrome/common/pref_names.h"
12 #include "components/url_fixer/url_fixer.h"
13
14 #if defined(OS_CHROMEOS)
15 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
16 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_fact ory.h"
17 #include "chrome/browser/chromeos/settings/cros_settings.h"
18 #endif
10 19
11 namespace extensions { 20 namespace extensions {
12 21
13 namespace settings_private = api::settings_private; 22 namespace settings_private = api::settings_private;
14 23
15 namespace prefs_util { 24 PrefsUtil::PrefsUtil(Profile* profile) : profile_(profile) {
25 }
16 26
17 const TypedPrefMap& GetWhitelistedKeys() { 27 PrefsUtil::~PrefsUtil() {
18 static TypedPrefMap* s_whitelist = nullptr; 28 }
29
30 #if defined(OS_CHROMEOS)
31 using CrosSettings = chromeos::CrosSettings;
32 #endif
33
34 const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() {
35 static PrefsUtil::TypedPrefMap* s_whitelist = nullptr;
19 if (s_whitelist) 36 if (s_whitelist)
20 return *s_whitelist; 37 return *s_whitelist;
21 s_whitelist = new TypedPrefMap(); 38 s_whitelist = new PrefsUtil::TypedPrefMap();
22 (*s_whitelist)["browser.show_home_button"] = 39 (*s_whitelist)["browser.show_home_button"] =
23 settings_private::PrefType::PREF_TYPE_BOOLEAN; 40 settings_private::PrefType::PREF_TYPE_BOOLEAN;
24 (*s_whitelist)["bookmark_bar.show_on_all_tabs"] = 41 (*s_whitelist)["bookmark_bar.show_on_all_tabs"] =
25 settings_private::PrefType::PREF_TYPE_BOOLEAN; 42 settings_private::PrefType::PREF_TYPE_BOOLEAN;
26 (*s_whitelist)["download.default_directory"] = 43 (*s_whitelist)["download.default_directory"] =
27 settings_private::PrefType::PREF_TYPE_STRING; 44 settings_private::PrefType::PREF_TYPE_STRING;
28 (*s_whitelist)["download.prompt_for_download"] = 45 (*s_whitelist)["download.prompt_for_download"] =
29 settings_private::PrefType::PREF_TYPE_BOOLEAN; 46 settings_private::PrefType::PREF_TYPE_BOOLEAN;
30 (*s_whitelist)["homepage"] = settings_private::PrefType::PREF_TYPE_URL; 47 (*s_whitelist)["homepage"] = settings_private::PrefType::PREF_TYPE_URL;
31 48
32 #if defined(OS_CHROMEOS) 49 #if defined(OS_CHROMEOS)
50 (*s_whitelist)["cros.accounts.allowBWSI"] =
51 settings_private::PrefType::PREF_TYPE_BOOLEAN;
52 (*s_whitelist)["cros.accounts.supervisedUsersEnabled"] =
53 settings_private::PrefType::PREF_TYPE_BOOLEAN;
54 (*s_whitelist)["cros.accounts.showUserNamesOnSignIn"] =
55 settings_private::PrefType::PREF_TYPE_BOOLEAN;
56 (*s_whitelist)["cros.accounts.allowGuest"] =
57 settings_private::PrefType::PREF_TYPE_BOOLEAN;
33 (*s_whitelist)["settings.accessibility"] = 58 (*s_whitelist)["settings.accessibility"] =
34 settings_private::PrefType::PREF_TYPE_BOOLEAN; 59 settings_private::PrefType::PREF_TYPE_BOOLEAN;
35 (*s_whitelist)["settings.a11y.autoclick"] = 60 (*s_whitelist)["settings.a11y.autoclick"] =
36 settings_private::PrefType::PREF_TYPE_BOOLEAN; 61 settings_private::PrefType::PREF_TYPE_BOOLEAN;
37 (*s_whitelist)["settings.a11y.autoclick_delay_ms"] = 62 (*s_whitelist)["settings.a11y.autoclick_delay_ms"] =
38 settings_private::PrefType::PREF_TYPE_BOOLEAN; 63 settings_private::PrefType::PREF_TYPE_BOOLEAN;
39 (*s_whitelist)["settings.a11y.enable_menu"] = 64 (*s_whitelist)["settings.a11y.enable_menu"] =
40 settings_private::PrefType::PREF_TYPE_BOOLEAN; 65 settings_private::PrefType::PREF_TYPE_BOOLEAN;
41 (*s_whitelist)["settings.a11y.high_contrast_enabled"] = 66 (*s_whitelist)["settings.a11y.high_contrast_enabled"] =
42 settings_private::PrefType::PREF_TYPE_BOOLEAN; 67 settings_private::PrefType::PREF_TYPE_BOOLEAN;
43 (*s_whitelist)["settings.a11y.large_cursor_enabled"] = 68 (*s_whitelist)["settings.a11y.large_cursor_enabled"] =
44 settings_private::PrefType::PREF_TYPE_BOOLEAN; 69 settings_private::PrefType::PREF_TYPE_BOOLEAN;
45 (*s_whitelist)["settings.a11y.screen_magnifier"] = 70 (*s_whitelist)["settings.a11y.screen_magnifier"] =
46 settings_private::PrefType::PREF_TYPE_BOOLEAN; 71 settings_private::PrefType::PREF_TYPE_BOOLEAN;
47 (*s_whitelist)["settings.a11y.sticky_keys_enabled"] = 72 (*s_whitelist)["settings.a11y.sticky_keys_enabled"] =
48 settings_private::PrefType::PREF_TYPE_BOOLEAN; 73 settings_private::PrefType::PREF_TYPE_BOOLEAN;
49 (*s_whitelist)["settings.a11y.virtual_keyboard"] = 74 (*s_whitelist)["settings.a11y.virtual_keyboard"] =
50 settings_private::PrefType::PREF_TYPE_BOOLEAN; 75 settings_private::PrefType::PREF_TYPE_BOOLEAN;
51 (*s_whitelist)["settings.clock.use_24hour_clock"] = 76 (*s_whitelist)["settings.clock.use_24hour_clock"] =
52 settings_private::PrefType::PREF_TYPE_BOOLEAN; 77 settings_private::PrefType::PREF_TYPE_BOOLEAN;
53 (*s_whitelist)["settings.touchpad.enable_tap_dragging"] = 78 (*s_whitelist)["settings.touchpad.enable_tap_dragging"] =
54 settings_private::PrefType::PREF_TYPE_BOOLEAN; 79 settings_private::PrefType::PREF_TYPE_BOOLEAN;
55 #endif 80 #endif
56 81
57 return *s_whitelist; 82 return *s_whitelist;
58 } 83 }
59 84
60 scoped_ptr<api::settings_private::PrefObject> GetPref(Profile* profile, 85 api::settings_private::PrefType PrefsUtil::GetType(const std::string& name,
61 const std::string& name) { 86 base::Value::Type type) {
87 switch (type) {
88 case base::Value::Type::TYPE_BOOLEAN:
89 return api::settings_private::PrefType::PREF_TYPE_BOOLEAN;
90 case base::Value::Type::TYPE_INTEGER:
91 case base::Value::Type::TYPE_DOUBLE:
92 return api::settings_private::PrefType::PREF_TYPE_NUMBER;
93 case base::Value::Type::TYPE_STRING:
94 return IsPrefTypeURL(name)
95 ? api::settings_private::PrefType::PREF_TYPE_URL
96 : api::settings_private::PrefType::PREF_TYPE_STRING;
97 case base::Value::Type::TYPE_LIST:
98 return api::settings_private::PrefType::PREF_TYPE_LIST;
99 default:
100 return api::settings_private::PrefType::PREF_TYPE_NONE;
101 }
102 }
103
104 scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetCrosSettingsPref(
105 const std::string& name) {
62 scoped_ptr<api::settings_private::PrefObject> pref_object( 106 scoped_ptr<api::settings_private::PrefObject> pref_object(
63 new api::settings_private::PrefObject()); 107 new api::settings_private::PrefObject());
64 108
65 PrefService* pref_service = FindServiceForPref(profile, name); 109 #if defined(OS_CHROMEOS)
110 const base::Value* value = CrosSettings::Get()->GetPref(name);
111 pref_object->key = name;
112 pref_object->type = GetType(name, value->GetType());
Oren Blasberg 2015/06/06 00:42:55 Somehow, this line segfaults if name is 'cros.acco
stevenjb 2015/06/06 00:48:17 Is value maybe NULL?
Oren Blasberg 2015/06/06 01:02:11 Whoops, you're right, it's null. However, I don't
113 pref_object->value.reset(value->DeepCopy());
114 #endif
115
116 return pref_object.Pass();
117 }
118
119 scoped_ptr<api::settings_private::PrefObject> PrefsUtil::GetPref(
120 const std::string& name) {
121 scoped_ptr<api::settings_private::PrefObject> pref_object(
122 new api::settings_private::PrefObject());
123
124 if (IsCrosSetting(name))
125 return GetCrosSettingsPref(name);
126
127 PrefService* pref_service = FindServiceForPref(name);
66 const PrefService::Preference* pref = pref_service->FindPreference(name); 128 const PrefService::Preference* pref = pref_service->FindPreference(name);
67 if (!pref) 129 if (!pref)
68 return pref_object.Pass(); 130 return pref_object.Pass();
69 131
70 pref_object->key = pref->name(); 132 pref_object->key = pref->name();
71 switch (pref->GetType()) { 133 pref_object->type = GetType(name, pref->GetType());
72 case base::Value::Type::TYPE_BOOLEAN:
73 pref_object->type = api::settings_private::PrefType::PREF_TYPE_BOOLEAN;
74 break;
75 case base::Value::Type::TYPE_INTEGER:
76 case base::Value::Type::TYPE_DOUBLE:
77 pref_object->type = api::settings_private::PrefType::PREF_TYPE_NUMBER;
78 break;
79 case base::Value::Type::TYPE_STRING:
80 pref_object->type =
81 IsPrefTypeURL(name)
82 ? api::settings_private::PrefType::PREF_TYPE_URL
83 : api::settings_private::PrefType::PREF_TYPE_STRING;
84 break;
85 case base::Value::Type::TYPE_LIST:
86 pref_object->type = api::settings_private::PrefType::PREF_TYPE_LIST;
87 break;
88 default:
89 break;
90 }
91
92 pref_object->value.reset(pref->GetValue()->DeepCopy()); 134 pref_object->value.reset(pref->GetValue()->DeepCopy());
93 135
94 if (pref->IsManaged()) { 136 if (pref->IsManaged()) {
95 if (pref->IsManagedByCustodian()) { 137 if (pref->IsManagedByCustodian()) {
96 pref_object->policy_source = 138 pref_object->policy_source =
97 api::settings_private::PolicySource::POLICY_SOURCE_DEVICE; 139 api::settings_private::PolicySource::POLICY_SOURCE_DEVICE;
98 } else { 140 } else {
99 pref_object->policy_source = 141 pref_object->policy_source =
100 api::settings_private::PolicySource::POLICY_SOURCE_USER; 142 api::settings_private::PolicySource::POLICY_SOURCE_USER;
101 } 143 }
102 pref_object->policy_enforcement = 144 pref_object->policy_enforcement =
103 pref->IsRecommended() ? api::settings_private::PolicyEnforcement:: 145 pref->IsRecommended() ? api::settings_private::PolicyEnforcement::
104 POLICY_ENFORCEMENT_RECOMMENDED 146 POLICY_ENFORCEMENT_RECOMMENDED
105 : api::settings_private::PolicyEnforcement:: 147 : api::settings_private::PolicyEnforcement::
106 POLICY_ENFORCEMENT_ENFORCED; 148 POLICY_ENFORCEMENT_ENFORCED;
107 } else if (!IsPrefUserModifiable(profile, name)) { 149 } else if (!IsPrefUserModifiable(name)) {
108 pref_object->policy_source = 150 pref_object->policy_source =
109 api::settings_private::PolicySource::POLICY_SOURCE_USER; 151 api::settings_private::PolicySource::POLICY_SOURCE_USER;
110 pref_object->policy_enforcement = 152 pref_object->policy_enforcement =
111 api::settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED; 153 api::settings_private::PolicyEnforcement::POLICY_ENFORCEMENT_ENFORCED;
112 } 154 }
113 155
114 return pref_object.Pass(); 156 return pref_object.Pass();
115 } 157 }
116 158
117 bool IsPrefTypeURL(const std::string& pref_name) { 159 bool PrefsUtil::SetPref(const std::string& pref_name,
160 const base::Value* value) {
161 if (IsCrosSetting(pref_name))
162 return SetCrosSettingsPref(pref_name, value);
163
164 PrefService* pref_service = FindServiceForPref(pref_name);
165
166 if (!IsPrefUserModifiable(pref_name))
167 return false;
168
169 const PrefService::Preference* pref =
170 pref_service->FindPreference(pref_name.c_str());
171 if (!pref)
172 return false;
173
174 DCHECK_EQ(pref->GetType(), value->GetType());
175
176 scoped_ptr<base::Value> temp_value;
177
178 switch (pref->GetType()) {
179 case base::Value::TYPE_INTEGER: {
180 // In JS all numbers are doubles.
181 double double_value;
182 if (!value->GetAsDouble(&double_value))
183 return false;
184
185 int int_value = static_cast<int>(double_value);
186 temp_value.reset(new base::FundamentalValue(int_value));
187 value = temp_value.get();
188 break;
189 }
190 case base::Value::TYPE_STRING: {
191 std::string original;
192 if (!value->GetAsString(&original))
193 return false;
194
195 if (IsPrefTypeURL(pref_name)) {
196 GURL fixed = url_fixer::FixupURL(original, std::string());
197 temp_value.reset(new base::StringValue(fixed.spec()));
198 value = temp_value.get();
199 }
200 break;
201 }
202 case base::Value::TYPE_LIST: {
203 // In case we have a List pref we got a JSON string.
204 std::string json_string;
205 if (!value->GetAsString(&json_string))
206 return false;
207
208 temp_value.reset(base::JSONReader::DeprecatedRead(json_string));
209 value = temp_value.get();
210 if (!value->IsType(base::Value::TYPE_LIST))
211 return false;
212
213 break;
214 }
215 case base::Value::TYPE_BOOLEAN:
216 case base::Value::TYPE_DOUBLE:
217 break;
218 default:
219 return false;
220 }
221
222 // TODO(orenb): Process setting metrics here and in the CrOS setting method
223 // too (like "ProcessUserMetric" in CoreOptionsHandler).
224 pref_service->Set(pref_name.c_str(), *value);
225 return true;
226 }
227
228 bool PrefsUtil::SetCrosSettingsPref(const std::string& pref_name,
229 const base::Value* value) {
230 #if defined(OS_CHROMEOS)
231 chromeos::OwnerSettingsServiceChromeOS* service =
232 chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(
233 profile_);
234
235 // Returns false if not the owner, for settings requiring owner.
236 if (service && service->HandlesSetting(pref_name))
237 return service->Set(pref_name, *value);
238
239 chromeos::CrosSettings::Get()->Set(pref_name, *value);
240 return true;
241 #else
242 return false;
243 #endif
244 }
245
246 bool PrefsUtil::AppendToListCrosSetting(const std::string& setting,
247 const base::Value& value) {
248 #if defined(OS_CHROMEOS)
249 chromeos::OwnerSettingsServiceChromeOS* service =
250 chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(
251 profile_);
252 DCHECK(service);
253 return service->AppendToList(setting, value);
254 #else
255 return false;
256 #endif
257 }
258
259 bool PrefsUtil::RemoveFromListCrosSetting(const std::string& setting,
260 const base::Value& value) {
261 #if defined(OS_CHROMEOS)
262 chromeos::OwnerSettingsServiceChromeOS* service =
263 chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext(
264 profile_);
265 DCHECK(service);
266 return service->RemoveFromList(setting, value);
267 #else
268 return false;
269 #endif
270 }
271
272 bool PrefsUtil::IsPrefTypeURL(const std::string& pref_name) {
118 settings_private::PrefType pref_type = 273 settings_private::PrefType pref_type =
119 settings_private::PrefType::PREF_TYPE_NONE; 274 settings_private::PrefType::PREF_TYPE_NONE;
120 275
121 const TypedPrefMap keys = GetWhitelistedKeys(); 276 const TypedPrefMap keys = GetWhitelistedKeys();
122 const auto& iter = keys.find(pref_name); 277 const auto& iter = keys.find(pref_name);
123 if (iter != keys.end()) 278 if (iter != keys.end())
124 pref_type = iter->second; 279 pref_type = iter->second;
125 280
126 return pref_type == settings_private::PrefType::PREF_TYPE_URL; 281 return pref_type == settings_private::PrefType::PREF_TYPE_URL;
127 } 282 }
128 283
129 bool IsPrefUserModifiable(Profile* profile, const std::string& pref_name) { 284 bool PrefsUtil::IsPrefUserModifiable(const std::string& pref_name) {
130 if (pref_name != prefs::kBrowserGuestModeEnabled && 285 if (pref_name != prefs::kBrowserGuestModeEnabled &&
131 pref_name != prefs::kBrowserAddPersonEnabled) { 286 pref_name != prefs::kBrowserAddPersonEnabled) {
132 return true; 287 return true;
133 } 288 }
134 289
135 PrefService* pref_service = profile->GetPrefs(); 290 PrefService* pref_service = profile_->GetPrefs();
136 const PrefService::Preference* pref = 291 const PrefService::Preference* pref =
137 pref_service->FindPreference(pref_name.c_str()); 292 pref_service->FindPreference(pref_name.c_str());
138 if (!pref || !pref->IsUserModifiable() || profile->IsSupervised()) 293 if (!pref || !pref->IsUserModifiable() || profile_->IsSupervised())
139 return false; 294 return false;
140 295
141 return true; 296 return true;
142 } 297 }
143 298
144 PrefService* FindServiceForPref(Profile* profile, 299 PrefService* PrefsUtil::FindServiceForPref(const std::string& pref_name) {
145 const std::string& pref_name) { 300 PrefService* user_prefs = profile_->GetPrefs();
146 PrefService* user_prefs = profile->GetPrefs();
147 301
148 // Proxy is a peculiar case: on ChromeOS, settings exist in both user 302 // Proxy is a peculiar case: on ChromeOS, settings exist in both user
149 // prefs and local state, but chrome://settings should affect only user prefs. 303 // prefs and local state, but chrome://settings should affect only user prefs.
150 // Elsewhere the proxy settings are stored in local state. 304 // Elsewhere the proxy settings are stored in local state.
151 // See http://crbug.com/157147 305 // See http://crbug.com/157147
152 306
153 if (pref_name == prefs::kProxy) { 307 if (pref_name == prefs::kProxy) {
154 #if defined(OS_CHROMEOS) 308 #if defined(OS_CHROMEOS)
155 return user_prefs; 309 return user_prefs;
156 #else 310 #else
157 return g_browser_process->local_state(); 311 return g_browser_process->local_state();
158 #endif 312 #endif
159 } 313 }
160 314
161 // Find which PrefService contains the given pref. Pref names should not 315 // Find which PrefService contains the given pref. Pref names should not
162 // be duplicated across services, however if they are, prefer the user's 316 // be duplicated across services, however if they are, prefer the user's
163 // prefs. 317 // prefs.
164 if (user_prefs->FindPreference(pref_name)) 318 if (user_prefs->FindPreference(pref_name))
165 return user_prefs; 319 return user_prefs;
166 320
167 if (g_browser_process->local_state()->FindPreference(pref_name)) 321 if (g_browser_process->local_state()->FindPreference(pref_name))
168 return g_browser_process->local_state(); 322 return g_browser_process->local_state();
169 323
170 return user_prefs; 324 return user_prefs;
171 } 325 }
172 326
173 } // namespace prefs_util 327 bool PrefsUtil::IsCrosSetting(const std::string& pref_name) {
328 #if defined(OS_CHROMEOS)
329 return CrosSettings::Get()->IsCrosSettings(pref_name);
330 #else
331 return false;
332 #endif
333 }
174 334
175 } // namespace extensions 335 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698