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 "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 Loading... |
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 |
OLD | NEW |