blob: a9749b2ba836f6423c8d1696c038ae0b5e139cf0 [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]3853a4c2013-02-11 17:15:575#include "base/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]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
skyostil054861d2015-04-30 19:06:1511#include "base/location.h"
initial.commit09911bf2008-07-26 23:55:2912#include "base/logging.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]3853a4c2013-02-11 17:15:5715#include "base/prefs/pref_notifier_impl.h"
16#include "base/prefs/pref_registry.h"
17#include "base/prefs/pref_value_store.h"
skyostil054861d2015-04-30 19:06:1518#include "base/single_thread_task_runner.h"
[email protected]7286e3fc2011-07-19 22:13:2419#include "base/stl_util.h"
[email protected]3ea1b182013-02-08 22:38:4120#include "base/strings/string_number_conversions.h"
[email protected]d529cb02013-06-10 19:06:5721#include "base/strings/string_util.h"
skyostil054861d2015-04-30 19:06:1522#include "base/thread_task_runner_handle.h"
[email protected]8703b2b2011-03-15 09:51:5023#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4024#include "build/build_config.h"
initial.commit09911bf2008-07-26 23:55:2925
26namespace {
27
[email protected]845b43a82011-05-11 10:14:4328class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
29 public:
[email protected]70a317a2012-12-19 20:59:3330 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb)
31 : callback_(cb) {}
[email protected]845b43a82011-05-11 10:14:4332
dcheng56488182014-10-21 10:54:5133 void OnError(PersistentPrefStore::PrefReadError error) override {
[email protected]70a317a2012-12-19 20:59:3334 callback_.Run(error);
[email protected]845b43a82011-05-11 10:14:4335 }
[email protected]70a317a2012-12-19 20:59:3336
37 private:
38 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_;
[email protected]845b43a82011-05-11 10:14:4339};
40
raymes76de1af2015-05-06 03:22:2141// Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
42// |path|.
raymesf3a929b02015-05-07 03:54:4543uint32 GetWriteFlags(const PrefService::Preference* pref) {
raymes76de1af2015-05-06 03:22:2144 uint32 write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
raymesf3a929b02015-05-07 03:54:4545
46 if (!pref)
47 return write_flags;
48
raymes76de1af2015-05-06 03:22:2149 if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
raymesf3a929b02015-05-07 03:54:4550 write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
raymes76de1af2015-05-06 03:22:2151 return write_flags;
52}
53
initial.commit09911bf2008-07-26 23:55:2954} // namespace
55
[email protected]70a317a2012-12-19 20:59:3356PrefService::PrefService(
57 PrefNotifierImpl* pref_notifier,
58 PrefValueStore* pref_value_store,
59 PersistentPrefStore* user_prefs,
[email protected]b1de2c72013-02-06 02:45:4760 PrefRegistry* pref_registry,
[email protected]70a317a2012-12-19 20:59:3361 base::Callback<void(PersistentPrefStore::PrefReadError)>
62 read_error_callback,
63 bool async)
[email protected]361d37f62011-11-22 10:37:0264 : pref_notifier_(pref_notifier),
65 pref_value_store_(pref_value_store),
[email protected]b1de2c72013-02-06 02:45:4766 pref_registry_(pref_registry),
[email protected]361d37f62011-11-22 10:37:0267 user_pref_store_(user_prefs),
[email protected]5b199522012-12-22 17:24:4468 read_error_callback_(read_error_callback) {
[email protected]361d37f62011-11-22 10:37:0269 pref_notifier_->SetPrefService(this);
[email protected]b1de2c72013-02-06 02:45:4770
battre0a69def2015-01-05 18:50:1971 // TODO(battre): This is a check for crbug.com/435208 to make sure that
72 // access violations are caused by a use-after-free bug and not by an
73 // initialization bug.
74 CHECK(pref_registry_);
75 CHECK(pref_value_store_);
76
[email protected]361d37f62011-11-22 10:37:0277 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:3378}
79
initial.commit09911bf2008-07-26 23:55:2980PrefService::~PrefService() {
81 DCHECK(CalledOnValidThread());
[email protected]a98ce1262011-01-28 13:20:2382
[email protected]a98ce1262011-01-28 13:20:2383 // Reset pointers so accesses after destruction reliably crash.
84 pref_value_store_.reset();
[email protected]b1de2c72013-02-06 02:45:4785 pref_registry_ = NULL;
[email protected]a98ce1262011-01-28 13:20:2386 user_pref_store_ = NULL;
[email protected]42f23782012-06-08 19:11:5387 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:2988}
89
[email protected]845b43a82011-05-11 10:14:4390void PrefService::InitFromStorage(bool async) {
[email protected]38d1aab2014-03-29 17:48:4991 if (user_pref_store_->IsInitializationComplete()) {
92 read_error_callback_.Run(user_pref_store_->GetReadError());
93 } else if (!async) {
[email protected]70a317a2012-12-19 20:59:3394 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:2195 } else {
[email protected]845b43a82011-05-11 10:14:4396 // Guarantee that initialization happens after this function returned.
skyostil054861d2015-04-30 19:06:1597 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]845b43a82011-05-11 10:14:4398 FROM_HERE,
skyostil054861d2015-04-30 19:06:1599 base::Bind(&PersistentPrefStore::ReadPrefsAsync, user_pref_store_.get(),
[email protected]70a317a2012-12-19 20:59:33100 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:21101 }
[email protected]ba399672010-04-06 15:42:39102}
103
[email protected]3826fed2011-03-25 10:59:56104void PrefService::CommitPendingWrite() {
105 DCHECK(CalledOnValidThread());
106 user_pref_store_->CommitPendingWrite();
107}
108
benwells26730592015-05-28 13:08:08109void PrefService::SchedulePendingLossyWrites() {
110 DCHECK(CalledOnValidThread());
111 user_pref_store_->SchedulePendingLossyWrites();
112}
113
georgesak7da6e9d2014-12-03 01:10:29114bool PrefService::GetBoolean(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29115 DCHECK(CalledOnValidThread());
116
117 bool result = false;
initial.commit09911bf2008-07-26 23:55:29118
[email protected]18038f82012-11-20 13:46:58119 const base::Value* value = GetPreferenceValue(path);
120 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40121 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29122 return result;
123 }
[email protected]18038f82012-11-20 13:46:58124 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29125 DCHECK(rv);
126 return result;
127}
128
georgesak7da6e9d2014-12-03 01:10:29129int PrefService::GetInteger(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29130 DCHECK(CalledOnValidThread());
131
132 int result = 0;
initial.commit09911bf2008-07-26 23:55:29133
[email protected]18038f82012-11-20 13:46:58134 const base::Value* value = GetPreferenceValue(path);
135 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40136 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29137 return result;
138 }
[email protected]18038f82012-11-20 13:46:58139 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29140 DCHECK(rv);
141 return result;
142}
143
georgesak7da6e9d2014-12-03 01:10:29144double PrefService::GetDouble(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29145 DCHECK(CalledOnValidThread());
146
147 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29148
[email protected]18038f82012-11-20 13:46:58149 const base::Value* value = GetPreferenceValue(path);
150 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40151 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29152 return result;
153 }
[email protected]18038f82012-11-20 13:46:58154 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29155 DCHECK(rv);
156 return result;
157}
158
georgesak7da6e9d2014-12-03 01:10:29159std::string PrefService::GetString(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29160 DCHECK(CalledOnValidThread());
161
[email protected]ddd231e2010-06-29 20:35:19162 std::string result;
[email protected]8e50b602009-03-03 22:59:43163
[email protected]18038f82012-11-20 13:46:58164 const base::Value* value = GetPreferenceValue(path);
165 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40166 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29167 return result;
168 }
[email protected]18038f82012-11-20 13:46:58169 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29170 DCHECK(rv);
171 return result;
172}
173
georgesak7da6e9d2014-12-03 01:10:29174base::FilePath PrefService::GetFilePath(const std::string& path) const {
[email protected]b9636002009-03-04 00:05:25175 DCHECK(CalledOnValidThread());
176
[email protected]650b2d52013-02-10 03:41:45177 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25178
[email protected]18038f82012-11-20 13:46:58179 const base::Value* value = GetPreferenceValue(path);
180 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40181 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45182 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25183 }
[email protected]18038f82012-11-20 13:46:58184 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25185 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04186 return result;
[email protected]b9636002009-03-04 00:05:25187}
188
georgesak7da6e9d2014-12-03 01:10:29189bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33190 const Preference* pref = FindPreference(path);
191 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29192}
193
[email protected]ddf421c32013-11-01 00:52:35194scoped_ptr<base::DictionaryValue> PrefService::GetPreferenceValues() const {
[email protected]ebd0b022011-01-27 13:24:14195 DCHECK(CalledOnValidThread());
[email protected]ddf421c32013-11-01 00:52:35196 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18197 for (const auto& it : *pref_registry_) {
estadea68b0442015-05-12 18:11:50198 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
asvitkine36ff0c5822014-11-25 22:58:18199 }
200 return out.Pass();
201}
202
203scoped_ptr<base::DictionaryValue> PrefService::GetPreferenceValuesOmitDefaults()
204 const {
205 DCHECK(CalledOnValidThread());
206 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
207 for (const auto& it : *pref_registry_) {
georgesak7da6e9d2014-12-03 01:10:29208 const Preference* pref = FindPreference(it.first);
asvitkine36ff0c5822014-11-25 22:58:18209 if (pref->IsDefaultValue())
210 continue;
estadea68b0442015-05-12 18:11:50211 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
[email protected]ebd0b022011-01-27 13:24:14212 }
[email protected]ddf421c32013-11-01 00:52:35213 return out.Pass();
[email protected]ebd0b022011-01-27 13:24:14214}
215
[email protected]ddf421c32013-11-01 00:52:35216scoped_ptr<base::DictionaryValue>
217PrefService::GetPreferenceValuesWithoutPathExpansion() const {
[email protected]2a1965c2013-10-02 16:07:01218 DCHECK(CalledOnValidThread());
[email protected]ddf421c32013-11-01 00:52:35219 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18220 for (const auto& it : *pref_registry_) {
221 const base::Value* value = GetPreferenceValue(it.first);
[email protected]2a1965c2013-10-02 16:07:01222 DCHECK(value);
estadea68b0442015-05-12 18:11:50223 out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
[email protected]2a1965c2013-10-02 16:07:01224 }
[email protected]ddf421c32013-11-01 00:52:35225 return out.Pass();
[email protected]2a1965c2013-10-02 16:07:01226}
227
initial.commit09911bf2008-07-26 23:55:29228const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29229 const std::string& pref_name) const {
initial.commit09911bf2008-07-26 23:55:29230 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42231 PreferenceMap::iterator it = prefs_map_.find(pref_name);
232 if (it != prefs_map_.end())
233 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47234 const base::Value* default_value = NULL;
235 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33236 return NULL;
[email protected]d15d5682012-10-23 17:50:42237 it = prefs_map_.insert(
[email protected]b1de2c72013-02-06 02:45:47238 std::make_pair(pref_name, Preference(
239 this, pref_name, default_value->GetType()))).first;
[email protected]d15d5682012-10-23 17:50:42240 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29241}
242
[email protected]acd78969c2010-12-08 09:49:11243bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17244 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11245}
246
[email protected]59c10712012-03-13 02:10:34247PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
248 const {
249 if (!user_pref_store_->IsInitializationComplete())
250 return INITIALIZATION_STATUS_WAITING;
251
252 switch (user_pref_store_->GetReadError()) {
253 case PersistentPrefStore::PREF_READ_ERROR_NONE:
254 return INITIALIZATION_STATUS_SUCCESS;
255 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18256 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34257 default:
258 return INITIALIZATION_STATUS_ERROR;
259 }
260}
261
georgesak7da6e9d2014-12-03 01:10:29262bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48263 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33264 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48265}
266
khannansb2025b72014-12-19 16:04:25267bool PrefService::IsPreferenceManagedByCustodian(
268 const std::string& pref_name) const {
269 const Preference* pref = FindPreference(pref_name);
270 return pref && pref->IsManagedByCustodian();
271}
272
georgesak7da6e9d2014-12-03 01:10:29273bool PrefService::IsUserModifiablePreference(
274 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07275 const Preference* pref = FindPreference(pref_name);
276 return pref && pref->IsUserModifiable();
277}
278
[email protected]a43a667b2013-06-14 17:56:08279const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29280 const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29281 DCHECK(CalledOnValidThread());
282
[email protected]a43a667b2013-06-14 17:56:08283 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58284 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40285 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29286 return NULL;
287 }
[email protected]a43a667b2013-06-14 17:56:08288 if (value->GetType() != base::Value::TYPE_DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25289 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29290 return NULL;
[email protected]11b040b2011-02-02 12:42:25291 }
[email protected]a43a667b2013-06-14 17:56:08292 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29293}
294
georgesak7da6e9d2014-12-03 01:10:29295const base::Value* PrefService::GetUserPrefValue(
296 const std::string& path) const {
[email protected]1a5a31f2012-04-26 20:21:34297 DCHECK(CalledOnValidThread());
298
299 const Preference* pref = FindPreference(path);
300 if (!pref) {
301 NOTREACHED() << "Trying to get an unregistered pref: " << path;
302 return NULL;
303 }
304
305 // Look for an existing preference in the user store. If it doesn't
306 // exist, return NULL.
307 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34308 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34309 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34310
311 if (!value->IsType(pref->GetType())) {
312 NOTREACHED() << "Pref value type doesn't match registered type.";
313 return NULL;
314 }
315
316 return value;
317}
318
georgesak7da6e9d2014-12-03 01:10:29319void PrefService::SetDefaultPrefValue(const std::string& path,
[email protected]5879cef2013-03-02 17:02:25320 base::Value* value) {
321 DCHECK(CalledOnValidThread());
322 pref_registry_->SetDefaultPrefValue(path, value);
323}
324
georgesak7da6e9d2014-12-03 01:10:29325const base::Value* PrefService::GetDefaultPrefValue(
326 const std::string& path) const {
[email protected]35a6fd12012-05-28 18:08:08327 DCHECK(CalledOnValidThread());
328 // Lookup the preference in the default store.
329 const base::Value* value = NULL;
[email protected]b1de2c72013-02-06 02:45:47330 if (!pref_registry_->defaults()->GetValue(path, &value)) {
[email protected]35a6fd12012-05-28 18:08:08331 NOTREACHED() << "Default value missing for pref: " << path;
332 return NULL;
333 }
334 return value;
335}
336
georgesak7da6e9d2014-12-03 01:10:29337const base::ListValue* PrefService::GetList(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29338 DCHECK(CalledOnValidThread());
339
[email protected]a43a667b2013-06-14 17:56:08340 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58341 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40342 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29343 return NULL;
344 }
[email protected]a43a667b2013-06-14 17:56:08345 if (value->GetType() != base::Value::TYPE_LIST) {
[email protected]11b040b2011-02-02 12:42:25346 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29347 return NULL;
[email protected]11b040b2011-02-02 12:42:25348 }
[email protected]a43a667b2013-06-14 17:56:08349 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29350}
351
georgesak7da6e9d2014-12-03 01:10:29352void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50353 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29354}
355
georgesak7da6e9d2014-12-03 01:10:29356void PrefService::RemovePrefObserver(const std::string& path,
357 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50358 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29359}
360
[email protected]a6a7ced2012-11-01 17:24:18361void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
362 pref_notifier_->AddInitObserver(obs);
363}
364
[email protected]b1de2c72013-02-06 02:45:47365PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
366 return pref_registry_.get();
367}
368
georgesak7da6e9d2014-12-03 01:10:29369void PrefService::ClearPref(const std::string& path) {
initial.commit09911bf2008-07-26 23:55:29370 DCHECK(CalledOnValidThread());
371
372 const Preference* pref = FindPreference(path);
373 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40374 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29375 return;
376 }
raymesf3a929b02015-05-07 03:54:45377 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29378}
379
georgesak7da6e9d2014-12-03 01:10:29380void PrefService::Set(const std::string& path, const base::Value& value) {
[email protected]b99c41c2011-04-27 15:18:48381 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39382}
383
georgesak7da6e9d2014-12-03 01:10:29384void PrefService::SetBoolean(const std::string& path, bool value) {
[email protected]b54e6252014-01-30 10:32:41385 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29386}
387
georgesak7da6e9d2014-12-03 01:10:29388void PrefService::SetInteger(const std::string& path, int value) {
[email protected]b54e6252014-01-30 10:32:41389 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29390}
391
georgesak7da6e9d2014-12-03 01:10:29392void PrefService::SetDouble(const std::string& path, double value) {
[email protected]b54e6252014-01-30 10:32:41393 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29394}
395
georgesak7da6e9d2014-12-03 01:10:29396void PrefService::SetString(const std::string& path, const std::string& value) {
[email protected]b54e6252014-01-30 10:32:41397 SetUserPrefValue(path, new base::StringValue(value));
initial.commit09911bf2008-07-26 23:55:29398}
399
georgesak7da6e9d2014-12-03 01:10:29400void PrefService::SetFilePath(const std::string& path,
401 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50402 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25403}
404
georgesak7da6e9d2014-12-03 01:10:29405void PrefService::SetInt64(const std::string& path, int64 value) {
[email protected]b54e6252014-01-30 10:32:41406 SetUserPrefValue(path, new base::StringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32407}
408
georgesak7da6e9d2014-12-03 01:10:29409int64 PrefService::GetInt64(const std::string& path) const {
[email protected]0bb1a622009-03-04 03:22:32410 DCHECK(CalledOnValidThread());
411
[email protected]a43a667b2013-06-14 17:56:08412 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58413 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40414 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08415 return 0;
[email protected]0bb1a622009-03-04 03:22:32416 }
[email protected]dc9a6762010-08-16 07:13:53417 std::string result("0");
[email protected]18038f82012-11-20 13:46:58418 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32419 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25420
421 int64 val;
[email protected]dc9a6762010-08-16 07:13:53422 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25423 return val;
[email protected]0bb1a622009-03-04 03:22:32424}
425
georgesak7da6e9d2014-12-03 01:10:29426void PrefService::SetUint64(const std::string& path, uint64 value) {
[email protected]b54e6252014-01-30 10:32:41427 SetUserPrefValue(path, new base::StringValue(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43428}
429
georgesak7da6e9d2014-12-03 01:10:29430uint64 PrefService::GetUint64(const std::string& path) const {
[email protected]3cbe0812012-07-03 02:51:43431 DCHECK(CalledOnValidThread());
432
[email protected]a43a667b2013-06-14 17:56:08433 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58434 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43435 NOTREACHED() << "Trying to read an unregistered pref: " << path;
436 return 0;
437 }
438 std::string result("0");
[email protected]18038f82012-11-20 13:46:58439 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43440 DCHECK(rv);
441
442 uint64 val;
443 base::StringToUint64(result, &val);
444 return val;
445}
446
georgesak7da6e9d2014-12-03 01:10:29447base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08448 base::Value::Type type) {
449 CHECK(type == base::Value::TYPE_DICTIONARY || type == base::Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29450 DCHECK(CalledOnValidThread());
451
452 const Preference* pref = FindPreference(path);
453 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40454 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29455 return NULL;
456 }
[email protected]26418b72011-03-30 14:07:39457 if (pref->GetType() != type) {
458 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29459 return NULL;
460 }
461
[email protected]e0250892010-10-01 18:57:53462 // Look for an existing preference in the user store. If it doesn't
463 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08464 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34465 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39466 !value->IsType(type)) {
[email protected]a43a667b2013-06-14 17:56:08467 if (type == base::Value::TYPE_DICTIONARY) {
468 value = new base::DictionaryValue;
469 } else if (type == base::Value::TYPE_LIST) {
470 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39471 } else {
472 NOTREACHED();
473 }
raymesf3a929b02015-05-07 03:54:45474 user_pref_store_->SetValueSilently(path, value, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29475 }
[email protected]26418b72011-03-30 14:07:39476 return value;
477}
478
[email protected]68bf41a2011-03-25 16:38:31479void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]86bb4e652014-07-10 17:09:51480 DCHECK(CalledOnValidThread());
raymesf3a929b02015-05-07 03:54:45481 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27482}
483
georgesak7da6e9d2014-12-03 01:10:29484void PrefService::SetUserPrefValue(const std::string& path,
485 base::Value* new_value) {
[email protected]a43a667b2013-06-14 17:56:08486 scoped_ptr<base::Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07487 DCHECK(CalledOnValidThread());
488
489 const Preference* pref = FindPreference(path);
490 if (!pref) {
491 NOTREACHED() << "Trying to write an unregistered pref: " << path;
492 return;
493 }
[email protected]99cc9a02010-09-17 07:53:28494 if (pref->GetType() != new_value->GetType()) {
495 NOTREACHED() << "Trying to set pref " << path
496 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07497 << " to value of type " << new_value->GetType();
498 return;
499 }
500
raymesf3a929b02015-05-07 03:54:45501 user_pref_store_->SetValue(path, owned_value.release(), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43502}
503
[email protected]5b199522012-12-22 17:24:44504void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
505 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05506}
507
initial.commit09911bf2008-07-26 23:55:29508///////////////////////////////////////////////////////////////////////////////
509// PrefService::Preference
510
[email protected]c3b54f372010-09-14 08:25:07511PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29512 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02513 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29514 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07515 DCHECK(service);
raymes76de1af2015-05-06 03:22:21516 // Cache the registration flags at creation time to avoid multiple map lookups
517 // later.
518 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28519}
520
[email protected]fb8fdf12012-08-21 16:28:20521const std::string PrefService::Preference::name() const {
522 return name_;
523}
524
[email protected]bab1c13f2011-08-12 20:59:02525base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33526 return type_;
initial.commit09911bf2008-07-26 23:55:29527}
528
[email protected]a43a667b2013-06-14 17:56:08529const base::Value* PrefService::Preference::GetValue() const {
530 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58531 DCHECK(result) << "Must register pref before getting its value";
532 return result;
[email protected]40a47c162010-09-09 11:14:01533}
534
[email protected]a43a667b2013-06-14 17:56:08535const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29536 DCHECK(pref_service_->FindPreference(name_))
537 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03538
[email protected]a43a667b2013-06-14 17:56:08539 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03540 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
541 DCHECK(found_value->IsType(type_));
542 return found_value;
543 }
544
545 // The pref has no recommended value.
546 return NULL;
547}
548
[email protected]40a47c162010-09-09 11:14:01549bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29550 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01551}
552
khannansb2025b72014-12-19 16:04:25553bool PrefService::Preference::IsManagedByCustodian() const {
554 return pref_value_store()->PrefValueInSupervisedStore(name_.c_str());
555}
556
[email protected]a5437282011-12-12 12:33:21557bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29558 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21559}
560
[email protected]40a47c162010-09-09 11:14:01561bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29562 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01563}
564
565bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29566 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01567}
568
569bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29570 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01571}
572
573bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29574 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07575}
576
577bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29578 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35579}
[email protected]74379bc52010-07-21 13:54:08580
581bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29582 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08583}
[email protected]9a28f132011-02-24 21:15:16584
585bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29586 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16587}
[email protected]18038f82012-11-20 13:46:58588
589const base::Value* PrefService::GetPreferenceValue(
590 const std::string& path) const {
591 DCHECK(CalledOnValidThread());
battre0a69def2015-01-05 18:50:19592
593 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
594 // crash dumps it looks like the PrefService is accessed even though it has
595 // been cleared already.
596 CHECK(pref_registry_);
597 CHECK(pref_registry_->defaults());
598 CHECK(pref_value_store_);
599
[email protected]a43a667b2013-06-14 17:56:08600 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47601 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08602 const base::Value* found_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47603 base::Value::Type default_type = default_value->GetType();
604 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
605 DCHECK(found_value->IsType(default_type));
606 return found_value;
607 } else {
608 // Every registered preference has at least a default value.
609 NOTREACHED() << "no valid value found for registered pref " << path;
610 }
[email protected]18038f82012-11-20 13:46:58611 }
612
[email protected]18038f82012-11-20 13:46:58613 return NULL;
614}