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