blob: 825eee3c3188038006bc0dcacaa9d9307d471891 [file] [log] [blame]
[email protected]32c3c752012-01-05 17:33:471// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]37858e52010-08-26 00:22:025#include "chrome/browser/prefs/pref_service.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]1cb92b82010-03-08 23:12:157#include <algorithm>
[email protected]1cb92b82010-03-08 23:12:158
[email protected]bebe69432011-09-28 18:36:459#include "base/bind.h"
[email protected]aa4dc5e22010-06-16 11:32:5410#include "base/command_line.h"
[email protected]c02c853d72010-08-07 06:23:2411#include "base/file_path.h"
[email protected]1d01d412010-08-20 00:36:0112#include "base/file_util.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/logging.h"
14#include "base/message_loop.h"
[email protected]835d7c82010-10-14 04:38:3815#include "base/metrics/histogram.h"
[email protected]7286e3fc2011-07-19 22:13:2416#include "base/stl_util.h"
[email protected]e83326f2010-07-31 17:29:2517#include "base/string_number_conversions.h"
initial.commit09911bf2008-07-26 23:55:2918#include "base/string_util.h"
[email protected]8703b2b2011-03-15 09:51:5019#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4020#include "build/build_config.h"
[email protected]d36f941b2011-05-09 06:19:1621#include "chrome/browser/browser_process.h"
[email protected]9a8c4022011-01-25 14:25:3322#include "chrome/browser/extensions/extension_pref_store.h"
[email protected]acd78969c2010-12-08 09:49:1123#include "chrome/browser/policy/configuration_policy_pref_store.h"
24#include "chrome/browser/prefs/command_line_pref_store.h"
[email protected]f2d1f612010-12-09 15:10:1725#include "chrome/browser/prefs/default_pref_store.h"
[email protected]32c3c752012-01-05 17:33:4726#include "chrome/browser/prefs/overlay_user_pref_store.h"
[email protected]d36f941b2011-05-09 06:19:1627#include "chrome/browser/prefs/pref_model_associator.h"
[email protected]acd78969c2010-12-08 09:49:1128#include "chrome/browser/prefs/pref_notifier_impl.h"
[email protected]39d9f62c2010-12-03 10:48:5029#include "chrome/browser/prefs/pref_value_store.h"
[email protected]fb8fdf12012-08-21 16:28:2030#include "chrome/browser/profiles/profile.h"
[email protected]32c3c752012-01-05 17:33:4731#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
[email protected]c7fb2da32011-04-14 20:47:1032#include "chrome/browser/ui/profile_error_dialog.h"
[email protected]e4f86492011-04-13 12:23:5333#include "chrome/common/json_pref_store.h"
[email protected]32c3c752012-01-05 17:33:4734#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4935#include "content/public/browser/browser_thread.h"
[email protected]ba399672010-04-06 15:42:3936#include "grit/chromium_strings.h"
[email protected]34ac8f32009-02-22 23:03:2737#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1738#include "ui/base/l10n/l10n_util.h"
initial.commit09911bf2008-07-26 23:55:2939
[email protected]631bb742011-11-02 11:29:3940using content::BrowserThread;
41
initial.commit09911bf2008-07-26 23:55:2942namespace {
43
initial.commit09911bf2008-07-26 23:55:2944// A helper function for RegisterLocalized*Pref that creates a Value* based on
45// the string value in the locale dll. Because we control the values in a
46// locale dll, this should always return a Value of the appropriate type.
[email protected]bab1c13f2011-08-12 20:59:0247Value* CreateLocaleDefaultValue(base::Value::Type type, int message_id) {
[email protected]16b527162010-08-15 18:37:1048 std::string resource_string = l10n_util::GetStringUTF8(message_id);
initial.commit09911bf2008-07-26 23:55:2949 DCHECK(!resource_string.empty());
50 switch (type) {
51 case Value::TYPE_BOOLEAN: {
[email protected]16b527162010-08-15 18:37:1052 if ("true" == resource_string)
initial.commit09911bf2008-07-26 23:55:2953 return Value::CreateBooleanValue(true);
[email protected]16b527162010-08-15 18:37:1054 if ("false" == resource_string)
initial.commit09911bf2008-07-26 23:55:2955 return Value::CreateBooleanValue(false);
56 break;
57 }
58
59 case Value::TYPE_INTEGER: {
[email protected]e83326f2010-07-31 17:29:2560 int val;
[email protected]16b527162010-08-15 18:37:1061 base::StringToInt(resource_string, &val);
[email protected]e83326f2010-07-31 17:29:2562 return Value::CreateIntegerValue(val);
initial.commit09911bf2008-07-26 23:55:2963 }
64
[email protected]fb534c92011-02-01 01:02:0765 case Value::TYPE_DOUBLE: {
[email protected]e83326f2010-07-31 17:29:2566 double val;
[email protected]16b527162010-08-15 18:37:1067 base::StringToDouble(resource_string, &val);
[email protected]fb534c92011-02-01 01:02:0768 return Value::CreateDoubleValue(val);
initial.commit09911bf2008-07-26 23:55:2969 }
70
71 case Value::TYPE_STRING: {
72 return Value::CreateStringValue(resource_string);
initial.commit09911bf2008-07-26 23:55:2973 }
74
75 default: {
[email protected]b154e6f2009-03-06 01:52:4076 NOTREACHED() <<
[email protected]c3b54f372010-09-14 08:25:0777 "list and dictionary types cannot have default locale values";
initial.commit09911bf2008-07-26 23:55:2978 }
79 }
80 NOTREACHED();
81 return Value::CreateNullValue();
82}
83
[email protected]ba399672010-04-06 15:42:3984// Forwards a notification after a PostMessage so that we can wait for the
85// MessageLoop to run.
[email protected]845b43a82011-05-11 10:14:4386void NotifyReadError(int message_id) {
[email protected]c7fb2da32011-04-14 20:47:1087 ShowProfileErrorDialog(message_id);
[email protected]ba399672010-04-06 15:42:3988}
89
[email protected]845b43a82011-05-11 10:14:4390// Shows notifications which correspond to PersistentPrefStore's reading errors.
91class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
92 public:
93 virtual void OnError(PersistentPrefStore::PrefReadError error) {
94 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
95 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
96 // an example problem that this can cause.
97 // Do some diagnosis and try to avoid losing data.
98 int message_id = 0;
99 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
100 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
101 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
102 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
103 }
104
105 if (message_id) {
106 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45107 base::Bind(&NotifyReadError, message_id));
[email protected]845b43a82011-05-11 10:14:43108 }
[email protected]ff3c69a2011-09-15 00:36:48109 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
110 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
[email protected]845b43a82011-05-11 10:14:43111 }
112 }
113};
114
initial.commit09911bf2008-07-26 23:55:29115} // namespace
116
[email protected]fb8fdf12012-08-21 16:28:20117PrefServiceBase* PrefServiceBase::ForProfile(Profile* profile) {
118 return profile->GetPrefs();
119}
120
[email protected]db198b22010-07-12 16:48:49121// static
[email protected]21d3a882012-05-31 14:41:55122PrefService* PrefService::CreatePrefService(
123 const FilePath& pref_filename,
124 policy::PolicyService* policy_service,
125 PrefStore* extension_prefs,
126 bool async) {
[email protected]acd78969c2010-12-08 09:49:11127 using policy::ConfigurationPolicyPrefStore;
128
[email protected]1d01d412010-08-20 00:36:01129#if defined(OS_LINUX)
130 // We'd like to see what fraction of our users have the preferences
131 // stored on a network file system, as we've had no end of troubles
132 // with NFS/AFS.
133 // TODO(evanm): remove this once we've collected state.
134 file_util::FileSystemType fstype;
135 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
136 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
137 static_cast<int>(fstype),
138 file_util::FILE_SYSTEM_TYPE_COUNT);
139 }
140#endif
141
[email protected]f31e2e52011-07-14 16:01:19142#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]4eb4d6ce2012-04-02 14:06:57143 ConfigurationPolicyPrefStore* managed =
[email protected]21d3a882012-05-31 14:41:55144 ConfigurationPolicyPrefStore::CreateMandatoryPolicyPrefStore(
145 policy_service);
[email protected]4eb4d6ce2012-04-02 14:06:57146 ConfigurationPolicyPrefStore* recommended =
[email protected]21d3a882012-05-31 14:41:55147 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(
148 policy_service);
[email protected]f31e2e52011-07-14 16:01:19149#else
[email protected]4eb4d6ce2012-04-02 14:06:57150 ConfigurationPolicyPrefStore* managed = NULL;
151 ConfigurationPolicyPrefStore* recommended = NULL;
[email protected]f31e2e52011-07-14 16:01:19152#endif // ENABLE_CONFIGURATION_POLICY
153
[email protected]acd78969c2010-12-08 09:49:11154 CommandLinePrefStore* command_line =
155 new CommandLinePrefStore(CommandLine::ForCurrentProcess());
[email protected]370bc732012-05-07 21:25:20156 JsonPrefStore* user = new JsonPrefStore(
157 pref_filename,
158 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
[email protected]9a8c4022011-01-25 14:25:33159 DefaultPrefStore* default_pref_store = new DefaultPrefStore();
[email protected]acd78969c2010-12-08 09:49:11160
[email protected]361d37f62011-11-22 10:37:02161 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
162 PrefModelAssociator* pref_sync_associator = new PrefModelAssociator();
163
[email protected]845b43a82011-05-11 10:14:43164 return new PrefService(
[email protected]361d37f62011-11-22 10:37:02165 pref_notifier,
166 new PrefValueStore(
[email protected]4eb4d6ce2012-04-02 14:06:57167 managed,
[email protected]361d37f62011-11-22 10:37:02168 extension_prefs,
169 command_line,
170 user,
[email protected]4eb4d6ce2012-04-02 14:06:57171 recommended,
[email protected]361d37f62011-11-22 10:37:02172 default_pref_store,
173 pref_sync_associator,
174 pref_notifier),
175 user,
176 default_pref_store,
177 pref_sync_associator,
178 async);
[email protected]9a8c4022011-01-25 14:25:33179}
180
181PrefService* PrefService::CreateIncognitoPrefService(
182 PrefStore* incognito_extension_prefs) {
[email protected]d3b05ea2012-01-24 22:57:05183 pref_service_forked_ = true;
[email protected]361d37f62011-11-22 10:37:02184 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
[email protected]32c3c752012-01-05 17:33:47185 OverlayUserPrefStore* incognito_pref_store =
186 new OverlayUserPrefStore(user_pref_store_.get());
187 PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store);
[email protected]361d37f62011-11-22 10:37:02188 return new PrefService(
189 pref_notifier,
190 pref_value_store_->CloneAndSpecialize(
[email protected]4eb4d6ce2012-04-02 14:06:57191 NULL, // managed
[email protected]361d37f62011-11-22 10:37:02192 incognito_extension_prefs,
[email protected]d3b05ea2012-01-24 22:57:05193 NULL, // command_line_prefs
[email protected]361d37f62011-11-22 10:37:02194 incognito_pref_store,
[email protected]4eb4d6ce2012-04-02 14:06:57195 NULL, // recommended
[email protected]361d37f62011-11-22 10:37:02196 default_store_.get(),
[email protected]d3b05ea2012-01-24 22:57:05197 NULL, // pref_sync_associator
[email protected]361d37f62011-11-22 10:37:02198 pref_notifier),
199 incognito_pref_store,
[email protected]9a8c4022011-01-25 14:25:33200 default_store_.get(),
[email protected]361d37f62011-11-22 10:37:02201 NULL,
202 false);
203}
204
[email protected]361d37f62011-11-22 10:37:02205PrefService::PrefService(PrefNotifierImpl* pref_notifier,
206 PrefValueStore* pref_value_store,
207 PersistentPrefStore* user_prefs,
208 DefaultPrefStore* default_store,
209 PrefModelAssociator* pref_sync_associator,
210 bool async)
211 : pref_notifier_(pref_notifier),
212 pref_value_store_(pref_value_store),
213 user_pref_store_(user_prefs),
214 default_store_(default_store),
[email protected]d3b05ea2012-01-24 22:57:05215 pref_sync_associator_(pref_sync_associator),
216 pref_service_forked_(false) {
[email protected]361d37f62011-11-22 10:37:02217 pref_notifier_->SetPrefService(this);
218 if (pref_sync_associator_.get())
219 pref_sync_associator_->SetPrefService(this);
220 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:33221}
222
initial.commit09911bf2008-07-26 23:55:29223PrefService::~PrefService() {
224 DCHECK(CalledOnValidThread());
initial.commit09911bf2008-07-26 23:55:29225 STLDeleteContainerPointers(prefs_.begin(), prefs_.end());
226 prefs_.clear();
[email protected]a98ce1262011-01-28 13:20:23227
228 // Reset pointers so accesses after destruction reliably crash.
229 pref_value_store_.reset();
230 user_pref_store_ = NULL;
231 default_store_ = NULL;
[email protected]d36f941b2011-05-09 06:19:16232 pref_sync_associator_.reset();
[email protected]42f23782012-06-08 19:11:53233 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:29234}
235
[email protected]845b43a82011-05-11 10:14:43236void PrefService::InitFromStorage(bool async) {
237 if (!async) {
238 ReadErrorHandler error_handler;
239 error_handler.OnError(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:21240 } else {
[email protected]845b43a82011-05-11 10:14:43241 // Guarantee that initialization happens after this function returned.
242 MessageLoop::current()->PostTask(
243 FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45244 base::Bind(&PersistentPrefStore::ReadPrefsAsync,
245 user_pref_store_.get(),
246 new ReadErrorHandler()));
[email protected]844a1002011-04-19 11:37:21247 }
[email protected]ba399672010-04-06 15:42:39248}
249
250bool PrefService::ReloadPersistentPrefs() {
[email protected]f2d1f612010-12-09 15:10:17251 return user_pref_store_->ReadPrefs() ==
252 PersistentPrefStore::PREF_READ_ERROR_NONE;
initial.commit09911bf2008-07-26 23:55:29253}
254
[email protected]3826fed2011-03-25 10:59:56255void PrefService::CommitPendingWrite() {
256 DCHECK(CalledOnValidThread());
257 user_pref_store_->CommitPendingWrite();
258}
259
[email protected]d36f941b2011-05-09 06:19:16260namespace {
261
262// If there's no g_browser_process or no local state, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05263bool IsLocalStatePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16264 return (!g_browser_process ||
265 !g_browser_process->local_state() ||
266 g_browser_process->local_state() == prefs);
267}
268
269// If there's no g_browser_process, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05270bool IsProfilePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16271 // TODO(zea): uncomment this once all preferences are only ever registered
272 // with either the local_state's pref service or the profile's pref service.
273 // return (!g_browser_process || g_browser_process->local_state() != prefs);
274 return true;
275}
276
277} // namespace
278
279
280// Local State prefs.
[email protected]57ecc4b2010-08-11 03:02:51281void PrefService::RegisterBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29282 bool default_value) {
[email protected]d36f941b2011-05-09 06:19:16283 // If this fails, the pref service in use is a profile pref service, so the
284 // sync status must be provided (see profile pref registration calls below).
285 DCHECK(IsLocalStatePrefService(this));
286 RegisterPreference(path,
287 Value::CreateBooleanValue(default_value),
288 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29289}
290
[email protected]57ecc4b2010-08-11 03:02:51291void PrefService::RegisterIntegerPref(const char* path, int default_value) {
[email protected]d36f941b2011-05-09 06:19:16292 // If this fails, the pref service in use is a profile pref service, so the
293 // sync status must be provided (see profile pref registration calls below).
294 DCHECK(IsLocalStatePrefService(this));
295 RegisterPreference(path,
296 Value::CreateIntegerValue(default_value),
297 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29298}
299
[email protected]fb534c92011-02-01 01:02:07300void PrefService::RegisterDoublePref(const char* path, double default_value) {
[email protected]d36f941b2011-05-09 06:19:16301 // If this fails, the pref service in use is a profile pref service, so the
302 // sync status must be provided (see profile pref registration calls below).
303 DCHECK(IsLocalStatePrefService(this));
304 RegisterPreference(path,
305 Value::CreateDoubleValue(default_value),
306 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29307}
308
[email protected]57ecc4b2010-08-11 03:02:51309void PrefService::RegisterStringPref(const char* path,
[email protected]20ce516d2010-06-18 02:20:04310 const std::string& default_value) {
[email protected]d36f941b2011-05-09 06:19:16311 // If this fails, the pref service in use is a profile pref service, so the
312 // sync status must be provided (see profile pref registration calls below).
313 DCHECK(IsLocalStatePrefService(this));
314 RegisterPreference(path,
315 Value::CreateStringValue(default_value),
316 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29317}
318
[email protected]57ecc4b2010-08-11 03:02:51319void PrefService::RegisterFilePathPref(const char* path,
[email protected]b9636002009-03-04 00:05:25320 const FilePath& default_value) {
[email protected]d36f941b2011-05-09 06:19:16321 // If this fails, the pref service in use is a profile pref service, so the
322 // sync status must be provided (see profile pref registration calls below).
323 DCHECK(IsLocalStatePrefService(this));
324 RegisterPreference(path,
325 Value::CreateStringValue(default_value.value()),
326 UNSYNCABLE_PREF);
[email protected]b9636002009-03-04 00:05:25327}
328
[email protected]57ecc4b2010-08-11 03:02:51329void PrefService::RegisterListPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16330 // If this fails, the pref service in use is a profile pref service, so the
331 // sync status must be provided (see profile pref registration calls below).
332 DCHECK(IsLocalStatePrefService(this));
333 RegisterPreference(path,
334 new ListValue(),
335 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29336}
337
[email protected]c2f23d012011-02-09 14:52:17338void PrefService::RegisterListPref(const char* path, ListValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16339 // If this fails, the pref service in use is a profile pref service, so the
340 // sync status must be provided (see profile pref registration calls below).
341 DCHECK(IsLocalStatePrefService(this));
342 RegisterPreference(path,
343 default_value,
344 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17345}
346
[email protected]57ecc4b2010-08-11 03:02:51347void PrefService::RegisterDictionaryPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16348 // If this fails, the pref service in use is a profile pref service, so the
349 // sync status must be provided (see profile pref registration calls below).
350 DCHECK(IsLocalStatePrefService(this));
351 RegisterPreference(path,
352 new DictionaryValue(),
353 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29354}
355
[email protected]c2f23d012011-02-09 14:52:17356void PrefService::RegisterDictionaryPref(const char* path,
357 DictionaryValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16358 // If this fails, the pref service in use is a profile pref service, so the
359 // sync status must be provided (see profile pref registration calls below).
360 DCHECK(IsLocalStatePrefService(this));
361 RegisterPreference(path,
362 default_value,
363 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17364}
365
[email protected]57ecc4b2010-08-11 03:02:51366void PrefService::RegisterLocalizedBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29367 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16368 // If this fails, the pref service in use is a profile pref service, so the
369 // sync status must be provided (see profile pref registration calls below).
370 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07371 RegisterPreference(
372 path,
[email protected]d36f941b2011-05-09 06:19:16373 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
374 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29375}
376
[email protected]57ecc4b2010-08-11 03:02:51377void PrefService::RegisterLocalizedIntegerPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29378 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16379 // If this fails, the pref service in use is a profile pref service, so the
380 // sync status must be provided (see profile pref registration calls below).
381 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07382 RegisterPreference(
383 path,
[email protected]d36f941b2011-05-09 06:19:16384 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
385 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29386}
387
[email protected]fb534c92011-02-01 01:02:07388void PrefService::RegisterLocalizedDoublePref(const char* path,
389 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16390 // If this fails, the pref service in use is a profile pref service, so the
391 // sync status must be provided (see profile pref registration calls below).
392 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07393 RegisterPreference(
394 path,
[email protected]d36f941b2011-05-09 06:19:16395 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
396 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29397}
398
[email protected]57ecc4b2010-08-11 03:02:51399void PrefService::RegisterLocalizedStringPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29400 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16401 // If this fails, the pref service in use is a profile pref service, so the
402 // sync status must be provided (see profile pref registration calls below).
403 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07404 RegisterPreference(
405 path,
[email protected]d36f941b2011-05-09 06:19:16406 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
407 UNSYNCABLE_PREF);
408}
409
410void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
411 // If this fails, the pref service in use is a profile pref service, so the
412 // sync status must be provided (see profile pref registration calls below).
413 DCHECK(IsLocalStatePrefService(this));
414 RegisterPreference(
415 path,
416 Value::CreateStringValue(base::Int64ToString(default_value)),
417 UNSYNCABLE_PREF);
418}
419
420// Profile prefs (must use the sync_status variable).
421void PrefService::RegisterBooleanPref(const char* path,
422 bool default_value,
423 PrefSyncStatus sync_status) {
424 DCHECK(IsProfilePrefService(this));
425 RegisterPreference(path,
426 Value::CreateBooleanValue(default_value),
427 sync_status);
428}
429
430void PrefService::RegisterIntegerPref(const char* path,
431 int default_value,
432 PrefSyncStatus sync_status) {
433 DCHECK(IsProfilePrefService(this));
434 RegisterPreference(path,
435 Value::CreateIntegerValue(default_value),
436 sync_status);
437}
438
439void PrefService::RegisterDoublePref(const char* path,
440 double default_value,
441 PrefSyncStatus sync_status) {
442 DCHECK(IsProfilePrefService(this));
443 RegisterPreference(path,
444 Value::CreateDoubleValue(default_value),
445 sync_status);
446}
447
448void PrefService::RegisterStringPref(const char* path,
449 const std::string& default_value,
450 PrefSyncStatus sync_status) {
451 DCHECK(IsProfilePrefService(this));
452 RegisterPreference(path,
453 Value::CreateStringValue(default_value),
454 sync_status);
455}
456
457void PrefService::RegisterFilePathPref(const char* path,
458 const FilePath& default_value,
459 PrefSyncStatus sync_status) {
460 DCHECK(IsProfilePrefService(this));
461 RegisterPreference(path,
462 Value::CreateStringValue(default_value.value()),
463 sync_status);
464}
465
466void PrefService::RegisterListPref(const char* path,
467 PrefSyncStatus sync_status) {
468 DCHECK(IsProfilePrefService(this));
469 RegisterPreference(path, new ListValue(), sync_status);
470}
471
472void PrefService::RegisterListPref(const char* path,
473 ListValue* default_value,
474 PrefSyncStatus sync_status) {
475 DCHECK(IsProfilePrefService(this));
476 RegisterPreference(path, default_value, sync_status);
477}
478
479void PrefService::RegisterDictionaryPref(const char* path,
480 PrefSyncStatus sync_status) {
481 DCHECK(IsProfilePrefService(this));
482 RegisterPreference(path, new DictionaryValue(), sync_status);
483}
484
485void PrefService::RegisterDictionaryPref(const char* path,
486 DictionaryValue* default_value,
487 PrefSyncStatus sync_status) {
488 DCHECK(IsProfilePrefService(this));
489 RegisterPreference(path, default_value, sync_status);
490}
491
492void PrefService::RegisterLocalizedBooleanPref(const char* path,
493 int locale_default_message_id,
494 PrefSyncStatus sync_status) {
495 DCHECK(IsProfilePrefService(this));
496 RegisterPreference(
497 path,
[email protected]d3b05ea2012-01-24 22:57:05498 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
[email protected]d36f941b2011-05-09 06:19:16499 sync_status);
500}
501
502void PrefService::RegisterLocalizedIntegerPref(const char* path,
503 int locale_default_message_id,
504 PrefSyncStatus sync_status) {
505 DCHECK(IsProfilePrefService(this));
506 RegisterPreference(
507 path,
508 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
509 sync_status);
510}
511
512void PrefService::RegisterLocalizedDoublePref(const char* path,
513 int locale_default_message_id,
514 PrefSyncStatus sync_status) {
515 DCHECK(IsProfilePrefService(this));
516 RegisterPreference(
517 path,
518 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
519 sync_status);
520}
521
522void PrefService::RegisterLocalizedStringPref(const char* path,
523 int locale_default_message_id,
524 PrefSyncStatus sync_status) {
525 DCHECK(IsProfilePrefService(this));
526 RegisterPreference(
527 path,
528 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
529 sync_status);
530}
531
532void PrefService::RegisterInt64Pref(const char* path,
533 int64 default_value,
534 PrefSyncStatus sync_status) {
535 DCHECK(IsProfilePrefService(this));
536 RegisterPreference(
537 path,
538 Value::CreateStringValue(base::Int64ToString(default_value)),
539 sync_status);
initial.commit09911bf2008-07-26 23:55:29540}
541
[email protected]3cbe0812012-07-03 02:51:43542void PrefService::RegisterUint64Pref(const char* path,
543 uint64 default_value,
544 PrefSyncStatus sync_status) {
545 DCHECK(IsProfilePrefService(this));
546 RegisterPreference(
547 path,
548 Value::CreateStringValue(base::Uint64ToString(default_value)),
549 sync_status);
550}
551
[email protected]57ecc4b2010-08-11 03:02:51552bool PrefService::GetBoolean(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29553 DCHECK(CalledOnValidThread());
554
555 bool result = false;
initial.commit09911bf2008-07-26 23:55:29556
557 const Preference* pref = FindPreference(path);
558 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40559 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29560 return result;
561 }
562 bool rv = pref->GetValue()->GetAsBoolean(&result);
563 DCHECK(rv);
564 return result;
565}
566
[email protected]57ecc4b2010-08-11 03:02:51567int PrefService::GetInteger(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29568 DCHECK(CalledOnValidThread());
569
570 int result = 0;
initial.commit09911bf2008-07-26 23:55:29571
572 const Preference* pref = FindPreference(path);
573 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40574 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29575 return result;
576 }
577 bool rv = pref->GetValue()->GetAsInteger(&result);
578 DCHECK(rv);
579 return result;
580}
581
[email protected]fb534c92011-02-01 01:02:07582double PrefService::GetDouble(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29583 DCHECK(CalledOnValidThread());
584
585 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29586
587 const Preference* pref = FindPreference(path);
588 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40589 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29590 return result;
591 }
[email protected]fb534c92011-02-01 01:02:07592 bool rv = pref->GetValue()->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29593 DCHECK(rv);
594 return result;
595}
596
[email protected]57ecc4b2010-08-11 03:02:51597std::string PrefService::GetString(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29598 DCHECK(CalledOnValidThread());
599
[email protected]ddd231e2010-06-29 20:35:19600 std::string result;
[email protected]8e50b602009-03-03 22:59:43601
initial.commit09911bf2008-07-26 23:55:29602 const Preference* pref = FindPreference(path);
603 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40604 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29605 return result;
606 }
607 bool rv = pref->GetValue()->GetAsString(&result);
608 DCHECK(rv);
609 return result;
610}
611
[email protected]57ecc4b2010-08-11 03:02:51612FilePath PrefService::GetFilePath(const char* path) const {
[email protected]b9636002009-03-04 00:05:25613 DCHECK(CalledOnValidThread());
614
[email protected]68d9d352011-02-21 16:35:04615 FilePath result;
[email protected]b9636002009-03-04 00:05:25616
617 const Preference* pref = FindPreference(path);
618 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40619 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]b9636002009-03-04 00:05:25620 return FilePath(result);
621 }
[email protected]8703b2b2011-03-15 09:51:50622 bool rv = base::GetValueAsFilePath(*pref->GetValue(), &result);
[email protected]b9636002009-03-04 00:05:25623 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04624 return result;
[email protected]b9636002009-03-04 00:05:25625}
626
[email protected]57ecc4b2010-08-11 03:02:51627bool PrefService::HasPrefPath(const char* path) const {
[email protected]9a8c4022011-01-25 14:25:33628 const Preference* pref = FindPreference(path);
629 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29630}
631
[email protected]ebd0b022011-01-27 13:24:14632DictionaryValue* PrefService::GetPreferenceValues() const {
633 DCHECK(CalledOnValidThread());
634 DictionaryValue* out = new DictionaryValue;
635 DefaultPrefStore::const_iterator i = default_store_->begin();
636 for (; i != default_store_->end(); ++i) {
[email protected]8874e02172011-03-11 19:44:08637 const Preference* pref = FindPreference(i->first.c_str());
638 DCHECK(pref);
639 const Value* value = pref->GetValue();
640 DCHECK(value);
[email protected]ebd0b022011-01-27 13:24:14641 out->Set(i->first, value->DeepCopy());
642 }
643 return out;
644}
645
initial.commit09911bf2008-07-26 23:55:29646const PrefService::Preference* PrefService::FindPreference(
[email protected]57ecc4b2010-08-11 03:02:51647 const char* pref_name) const {
initial.commit09911bf2008-07-26 23:55:29648 DCHECK(CalledOnValidThread());
[email protected]9a8c4022011-01-25 14:25:33649 Preference p(this, pref_name, Value::TYPE_NULL);
initial.commit09911bf2008-07-26 23:55:29650 PreferenceSet::const_iterator it = prefs_.find(&p);
[email protected]9a8c4022011-01-25 14:25:33651 if (it != prefs_.end())
652 return *it;
[email protected]bab1c13f2011-08-12 20:59:02653 const base::Value::Type type = default_store_->GetType(pref_name);
[email protected]9a8c4022011-01-25 14:25:33654 if (type == Value::TYPE_NULL)
655 return NULL;
656 Preference* new_pref = new Preference(this, pref_name, type);
657 prefs_.insert(new_pref);
658 return new_pref;
initial.commit09911bf2008-07-26 23:55:29659}
660
[email protected]acd78969c2010-12-08 09:49:11661bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17662 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11663}
664
[email protected]59c10712012-03-13 02:10:34665PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
666 const {
667 if (!user_pref_store_->IsInitializationComplete())
668 return INITIALIZATION_STATUS_WAITING;
669
670 switch (user_pref_store_->GetReadError()) {
671 case PersistentPrefStore::PREF_READ_ERROR_NONE:
672 return INITIALIZATION_STATUS_SUCCESS;
673 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
674 return INITIALIZATION_STATUS_CREATED_NEW_PROFILE;
675 default:
676 return INITIALIZATION_STATUS_ERROR;
677 }
678}
679
[email protected]57ecc4b2010-08-11 03:02:51680bool PrefService::IsManagedPreference(const char* pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48681 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33682 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48683}
684
[email protected]d6bbd2932012-03-19 17:10:07685bool PrefService::IsUserModifiablePreference(const char* pref_name) const {
686 const Preference* pref = FindPreference(pref_name);
687 return pref && pref->IsUserModifiable();
688}
689
[email protected]57ecc4b2010-08-11 03:02:51690const DictionaryValue* PrefService::GetDictionary(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29691 DCHECK(CalledOnValidThread());
692
initial.commit09911bf2008-07-26 23:55:29693 const Preference* pref = FindPreference(path);
694 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40695 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29696 return NULL;
697 }
698 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25699 if (value->GetType() != Value::TYPE_DICTIONARY) {
700 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29701 return NULL;
[email protected]11b040b2011-02-02 12:42:25702 }
initial.commit09911bf2008-07-26 23:55:29703 return static_cast<const DictionaryValue*>(value);
704}
705
[email protected]1a5a31f2012-04-26 20:21:34706const base::Value* PrefService::GetUserPrefValue(const char* path) const {
707 DCHECK(CalledOnValidThread());
708
709 const Preference* pref = FindPreference(path);
710 if (!pref) {
711 NOTREACHED() << "Trying to get an unregistered pref: " << path;
712 return NULL;
713 }
714
715 // Look for an existing preference in the user store. If it doesn't
716 // exist, return NULL.
717 base::Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08718 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK)
[email protected]1a5a31f2012-04-26 20:21:34719 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34720
721 if (!value->IsType(pref->GetType())) {
722 NOTREACHED() << "Pref value type doesn't match registered type.";
723 return NULL;
724 }
725
726 return value;
727}
728
[email protected]35a6fd12012-05-28 18:08:08729const base::Value* PrefService::GetDefaultPrefValue(const char* path) const {
730 DCHECK(CalledOnValidThread());
731 // Lookup the preference in the default store.
732 const base::Value* value = NULL;
733 if (default_store_->GetValue(path, &value) != PrefStore::READ_OK) {
734 NOTREACHED() << "Default value missing for pref: " << path;
735 return NULL;
736 }
737 return value;
738}
739
[email protected]57ecc4b2010-08-11 03:02:51740const ListValue* PrefService::GetList(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29741 DCHECK(CalledOnValidThread());
742
initial.commit09911bf2008-07-26 23:55:29743 const Preference* pref = FindPreference(path);
744 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40745 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29746 return NULL;
747 }
748 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25749 if (value->GetType() != Value::TYPE_LIST) {
750 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29751 return NULL;
[email protected]11b040b2011-02-02 12:42:25752 }
initial.commit09911bf2008-07-26 23:55:29753 return static_cast<const ListValue*>(value);
754}
755
[email protected]57ecc4b2010-08-11 03:02:51756void PrefService::AddPrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53757 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50758 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29759}
760
[email protected]57ecc4b2010-08-11 03:02:51761void PrefService::RemovePrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53762 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50763 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29764}
765
[email protected]d36f941b2011-05-09 06:19:16766void PrefService::RegisterPreference(const char* path,
767 Value* default_value,
768 PrefSyncStatus sync_status) {
initial.commit09911bf2008-07-26 23:55:29769 DCHECK(CalledOnValidThread());
770
[email protected]c3b54f372010-09-14 08:25:07771 // The main code path takes ownership, but most don't. We'll be safe.
772 scoped_ptr<Value> scoped_value(default_value);
773
774 if (FindPreference(path)) {
775 NOTREACHED() << "Tried to register duplicate pref " << path;
initial.commit09911bf2008-07-26 23:55:29776 return;
777 }
[email protected]c3b54f372010-09-14 08:25:07778
[email protected]bab1c13f2011-08-12 20:59:02779 base::Value::Type orig_type = default_value->GetType();
[email protected]99cc9a02010-09-17 07:53:28780 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
781 "invalid preference type: " << orig_type;
782
[email protected]ea3e4972012-04-12 03:41:37783 // For ListValue and DictionaryValue with non empty default, empty value
784 // for |path| needs to be persisted in |user_pref_store_|. So that
785 // non empty default is not used when user sets an empty ListValue or
786 // DictionaryValue.
787 bool needs_empty_value = false;
788 if (orig_type == base::Value::TYPE_LIST) {
789 const base::ListValue* list = NULL;
790 if (default_value->GetAsList(&list) && !list->empty())
791 needs_empty_value = true;
792 } else if (orig_type == base::Value::TYPE_DICTIONARY) {
793 const base::DictionaryValue* dict = NULL;
794 if (default_value->GetAsDictionary(&dict) && !dict->empty())
795 needs_empty_value = true;
796 }
797 if (needs_empty_value)
798 user_pref_store_->MarkNeedsEmptyValue(path);
799
[email protected]9a8c4022011-01-25 14:25:33800 // Hand off ownership.
801 default_store_->SetDefaultValue(path, scoped_value.release());
[email protected]d36f941b2011-05-09 06:19:16802
803 // Register with sync if necessary.
804 if (sync_status == SYNCABLE_PREF && pref_sync_associator_.get())
805 pref_sync_associator_->RegisterPref(path);
initial.commit09911bf2008-07-26 23:55:29806}
807
[email protected]7a5f5932011-12-29 10:35:49808void PrefService::UnregisterPreference(const char* path) {
809 DCHECK(CalledOnValidThread());
810
811 Preference p(this, path, Value::TYPE_NULL);
[email protected]398007ce2012-01-05 19:25:50812 PreferenceSet::iterator it = prefs_.find(&p);
[email protected]7a5f5932011-12-29 10:35:49813 if (it == prefs_.end()) {
814 NOTREACHED() << "Trying to unregister an unregistered pref: " << path;
815 return;
816 }
817
[email protected]5a56d372011-12-29 11:34:40818 delete *it;
[email protected]7a5f5932011-12-29 10:35:49819 prefs_.erase(it);
820 default_store_->RemoveDefaultValue(path);
821 if (pref_sync_associator_.get() &&
822 pref_sync_associator_->IsPrefRegistered(path)) {
823 pref_sync_associator_->UnregisterPref(path);
824 }
825}
826
[email protected]57ecc4b2010-08-11 03:02:51827void PrefService::ClearPref(const char* path) {
initial.commit09911bf2008-07-26 23:55:29828 DCHECK(CalledOnValidThread());
829
830 const Preference* pref = FindPreference(path);
831 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40832 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29833 return;
834 }
[email protected]f2d1f612010-12-09 15:10:17835 user_pref_store_->RemoveValue(path);
initial.commit09911bf2008-07-26 23:55:29836}
837
[email protected]57ecc4b2010-08-11 03:02:51838void PrefService::Set(const char* path, const Value& value) {
[email protected]b99c41c2011-04-27 15:18:48839 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39840}
841
[email protected]57ecc4b2010-08-11 03:02:51842void PrefService::SetBoolean(const char* path, bool value) {
[email protected]c3b54f372010-09-14 08:25:07843 SetUserPrefValue(path, Value::CreateBooleanValue(value));
initial.commit09911bf2008-07-26 23:55:29844}
845
[email protected]57ecc4b2010-08-11 03:02:51846void PrefService::SetInteger(const char* path, int value) {
[email protected]c3b54f372010-09-14 08:25:07847 SetUserPrefValue(path, Value::CreateIntegerValue(value));
initial.commit09911bf2008-07-26 23:55:29848}
849
[email protected]fb534c92011-02-01 01:02:07850void PrefService::SetDouble(const char* path, double value) {
851 SetUserPrefValue(path, Value::CreateDoubleValue(value));
initial.commit09911bf2008-07-26 23:55:29852}
853
[email protected]57ecc4b2010-08-11 03:02:51854void PrefService::SetString(const char* path, const std::string& value) {
[email protected]c3b54f372010-09-14 08:25:07855 SetUserPrefValue(path, Value::CreateStringValue(value));
initial.commit09911bf2008-07-26 23:55:29856}
857
[email protected]57ecc4b2010-08-11 03:02:51858void PrefService::SetFilePath(const char* path, const FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50859 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25860}
861
[email protected]57ecc4b2010-08-11 03:02:51862void PrefService::SetInt64(const char* path, int64 value) {
[email protected]c3b54f372010-09-14 08:25:07863 SetUserPrefValue(path, Value::CreateStringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32864}
865
[email protected]57ecc4b2010-08-11 03:02:51866int64 PrefService::GetInt64(const char* path) const {
[email protected]0bb1a622009-03-04 03:22:32867 DCHECK(CalledOnValidThread());
868
[email protected]0bb1a622009-03-04 03:22:32869 const Preference* pref = FindPreference(path);
870 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40871 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08872 return 0;
[email protected]0bb1a622009-03-04 03:22:32873 }
[email protected]dc9a6762010-08-16 07:13:53874 std::string result("0");
[email protected]0bb1a622009-03-04 03:22:32875 bool rv = pref->GetValue()->GetAsString(&result);
876 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25877
878 int64 val;
[email protected]dc9a6762010-08-16 07:13:53879 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25880 return val;
[email protected]0bb1a622009-03-04 03:22:32881}
882
[email protected]3cbe0812012-07-03 02:51:43883void PrefService::SetUint64(const char* path, uint64 value) {
884 SetUserPrefValue(path, Value::CreateStringValue(base::Uint64ToString(value)));
885}
886
887uint64 PrefService::GetUint64(const char* path) const {
888 DCHECK(CalledOnValidThread());
889
890 const Preference* pref = FindPreference(path);
891 if (!pref) {
892 NOTREACHED() << "Trying to read an unregistered pref: " << path;
893 return 0;
894 }
895 std::string result("0");
896 bool rv = pref->GetValue()->GetAsString(&result);
897 DCHECK(rv);
898
899 uint64 val;
900 base::StringToUint64(result, &val);
901 return val;
902}
903
[email protected]26418b72011-03-30 14:07:39904Value* PrefService::GetMutableUserPref(const char* path,
[email protected]bab1c13f2011-08-12 20:59:02905 base::Value::Type type) {
[email protected]26418b72011-03-30 14:07:39906 CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29907 DCHECK(CalledOnValidThread());
908
909 const Preference* pref = FindPreference(path);
910 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40911 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29912 return NULL;
913 }
[email protected]26418b72011-03-30 14:07:39914 if (pref->GetType() != type) {
915 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29916 return NULL;
917 }
918
[email protected]e0250892010-10-01 18:57:53919 // Look for an existing preference in the user store. If it doesn't
920 // exist or isn't the correct type, create a new user preference.
[email protected]26418b72011-03-30 14:07:39921 Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08922 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK ||
[email protected]26418b72011-03-30 14:07:39923 !value->IsType(type)) {
924 if (type == Value::TYPE_DICTIONARY) {
925 value = new DictionaryValue;
926 } else if (type == Value::TYPE_LIST) {
927 value = new ListValue;
928 } else {
929 NOTREACHED();
930 }
931 user_pref_store_->SetValueSilently(path, value);
initial.commit09911bf2008-07-26 23:55:29932 }
[email protected]26418b72011-03-30 14:07:39933 return value;
934}
935
[email protected]68bf41a2011-03-25 16:38:31936void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]f89ee342011-03-07 09:28:27937 user_pref_store_->ReportValueChanged(key);
938}
939
[email protected]c3b54f372010-09-14 08:25:07940void PrefService::SetUserPrefValue(const char* path, Value* new_value) {
[email protected]b99c41c2011-04-27 15:18:48941 scoped_ptr<Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07942 DCHECK(CalledOnValidThread());
943
944 const Preference* pref = FindPreference(path);
945 if (!pref) {
946 NOTREACHED() << "Trying to write an unregistered pref: " << path;
947 return;
948 }
[email protected]99cc9a02010-09-17 07:53:28949 if (pref->GetType() != new_value->GetType()) {
950 NOTREACHED() << "Trying to set pref " << path
951 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07952 << " to value of type " << new_value->GetType();
953 return;
954 }
955
[email protected]b99c41c2011-04-27 15:18:48956 user_pref_store_->SetValue(path, owned_value.release());
[email protected]73c47932010-12-06 18:13:43957}
958
[email protected]65f173552012-06-28 22:43:58959syncer::SyncableService* PrefService::GetSyncableService() {
[email protected]d36f941b2011-05-09 06:19:16960 return pref_sync_associator_.get();
961}
962
[email protected]d3b05ea2012-01-24 22:57:05963void PrefService::UpdateCommandLinePrefStore(CommandLine* command_line) {
964 // If |pref_service_forked_| is true, then this PrefService and the forked
965 // copies will be out of sync.
966 DCHECK(!pref_service_forked_);
967 pref_value_store_->UpdateCommandLinePrefStore(
968 new CommandLinePrefStore(command_line));
969}
970
initial.commit09911bf2008-07-26 23:55:29971///////////////////////////////////////////////////////////////////////////////
972// PrefService::Preference
973
[email protected]c3b54f372010-09-14 08:25:07974PrefService::Preference::Preference(const PrefService* service,
[email protected]9a8c4022011-01-25 14:25:33975 const char* name,
[email protected]bab1c13f2011-08-12 20:59:02976 base::Value::Type type)
[email protected]99cc9a02010-09-17 07:53:28977 : name_(name),
[email protected]9a8c4022011-01-25 14:25:33978 type_(type),
[email protected]c3b54f372010-09-14 08:25:07979 pref_service_(service) {
initial.commit09911bf2008-07-26 23:55:29980 DCHECK(name);
[email protected]c3b54f372010-09-14 08:25:07981 DCHECK(service);
[email protected]99cc9a02010-09-17 07:53:28982}
983
[email protected]fb8fdf12012-08-21 16:28:20984const std::string PrefService::Preference::name() const {
985 return name_;
986}
987
[email protected]bab1c13f2011-08-12 20:59:02988base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33989 return type_;
initial.commit09911bf2008-07-26 23:55:29990}
991
992const Value* PrefService::Preference::GetValue() const {
[email protected]c3b54f372010-09-14 08:25:07993 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
initial.commit09911bf2008-07-26 23:55:29994 "Must register pref before getting its value";
995
[email protected]68bf41a2011-03-25 16:38:31996 const Value* found_value = NULL;
[email protected]887288f02011-02-04 22:52:46997 if (pref_value_store()->GetValue(name_, type_, &found_value)) {
[email protected]9a8c4022011-01-25 14:25:33998 DCHECK(found_value->IsType(type_));
[email protected]99cc9a02010-09-17 07:53:28999 return found_value;
[email protected]9a8c4022011-01-25 14:25:331000 }
initial.commit09911bf2008-07-26 23:55:291001
[email protected]c3b54f372010-09-14 08:25:071002 // Every registered preference has at least a default value.
[email protected]99cc9a02010-09-17 07:53:281003 NOTREACHED() << "no valid value found for registered pref " << name_;
[email protected]c3b54f372010-09-14 08:25:071004 return NULL;
[email protected]40a47c162010-09-09 11:14:011005}
1006
[email protected]7ca0f362012-07-30 10:14:031007const Value* PrefService::Preference::GetRecommendedValue() const {
1008 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
1009 "Must register pref before getting its value";
1010
1011 const Value* found_value = NULL;
1012 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
1013 DCHECK(found_value->IsType(type_));
1014 return found_value;
1015 }
1016
1017 // The pref has no recommended value.
1018 return NULL;
1019}
1020
[email protected]40a47c162010-09-09 11:14:011021bool PrefService::Preference::IsManaged() const {
[email protected]887288f02011-02-04 22:52:461022 return pref_value_store()->PrefValueInManagedStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011023}
1024
[email protected]a5437282011-12-12 12:33:211025bool PrefService::Preference::IsRecommended() const {
1026 return pref_value_store()->PrefValueFromRecommendedStore(name_.c_str());
1027}
1028
[email protected]40a47c162010-09-09 11:14:011029bool PrefService::Preference::HasExtensionSetting() const {
[email protected]887288f02011-02-04 22:52:461030 return pref_value_store()->PrefValueInExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011031}
1032
1033bool PrefService::Preference::HasUserSetting() const {
[email protected]887288f02011-02-04 22:52:461034 return pref_value_store()->PrefValueInUserStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011035}
1036
1037bool PrefService::Preference::IsExtensionControlled() const {
[email protected]887288f02011-02-04 22:52:461038 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011039}
1040
1041bool PrefService::Preference::IsUserControlled() const {
[email protected]887288f02011-02-04 22:52:461042 return pref_value_store()->PrefValueFromUserStore(name_.c_str());
[email protected]c3b54f372010-09-14 08:25:071043}
1044
1045bool PrefService::Preference::IsDefaultValue() const {
[email protected]887288f02011-02-04 22:52:461046 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str());
[email protected]d7449e82010-07-14 11:42:351047}
[email protected]74379bc52010-07-21 13:54:081048
1049bool PrefService::Preference::IsUserModifiable() const {
[email protected]887288f02011-02-04 22:52:461050 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
[email protected]74379bc52010-07-21 13:54:081051}
[email protected]9a28f132011-02-24 21:15:161052
1053bool PrefService::Preference::IsExtensionModifiable() const {
1054 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
1055}