| 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 |