blob: 61f54f7f1f36acdf5ca20d96b01ae0cc27764c2c [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]c02c853d72010-08-07 06:23:2410#include "base/file_path.h"
initial.commit09911bf2008-07-26 23:55:2911#include "base/logging.h"
12#include "base/message_loop.h"
[email protected]835d7c82010-10-14 04:38:3813#include "base/metrics/histogram.h"
[email protected]03b9b4e2012-10-22 20:01:5214#include "base/prefs/default_pref_store.h"
[email protected]7286e3fc2011-07-19 22:13:2415#include "base/stl_util.h"
[email protected]e83326f2010-07-31 17:29:2516#include "base/string_number_conversions.h"
initial.commit09911bf2008-07-26 23:55:2917#include "base/string_util.h"
[email protected]8703b2b2011-03-15 09:51:5018#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4019#include "build/build_config.h"
[email protected]acd78969c2010-12-08 09:49:1120#include "chrome/browser/prefs/pref_notifier_impl.h"
[email protected]39d9f62c2010-12-03 10:48:5021#include "chrome/browser/prefs/pref_value_store.h"
initial.commit09911bf2008-07-26 23:55:2922
[email protected]6bb2d372012-09-13 20:27:0323using content::BrowserContext;
[email protected]631bb742011-11-02 11:29:3924
initial.commit09911bf2008-07-26 23:55:2925namespace {
26
[email protected]845b43a82011-05-11 10:14:4327class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
28 public:
[email protected]70a317a2012-12-19 20:59:3329 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb)
30 : callback_(cb) {}
[email protected]845b43a82011-05-11 10:14:4331
[email protected]70a317a2012-12-19 20:59:3332 virtual void OnError(PersistentPrefStore::PrefReadError error) {
33 callback_.Run(error);
[email protected]845b43a82011-05-11 10:14:4334 }
[email protected]70a317a2012-12-19 20:59:3335
36 private:
37 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_;
[email protected]845b43a82011-05-11 10:14:4338};
39
initial.commit09911bf2008-07-26 23:55:2940} // namespace
41
[email protected]70a317a2012-12-19 20:59:3342PrefService::PrefService(
43 PrefNotifierImpl* pref_notifier,
44 PrefValueStore* pref_value_store,
45 PersistentPrefStore* user_prefs,
46 DefaultPrefStore* default_store,
[email protected]70a317a2012-12-19 20:59:3347 base::Callback<void(PersistentPrefStore::PrefReadError)>
48 read_error_callback,
49 bool async)
[email protected]361d37f62011-11-22 10:37:0250 : pref_notifier_(pref_notifier),
51 pref_value_store_(pref_value_store),
52 user_pref_store_(user_prefs),
53 default_store_(default_store),
[email protected]5b199522012-12-22 17:24:4454 read_error_callback_(read_error_callback) {
[email protected]361d37f62011-11-22 10:37:0255 pref_notifier_->SetPrefService(this);
[email protected]361d37f62011-11-22 10:37:0256 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:3357}
58
initial.commit09911bf2008-07-26 23:55:2959PrefService::~PrefService() {
60 DCHECK(CalledOnValidThread());
[email protected]a98ce1262011-01-28 13:20:2361
62 // Reset pointers so accesses after destruction reliably crash.
63 pref_value_store_.reset();
64 user_pref_store_ = NULL;
65 default_store_ = NULL;
[email protected]42f23782012-06-08 19:11:5366 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:2967}
68
[email protected]845b43a82011-05-11 10:14:4369void PrefService::InitFromStorage(bool async) {
70 if (!async) {
[email protected]70a317a2012-12-19 20:59:3371 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:2172 } else {
[email protected]845b43a82011-05-11 10:14:4373 // Guarantee that initialization happens after this function returned.
74 MessageLoop::current()->PostTask(
75 FROM_HERE,
[email protected]bebe69432011-09-28 18:36:4576 base::Bind(&PersistentPrefStore::ReadPrefsAsync,
77 user_pref_store_.get(),
[email protected]70a317a2012-12-19 20:59:3378 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:2179 }
[email protected]ba399672010-04-06 15:42:3980}
81
82bool PrefService::ReloadPersistentPrefs() {
[email protected]f2d1f612010-12-09 15:10:1783 return user_pref_store_->ReadPrefs() ==
84 PersistentPrefStore::PREF_READ_ERROR_NONE;
initial.commit09911bf2008-07-26 23:55:2985}
86
[email protected]3826fed2011-03-25 10:59:5687void PrefService::CommitPendingWrite() {
88 DCHECK(CalledOnValidThread());
89 user_pref_store_->CommitPendingWrite();
90}
91
[email protected]57ecc4b2010-08-11 03:02:5192bool PrefService::GetBoolean(const char* path) const {
initial.commit09911bf2008-07-26 23:55:2993 DCHECK(CalledOnValidThread());
94
95 bool result = false;
initial.commit09911bf2008-07-26 23:55:2996
[email protected]18038f82012-11-20 13:46:5897 const base::Value* value = GetPreferenceValue(path);
98 if (!value) {
[email protected]b154e6f2009-03-06 01:52:4099 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29100 return result;
101 }
[email protected]18038f82012-11-20 13:46:58102 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29103 DCHECK(rv);
104 return result;
105}
106
[email protected]57ecc4b2010-08-11 03:02:51107int PrefService::GetInteger(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29108 DCHECK(CalledOnValidThread());
109
110 int result = 0;
initial.commit09911bf2008-07-26 23:55:29111
[email protected]18038f82012-11-20 13:46:58112 const base::Value* value = GetPreferenceValue(path);
113 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40114 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29115 return result;
116 }
[email protected]18038f82012-11-20 13:46:58117 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29118 DCHECK(rv);
119 return result;
120}
121
[email protected]fb534c92011-02-01 01:02:07122double PrefService::GetDouble(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29123 DCHECK(CalledOnValidThread());
124
125 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29126
[email protected]18038f82012-11-20 13:46:58127 const base::Value* value = GetPreferenceValue(path);
128 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40129 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29130 return result;
131 }
[email protected]18038f82012-11-20 13:46:58132 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29133 DCHECK(rv);
134 return result;
135}
136
[email protected]57ecc4b2010-08-11 03:02:51137std::string PrefService::GetString(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29138 DCHECK(CalledOnValidThread());
139
[email protected]ddd231e2010-06-29 20:35:19140 std::string result;
[email protected]8e50b602009-03-03 22:59:43141
[email protected]18038f82012-11-20 13:46:58142 const base::Value* value = GetPreferenceValue(path);
143 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40144 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29145 return result;
146 }
[email protected]18038f82012-11-20 13:46:58147 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29148 DCHECK(rv);
149 return result;
150}
151
[email protected]57ecc4b2010-08-11 03:02:51152FilePath PrefService::GetFilePath(const char* path) const {
[email protected]b9636002009-03-04 00:05:25153 DCHECK(CalledOnValidThread());
154
[email protected]68d9d352011-02-21 16:35:04155 FilePath result;
[email protected]b9636002009-03-04 00:05:25156
[email protected]18038f82012-11-20 13:46:58157 const base::Value* value = GetPreferenceValue(path);
158 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40159 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]b9636002009-03-04 00:05:25160 return FilePath(result);
161 }
[email protected]18038f82012-11-20 13:46:58162 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25163 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04164 return result;
[email protected]b9636002009-03-04 00:05:25165}
166
[email protected]57ecc4b2010-08-11 03:02:51167bool PrefService::HasPrefPath(const char* path) const {
[email protected]9a8c4022011-01-25 14:25:33168 const Preference* pref = FindPreference(path);
169 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29170}
171
[email protected]ebd0b022011-01-27 13:24:14172DictionaryValue* PrefService::GetPreferenceValues() const {
173 DCHECK(CalledOnValidThread());
174 DictionaryValue* out = new DictionaryValue;
175 DefaultPrefStore::const_iterator i = default_store_->begin();
176 for (; i != default_store_->end(); ++i) {
[email protected]18038f82012-11-20 13:46:58177 const Value* value = GetPreferenceValue(i->first);
[email protected]8874e02172011-03-11 19:44:08178 DCHECK(value);
[email protected]ebd0b022011-01-27 13:24:14179 out->Set(i->first, value->DeepCopy());
180 }
181 return out;
182}
183
initial.commit09911bf2008-07-26 23:55:29184const PrefService::Preference* PrefService::FindPreference(
[email protected]57ecc4b2010-08-11 03:02:51185 const char* pref_name) const {
initial.commit09911bf2008-07-26 23:55:29186 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42187 PreferenceMap::iterator it = prefs_map_.find(pref_name);
188 if (it != prefs_map_.end())
189 return &(it->second);
[email protected]bab1c13f2011-08-12 20:59:02190 const base::Value::Type type = default_store_->GetType(pref_name);
[email protected]9a8c4022011-01-25 14:25:33191 if (type == Value::TYPE_NULL)
192 return NULL;
[email protected]d15d5682012-10-23 17:50:42193 it = prefs_map_.insert(
194 std::make_pair(pref_name, Preference(this, pref_name, type))).first;
195 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29196}
197
[email protected]acd78969c2010-12-08 09:49:11198bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17199 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11200}
201
[email protected]59c10712012-03-13 02:10:34202PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
203 const {
204 if (!user_pref_store_->IsInitializationComplete())
205 return INITIALIZATION_STATUS_WAITING;
206
207 switch (user_pref_store_->GetReadError()) {
208 case PersistentPrefStore::PREF_READ_ERROR_NONE:
209 return INITIALIZATION_STATUS_SUCCESS;
210 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
211 return INITIALIZATION_STATUS_CREATED_NEW_PROFILE;
212 default:
213 return INITIALIZATION_STATUS_ERROR;
214 }
215}
216
[email protected]57ecc4b2010-08-11 03:02:51217bool PrefService::IsManagedPreference(const char* pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48218 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33219 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48220}
221
[email protected]d6bbd2932012-03-19 17:10:07222bool PrefService::IsUserModifiablePreference(const char* pref_name) const {
223 const Preference* pref = FindPreference(pref_name);
224 return pref && pref->IsUserModifiable();
225}
226
[email protected]57ecc4b2010-08-11 03:02:51227const DictionaryValue* PrefService::GetDictionary(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29228 DCHECK(CalledOnValidThread());
229
[email protected]18038f82012-11-20 13:46:58230 const Value* value = GetPreferenceValue(path);
231 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40232 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29233 return NULL;
234 }
[email protected]11b040b2011-02-02 12:42:25235 if (value->GetType() != Value::TYPE_DICTIONARY) {
236 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29237 return NULL;
[email protected]11b040b2011-02-02 12:42:25238 }
initial.commit09911bf2008-07-26 23:55:29239 return static_cast<const DictionaryValue*>(value);
240}
241
[email protected]1a5a31f2012-04-26 20:21:34242const base::Value* PrefService::GetUserPrefValue(const char* path) const {
243 DCHECK(CalledOnValidThread());
244
245 const Preference* pref = FindPreference(path);
246 if (!pref) {
247 NOTREACHED() << "Trying to get an unregistered pref: " << path;
248 return NULL;
249 }
250
251 // Look for an existing preference in the user store. If it doesn't
252 // exist, return NULL.
253 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34254 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34255 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34256
257 if (!value->IsType(pref->GetType())) {
258 NOTREACHED() << "Pref value type doesn't match registered type.";
259 return NULL;
260 }
261
262 return value;
263}
264
[email protected]35a6fd12012-05-28 18:08:08265const base::Value* PrefService::GetDefaultPrefValue(const char* path) const {
266 DCHECK(CalledOnValidThread());
267 // Lookup the preference in the default store.
268 const base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34269 if (!default_store_->GetValue(path, &value)) {
[email protected]35a6fd12012-05-28 18:08:08270 NOTREACHED() << "Default value missing for pref: " << path;
271 return NULL;
272 }
273 return value;
274}
275
[email protected]57ecc4b2010-08-11 03:02:51276const ListValue* PrefService::GetList(const char* path) const {
initial.commit09911bf2008-07-26 23:55:29277 DCHECK(CalledOnValidThread());
278
[email protected]18038f82012-11-20 13:46:58279 const Value* value = GetPreferenceValue(path);
280 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40281 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29282 return NULL;
283 }
[email protected]11b040b2011-02-02 12:42:25284 if (value->GetType() != Value::TYPE_LIST) {
285 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29286 return NULL;
[email protected]11b040b2011-02-02 12:42:25287 }
initial.commit09911bf2008-07-26 23:55:29288 return static_cast<const ListValue*>(value);
289}
290
[email protected]a6a7ced2012-11-01 17:24:18291void PrefService::AddPrefObserver(const char* path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50292 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29293}
294
[email protected]a6a7ced2012-11-01 17:24:18295void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50296 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29297}
298
[email protected]a6a7ced2012-11-01 17:24:18299void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
300 pref_notifier_->AddInitObserver(obs);
301}
302
[email protected]d36f941b2011-05-09 06:19:16303void PrefService::RegisterPreference(const char* path,
[email protected]5b199522012-12-22 17:24:44304 Value* default_value) {
initial.commit09911bf2008-07-26 23:55:29305 DCHECK(CalledOnValidThread());
306
[email protected]c3b54f372010-09-14 08:25:07307 // The main code path takes ownership, but most don't. We'll be safe.
308 scoped_ptr<Value> scoped_value(default_value);
309
[email protected]892f1d62012-11-08 18:24:34310 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path;
[email protected]c3b54f372010-09-14 08:25:07311
[email protected]bab1c13f2011-08-12 20:59:02312 base::Value::Type orig_type = default_value->GetType();
[email protected]99cc9a02010-09-17 07:53:28313 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
314 "invalid preference type: " << orig_type;
315
[email protected]ea3e4972012-04-12 03:41:37316 // For ListValue and DictionaryValue with non empty default, empty value
317 // for |path| needs to be persisted in |user_pref_store_|. So that
318 // non empty default is not used when user sets an empty ListValue or
319 // DictionaryValue.
320 bool needs_empty_value = false;
321 if (orig_type == base::Value::TYPE_LIST) {
322 const base::ListValue* list = NULL;
323 if (default_value->GetAsList(&list) && !list->empty())
324 needs_empty_value = true;
325 } else if (orig_type == base::Value::TYPE_DICTIONARY) {
326 const base::DictionaryValue* dict = NULL;
327 if (default_value->GetAsDictionary(&dict) && !dict->empty())
328 needs_empty_value = true;
329 }
330 if (needs_empty_value)
331 user_pref_store_->MarkNeedsEmptyValue(path);
332
[email protected]9a8c4022011-01-25 14:25:33333 // Hand off ownership.
334 default_store_->SetDefaultValue(path, scoped_value.release());
initial.commit09911bf2008-07-26 23:55:29335}
336
[email protected]7a5f5932011-12-29 10:35:49337void PrefService::UnregisterPreference(const char* path) {
338 DCHECK(CalledOnValidThread());
339
[email protected]d15d5682012-10-23 17:50:42340 PreferenceMap::iterator it = prefs_map_.find(path);
[email protected]892f1d62012-11-08 18:24:34341 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: "
342 << path;
[email protected]7a5f5932011-12-29 10:35:49343
[email protected]d15d5682012-10-23 17:50:42344 prefs_map_.erase(it);
[email protected]7a5f5932011-12-29 10:35:49345 default_store_->RemoveDefaultValue(path);
[email protected]7a5f5932011-12-29 10:35:49346}
347
[email protected]57ecc4b2010-08-11 03:02:51348void PrefService::ClearPref(const char* path) {
initial.commit09911bf2008-07-26 23:55:29349 DCHECK(CalledOnValidThread());
350
351 const Preference* pref = FindPreference(path);
352 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40353 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29354 return;
355 }
[email protected]f2d1f612010-12-09 15:10:17356 user_pref_store_->RemoveValue(path);
initial.commit09911bf2008-07-26 23:55:29357}
358
[email protected]57ecc4b2010-08-11 03:02:51359void PrefService::Set(const char* path, const Value& value) {
[email protected]b99c41c2011-04-27 15:18:48360 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39361}
362
[email protected]57ecc4b2010-08-11 03:02:51363void PrefService::SetBoolean(const char* path, bool value) {
[email protected]c3b54f372010-09-14 08:25:07364 SetUserPrefValue(path, Value::CreateBooleanValue(value));
initial.commit09911bf2008-07-26 23:55:29365}
366
[email protected]57ecc4b2010-08-11 03:02:51367void PrefService::SetInteger(const char* path, int value) {
[email protected]c3b54f372010-09-14 08:25:07368 SetUserPrefValue(path, Value::CreateIntegerValue(value));
initial.commit09911bf2008-07-26 23:55:29369}
370
[email protected]fb534c92011-02-01 01:02:07371void PrefService::SetDouble(const char* path, double value) {
372 SetUserPrefValue(path, Value::CreateDoubleValue(value));
initial.commit09911bf2008-07-26 23:55:29373}
374
[email protected]57ecc4b2010-08-11 03:02:51375void PrefService::SetString(const char* path, const std::string& value) {
[email protected]c3b54f372010-09-14 08:25:07376 SetUserPrefValue(path, Value::CreateStringValue(value));
initial.commit09911bf2008-07-26 23:55:29377}
378
[email protected]57ecc4b2010-08-11 03:02:51379void PrefService::SetFilePath(const char* path, const FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50380 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25381}
382
[email protected]57ecc4b2010-08-11 03:02:51383void PrefService::SetInt64(const char* path, int64 value) {
[email protected]c3b54f372010-09-14 08:25:07384 SetUserPrefValue(path, Value::CreateStringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32385}
386
[email protected]57ecc4b2010-08-11 03:02:51387int64 PrefService::GetInt64(const char* path) const {
[email protected]0bb1a622009-03-04 03:22:32388 DCHECK(CalledOnValidThread());
389
[email protected]18038f82012-11-20 13:46:58390 const Value* value = GetPreferenceValue(path);
391 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40392 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08393 return 0;
[email protected]0bb1a622009-03-04 03:22:32394 }
[email protected]dc9a6762010-08-16 07:13:53395 std::string result("0");
[email protected]18038f82012-11-20 13:46:58396 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32397 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25398
399 int64 val;
[email protected]dc9a6762010-08-16 07:13:53400 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25401 return val;
[email protected]0bb1a622009-03-04 03:22:32402}
403
[email protected]3cbe0812012-07-03 02:51:43404void PrefService::SetUint64(const char* path, uint64 value) {
405 SetUserPrefValue(path, Value::CreateStringValue(base::Uint64ToString(value)));
406}
407
408uint64 PrefService::GetUint64(const char* path) const {
409 DCHECK(CalledOnValidThread());
410
[email protected]18038f82012-11-20 13:46:58411 const Value* value = GetPreferenceValue(path);
412 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43413 NOTREACHED() << "Trying to read an unregistered pref: " << path;
414 return 0;
415 }
416 std::string result("0");
[email protected]18038f82012-11-20 13:46:58417 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43418 DCHECK(rv);
419
420 uint64 val;
421 base::StringToUint64(result, &val);
422 return val;
423}
424
[email protected]26418b72011-03-30 14:07:39425Value* PrefService::GetMutableUserPref(const char* path,
[email protected]bab1c13f2011-08-12 20:59:02426 base::Value::Type type) {
[email protected]26418b72011-03-30 14:07:39427 CHECK(type == Value::TYPE_DICTIONARY || type == Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29428 DCHECK(CalledOnValidThread());
429
430 const Preference* pref = FindPreference(path);
431 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40432 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29433 return NULL;
434 }
[email protected]26418b72011-03-30 14:07:39435 if (pref->GetType() != type) {
436 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29437 return NULL;
438 }
439
[email protected]e0250892010-10-01 18:57:53440 // Look for an existing preference in the user store. If it doesn't
441 // exist or isn't the correct type, create a new user preference.
[email protected]26418b72011-03-30 14:07:39442 Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34443 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39444 !value->IsType(type)) {
445 if (type == Value::TYPE_DICTIONARY) {
446 value = new DictionaryValue;
447 } else if (type == Value::TYPE_LIST) {
448 value = new ListValue;
449 } else {
450 NOTREACHED();
451 }
452 user_pref_store_->SetValueSilently(path, value);
initial.commit09911bf2008-07-26 23:55:29453 }
[email protected]26418b72011-03-30 14:07:39454 return value;
455}
456
[email protected]68bf41a2011-03-25 16:38:31457void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]f89ee342011-03-07 09:28:27458 user_pref_store_->ReportValueChanged(key);
459}
460
[email protected]c3b54f372010-09-14 08:25:07461void PrefService::SetUserPrefValue(const char* path, Value* new_value) {
[email protected]b99c41c2011-04-27 15:18:48462 scoped_ptr<Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07463 DCHECK(CalledOnValidThread());
464
465 const Preference* pref = FindPreference(path);
466 if (!pref) {
467 NOTREACHED() << "Trying to write an unregistered pref: " << path;
468 return;
469 }
[email protected]99cc9a02010-09-17 07:53:28470 if (pref->GetType() != new_value->GetType()) {
471 NOTREACHED() << "Trying to set pref " << path
472 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07473 << " to value of type " << new_value->GetType();
474 return;
475 }
476
[email protected]b99c41c2011-04-27 15:18:48477 user_pref_store_->SetValue(path, owned_value.release());
[email protected]73c47932010-12-06 18:13:43478}
479
[email protected]5b199522012-12-22 17:24:44480void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
481 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05482}
483
initial.commit09911bf2008-07-26 23:55:29484///////////////////////////////////////////////////////////////////////////////
485// PrefService::Preference
486
[email protected]c3b54f372010-09-14 08:25:07487PrefService::Preference::Preference(const PrefService* service,
[email protected]9a8c4022011-01-25 14:25:33488 const char* name,
[email protected]bab1c13f2011-08-12 20:59:02489 base::Value::Type type)
[email protected]99cc9a02010-09-17 07:53:28490 : name_(name),
[email protected]9a8c4022011-01-25 14:25:33491 type_(type),
[email protected]c3b54f372010-09-14 08:25:07492 pref_service_(service) {
initial.commit09911bf2008-07-26 23:55:29493 DCHECK(name);
[email protected]c3b54f372010-09-14 08:25:07494 DCHECK(service);
[email protected]99cc9a02010-09-17 07:53:28495}
496
[email protected]fb8fdf12012-08-21 16:28:20497const std::string PrefService::Preference::name() const {
498 return name_;
499}
500
[email protected]bab1c13f2011-08-12 20:59:02501base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33502 return type_;
initial.commit09911bf2008-07-26 23:55:29503}
504
505const Value* PrefService::Preference::GetValue() const {
[email protected]18038f82012-11-20 13:46:58506 const Value* result= pref_service_->GetPreferenceValue(name_);
507 DCHECK(result) << "Must register pref before getting its value";
508 return result;
[email protected]40a47c162010-09-09 11:14:01509}
510
[email protected]7ca0f362012-07-30 10:14:03511const Value* PrefService::Preference::GetRecommendedValue() const {
512 DCHECK(pref_service_->FindPreference(name_.c_str())) <<
513 "Must register pref before getting its value";
514
515 const Value* found_value = NULL;
516 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
517 DCHECK(found_value->IsType(type_));
518 return found_value;
519 }
520
521 // The pref has no recommended value.
522 return NULL;
523}
524
[email protected]40a47c162010-09-09 11:14:01525bool PrefService::Preference::IsManaged() const {
[email protected]887288f02011-02-04 22:52:46526 return pref_value_store()->PrefValueInManagedStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01527}
528
[email protected]a5437282011-12-12 12:33:21529bool PrefService::Preference::IsRecommended() const {
530 return pref_value_store()->PrefValueFromRecommendedStore(name_.c_str());
531}
532
[email protected]40a47c162010-09-09 11:14:01533bool PrefService::Preference::HasExtensionSetting() const {
[email protected]887288f02011-02-04 22:52:46534 return pref_value_store()->PrefValueInExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01535}
536
537bool PrefService::Preference::HasUserSetting() const {
[email protected]887288f02011-02-04 22:52:46538 return pref_value_store()->PrefValueInUserStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01539}
540
541bool PrefService::Preference::IsExtensionControlled() const {
[email protected]887288f02011-02-04 22:52:46542 return pref_value_store()->PrefValueFromExtensionStore(name_.c_str());
[email protected]40a47c162010-09-09 11:14:01543}
544
545bool PrefService::Preference::IsUserControlled() const {
[email protected]887288f02011-02-04 22:52:46546 return pref_value_store()->PrefValueFromUserStore(name_.c_str());
[email protected]c3b54f372010-09-14 08:25:07547}
548
549bool PrefService::Preference::IsDefaultValue() const {
[email protected]887288f02011-02-04 22:52:46550 return pref_value_store()->PrefValueFromDefaultStore(name_.c_str());
[email protected]d7449e82010-07-14 11:42:35551}
[email protected]74379bc52010-07-21 13:54:08552
553bool PrefService::Preference::IsUserModifiable() const {
[email protected]887288f02011-02-04 22:52:46554 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
[email protected]74379bc52010-07-21 13:54:08555}
[email protected]9a28f132011-02-24 21:15:16556
557bool PrefService::Preference::IsExtensionModifiable() const {
558 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
559}
[email protected]18038f82012-11-20 13:46:58560
561const base::Value* PrefService::GetPreferenceValue(
562 const std::string& path) const {
563 DCHECK(CalledOnValidThread());
564 const base::Value::Type type = default_store_->GetType(path);
565 if (type == Value::TYPE_NULL)
566 return NULL;
567 const Value* found_value = NULL;
568 if (pref_value_store_->GetValue(path, type, &found_value)) {
569 DCHECK(found_value->IsType(type));
570 return found_value;
571 }
572
573 // Every registered preference has at least a default value.
574 NOTREACHED() << "no valid value found for registered pref " << path;
575 return NULL;
576}