blob: 043be894b98e17abfb8a6f0b0d3478e1eea0309f [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]03b9b4e2012-10-22 20:01:5216#include "base/prefs/default_pref_store.h"
17#include "base/prefs/json_pref_store.h"
18#include "base/prefs/overlay_user_pref_store.h"
[email protected]7286e3fc2011-07-19 22:13:2419#include "base/stl_util.h"
[email protected]e83326f2010-07-31 17:29:2520#include "base/string_number_conversions.h"
initial.commit09911bf2008-07-26 23:55:2921#include "base/string_util.h"
[email protected]8703b2b2011-03-15 09:51:5022#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4023#include "build/build_config.h"
[email protected]d36f941b2011-05-09 06:19:1624#include "chrome/browser/browser_process.h"
[email protected]9a8c4022011-01-25 14:25:3325#include "chrome/browser/extensions/extension_pref_store.h"
[email protected]acd78969c2010-12-08 09:49:1126#include "chrome/browser/policy/configuration_policy_pref_store.h"
27#include "chrome/browser/prefs/command_line_pref_store.h"
[email protected]d36f941b2011-05-09 06:19:1628#include "chrome/browser/prefs/pref_model_associator.h"
[email protected]acd78969c2010-12-08 09:49:1129#include "chrome/browser/prefs/pref_notifier_impl.h"
[email protected]39d9f62c2010-12-03 10:48:5030#include "chrome/browser/prefs/pref_value_store.h"
[email protected]fb8fdf12012-08-21 16:28:2031#include "chrome/browser/profiles/profile.h"
[email protected]32c3c752012-01-05 17:33:4732#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
[email protected]c7fb2da32011-04-14 20:47:1033#include "chrome/browser/ui/profile_error_dialog.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]6bb2d372012-09-13 20:27:0340using content::BrowserContext;
[email protected]631bb742011-11-02 11:29:3941using content::BrowserThread;
42
initial.commit09911bf2008-07-26 23:55:2943namespace {
44
initial.commit09911bf2008-07-26 23:55:2945// A helper function for RegisterLocalized*Pref that creates a Value* based on
46// the string value in the locale dll. Because we control the values in a
47// locale dll, this should always return a Value of the appropriate type.
[email protected]bab1c13f2011-08-12 20:59:0248Value* CreateLocaleDefaultValue(base::Value::Type type, int message_id) {
[email protected]16b527162010-08-15 18:37:1049 std::string resource_string = l10n_util::GetStringUTF8(message_id);
initial.commit09911bf2008-07-26 23:55:2950 DCHECK(!resource_string.empty());
51 switch (type) {
52 case Value::TYPE_BOOLEAN: {
[email protected]16b527162010-08-15 18:37:1053 if ("true" == resource_string)
initial.commit09911bf2008-07-26 23:55:2954 return Value::CreateBooleanValue(true);
[email protected]16b527162010-08-15 18:37:1055 if ("false" == resource_string)
initial.commit09911bf2008-07-26 23:55:2956 return Value::CreateBooleanValue(false);
57 break;
58 }
59
60 case Value::TYPE_INTEGER: {
[email protected]e83326f2010-07-31 17:29:2561 int val;
[email protected]16b527162010-08-15 18:37:1062 base::StringToInt(resource_string, &val);
[email protected]e83326f2010-07-31 17:29:2563 return Value::CreateIntegerValue(val);
initial.commit09911bf2008-07-26 23:55:2964 }
65
[email protected]fb534c92011-02-01 01:02:0766 case Value::TYPE_DOUBLE: {
[email protected]e83326f2010-07-31 17:29:2567 double val;
[email protected]16b527162010-08-15 18:37:1068 base::StringToDouble(resource_string, &val);
[email protected]fb534c92011-02-01 01:02:0769 return Value::CreateDoubleValue(val);
initial.commit09911bf2008-07-26 23:55:2970 }
71
72 case Value::TYPE_STRING: {
73 return Value::CreateStringValue(resource_string);
initial.commit09911bf2008-07-26 23:55:2974 }
75
76 default: {
[email protected]b154e6f2009-03-06 01:52:4077 NOTREACHED() <<
[email protected]c3b54f372010-09-14 08:25:0778 "list and dictionary types cannot have default locale values";
initial.commit09911bf2008-07-26 23:55:2979 }
80 }
81 NOTREACHED();
82 return Value::CreateNullValue();
83}
84
[email protected]ba399672010-04-06 15:42:3985// Forwards a notification after a PostMessage so that we can wait for the
86// MessageLoop to run.
[email protected]845b43a82011-05-11 10:14:4387void NotifyReadError(int message_id) {
[email protected]c7fb2da32011-04-14 20:47:1088 ShowProfileErrorDialog(message_id);
[email protected]ba399672010-04-06 15:42:3989}
90
[email protected]845b43a82011-05-11 10:14:4391// Shows notifications which correspond to PersistentPrefStore's reading errors.
92class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
93 public:
94 virtual void OnError(PersistentPrefStore::PrefReadError error) {
95 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
96 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
97 // an example problem that this can cause.
98 // Do some diagnosis and try to avoid losing data.
99 int message_id = 0;
100 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
101 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
102 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
103 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
104 }
105
106 if (message_id) {
107 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45108 base::Bind(&NotifyReadError, message_id));
[email protected]845b43a82011-05-11 10:14:43109 }
[email protected]ff3c69a2011-09-15 00:36:48110 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
111 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
[email protected]845b43a82011-05-11 10:14:43112 }
113 }
114};
115
initial.commit09911bf2008-07-26 23:55:29116} // namespace
117
[email protected]cf32f4c2012-09-22 17:02:25118PrefServiceBase* PrefServiceBase::FromBrowserContext(BrowserContext* context) {
[email protected]6bb2d372012-09-13 20:27:03119 return static_cast<Profile*>(context)->GetPrefs();
[email protected]fb8fdf12012-08-21 16:28:20120}
121
[email protected]db198b22010-07-12 16:48:49122// static
[email protected]21d3a882012-05-31 14:41:55123PrefService* PrefService::CreatePrefService(
124 const FilePath& pref_filename,
125 policy::PolicyService* policy_service,
126 PrefStore* extension_prefs,
127 bool async) {
[email protected]acd78969c2010-12-08 09:49:11128 using policy::ConfigurationPolicyPrefStore;
129
[email protected]1d01d412010-08-20 00:36:01130#if defined(OS_LINUX)
131 // We'd like to see what fraction of our users have the preferences
132 // stored on a network file system, as we've had no end of troubles
133 // with NFS/AFS.
134 // TODO(evanm): remove this once we've collected state.
135 file_util::FileSystemType fstype;
136 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
137 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
138 static_cast<int>(fstype),
139 file_util::FILE_SYSTEM_TYPE_COUNT);
140 }
141#endif
142
[email protected]f31e2e52011-07-14 16:01:19143#if defined(ENABLE_CONFIGURATION_POLICY)
[email protected]4eb4d6ce2012-04-02 14:06:57144 ConfigurationPolicyPrefStore* managed =
[email protected]21d3a882012-05-31 14:41:55145 ConfigurationPolicyPrefStore::CreateMandatoryPolicyPrefStore(
146 policy_service);
[email protected]4eb4d6ce2012-04-02 14:06:57147 ConfigurationPolicyPrefStore* recommended =
[email protected]21d3a882012-05-31 14:41:55148 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(
149 policy_service);
[email protected]f31e2e52011-07-14 16:01:19150#else
[email protected]4eb4d6ce2012-04-02 14:06:57151 ConfigurationPolicyPrefStore* managed = NULL;
152 ConfigurationPolicyPrefStore* recommended = NULL;
[email protected]f31e2e52011-07-14 16:01:19153#endif // ENABLE_CONFIGURATION_POLICY
154
[email protected]acd78969c2010-12-08 09:49:11155 CommandLinePrefStore* command_line =
156 new CommandLinePrefStore(CommandLine::ForCurrentProcess());
[email protected]370bc732012-05-07 21:25:20157 JsonPrefStore* user = new JsonPrefStore(
158 pref_filename,
159 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
[email protected]9a8c4022011-01-25 14:25:33160 DefaultPrefStore* default_pref_store = new DefaultPrefStore();
[email protected]acd78969c2010-12-08 09:49:11161
[email protected]361d37f62011-11-22 10:37:02162 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
163 PrefModelAssociator* pref_sync_associator = new PrefModelAssociator();
164
[email protected]845b43a82011-05-11 10:14:43165 return new PrefService(
[email protected]361d37f62011-11-22 10:37:02166 pref_notifier,
167 new PrefValueStore(
[email protected]4eb4d6ce2012-04-02 14:06:57168 managed,
[email protected]361d37f62011-11-22 10:37:02169 extension_prefs,
170 command_line,
171 user,
[email protected]4eb4d6ce2012-04-02 14:06:57172 recommended,
[email protected]361d37f62011-11-22 10:37:02173 default_pref_store,
174 pref_sync_associator,
175 pref_notifier),
176 user,
177 default_pref_store,
178 pref_sync_associator,
179 async);
[email protected]9a8c4022011-01-25 14:25:33180}
181
182PrefService* PrefService::CreateIncognitoPrefService(
183 PrefStore* incognito_extension_prefs) {
[email protected]d3b05ea2012-01-24 22:57:05184 pref_service_forked_ = true;
[email protected]361d37f62011-11-22 10:37:02185 PrefNotifierImpl* pref_notifier = new PrefNotifierImpl();
[email protected]32c3c752012-01-05 17:33:47186 OverlayUserPrefStore* incognito_pref_store =
187 new OverlayUserPrefStore(user_pref_store_.get());
188 PrefsTabHelper::InitIncognitoUserPrefStore(incognito_pref_store);
[email protected]361d37f62011-11-22 10:37:02189 return new PrefService(
190 pref_notifier,
191 pref_value_store_->CloneAndSpecialize(
[email protected]4eb4d6ce2012-04-02 14:06:57192 NULL, // managed
[email protected]361d37f62011-11-22 10:37:02193 incognito_extension_prefs,
[email protected]d3b05ea2012-01-24 22:57:05194 NULL, // command_line_prefs
[email protected]361d37f62011-11-22 10:37:02195 incognito_pref_store,
[email protected]4eb4d6ce2012-04-02 14:06:57196 NULL, // recommended
[email protected]361d37f62011-11-22 10:37:02197 default_store_.get(),
[email protected]d3b05ea2012-01-24 22:57:05198 NULL, // pref_sync_associator
[email protected]361d37f62011-11-22 10:37:02199 pref_notifier),
200 incognito_pref_store,
[email protected]9a8c4022011-01-25 14:25:33201 default_store_.get(),
[email protected]361d37f62011-11-22 10:37:02202 NULL,
203 false);
204}
205
[email protected]361d37f62011-11-22 10:37:02206PrefService::PrefService(PrefNotifierImpl* pref_notifier,
207 PrefValueStore* pref_value_store,
208 PersistentPrefStore* user_prefs,
209 DefaultPrefStore* default_store,
210 PrefModelAssociator* pref_sync_associator,
211 bool async)
212 : pref_notifier_(pref_notifier),
213 pref_value_store_(pref_value_store),
214 user_pref_store_(user_prefs),
215 default_store_(default_store),
[email protected]d3b05ea2012-01-24 22:57:05216 pref_sync_associator_(pref_sync_associator),
217 pref_service_forked_(false) {
[email protected]361d37f62011-11-22 10:37:02218 pref_notifier_->SetPrefService(this);
219 if (pref_sync_associator_.get())
220 pref_sync_associator_->SetPrefService(this);
221 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:33222}
223
initial.commit09911bf2008-07-26 23:55:29224PrefService::~PrefService() {
225 DCHECK(CalledOnValidThread());
[email protected]a98ce1262011-01-28 13:20:23226
227 // Reset pointers so accesses after destruction reliably crash.
228 pref_value_store_.reset();
229 user_pref_store_ = NULL;
230 default_store_ = NULL;
[email protected]d36f941b2011-05-09 06:19:16231 pref_sync_associator_.reset();
[email protected]42f23782012-06-08 19:11:53232 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:29233}
234
[email protected]845b43a82011-05-11 10:14:43235void PrefService::InitFromStorage(bool async) {
236 if (!async) {
237 ReadErrorHandler error_handler;
238 error_handler.OnError(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:21239 } else {
[email protected]845b43a82011-05-11 10:14:43240 // Guarantee that initialization happens after this function returned.
241 MessageLoop::current()->PostTask(
242 FROM_HERE,
[email protected]bebe69432011-09-28 18:36:45243 base::Bind(&PersistentPrefStore::ReadPrefsAsync,
244 user_pref_store_.get(),
245 new ReadErrorHandler()));
[email protected]844a1002011-04-19 11:37:21246 }
[email protected]ba399672010-04-06 15:42:39247}
248
249bool PrefService::ReloadPersistentPrefs() {
[email protected]f2d1f612010-12-09 15:10:17250 return user_pref_store_->ReadPrefs() ==
251 PersistentPrefStore::PREF_READ_ERROR_NONE;
initial.commit09911bf2008-07-26 23:55:29252}
253
[email protected]3826fed2011-03-25 10:59:56254void PrefService::CommitPendingWrite() {
255 DCHECK(CalledOnValidThread());
256 user_pref_store_->CommitPendingWrite();
257}
258
[email protected]d36f941b2011-05-09 06:19:16259namespace {
260
261// If there's no g_browser_process or no local state, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05262bool IsLocalStatePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16263 return (!g_browser_process ||
264 !g_browser_process->local_state() ||
265 g_browser_process->local_state() == prefs);
266}
267
268// If there's no g_browser_process, return true (for testing).
[email protected]d3b05ea2012-01-24 22:57:05269bool IsProfilePrefService(PrefService* prefs) {
[email protected]d36f941b2011-05-09 06:19:16270 // TODO(zea): uncomment this once all preferences are only ever registered
271 // with either the local_state's pref service or the profile's pref service.
272 // return (!g_browser_process || g_browser_process->local_state() != prefs);
273 return true;
274}
275
276} // namespace
277
278
279// Local State prefs.
[email protected]57ecc4b2010-08-11 03:02:51280void PrefService::RegisterBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29281 bool default_value) {
[email protected]d36f941b2011-05-09 06:19:16282 // If this fails, the pref service in use is a profile pref service, so the
283 // sync status must be provided (see profile pref registration calls below).
284 DCHECK(IsLocalStatePrefService(this));
285 RegisterPreference(path,
286 Value::CreateBooleanValue(default_value),
287 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29288}
289
[email protected]57ecc4b2010-08-11 03:02:51290void PrefService::RegisterIntegerPref(const char* path, int default_value) {
[email protected]d36f941b2011-05-09 06:19:16291 // If this fails, the pref service in use is a profile pref service, so the
292 // sync status must be provided (see profile pref registration calls below).
293 DCHECK(IsLocalStatePrefService(this));
294 RegisterPreference(path,
295 Value::CreateIntegerValue(default_value),
296 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29297}
298
[email protected]fb534c92011-02-01 01:02:07299void PrefService::RegisterDoublePref(const char* path, double default_value) {
[email protected]d36f941b2011-05-09 06:19:16300 // If this fails, the pref service in use is a profile pref service, so the
301 // sync status must be provided (see profile pref registration calls below).
302 DCHECK(IsLocalStatePrefService(this));
303 RegisterPreference(path,
304 Value::CreateDoubleValue(default_value),
305 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29306}
307
[email protected]57ecc4b2010-08-11 03:02:51308void PrefService::RegisterStringPref(const char* path,
[email protected]20ce516d2010-06-18 02:20:04309 const std::string& default_value) {
[email protected]d36f941b2011-05-09 06:19:16310 // If this fails, the pref service in use is a profile pref service, so the
311 // sync status must be provided (see profile pref registration calls below).
312 DCHECK(IsLocalStatePrefService(this));
313 RegisterPreference(path,
314 Value::CreateStringValue(default_value),
315 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29316}
317
[email protected]57ecc4b2010-08-11 03:02:51318void PrefService::RegisterFilePathPref(const char* path,
[email protected]b9636002009-03-04 00:05:25319 const FilePath& default_value) {
[email protected]d36f941b2011-05-09 06:19:16320 // If this fails, the pref service in use is a profile pref service, so the
321 // sync status must be provided (see profile pref registration calls below).
322 DCHECK(IsLocalStatePrefService(this));
323 RegisterPreference(path,
324 Value::CreateStringValue(default_value.value()),
325 UNSYNCABLE_PREF);
[email protected]b9636002009-03-04 00:05:25326}
327
[email protected]57ecc4b2010-08-11 03:02:51328void PrefService::RegisterListPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16329 // If this fails, the pref service in use is a profile pref service, so the
330 // sync status must be provided (see profile pref registration calls below).
331 DCHECK(IsLocalStatePrefService(this));
332 RegisterPreference(path,
333 new ListValue(),
334 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29335}
336
[email protected]c2f23d012011-02-09 14:52:17337void PrefService::RegisterListPref(const char* path, ListValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16338 // If this fails, the pref service in use is a profile pref service, so the
339 // sync status must be provided (see profile pref registration calls below).
340 DCHECK(IsLocalStatePrefService(this));
341 RegisterPreference(path,
342 default_value,
343 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17344}
345
[email protected]57ecc4b2010-08-11 03:02:51346void PrefService::RegisterDictionaryPref(const char* path) {
[email protected]d36f941b2011-05-09 06:19:16347 // If this fails, the pref service in use is a profile pref service, so the
348 // sync status must be provided (see profile pref registration calls below).
349 DCHECK(IsLocalStatePrefService(this));
350 RegisterPreference(path,
351 new DictionaryValue(),
352 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29353}
354
[email protected]c2f23d012011-02-09 14:52:17355void PrefService::RegisterDictionaryPref(const char* path,
356 DictionaryValue* default_value) {
[email protected]d36f941b2011-05-09 06:19:16357 // If this fails, the pref service in use is a profile pref service, so the
358 // sync status must be provided (see profile pref registration calls below).
359 DCHECK(IsLocalStatePrefService(this));
360 RegisterPreference(path,
361 default_value,
362 UNSYNCABLE_PREF);
[email protected]c2f23d012011-02-09 14:52:17363}
364
[email protected]57ecc4b2010-08-11 03:02:51365void PrefService::RegisterLocalizedBooleanPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29366 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16367 // If this fails, the pref service in use is a profile pref service, so the
368 // sync status must be provided (see profile pref registration calls below).
369 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07370 RegisterPreference(
371 path,
[email protected]d36f941b2011-05-09 06:19:16372 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
373 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29374}
375
[email protected]57ecc4b2010-08-11 03:02:51376void PrefService::RegisterLocalizedIntegerPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29377 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16378 // If this fails, the pref service in use is a profile pref service, so the
379 // sync status must be provided (see profile pref registration calls below).
380 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07381 RegisterPreference(
382 path,
[email protected]d36f941b2011-05-09 06:19:16383 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
384 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29385}
386
[email protected]fb534c92011-02-01 01:02:07387void PrefService::RegisterLocalizedDoublePref(const char* path,
388 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16389 // If this fails, the pref service in use is a profile pref service, so the
390 // sync status must be provided (see profile pref registration calls below).
391 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07392 RegisterPreference(
393 path,
[email protected]d36f941b2011-05-09 06:19:16394 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
395 UNSYNCABLE_PREF);
initial.commit09911bf2008-07-26 23:55:29396}
397
[email protected]57ecc4b2010-08-11 03:02:51398void PrefService::RegisterLocalizedStringPref(const char* path,
initial.commit09911bf2008-07-26 23:55:29399 int locale_default_message_id) {
[email protected]d36f941b2011-05-09 06:19:16400 // If this fails, the pref service in use is a profile pref service, so the
401 // sync status must be provided (see profile pref registration calls below).
402 DCHECK(IsLocalStatePrefService(this));
[email protected]c3b54f372010-09-14 08:25:07403 RegisterPreference(
404 path,
[email protected]d36f941b2011-05-09 06:19:16405 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
406 UNSYNCABLE_PREF);
407}
408
409void PrefService::RegisterInt64Pref(const char* path, int64 default_value) {
410 // If this fails, the pref service in use is a profile pref service, so the
411 // sync status must be provided (see profile pref registration calls below).
412 DCHECK(IsLocalStatePrefService(this));
413 RegisterPreference(
414 path,
415 Value::CreateStringValue(base::Int64ToString(default_value)),
416 UNSYNCABLE_PREF);
417}
418
419// Profile prefs (must use the sync_status variable).
420void PrefService::RegisterBooleanPref(const char* path,
421 bool default_value,
422 PrefSyncStatus sync_status) {
423 DCHECK(IsProfilePrefService(this));
424 RegisterPreference(path,
425 Value::CreateBooleanValue(default_value),
426 sync_status);
427}
428
429void PrefService::RegisterIntegerPref(const char* path,
430 int default_value,
431 PrefSyncStatus sync_status) {
432 DCHECK(IsProfilePrefService(this));
433 RegisterPreference(path,
434 Value::CreateIntegerValue(default_value),
435 sync_status);
436}
437
438void PrefService::RegisterDoublePref(const char* path,
439 double default_value,
440 PrefSyncStatus sync_status) {
441 DCHECK(IsProfilePrefService(this));
442 RegisterPreference(path,
443 Value::CreateDoubleValue(default_value),
444 sync_status);
445}
446
447void PrefService::RegisterStringPref(const char* path,
448 const std::string& default_value,
449 PrefSyncStatus sync_status) {
450 DCHECK(IsProfilePrefService(this));
451 RegisterPreference(path,
452 Value::CreateStringValue(default_value),
453 sync_status);
454}
455
456void PrefService::RegisterFilePathPref(const char* path,
457 const FilePath& default_value,
458 PrefSyncStatus sync_status) {
459 DCHECK(IsProfilePrefService(this));
460 RegisterPreference(path,
461 Value::CreateStringValue(default_value.value()),
462 sync_status);
463}
464
465void PrefService::RegisterListPref(const char* path,
466 PrefSyncStatus sync_status) {
467 DCHECK(IsProfilePrefService(this));
468 RegisterPreference(path, new ListValue(), sync_status);
469}
470
471void PrefService::RegisterListPref(const char* path,
472 ListValue* default_value,
473 PrefSyncStatus sync_status) {
474 DCHECK(IsProfilePrefService(this));
475 RegisterPreference(path, default_value, sync_status);
476}
477
478void PrefService::RegisterDictionaryPref(const char* path,
479 PrefSyncStatus sync_status) {
480 DCHECK(IsProfilePrefService(this));
481 RegisterPreference(path, new DictionaryValue(), sync_status);
482}
483
484void PrefService::RegisterDictionaryPref(const char* path,
485 DictionaryValue* default_value,
486 PrefSyncStatus sync_status) {
487 DCHECK(IsProfilePrefService(this));
488 RegisterPreference(path, default_value, sync_status);
489}
490
491void PrefService::RegisterLocalizedBooleanPref(const char* path,
492 int locale_default_message_id,
493 PrefSyncStatus sync_status) {
494 DCHECK(IsProfilePrefService(this));
495 RegisterPreference(
496 path,
[email protected]d3b05ea2012-01-24 22:57:05497 CreateLocaleDefaultValue(Value::TYPE_BOOLEAN, locale_default_message_id),
[email protected]d36f941b2011-05-09 06:19:16498 sync_status);
499}
500
501void PrefService::RegisterLocalizedIntegerPref(const char* path,
502 int locale_default_message_id,
503 PrefSyncStatus sync_status) {
504 DCHECK(IsProfilePrefService(this));
505 RegisterPreference(
506 path,
507 CreateLocaleDefaultValue(Value::TYPE_INTEGER, locale_default_message_id),
508 sync_status);
509}
510
511void PrefService::RegisterLocalizedDoublePref(const char* path,
512 int locale_default_message_id,
513 PrefSyncStatus sync_status) {
514 DCHECK(IsProfilePrefService(this));
515 RegisterPreference(
516 path,
517 CreateLocaleDefaultValue(Value::TYPE_DOUBLE, locale_default_message_id),
518 sync_status);
519}
520
521void PrefService::RegisterLocalizedStringPref(const char* path,
522 int locale_default_message_id,
523 PrefSyncStatus sync_status) {
524 DCHECK(IsProfilePrefService(this));
525 RegisterPreference(
526 path,
527 CreateLocaleDefaultValue(Value::TYPE_STRING, locale_default_message_id),
528 sync_status);
529}
530
531void PrefService::RegisterInt64Pref(const char* path,
532 int64 default_value,
533 PrefSyncStatus sync_status) {
534 DCHECK(IsProfilePrefService(this));
535 RegisterPreference(
536 path,
537 Value::CreateStringValue(base::Int64ToString(default_value)),
538 sync_status);
initial.commit09911bf2008-07-26 23:55:29539}
540
[email protected]3cbe0812012-07-03 02:51:43541void PrefService::RegisterUint64Pref(const char* path,
542 uint64 default_value,
543 PrefSyncStatus sync_status) {
544 DCHECK(IsProfilePrefService(this));
545 RegisterPreference(
546 path,
547 Value::CreateStringValue(base::Uint64ToString(default_value)),
548 sync_status);
549}
550
[email protected]57ecc4b2010-08-11 03:02:51551bool PrefService::GetBoolean(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29552 DCHECK(CalledOnValidThread());
553
554 bool result = false;
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()->GetAsBoolean(&result);
562 DCHECK(rv);
563 return result;
564}
565
[email protected]57ecc4b2010-08-11 03:02:51566int PrefService::GetInteger(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29567 DCHECK(CalledOnValidThread());
568
569 int result = 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 }
576 bool rv = pref->GetValue()->GetAsInteger(&result);
577 DCHECK(rv);
578 return result;
579}
580
[email protected]fb534c92011-02-01 01:02:07581double PrefService::GetDouble(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29582 DCHECK(CalledOnValidThread());
583
584 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29585
586 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 }
[email protected]fb534c92011-02-01 01:02:07591 bool rv = pref->GetValue()->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29592 DCHECK(rv);
593 return result;
594}
595
[email protected]57ecc4b2010-08-11 03:02:51596std::string PrefService::GetString(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29597 DCHECK(CalledOnValidThread());
598
[email protected]ddd231e2010-06-29 20:35:19599 std::string result;
[email protected]8e50b602009-03-03 22:59:43600
initial.commit09911bf2008-07-26 23:55:29601 const Preference* pref = FindPreference(path);
602 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40603 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29604 return result;
605 }
606 bool rv = pref->GetValue()->GetAsString(&result);
607 DCHECK(rv);
608 return result;
609}
610
[email protected]57ecc4b2010-08-11 03:02:51611FilePath PrefService::GetFilePath(const char* path) const {
[email protected]b9636002009-03-04 00:05:25612 DCHECK(CalledOnValidThread());
613
[email protected]68d9d352011-02-21 16:35:04614 FilePath result;
[email protected]b9636002009-03-04 00:05:25615
616 const Preference* pref = FindPreference(path);
617 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40618 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]b9636002009-03-04 00:05:25619 return FilePath(result);
620 }
[email protected]8703b2b2011-03-15 09:51:50621 bool rv = base::GetValueAsFilePath(*pref->GetValue(), &result);
[email protected]b9636002009-03-04 00:05:25622 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04623 return result;
[email protected]b9636002009-03-04 00:05:25624}
625
[email protected]57ecc4b2010-08-11 03:02:51626bool PrefService::HasPrefPath(const char* path) const {
[email protected]9a8c4022011-01-25 14:25:33627 const Preference* pref = FindPreference(path);
628 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29629}
630
[email protected]ebd0b022011-01-27 13:24:14631DictionaryValue* PrefService::GetPreferenceValues() const {
632 DCHECK(CalledOnValidThread());
633 DictionaryValue* out = new DictionaryValue;
634 DefaultPrefStore::const_iterator i = default_store_->begin();
635 for (; i != default_store_->end(); ++i) {
[email protected]8874e02172011-03-11 19:44:08636 const Preference* pref = FindPreference(i->first.c_str());
637 DCHECK(pref);
638 const Value* value = pref->GetValue();
639 DCHECK(value);
[email protected]ebd0b022011-01-27 13:24:14640 out->Set(i->first, value->DeepCopy());
641 }
642 return out;
643}
644
initial.commit09911bf2008-07-26 23:55:29645const PrefService::Preference* PrefService::FindPreference(
[email protected]57ecc4b2010-08-11 03:02:51646 const char* pref_name) const {
initial.commit09911bf2008-07-26 23:55:29647 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42648 PreferenceMap::iterator it = prefs_map_.find(pref_name);
649 if (it != prefs_map_.end())
650 return &(it->second);
[email protected]bab1c13f2011-08-12 20:59:02651 const base::Value::Type type = default_store_->GetType(pref_name);
[email protected]9a8c4022011-01-25 14:25:33652 if (type == Value::TYPE_NULL)
653 return NULL;
[email protected]d15d5682012-10-23 17:50:42654 it = prefs_map_.insert(
655 std::make_pair(pref_name, Preference(this, pref_name, type))).first;
656 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29657}
658
[email protected]acd78969c2010-12-08 09:49:11659bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17660 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11661}
662
[email protected]59c10712012-03-13 02:10:34663PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
664 const {
665 if (!user_pref_store_->IsInitializationComplete())
666 return INITIALIZATION_STATUS_WAITING;
667
668 switch (user_pref_store_->GetReadError()) {
669 case PersistentPrefStore::PREF_READ_ERROR_NONE:
670 return INITIALIZATION_STATUS_SUCCESS;
671 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
672 return INITIALIZATION_STATUS_CREATED_NEW_PROFILE;
673 default:
674 return INITIALIZATION_STATUS_ERROR;
675 }
676}
677
[email protected]57ecc4b2010-08-11 03:02:51678bool PrefService::IsManagedPreference(const char* pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48679 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33680 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48681}
682
[email protected]d6bbd2932012-03-19 17:10:07683bool PrefService::IsUserModifiablePreference(const char* pref_name) const {
684 const Preference* pref = FindPreference(pref_name);
685 return pref && pref->IsUserModifiable();
686}
687
[email protected]57ecc4b2010-08-11 03:02:51688const DictionaryValue* PrefService::GetDictionary(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29689 DCHECK(CalledOnValidThread());
690
initial.commit09911bf2008-07-26 23:55:29691 const Preference* pref = FindPreference(path);
692 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40693 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29694 return NULL;
695 }
696 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25697 if (value->GetType() != Value::TYPE_DICTIONARY) {
698 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29699 return NULL;
[email protected]11b040b2011-02-02 12:42:25700 }
initial.commit09911bf2008-07-26 23:55:29701 return static_cast<const DictionaryValue*>(value);
702}
703
[email protected]1a5a31f2012-04-26 20:21:34704const base::Value* PrefService::GetUserPrefValue(const char* path) const {
705 DCHECK(CalledOnValidThread());
706
707 const Preference* pref = FindPreference(path);
708 if (!pref) {
709 NOTREACHED() << "Trying to get an unregistered pref: " << path;
710 return NULL;
711 }
712
713 // Look for an existing preference in the user store. If it doesn't
714 // exist, return NULL.
715 base::Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08716 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK)
[email protected]1a5a31f2012-04-26 20:21:34717 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34718
719 if (!value->IsType(pref->GetType())) {
720 NOTREACHED() << "Pref value type doesn't match registered type.";
721 return NULL;
722 }
723
724 return value;
725}
726
[email protected]35a6fd12012-05-28 18:08:08727const base::Value* PrefService::GetDefaultPrefValue(const char* path) const {
728 DCHECK(CalledOnValidThread());
729 // Lookup the preference in the default store.
730 const base::Value* value = NULL;
731 if (default_store_->GetValue(path, &value) != PrefStore::READ_OK) {
732 NOTREACHED() << "Default value missing for pref: " << path;
733 return NULL;
734 }
735 return value;
736}
737
[email protected]57ecc4b2010-08-11 03:02:51738const ListValue* PrefService::GetList(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29739 DCHECK(CalledOnValidThread());
740
initial.commit09911bf2008-07-26 23:55:29741 const Preference* pref = FindPreference(path);
742 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40743 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29744 return NULL;
745 }
746 const Value* value = pref->GetValue();
[email protected]11b040b2011-02-02 12:42:25747 if (value->GetType() != Value::TYPE_LIST) {
748 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29749 return NULL;
[email protected]11b040b2011-02-02 12:42:25750 }
initial.commit09911bf2008-07-26 23:55:29751 return static_cast<const ListValue*>(value);
752}
753
[email protected]57ecc4b2010-08-11 03:02:51754void PrefService::AddPrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53755 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50756 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29757}
758
[email protected]57ecc4b2010-08-11 03:02:51759void PrefService::RemovePrefObserver(const char* path,
[email protected]6c2381d2011-10-19 02:52:53760 content::NotificationObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50761 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29762}
763
[email protected]d36f941b2011-05-09 06:19:16764void PrefService::RegisterPreference(const char* path,
765 Value* default_value,
766 PrefSyncStatus sync_status) {
initial.commit09911bf2008-07-26 23:55:29767 DCHECK(CalledOnValidThread());
768
[email protected]c3b54f372010-09-14 08:25:07769 // The main code path takes ownership, but most don't. We'll be safe.
770 scoped_ptr<Value> scoped_value(default_value);
771
772 if (FindPreference(path)) {
773 NOTREACHED() << "Tried to register duplicate pref " << path;
initial.commit09911bf2008-07-26 23:55:29774 return;
775 }
[email protected]c3b54f372010-09-14 08:25:07776
[email protected]bab1c13f2011-08-12 20:59:02777 base::Value::Type orig_type = default_value->GetType();
[email protected]99cc9a02010-09-17 07:53:28778 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
779 "invalid preference type: " << orig_type;
780
[email protected]ea3e4972012-04-12 03:41:37781 // For ListValue and DictionaryValue with non empty default, empty value
782 // for |path| needs to be persisted in |user_pref_store_|. So that
783 // non empty default is not used when user sets an empty ListValue or
784 // DictionaryValue.
785 bool needs_empty_value = false;
786 if (orig_type == base::Value::TYPE_LIST) {
787 const base::ListValue* list = NULL;
788 if (default_value->GetAsList(&list) && !list->empty())
789 needs_empty_value = true;
790 } else if (orig_type == base::Value::TYPE_DICTIONARY) {
791 const base::DictionaryValue* dict = NULL;
792 if (default_value->GetAsDictionary(&dict) && !dict->empty())
793 needs_empty_value = true;
794 }
795 if (needs_empty_value)
796 user_pref_store_->MarkNeedsEmptyValue(path);
797
[email protected]9a8c4022011-01-25 14:25:33798 // Hand off ownership.
799 default_store_->SetDefaultValue(path, scoped_value.release());
[email protected]d36f941b2011-05-09 06:19:16800
801 // Register with sync if necessary.
802 if (sync_status == SYNCABLE_PREF && pref_sync_associator_.get())
803 pref_sync_associator_->RegisterPref(path);
initial.commit09911bf2008-07-26 23:55:29804}
805
[email protected]7a5f5932011-12-29 10:35:49806void PrefService::UnregisterPreference(const char* path) {
807 DCHECK(CalledOnValidThread());
808
[email protected]d15d5682012-10-23 17:50:42809 PreferenceMap::iterator it = prefs_map_.find(path);
810 if (it == prefs_map_.end()) {
[email protected]7a5f5932011-12-29 10:35:49811 NOTREACHED() << "Trying to unregister an unregistered pref: " << path;
812 return;
813 }
814
[email protected]d15d5682012-10-23 17:50:42815 prefs_map_.erase(it);
[email protected]7a5f5932011-12-29 10:35:49816 default_store_->RemoveDefaultValue(path);
817 if (pref_sync_associator_.get() &&
818 pref_sync_associator_->IsPrefRegistered(path)) {
819 pref_sync_associator_->UnregisterPref(path);
820 }
821}
822
[email protected]57ecc4b2010-08-11 03:02:51823void PrefService::ClearPref(const char* path) {
initial.commit09911bf2008-07-26 23:55:29824 DCHECK(CalledOnValidThread());
825
826 const Preference* pref = FindPreference(path);
827 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40828 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29829 return;
830 }
[email protected]f2d1f612010-12-09 15:10:17831 user_pref_store_->RemoveValue(path);
initial.commit09911bf2008-07-26 23:55:29832}
833
[email protected]57ecc4b2010-08-11 03:02:51834void PrefService::Set(const char* path, const Value& value) {
[email protected]b99c41c2011-04-27 15:18:48835 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39836}
837
[email protected]57ecc4b2010-08-11 03:02:51838void PrefService::SetBoolean(const char* path, bool value) {
[email protected]c3b54f372010-09-14 08:25:07839 SetUserPrefValue(path, Value::CreateBooleanValue(value));
initial.commit09911bf2008-07-26 23:55:29840}
841
[email protected]57ecc4b2010-08-11 03:02:51842void PrefService::SetInteger(const char* path, int value) {
[email protected]c3b54f372010-09-14 08:25:07843 SetUserPrefValue(path, Value::CreateIntegerValue(value));
initial.commit09911bf2008-07-26 23:55:29844}
845
[email protected]fb534c92011-02-01 01:02:07846void PrefService::SetDouble(const char* path, double value) {
847 SetUserPrefValue(path, Value::CreateDoubleValue(value));
initial.commit09911bf2008-07-26 23:55:29848}
849
[email protected]57ecc4b2010-08-11 03:02:51850void PrefService::SetString(const char* path, const std::string& value) {
[email protected]c3b54f372010-09-14 08:25:07851 SetUserPrefValue(path, Value::CreateStringValue(value));
initial.commit09911bf2008-07-26 23:55:29852}
853
[email protected]57ecc4b2010-08-11 03:02:51854void PrefService::SetFilePath(const char* path, const FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50855 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25856}
857
[email protected]57ecc4b2010-08-11 03:02:51858void PrefService::SetInt64(const char* path, int64 value) {
[email protected]c3b54f372010-09-14 08:25:07859 SetUserPrefValue(path, Value::CreateStringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32860}
861
[email protected]57ecc4b2010-08-11 03:02:51862int64 PrefService::GetInt64(const char* path) const {
[email protected]0bb1a622009-03-04 03:22:32863 DCHECK(CalledOnValidThread());
864
[email protected]0bb1a622009-03-04 03:22:32865 const Preference* pref = FindPreference(path);
866 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40867 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08868 return 0;
[email protected]0bb1a622009-03-04 03:22:32869 }
[email protected]dc9a6762010-08-16 07:13:53870 std::string result("0");
[email protected]0bb1a622009-03-04 03:22:32871 bool rv = pref->GetValue()->GetAsString(&result);
872 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25873
874 int64 val;
[email protected]dc9a6762010-08-16 07:13:53875 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25876 return val;
[email protected]0bb1a622009-03-04 03:22:32877}
878
[email protected]3cbe0812012-07-03 02:51:43879void PrefService::SetUint64(const char* path, uint64 value) {
880 SetUserPrefValue(path, Value::CreateStringValue(base::Uint64ToString(value)));
881}
882
883uint64 PrefService::GetUint64(const char* path) const {
884 DCHECK(CalledOnValidThread());
885
886 const Preference* pref = FindPreference(path);
887 if (!pref) {
888 NOTREACHED() << "Trying to read an unregistered pref: " << path;
889 return 0;
890 }
891 std::string result("0");
892 bool rv = pref->GetValue()->GetAsString(&result);
893 DCHECK(rv);
894
895 uint64 val;
896 base::StringToUint64(result, &val);
897 return val;
898}
899
[email protected]26418b72011-03-30 14:07:39900Value* PrefService::GetMutableUserPref(const char* path,
[email protected]bab1c13f2011-08-12 20:59:02901 base::Value::Type type) {
[email protected]26418b72011-03-30 14:07:39902 CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29903 DCHECK(CalledOnValidThread());
904
905 const Preference* pref = FindPreference(path);
906 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40907 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29908 return NULL;
909 }
[email protected]26418b72011-03-30 14:07:39910 if (pref->GetType() != type) {
911 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29912 return NULL;
913 }
914
[email protected]e0250892010-10-01 18:57:53915 // Look for an existing preference in the user store. If it doesn't
916 // exist or isn't the correct type, create a new user preference.
[email protected]26418b72011-03-30 14:07:39917 Value* value = NULL;
[email protected]35a6fd12012-05-28 18:08:08918 if (user_pref_store_->GetMutableValue(path, &value) != PrefStore::READ_OK ||
[email protected]26418b72011-03-30 14:07:39919 !value->IsType(type)) {
920 if (type == Value::TYPE_DICTIONARY) {
921 value = new DictionaryValue;
922 } else if (type == Value::TYPE_LIST) {
923 value = new ListValue;
924 } else {
925 NOTREACHED();
926 }
927 user_pref_store_->SetValueSilently(path, value);
initial.commit09911bf2008-07-26 23:55:29928 }
[email protected]26418b72011-03-30 14:07:39929 return value;
930}
931
[email protected]68bf41a2011-03-25 16:38:31932void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]f89ee342011-03-07 09:28:27933 user_pref_store_->ReportValueChanged(key);
934}
935
[email protected]c3b54f372010-09-14 08:25:07936void PrefService::SetUserPrefValue(const char* path, Value* new_value) {
[email protected]b99c41c2011-04-27 15:18:48937 scoped_ptr<Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07938 DCHECK(CalledOnValidThread());
939
940 const Preference* pref = FindPreference(path);
941 if (!pref) {
942 NOTREACHED() << "Trying to write an unregistered pref: " << path;
943 return;
944 }
[email protected]99cc9a02010-09-17 07:53:28945 if (pref->GetType() != new_value->GetType()) {
946 NOTREACHED() << "Trying to set pref " << path
947 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07948 << " to value of type " << new_value->GetType();
949 return;
950 }
951
[email protected]b99c41c2011-04-27 15:18:48952 user_pref_store_->SetValue(path, owned_value.release());
[email protected]73c47932010-12-06 18:13:43953}
954
[email protected]65f173552012-06-28 22:43:58955syncer::SyncableService* PrefService::GetSyncableService() {
[email protected]d36f941b2011-05-09 06:19:16956 return pref_sync_associator_.get();
957}
958
[email protected]d3b05ea2012-01-24 22:57:05959void PrefService::UpdateCommandLinePrefStore(CommandLine* command_line) {
960 // If |pref_service_forked_| is true, then this PrefService and the forked
961 // copies will be out of sync.
962 DCHECK(!pref_service_forked_);
963 pref_value_store_->UpdateCommandLinePrefStore(
964 new CommandLinePrefStore(command_line));
965}
966
initial.commit09911bf2008-07-26 23:55:29967///////////////////////////////////////////////////////////////////////////////
968// PrefService::Preference
969
[email protected]c3b54f372010-09-14 08:25:07970PrefService::Preference::Preference(const PrefService* service,
[email protected]9a8c4022011-01-25 14:25:33971 const char* name,
[email protected]bab1c13f2011-08-12 20:59:02972 base::Value::Type type)
[email protected]99cc9a02010-09-17 07:53:28973 : name_(name),
[email protected]9a8c4022011-01-25 14:25:33974 type_(type),
[email protected]c3b54f372010-09-14 08:25:07975 pref_service_(service) {
initial.commit09911bf2008-07-26 23:55:29976 DCHECK(name);
[email protected]c3b54f372010-09-14 08:25:07977 DCHECK(service);
[email protected]99cc9a02010-09-17 07:53:28978}
979
[email protected]fb8fdf12012-08-21 16:28:20980const std::string PrefService::Preference::name() const {
981 return name_;
982}
983
[email protected]bab1c13f2011-08-12 20:59:02984base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33985 return type_;
initial.commit09911bf2008-07-26 23:55:29986}
987
988const Value* PrefService::Preference::GetValue() const {
[email protected]c3b54f372010-09-14 08:25:07989 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
initial.commit09911bf2008-07-26 23:55:29990 "Must register pref before getting its value";
991
[email protected]68bf41a2011-03-25 16:38:31992 const Value* found_value = NULL;
[email protected]887288f02011-02-04 22:52:46993 if (pref_value_store()->GetValue(name_, type_, &found_value)) {
[email protected]9a8c4022011-01-25 14:25:33994 DCHECK(found_value->IsType(type_));
[email protected]99cc9a02010-09-17 07:53:28995 return found_value;
[email protected]9a8c4022011-01-25 14:25:33996 }
initial.commit09911bf2008-07-26 23:55:29997
[email protected]c3b54f372010-09-14 08:25:07998 // Every registered preference has at least a default value.
[email protected]99cc9a02010-09-17 07:53:28999 NOTREACHED() << "no valid value found for registered pref " << name_;
[email protected]c3b54f372010-09-14 08:25:071000 return NULL;
[email protected]40a47c162010-09-09 11:14:011001}
1002
[email protected]7ca0f362012-07-30 10:14:031003const Value* PrefService::Preference::GetRecommendedValue() const {
1004 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
1005 "Must register pref before getting its value";
1006
1007 const Value* found_value = NULL;
1008 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
1009 DCHECK(found_value->IsType(type_));
1010 return found_value;
1011 }
1012
1013 // The pref has no recommended value.
1014 return NULL;
1015}
1016
[email protected]40a47c162010-09-09 11:14:011017bool PrefService::Preference::IsManaged() const {
[email protected]887288f02011-02-04 22:52:461018 return pref_value_store()->PrefValueInManagedStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011019}
1020
[email protected]a5437282011-12-12 12:33:211021bool PrefService::Preference::IsRecommended() const {
1022 return pref_value_store()->PrefValueFromRecommendedStore(name_.c_str());
1023}
1024
[email protected]40a47c162010-09-09 11:14:011025bool PrefService::Preference::HasExtensionSetting() const {
[email protected]887288f02011-02-04 22:52:461026 return pref_value_store()->PrefValueInExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011027}
1028
1029bool PrefService::Preference::HasUserSetting() const {
[email protected]887288f02011-02-04 22:52:461030 return pref_value_store()->PrefValueInUserStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011031}
1032
1033bool PrefService::Preference::IsExtensionControlled() const {
[email protected]887288f02011-02-04 22:52:461034 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:011035}
1036
1037bool PrefService::Preference::IsUserControlled() const {
[email protected]887288f02011-02-04 22:52:461038 return pref_value_store()->PrefValueFromUserStore(name_.c_str());
[email protected]c3b54f372010-09-14 08:25:071039}
1040
1041bool PrefService::Preference::IsDefaultValue() const {
[email protected]887288f02011-02-04 22:52:461042 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str());
[email protected]d7449e82010-07-14 11:42:351043}
[email protected]74379bc52010-07-21 13:54:081044
1045bool PrefService::Preference::IsUserModifiable() const {
[email protected]887288f02011-02-04 22:52:461046 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
[email protected]74379bc52010-07-21 13:54:081047}
[email protected]9a28f132011-02-24 21:15:161048
1049bool PrefService::Preference::IsExtensionModifiable() const {
1050 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
1051}