blob: 48c255b78e734190a9ac8ee1f3846634f6272b71 [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]32c3c752012-01-05 17:33:4730#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
[email protected]c7fb2da32011-04-14 20:47:1031#include "chrome/browser/ui/profile_error_dialog.h"
[email protected]e4f86492011-04-13 12:23:5332#include "chrome/common/json_pref_store.h"
[email protected]32c3c752012-01-05 17:33:4733#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4934#include "content/public/browser/browser_thread.h"
[email protected]ba399672010-04-06 15:42:3935#include "grit/chromium_strings.h"
[email protected]34ac8f32009-02-22 23:03:2736#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1737#include "ui/base/l10n/l10n_util.h"
initial.commit09911bf2008-07-26 23:55:2938
[email protected]631bb742011-11-02 11:29:3939using content::BrowserThread;
40
initial.commit09911bf2008-07-26 23:55:2941namespace {
42
initial.commit09911bf2008-07-26 23:55:2943// A helper function for RegisterLocalized*Pref that creates a Value* based on
44// the string value in the locale dll. Because we control the values in a
45// locale dll, this should always return a Value of the appropriate type.
[email protected]bab1c13f2011-08-12 20:59:0246Value* CreateLocaleDefaultValue(base::Value::Type type, int message_id) {
[email protected]16b527162010-08-15 18:37:1047 std::string resource_string = l10n_util::GetStringUTF8(message_id);
initial.commit09911bf2008-07-26 23:55:2948 DCHECK(!resource_string.empty());
49 switch (type) {
50 case Value::TYPE_BOOLEAN: {
[email protected]16b527162010-08-15 18:37:1051 if ("true" == resource_string)
initial.commit09911bf2008-07-26 23:55:2952 return Value::CreateBooleanValue(true);
[email protected]16b527162010-08-15 18:37:1053 if ("false" == resource_string)
initial.commit09911bf2008-07-26 23:55:2954 return Value::CreateBooleanValue(false);
55 break;
56 }
57
58 case Value::TYPE_INTEGER: {
[email protected]e83326f2010-07-31 17:29:2559 int val;
[email protected]16b527162010-08-15 18:37:1060 base::StringToInt(resource_string, &val);
[email protected]e83326f2010-07-31 17:29:2561 return Value::CreateIntegerValue(val);
initial.commit09911bf2008-07-26 23:55:2962 }
63
[email protected]fb534c92011-02-01 01:02:0764 case Value::TYPE_DOUBLE: {
[email protected]e83326f2010-07-31 17:29:2565 double val;
[email protected]16b527162010-08-15 18:37:1066 base::StringToDouble(resource_string, &val);
[email protected]fb534c92011-02-01 01:02:0767 return Value::CreateDoubleValue(val);
initial.commit09911bf2008-07-26 23:55:2968 }
69
70 case Value::TYPE_STRING: {
71 return Value::CreateStringValue(resource_string);
initial.commit09911bf2008-07-26 23:55:2972 }
73
74 default: {
[email protected]b154e6f2009-03-06 01:52:4075 NOTREACHED() <<
[email protected]c3b54f372010-09-14 08:25:0776 "list and dictionary types cannot have default locale values";
initial.commit09911bf2008-07-26 23:55:2977 }
78 }
79 NOTREACHED();
80 return Value::CreateNullValue();
81}
82
[email protected]ba399672010-04-06 15:42:3983// Forwards a notification after a PostMessage so that we can wait for the
84// MessageLoop to run.
[email protected]845b43a82011-05-11 10:14:4385void NotifyReadError(int message_id) {
[email protected]c7fb2da32011-04-14 20:47:1086 ShowProfileErrorDialog(message_id);
[email protected]ba399672010-04-06 15:42:3987}
88
[email protected]845b43a82011-05-11 10:14:4389// Shows notifications which correspond to PersistentPrefStore's reading errors.
90class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
91 public:
92 virtual void OnError(PersistentPrefStore::PrefReadError error) {
93 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
94 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
95 // an example problem that this can cause.
96 // Do some diagnosis and try to avoid losing data.
97 int message_id = 0;
98 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
99 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
100 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
101 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
102 }
103
104 if (message_id) {
105 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45106 base::Bind(&NotifyReadError, message_id));
[email protected]845b43a82011-05-11 10:14:43107 }
[email protected]ff3c69a2011-09-15 00:36:48108 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
109 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
[email protected]845b43a82011-05-11 10:14:43110 }
111 }
112};
113
initial.commit09911bf2008-07-26 23:55:29114} // namespace
115
[email protected]db198b22010-07-12 16:48:49116// static
[email protected]21d3a882012-05-31 14:41:55117PrefService* PrefService::CreatePrefService(
118 const FilePath& pref_filename,
119 policy::PolicyService* policy_service,
120 PrefStore* extension_prefs,
121 bool async) {
[email protected]acd78969c2010-12-08 09:49:11122 using policy::ConfigurationPolicyPrefStore;
123
[email protected]1d01d412010-08-20 00:36:01124#if defined(OS_LINUX)
125 // We'd like to see what fraction of our users have the preferences
126 // stored on a network file system, as we've had no end of troubles
127 // with NFS/AFS.
128 // TODO(evanm): remove this once we've collected state.
129 file_util::FileSystemType fstype;
130 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
131 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
132 static_cast<int>(fstype),
133 file_util::FILE_SYSTEM_TYPE_COUNT);
134 }
135#endif
136
[email protected]f31e2e52011-07-14 16:01:19137#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]4eb4d6ce2012-04-02 14:06:57138 ConfigurationPolicyPrefStore* managed =
[email protected]21d3a882012-05-31 14:41:55139 ConfigurationPolicyPrefStore::CreateMandatoryPolicyPrefStore(
140 policy_service);
[email protected]4eb4d6ce2012-04-02 14:06:57141 ConfigurationPolicyPrefStore* recommended =
[email protected]21d3a882012-05-31 14:41:55142 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(
143 policy_service);
[email protected]f31e2e52011-07-14 16:01:19144#else
[email protected]4eb4d6ce2012-04-02 14:06:57145 ConfigurationPolicyPrefStore* managed = NULL;
146 ConfigurationPolicyPrefStore* recommended = NULL;
[email protected]f31e2e52011-07-14 16:01:19147#endif // ENABLE_CONFIGURATION_POLICY
148
[email protected]acd78969c2010-12-08 09:49:11149 CommandLinePrefStore* command_line =
150 new CommandLinePrefStore(CommandLine::ForCurrentProcess());
[email protected]370bc732012-05-07 21:25:20151 JsonPrefStore* user = new JsonPrefStore(
152 pref_filename,
153 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
[email protected]9a8c4022011-01-25 14:25:33154 DefaultPrefStore* default_pref_store = new DefaultPrefStore();
[email protected]acd78969c2010-12-08 09:49:11155
[email protected]361d37f62011-11-22 10:37:02156 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
157 PrefModelAssociator* pref_sync_associator = new PrefModelAssociator();
158
[email protected]845b43a82011-05-11 10:14:43159 return new PrefService(
[email protected]361d37f62011-11-22 10:37:02160 pref_notifier,
161 new PrefValueStore(
[email protected]4eb4d6ce2012-04-02 14:06:57162 managed,
[email protected]361d37f62011-11-22 10:37:02163 extension_prefs,
164 command_line,
165 user,
[email protected]4eb4d6ce2012-04-02 14:06:57166 recommended,
[email protected]361d37f62011-11-22 10:37:02167 default_pref_store,
168 pref_sync_associator,
169 pref_notifier),
170 user,
171 default_pref_store,
172 pref_sync_associator,
173 async);
[email protected]9a8c4022011-01-25 14:25:33174}
175
176PrefService* PrefService::CreateIncognitoPrefService(
177 PrefStore* incognito_extension_prefs) {
[email protected]d3b05ea2012-01-24 22:57:05178 pref_service_forked_ = true;
[email protected]361d37f62011-11-22 10:37:02179 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
[email protected]32c3c752012-01-05 17:33:47180 OverlayUserPrefStore* incognito_pref_store =
181 new OverlayUserPrefStore(user_pref_store_.get());
182 PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store);
[email protected]361d37f62011-11-22 10:37:02183 return new PrefService(
184 pref_notifier,
185 pref_value_store_->CloneAndSpecialize(
[email protected]4eb4d6ce2012-04-02 14:06:57186 NULL, // managed
[email protected]361d37f62011-11-22 10:37:02187 incognito_extension_prefs,
[email protected]d3b05ea2012-01-24 22:57:05188 NULL, // command_line_prefs
[email protected]361d37f62011-11-22 10:37:02189 incognito_pref_store,
[email protected]4eb4d6ce2012-04-02 14:06:57190 NULL, // recommended
[email protected]361d37f62011-11-22 10:37:02191 default_store_.get(),
[email protected]d3b05ea2012-01-24 22:57:05192 NULL, // pref_sync_associator
[email protected]361d37f62011-11-22 10:37:02193 pref_notifier),
194 incognito_pref_store,
[email protected]9a8c4022011-01-25 14:25:33195 default_store_.get(),
[email protected]361d37f62011-11-22 10:37:02196 NULL,
197 false);
198}
199
[email protected]361d37f62011-11-22 10:37:02200PrefService::PrefService(PrefNotifierImpl* pref_notifier,
201 PrefValueStore* pref_value_store,
202 PersistentPrefStore* user_prefs,
203 DefaultPrefStore* default_store,
204 PrefModelAssociator* pref_sync_associator,
205 bool async)
206 : pref_notifier_(pref_notifier),
207 pref_value_store_(pref_value_store),
208 user_pref_store_(user_prefs),
209 default_store_(default_store),
[email protected]d3b05ea2012-01-24 22:57:05210 pref_sync_associator_(pref_sync_associator),
211 pref_service_forked_(false) {
[email protected]361d37f62011-11-22 10:37:02212 pref_notifier_->SetPrefService(this);
213 if (pref_sync_associator_.get())
214 pref_sync_associator_->SetPrefService(this);
215 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:33216}
217
initial.commit09911bf2008-07-26 23:55:29218PrefService::~PrefService() {
219 DCHECK(CalledOnValidThread());
initial.commit09911bf2008-07-26 23:55:29220 STLDeleteContainerPointers(prefs_.begin(), prefs_.end());
221 prefs_.clear();
[email protected]a98ce1262011-01-28 13:20:23222
223 // Reset pointers so accesses after destruction reliably crash.
224 pref_value_store_.reset();
225 user_pref_store_ = NULL;
226 default_store_ = NULL;
[email protected]d36f941b2011-05-09 06:19:16227 pref_sync_associator_.reset();
initial.commit09911bf2008-07-26 23:55:29228}
229
[email protected]845b43a82011-05-11 10:14:43230void PrefService::InitFromStorage(bool async) {
231 if (!async) {
232 ReadErrorHandler error_handler;
233 error_handler.OnError(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:21234 } else {
[email protected]845b43a82011-05-11 10:14:43235 // Guarantee that initialization happens after this function returned.
236 MessageLoop::current()->PostTask(
237 FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45238 base::Bind(&PersistentPrefStore::ReadPrefsAsync,
239 user_pref_store_.get(),
240 new ReadErrorHandler()));
[email protected]844a1002011-04-19 11:37:21241 }
[email protected]ba399672010-04-06 15:42:39242}
243
244bool PrefService::ReloadPersistentPrefs() {
[email protected]f2d1f612010-12-09 15:10:17245 return user_pref_store_->ReadPrefs() ==
246 PersistentPrefStore::PREF_READ_ERROR_NONE;
initial.commit09911bf2008-07-26 23:55:29247}
248
[email protected]3826fed2011-03-25 10:59:56249void PrefService::CommitPendingWrite() {
250 DCHECK(CalledOnValidThread());
251 user_pref_store_->CommitPendingWrite();
252}
253
[email protected]d36f941b2011-05-09 06:19:16254namespace {
255
256// If there's no g_browser_process or no local state, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05257bool IsLocalStatePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16258 return (!g_browser_process ||
259 !g_browser_process->local_state() ||
260 g_browser_process->local_state() == prefs);
261}
262
263// If there's no g_browser_process, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05264bool IsProfilePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16265 // TODO(zea): uncomment this once all preferences are only ever registered
266 // with either the local_state's pref service or the profile's pref service.
267 // return (!g_browser_process || g_browser_process->local_state() != prefs);
268 return true;
269}
270
271} // namespace
272
273
274// Local State prefs.
[email protected]57ecc4b2010-08-11 03:02:51275void PrefService::RegisterBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29276 bool default_value) {
[email protected]d36f941b2011-05-09 06:19:16277 // If this fails, the pref service in use is a profile pref service, so the
278 // sync status must be provided (see profile pref registration calls below).
279 DCHECK(IsLocalStatePrefService(this));
280 RegisterPreference(path,
281 Value::CreateBooleanValue(default_value),
282 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29283}
284
[email protected]57ecc4b2010-08-11 03:02:51285void PrefService::RegisterIntegerPref(const char* path, int default_value) {
[email protected]d36f941b2011-05-09 06:19:16286 // If this fails, the pref service in use is a profile pref service, so the
287 // sync status must be provided (see profile pref registration calls below).
288 DCHECK(IsLocalStatePrefService(this));
289 RegisterPreference(path,
290 Value::CreateIntegerValue(default_value),
291 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29292}
293
[email protected]fb534c92011-02-01 01:02:07294void PrefService::RegisterDoublePref(const char* path, double default_value) {
[email protected]d36f941b2011-05-09 06:19:16295 // If this fails, the pref service in use is a profile pref service, so the
296 // sync status must be provided (see profile pref registration calls below).
297 DCHECK(IsLocalStatePrefService(this));
298 RegisterPreference(path,
299 Value::CreateDoubleValue(default_value),
300 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29301}
302
[email protected]57ecc4b2010-08-11 03:02:51303void PrefService::RegisterStringPref(const char* path,
[email protected]20ce516d2010-06-18 02:20:04304 const std::string& default_value) {
[email protected]d36f941b2011-05-09 06:19:16305 // If this fails, the pref service in use is a profile pref service, so the
306 // sync status must be provided (see profile pref registration calls below).
307 DCHECK(IsLocalStatePrefService(this));
308 RegisterPreference(path,
309 Value::CreateStringValue(default_value),
310 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29311}
312
[email protected]57ecc4b2010-08-11 03:02:51313void PrefService::RegisterFilePathPref(const char* path,
[email protected]b9636002009-03-04 00:05:25314 const FilePath& default_value) {
[email protected]d36f941b2011-05-09 06:19:16315 // If this fails, the pref service in use is a profile pref service, so the
316 // sync status must be provided (see profile pref registration calls below).
317 DCHECK(IsLocalStatePrefService(this));
318 RegisterPreference(path,
319 Value::CreateStringValue(default_value.value()),
320 UNSYNCABLE_PREF);
[email protected]b9636002009-03-04 00:05:25321}
322
[email protected]57ecc4b2010-08-11 03:02:51323void PrefService::RegisterListPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16324 // If this fails, the pref service in use is a profile pref service, so the
325 // sync status must be provided (see profile pref registration calls below).
326 DCHECK(IsLocalStatePrefService(this));
327 RegisterPreference(path,
328 new ListValue(),
329 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29330}
331
[email protected]c2f23d012011-02-09 14:52:17332void PrefService::RegisterListPref(const char* path, ListValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16333 // If this fails, the pref service in use is a profile pref service, so the
334 // sync status must be provided (see profile pref registration calls below).
335 DCHECK(IsLocalStatePrefService(this));
336 RegisterPreference(path,
337 default_value,
338 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17339}
340
[email protected]57ecc4b2010-08-11 03:02:51341void PrefService::RegisterDictionaryPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16342 // If this fails, the pref service in use is a profile pref service, so the
343 // sync status must be provided (see profile pref registration calls below).
344 DCHECK(IsLocalStatePrefService(this));
345 RegisterPreference(path,
346 new DictionaryValue(),
347 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29348}
349
[email protected]c2f23d012011-02-09 14:52:17350void PrefService::RegisterDictionaryPref(const char* path,
351 DictionaryValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16352 // If this fails, the pref service in use is a profile pref service, so the
353 // sync status must be provided (see profile pref registration calls below).
354 DCHECK(IsLocalStatePrefService(this));
355 RegisterPreference(path,
356 default_value,
357 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17358}
359
[email protected]57ecc4b2010-08-11 03:02:51360void PrefService::RegisterLocalizedBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29361 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16362 // If this fails, the pref service in use is a profile pref service, so the
363 // sync status must be provided (see profile pref registration calls below).
364 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07365 RegisterPreference(
366 path,
[email protected]d36f941b2011-05-09 06:19:16367 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
368 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29369}
370
[email protected]57ecc4b2010-08-11 03:02:51371void PrefService::RegisterLocalizedIntegerPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29372 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16373 // If this fails, the pref service in use is a profile pref service, so the
374 // sync status must be provided (see profile pref registration calls below).
375 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07376 RegisterPreference(
377 path,
[email protected]d36f941b2011-05-09 06:19:16378 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
379 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29380}
381
[email protected]fb534c92011-02-01 01:02:07382void PrefService::RegisterLocalizedDoublePref(const char* path,
383 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16384 // If this fails, the pref service in use is a profile pref service, so the
385 // sync status must be provided (see profile pref registration calls below).
386 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07387 RegisterPreference(
388 path,
[email protected]d36f941b2011-05-09 06:19:16389 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
390 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29391}
392
[email protected]57ecc4b2010-08-11 03:02:51393void PrefService::RegisterLocalizedStringPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29394 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16395 // If this fails, the pref service in use is a profile pref service, so the
396 // sync status must be provided (see profile pref registration calls below).
397 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07398 RegisterPreference(
399 path,
[email protected]d36f941b2011-05-09 06:19:16400 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
401 UNSYNCABLE_PREF);
402}
403
404void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
405 // If this fails, the pref service in use is a profile pref service, so the
406 // sync status must be provided (see profile pref registration calls below).
407 DCHECK(IsLocalStatePrefService(this));
408 RegisterPreference(
409 path,
410 Value::CreateStringValue(base::Int64ToString(default_value)),
411 UNSYNCABLE_PREF);
412}
413
414// Profile prefs (must use the sync_status variable).
415void PrefService::RegisterBooleanPref(const char* path,
416 bool default_value,
417 PrefSyncStatus sync_status) {
418 DCHECK(IsProfilePrefService(this));
419 RegisterPreference(path,
420 Value::CreateBooleanValue(default_value),
421 sync_status);
422}
423
424void PrefService::RegisterIntegerPref(const char* path,
425 int default_value,
426 PrefSyncStatus sync_status) {
427 DCHECK(IsProfilePrefService(this));
428 RegisterPreference(path,
429 Value::CreateIntegerValue(default_value),
430 sync_status);
431}
432
433void PrefService::RegisterDoublePref(const char* path,
434 double default_value,
435 PrefSyncStatus sync_status) {
436 DCHECK(IsProfilePrefService(this));
437 RegisterPreference(path,
438 Value::CreateDoubleValue(default_value),
439 sync_status);
440}
441
442void PrefService::RegisterStringPref(const char* path,
443 const std::string& default_value,
444 PrefSyncStatus sync_status) {
445 DCHECK(IsProfilePrefService(this));
446 RegisterPreference(path,
447 Value::CreateStringValue(default_value),
448 sync_status);
449}
450
451void PrefService::RegisterFilePathPref(const char* path,
452 const FilePath& default_value,
453 PrefSyncStatus sync_status) {
454 DCHECK(IsProfilePrefService(this));
455 RegisterPreference(path,
456 Value::CreateStringValue(default_value.value()),
457 sync_status);
458}
459
460void PrefService::RegisterListPref(const char* path,
461 PrefSyncStatus sync_status) {
462 DCHECK(IsProfilePrefService(this));
463 RegisterPreference(path, new ListValue(), sync_status);
464}
465
466void PrefService::RegisterListPref(const char* path,
467 ListValue* default_value,
468 PrefSyncStatus sync_status) {
469 DCHECK(IsProfilePrefService(this));
470 RegisterPreference(path, default_value, sync_status);
471}
472
473void PrefService::RegisterDictionaryPref(const char* path,
474 PrefSyncStatus sync_status) {
475 DCHECK(IsProfilePrefService(this));
476 RegisterPreference(path, new DictionaryValue(), sync_status);
477}
478
479void PrefService::RegisterDictionaryPref(const char* path,
480 DictionaryValue* default_value,
481 PrefSyncStatus sync_status) {
482 DCHECK(IsProfilePrefService(this));
483 RegisterPreference(path, default_value, sync_status);
484}
485
486void PrefService::RegisterLocalizedBooleanPref(const char* path,
487 int locale_default_message_id,
488 PrefSyncStatus sync_status) {
489 DCHECK(IsProfilePrefService(this));
490 RegisterPreference(
491 path,
[email protected]d3b05ea2012-01-24 22:57:05492 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
[email protected]d36f941b2011-05-09 06:19:16493 sync_status);
494}
495
496void PrefService::RegisterLocalizedIntegerPref(const char* path,
497 int locale_default_message_id,
498 PrefSyncStatus sync_status) {
499 DCHECK(IsProfilePrefService(this));
500 RegisterPreference(
501 path,
502 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
503 sync_status);
504}
505
506void PrefService::RegisterLocalizedDoublePref(const char* path,
507 int locale_default_message_id,
508 PrefSyncStatus sync_status) {
509 DCHECK(IsProfilePrefService(this));
510 RegisterPreference(
511 path,
512 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
513 sync_status);
514}
515
516void PrefService::RegisterLocalizedStringPref(const char* path,
517 int locale_default_message_id,
518 PrefSyncStatus sync_status) {
519 DCHECK(IsProfilePrefService(this));
520 RegisterPreference(
521 path,
522 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
523 sync_status);
524}
525
526void PrefService::RegisterInt64Pref(const char* path,
527 int64 default_value,
528 PrefSyncStatus sync_status) {
529 DCHECK(IsProfilePrefService(this));
530 RegisterPreference(
531 path,
532 Value::CreateStringValue(base::Int64ToString(default_value)),
533 sync_status);
initial.commit09911bf2008-07-26 23:55:29534}
535
[email protected]57ecc4b2010-08-11 03:02:51536bool PrefService::GetBoolean(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29537 DCHECK(CalledOnValidThread());
538
539 bool result = false;
initial.commit09911bf2008-07-26 23:55:29540
541 const Preference* pref = FindPreference(path);
542 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40543 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29544 return result;
545 }
546 bool rv = pref->GetValue()->GetAsBoolean(&result);
547 DCHECK(rv);
548 return result;
549}
550
[email protected]57ecc4b2010-08-11 03:02:51551int PrefService::GetInteger(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29552 DCHECK(CalledOnValidThread());
553
554 int result = 0;
initial.commit09911bf2008-07-26 23:55:29555
556 const Preference* pref = FindPreference(path);
557 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40558 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29559 return result;
560 }
561 bool rv = pref->GetValue()->GetAsInteger(&result);
562 DCHECK(rv);
563 return result;
564}
565
[email protected]fb534c92011-02-01 01:02:07566double PrefService::GetDouble(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29567 DCHECK(CalledOnValidThread());
568
569 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29570
571 const Preference* pref = FindPreference(path);
572 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40573 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29574 return result;
575 }
[email protected]fb534c92011-02-01 01:02:07576 bool rv = pref->GetValue()->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29577 DCHECK(rv);
578 return result;
579}
580
[email protected]57ecc4b2010-08-11 03:02:51581std::string PrefService::GetString(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29582 DCHECK(CalledOnValidThread());
583
[email protected]ddd231e2010-06-29 20:35:19584 std::string result;
[email protected]8e50b602009-03-03 22:59:43585
initial.commit09911bf2008-07-26 23:55:29586 const Preference* pref = FindPreference(path);
587 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40588 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29589 return result;
590 }
591 bool rv = pref->GetValue()->GetAsString(&result);
592 DCHECK(rv);
593 return result;
594}
595
[email protected]57ecc4b2010-08-11 03:02:51596FilePath PrefService::GetFilePath(const char* path) const {
[email protected]b9636002009-03-04 00:05:25597 DCHECK(CalledOnValidThread());
598
[email protected]68d9d352011-02-21 16:35:04599 FilePath result;
[email protected]b9636002009-03-04 00:05:25600
601 const Preference* pref = FindPreference(path);
602 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40603 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]b9636002009-03-04 00:05:25604 return FilePath(result);
605 }
[email protected]8703b2b2011-03-15 09:51:50606 bool rv = base::GetValueAsFilePath(*pref->GetValue(), &result);
[email protected]b9636002009-03-04 00:05:25607 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04608 return result;
[email protected]b9636002009-03-04 00:05:25609}
610
[email protected]57ecc4b2010-08-11 03:02:51611bool PrefService::HasPrefPath(const char* path) const {
[email protected]9a8c4022011-01-25 14:25:33612 const Preference* pref = FindPreference(path);
613 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29614}
615
[email protected]ebd0b022011-01-27 13:24:14616DictionaryValue* PrefService::GetPreferenceValues() const {
617 DCHECK(CalledOnValidThread());
618 DictionaryValue* out = new DictionaryValue;
619 DefaultPrefStore::const_iterator i = default_store_->begin();
620 for (; i != default_store_->end(); ++i) {
[email protected]8874e02172011-03-11 19:44:08621 const Preference* pref = FindPreference(i->first.c_str());
622 DCHECK(pref);
623 const Value* value = pref->GetValue();
624 DCHECK(value);
[email protected]ebd0b022011-01-27 13:24:14625 out->Set(i->first, value->DeepCopy());
626 }
627 return out;
628}
629
initial.commit09911bf2008-07-26 23:55:29630const PrefService::Preference* PrefService::FindPreference(
[email protected]57ecc4b2010-08-11 03:02:51631 const char* pref_name) const {
initial.commit09911bf2008-07-26 23:55:29632 DCHECK(CalledOnValidThread());
[email protected]9a8c4022011-01-25 14:25:33633 Preference p(this, pref_name, Value::TYPE_NULL);
initial.commit09911bf2008-07-26 23:55:29634 PreferenceSet::const_iterator it = prefs_.find(&p);
[email protected]9a8c4022011-01-25 14:25:33635 if (it != prefs_.end())
636 return *it;
[email protected]bab1c13f2011-08-12 20:59:02637 const base::Value::Type type = default_store_->GetType(pref_name);
[email protected]9a8c4022011-01-25 14:25:33638 if (type == Value::TYPE_NULL)
639 return NULL;
640 Preference* new_pref = new Preference(this, pref_name, type);
641 prefs_.insert(new_pref);
642 return new_pref;
initial.commit09911bf2008-07-26 23:55:29643}
644
[email protected]acd78969c2010-12-08 09:49:11645bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17646 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11647}
648
[email protected]59c10712012-03-13 02:10:34649PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
650 const {
651 if (!user_pref_store_->IsInitializationComplete())
652 return INITIALIZATION_STATUS_WAITING;
653
654 switch (user_pref_store_->GetReadError()) {
655 case PersistentPrefStore::PREF_READ_ERROR_NONE:
656 return INITIALIZATION_STATUS_SUCCESS;
657 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
658 return INITIALIZATION_STATUS_CREATED_NEW_PROFILE;
659 default:
660 return INITIALIZATION_STATUS_ERROR;
661 }
662}
663
[email protected]57ecc4b2010-08-11 03:02:51664bool PrefService::IsManagedPreference(const char* pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48665 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33666 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48667}
668
[email protected]d6bbd2932012-03-19 17:10:07669bool PrefService::IsUserModifiablePreference(const char* pref_name) const {
670 const Preference* pref = FindPreference(pref_name);
671 return pref && pref->IsUserModifiable();
672}
673
[email protected]57ecc4b2010-08-11 03:02:51674const DictionaryValue* PrefService::GetDictionary(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29675 DCHECK(CalledOnValidThread());
676
initial.commit09911bf2008-07-26 23:55:29677 const Preference* pref = FindPreference(path);
678 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40679 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29680 return NULL;
681 }
682 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25683 if (value->GetType() != Value::TYPE_DICTIONARY) {
684 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29685 return NULL;
[email protected]11b040b2011-02-02 12:42:25686 }
initial.commit09911bf2008-07-26 23:55:29687 return static_cast<const DictionaryValue*>(value);
688}
689
[email protected]1a5a31f2012-04-26 20:21:34690const base::Value* PrefService::GetUserPrefValue(const char* path) const {
691 DCHECK(CalledOnValidThread());
692
693 const Preference* pref = FindPreference(path);
694 if (!pref) {
695 NOTREACHED() << "Trying to get an unregistered pref: " << path;
696 return NULL;
697 }
698
699 // Look for an existing preference in the user store. If it doesn't
700 // exist, return NULL.
701 base::Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08702 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK)
[email protected]1a5a31f2012-04-26 20:21:34703 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34704
705 if (!value->IsType(pref->GetType())) {
706 NOTREACHED() << "Pref value type doesn't match registered type.";
707 return NULL;
708 }
709
710 return value;
711}
712
[email protected]35a6fd12012-05-28 18:08:08713const base::Value* PrefService::GetDefaultPrefValue(const char* path) const {
714 DCHECK(CalledOnValidThread());
715 // Lookup the preference in the default store.
716 const base::Value* value = NULL;
717 if (default_store_->GetValue(path, &value) != PrefStore::READ_OK) {
718 NOTREACHED() << "Default value missing for pref: " << path;
719 return NULL;
720 }
721 return value;
722}
723
[email protected]57ecc4b2010-08-11 03:02:51724const ListValue* PrefService::GetList(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29725 DCHECK(CalledOnValidThread());
726
initial.commit09911bf2008-07-26 23:55:29727 const Preference* pref = FindPreference(path);
728 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40729 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29730 return NULL;
731 }
732 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25733 if (value->GetType() != Value::TYPE_LIST) {
734 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29735 return NULL;
[email protected]11b040b2011-02-02 12:42:25736 }
initial.commit09911bf2008-07-26 23:55:29737 return static_cast<const ListValue*>(value);
738}
739
[email protected]57ecc4b2010-08-11 03:02:51740void PrefService::AddPrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53741 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50742 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29743}
744
[email protected]57ecc4b2010-08-11 03:02:51745void PrefService::RemovePrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53746 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50747 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29748}
749
[email protected]d36f941b2011-05-09 06:19:16750void PrefService::RegisterPreference(const char* path,
751 Value* default_value,
752 PrefSyncStatus sync_status) {
initial.commit09911bf2008-07-26 23:55:29753 DCHECK(CalledOnValidThread());
754
[email protected]c3b54f372010-09-14 08:25:07755 // The main code path takes ownership, but most don't. We'll be safe.
756 scoped_ptr<Value> scoped_value(default_value);
757
758 if (FindPreference(path)) {
759 NOTREACHED() << "Tried to register duplicate pref " << path;
initial.commit09911bf2008-07-26 23:55:29760 return;
761 }
[email protected]c3b54f372010-09-14 08:25:07762
[email protected]bab1c13f2011-08-12 20:59:02763 base::Value::Type orig_type = default_value->GetType();
[email protected]99cc9a02010-09-17 07:53:28764 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
765 "invalid preference type: " << orig_type;
766
[email protected]ea3e4972012-04-12 03:41:37767 // For ListValue and DictionaryValue with non empty default, empty value
768 // for |path| needs to be persisted in |user_pref_store_|. So that
769 // non empty default is not used when user sets an empty ListValue or
770 // DictionaryValue.
771 bool needs_empty_value = false;
772 if (orig_type == base::Value::TYPE_LIST) {
773 const base::ListValue* list = NULL;
774 if (default_value->GetAsList(&list) && !list->empty())
775 needs_empty_value = true;
776 } else if (orig_type == base::Value::TYPE_DICTIONARY) {
777 const base::DictionaryValue* dict = NULL;
778 if (default_value->GetAsDictionary(&dict) && !dict->empty())
779 needs_empty_value = true;
780 }
781 if (needs_empty_value)
782 user_pref_store_->MarkNeedsEmptyValue(path);
783
[email protected]9a8c4022011-01-25 14:25:33784 // Hand off ownership.
785 default_store_->SetDefaultValue(path, scoped_value.release());
[email protected]d36f941b2011-05-09 06:19:16786
787 // Register with sync if necessary.
788 if (sync_status == SYNCABLE_PREF && pref_sync_associator_.get())
789 pref_sync_associator_->RegisterPref(path);
initial.commit09911bf2008-07-26 23:55:29790}
791
[email protected]7a5f5932011-12-29 10:35:49792void PrefService::UnregisterPreference(const char* path) {
793 DCHECK(CalledOnValidThread());
794
795 Preference p(this, path, Value::TYPE_NULL);
[email protected]398007ce2012-01-05 19:25:50796 PreferenceSet::iterator it = prefs_.find(&p);
[email protected]7a5f5932011-12-29 10:35:49797 if (it == prefs_.end()) {
798 NOTREACHED() << "Trying to unregister an unregistered pref: " << path;
799 return;
800 }
801
[email protected]5a56d372011-12-29 11:34:40802 delete *it;
[email protected]7a5f5932011-12-29 10:35:49803 prefs_.erase(it);
804 default_store_->RemoveDefaultValue(path);
805 if (pref_sync_associator_.get() &&
806 pref_sync_associator_->IsPrefRegistered(path)) {
807 pref_sync_associator_->UnregisterPref(path);
808 }
809}
810
[email protected]57ecc4b2010-08-11 03:02:51811void PrefService::ClearPref(const char* path) {
initial.commit09911bf2008-07-26 23:55:29812 DCHECK(CalledOnValidThread());
813
814 const Preference* pref = FindPreference(path);
815 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40816 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29817 return;
818 }
[email protected]f2d1f612010-12-09 15:10:17819 user_pref_store_->RemoveValue(path);
initial.commit09911bf2008-07-26 23:55:29820}
821
[email protected]57ecc4b2010-08-11 03:02:51822void PrefService::Set(const char* path, const Value& value) {
[email protected]b99c41c2011-04-27 15:18:48823 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39824}
825
[email protected]57ecc4b2010-08-11 03:02:51826void PrefService::SetBoolean(const char* path, bool value) {
[email protected]c3b54f372010-09-14 08:25:07827 SetUserPrefValue(path, Value::CreateBooleanValue(value));
initial.commit09911bf2008-07-26 23:55:29828}
829
[email protected]57ecc4b2010-08-11 03:02:51830void PrefService::SetInteger(const char* path, int value) {
[email protected]c3b54f372010-09-14 08:25:07831 SetUserPrefValue(path, Value::CreateIntegerValue(value));
initial.commit09911bf2008-07-26 23:55:29832}
833
[email protected]fb534c92011-02-01 01:02:07834void PrefService::SetDouble(const char* path, double value) {
835 SetUserPrefValue(path, Value::CreateDoubleValue(value));
initial.commit09911bf2008-07-26 23:55:29836}
837
[email protected]57ecc4b2010-08-11 03:02:51838void PrefService::SetString(const char* path, const std::string& value) {
[email protected]c3b54f372010-09-14 08:25:07839 SetUserPrefValue(path, Value::CreateStringValue(value));
initial.commit09911bf2008-07-26 23:55:29840}
841
[email protected]57ecc4b2010-08-11 03:02:51842void PrefService::SetFilePath(const char* path, const FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50843 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25844}
845
[email protected]57ecc4b2010-08-11 03:02:51846void PrefService::SetInt64(const char* path, int64 value) {
[email protected]c3b54f372010-09-14 08:25:07847 SetUserPrefValue(path, Value::CreateStringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32848}
849
[email protected]57ecc4b2010-08-11 03:02:51850int64 PrefService::GetInt64(const char* path) const {
[email protected]0bb1a622009-03-04 03:22:32851 DCHECK(CalledOnValidThread());
852
[email protected]0bb1a622009-03-04 03:22:32853 const Preference* pref = FindPreference(path);
854 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40855 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08856 return 0;
[email protected]0bb1a622009-03-04 03:22:32857 }
[email protected]dc9a6762010-08-16 07:13:53858 std::string result("0");
[email protected]0bb1a622009-03-04 03:22:32859 bool rv = pref->GetValue()->GetAsString(&result);
860 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25861
862 int64 val;
[email protected]dc9a6762010-08-16 07:13:53863 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25864 return val;
[email protected]0bb1a622009-03-04 03:22:32865}
866
[email protected]26418b72011-03-30 14:07:39867Value* PrefService::GetMutableUserPref(const char* path,
[email protected]bab1c13f2011-08-12 20:59:02868 base::Value::Type type) {
[email protected]26418b72011-03-30 14:07:39869 CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29870 DCHECK(CalledOnValidThread());
871
872 const Preference* pref = FindPreference(path);
873 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40874 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29875 return NULL;
876 }
[email protected]26418b72011-03-30 14:07:39877 if (pref->GetType() != type) {
878 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29879 return NULL;
880 }
881
[email protected]e0250892010-10-01 18:57:53882 // Look for an existing preference in the user store. If it doesn't
883 // exist or isn't the correct type, create a new user preference.
[email protected]26418b72011-03-30 14:07:39884 Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08885 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK ||
[email protected]26418b72011-03-30 14:07:39886 !value->IsType(type)) {
887 if (type == Value::TYPE_DICTIONARY) {
888 value = new DictionaryValue;
889 } else if (type == Value::TYPE_LIST) {
890 value = new ListValue;
891 } else {
892 NOTREACHED();
893 }
894 user_pref_store_->SetValueSilently(path, value);
initial.commit09911bf2008-07-26 23:55:29895 }
[email protected]26418b72011-03-30 14:07:39896 return value;
897}
898
[email protected]68bf41a2011-03-25 16:38:31899void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]f89ee342011-03-07 09:28:27900 user_pref_store_->ReportValueChanged(key);
901}
902
[email protected]c3b54f372010-09-14 08:25:07903void PrefService::SetUserPrefValue(const char* path, Value* new_value) {
[email protected]b99c41c2011-04-27 15:18:48904 scoped_ptr<Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07905 DCHECK(CalledOnValidThread());
906
907 const Preference* pref = FindPreference(path);
908 if (!pref) {
909 NOTREACHED() << "Trying to write an unregistered pref: " << path;
910 return;
911 }
[email protected]99cc9a02010-09-17 07:53:28912 if (pref->GetType() != new_value->GetType()) {
913 NOTREACHED() << "Trying to set pref " << path
914 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07915 << " to value of type " << new_value->GetType();
916 return;
917 }
918
[email protected]b99c41c2011-04-27 15:18:48919 user_pref_store_->SetValue(path, owned_value.release());
[email protected]73c47932010-12-06 18:13:43920}
921
[email protected]d36f941b2011-05-09 06:19:16922SyncableService* PrefService::GetSyncableService() {
923 return pref_sync_associator_.get();
924}
925
[email protected]d3b05ea2012-01-24 22:57:05926void PrefService::UpdateCommandLinePrefStore(CommandLine* command_line) {
927 // If |pref_service_forked_| is true, then this PrefService and the forked
928 // copies will be out of sync.
929 DCHECK(!pref_service_forked_);
930 pref_value_store_->UpdateCommandLinePrefStore(
931 new CommandLinePrefStore(command_line));
932}
933
initial.commit09911bf2008-07-26 23:55:29934///////////////////////////////////////////////////////////////////////////////
935// PrefService::Preference
936
[email protected]c3b54f372010-09-14 08:25:07937PrefService::Preference::Preference(const PrefService* service,
[email protected]9a8c4022011-01-25 14:25:33938 const char* name,
[email protected]bab1c13f2011-08-12 20:59:02939 base::Value::Type type)
[email protected]99cc9a02010-09-17 07:53:28940 : name_(name),
[email protected]9a8c4022011-01-25 14:25:33941 type_(type),
[email protected]c3b54f372010-09-14 08:25:07942 pref_service_(service) {
initial.commit09911bf2008-07-26 23:55:29943 DCHECK(name);
[email protected]c3b54f372010-09-14 08:25:07944 DCHECK(service);
[email protected]99cc9a02010-09-17 07:53:28945}
946
[email protected]bab1c13f2011-08-12 20:59:02947base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33948 return type_;
initial.commit09911bf2008-07-26 23:55:29949}
950
951const Value* PrefService::Preference::GetValue() const {
[email protected]c3b54f372010-09-14 08:25:07952 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
initial.commit09911bf2008-07-26 23:55:29953 "Must register pref before getting its value";
954
[email protected]68bf41a2011-03-25 16:38:31955 const Value* found_value = NULL;
[email protected]887288f02011-02-04 22:52:46956 if (pref_value_store()->GetValue(name_, type_, &found_value)) {
[email protected]9a8c4022011-01-25 14:25:33957 DCHECK(found_value->IsType(type_));
[email protected]99cc9a02010-09-17 07:53:28958 return found_value;
[email protected]9a8c4022011-01-25 14:25:33959 }
initial.commit09911bf2008-07-26 23:55:29960
[email protected]c3b54f372010-09-14 08:25:07961 // Every registered preference has at least a default value.
[email protected]99cc9a02010-09-17 07:53:28962 NOTREACHED() << "no valid value found for registered pref " << name_;
[email protected]c3b54f372010-09-14 08:25:07963 return NULL;
[email protected]40a47c162010-09-09 11:14:01964}
965
966bool PrefService::Preference::IsManaged() const {
[email protected]887288f02011-02-04 22:52:46967 return pref_value_store()->PrefValueInManagedStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01968}
969
[email protected]a5437282011-12-12 12:33:21970bool PrefService::Preference::IsRecommended() const {
971 return pref_value_store()->PrefValueFromRecommendedStore(name_.c_str());
972}
973
[email protected]40a47c162010-09-09 11:14:01974bool PrefService::Preference::HasExtensionSetting() const {
[email protected]887288f02011-02-04 22:52:46975 return pref_value_store()->PrefValueInExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01976}
977
978bool PrefService::Preference::HasUserSetting() const {
[email protected]887288f02011-02-04 22:52:46979 return pref_value_store()->PrefValueInUserStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01980}
981
982bool PrefService::Preference::IsExtensionControlled() const {
[email protected]887288f02011-02-04 22:52:46983 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01984}
985
986bool PrefService::Preference::IsUserControlled() const {
[email protected]887288f02011-02-04 22:52:46987 return pref_value_store()->PrefValueFromUserStore(name_.c_str());
[email protected]c3b54f372010-09-14 08:25:07988}
989
990bool PrefService::Preference::IsDefaultValue() const {
[email protected]887288f02011-02-04 22:52:46991 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str());
[email protected]d7449e82010-07-14 11:42:35992}
[email protected]74379bc52010-07-21 13:54:08993
994bool PrefService::Preference::IsUserModifiable() const {
[email protected]887288f02011-02-04 22:52:46995 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
[email protected]74379bc52010-07-21 13:54:08996}
[email protected]9a28f132011-02-24 21:15:16997
998bool PrefService::Preference::IsExtensionModifiable() const {
999 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
1000}