blob: aaf9fa7bbab746756650ed1915e9c980164c8a31 [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
brettwf00b9b42016-02-01 22:11:385#include "components/prefs/pref_service.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]1cb92b82010-03-08 23:12:157#include <algorithm>
danakj0c8d4aa2015-11-25 05:29:588#include <utility>
[email protected]1cb92b82010-03-08 23:12:159
[email protected]bebe69432011-09-28 18:36:4510#include "base/bind.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
skyostil054861d2015-04-30 19:06:1512#include "base/location.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3814#include "base/metrics/histogram.h"
skyostil054861d2015-04-30 19:06:1515#include "base/single_thread_task_runner.h"
[email protected]7286e3fc2011-07-19 22:13:2416#include "base/stl_util.h"
[email protected]3ea1b182013-02-08 22:38:4117#include "base/strings/string_number_conversions.h"
[email protected]d529cb02013-06-10 19:06:5718#include "base/strings/string_util.h"
skyostil054861d2015-04-30 19:06:1519#include "base/thread_task_runner_handle.h"
[email protected]8703b2b2011-03-15 09:51:5020#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4021#include "build/build_config.h"
brettwf00b9b42016-02-01 22:11:3822#include "components/prefs/default_pref_store.h"
23#include "components/prefs/pref_notifier_impl.h"
24#include "components/prefs/pref_registry.h"
25#include "components/prefs/pref_value_store.h"
initial.commit09911bf2008-07-26 23:55:2926
27namespace {
28
[email protected]845b43a82011-05-11 10:14:4329class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
30 public:
[email protected]70a317a2012-12-19 20:59:3331 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb)
32 : callback_(cb) {}
[email protected]845b43a82011-05-11 10:14:4333
dcheng56488182014-10-21 10:54:5134 void OnError(PersistentPrefStore::PrefReadError error) override {
[email protected]70a317a2012-12-19 20:59:3335 callback_.Run(error);
[email protected]845b43a82011-05-11 10:14:4336 }
[email protected]70a317a2012-12-19 20:59:3337
38 private:
39 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_;
[email protected]845b43a82011-05-11 10:14:4340};
41
raymes76de1af2015-05-06 03:22:2142// Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
43// |path|.
avi9ef8bb02015-12-24 05:29:3644uint32_t GetWriteFlags(const PrefService::Preference* pref) {
45 uint32_t write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
raymesf3a929b02015-05-07 03:54:4546
47 if (!pref)
48 return write_flags;
49
raymes76de1af2015-05-06 03:22:2150 if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
raymesf3a929b02015-05-07 03:54:4551 write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
raymes76de1af2015-05-06 03:22:2152 return write_flags;
53}
54
initial.commit09911bf2008-07-26 23:55:2955} // namespace
56
[email protected]70a317a2012-12-19 20:59:3357PrefService::PrefService(
58 PrefNotifierImpl* pref_notifier,
59 PrefValueStore* pref_value_store,
60 PersistentPrefStore* user_prefs,
[email protected]b1de2c72013-02-06 02:45:4761 PrefRegistry* pref_registry,
[email protected]70a317a2012-12-19 20:59:3362 base::Callback<void(PersistentPrefStore::PrefReadError)>
63 read_error_callback,
64 bool async)
[email protected]361d37f62011-11-22 10:37:0265 : pref_notifier_(pref_notifier),
66 pref_value_store_(pref_value_store),
[email protected]b1de2c72013-02-06 02:45:4767 pref_registry_(pref_registry),
[email protected]361d37f62011-11-22 10:37:0268 user_pref_store_(user_prefs),
[email protected]5b199522012-12-22 17:24:4469 read_error_callback_(read_error_callback) {
[email protected]361d37f62011-11-22 10:37:0270 pref_notifier_->SetPrefService(this);
[email protected]b1de2c72013-02-06 02:45:4771
battre0a69def2015-01-05 18:50:1972 // TODO(battre): This is a check for crbug.com/435208 to make sure that
73 // access violations are caused by a use-after-free bug and not by an
74 // initialization bug.
75 CHECK(pref_registry_);
76 CHECK(pref_value_store_);
77
[email protected]361d37f62011-11-22 10:37:0278 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:3379}
80
initial.commit09911bf2008-07-26 23:55:2981PrefService::~PrefService() {
82 DCHECK(CalledOnValidThread());
[email protected]a98ce1262011-01-28 13:20:2383
[email protected]a98ce1262011-01-28 13:20:2384 // Reset pointers so accesses after destruction reliably crash.
85 pref_value_store_.reset();
[email protected]b1de2c72013-02-06 02:45:4786 pref_registry_ = NULL;
[email protected]a98ce1262011-01-28 13:20:2387 user_pref_store_ = NULL;
[email protected]42f23782012-06-08 19:11:5388 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:2989}
90
[email protected]845b43a82011-05-11 10:14:4391void PrefService::InitFromStorage(bool async) {
[email protected]38d1aab2014-03-29 17:48:4992 if (user_pref_store_->IsInitializationComplete()) {
93 read_error_callback_.Run(user_pref_store_->GetReadError());
94 } else if (!async) {
[email protected]70a317a2012-12-19 20:59:3395 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:2196 } else {
[email protected]845b43a82011-05-11 10:14:4397 // Guarantee that initialization happens after this function returned.
skyostil054861d2015-04-30 19:06:1598 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]845b43a82011-05-11 10:14:4399 FROM_HERE,
skyostil054861d2015-04-30 19:06:15100 base::Bind(&PersistentPrefStore::ReadPrefsAsync, user_pref_store_.get(),
[email protected]70a317a2012-12-19 20:59:33101 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:21102 }
[email protected]ba399672010-04-06 15:42:39103}
104
[email protected]3826fed2011-03-25 10:59:56105void PrefService::CommitPendingWrite() {
106 DCHECK(CalledOnValidThread());
107 user_pref_store_->CommitPendingWrite();
108}
109
benwells26730592015-05-28 13:08:08110void PrefService::SchedulePendingLossyWrites() {
111 DCHECK(CalledOnValidThread());
112 user_pref_store_->SchedulePendingLossyWrites();
113}
114
georgesak7da6e9d2014-12-03 01:10:29115bool PrefService::GetBoolean(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29116 DCHECK(CalledOnValidThread());
117
118 bool result = false;
initial.commit09911bf2008-07-26 23:55:29119
[email protected]18038f82012-11-20 13:46:58120 const base::Value* value = GetPreferenceValue(path);
121 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40122 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29123 return result;
124 }
[email protected]18038f82012-11-20 13:46:58125 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29126 DCHECK(rv);
127 return result;
128}
129
georgesak7da6e9d2014-12-03 01:10:29130int PrefService::GetInteger(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29131 DCHECK(CalledOnValidThread());
132
133 int result = 0;
initial.commit09911bf2008-07-26 23:55:29134
[email protected]18038f82012-11-20 13:46:58135 const base::Value* value = GetPreferenceValue(path);
136 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40137 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29138 return result;
139 }
[email protected]18038f82012-11-20 13:46:58140 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29141 DCHECK(rv);
142 return result;
143}
144
georgesak7da6e9d2014-12-03 01:10:29145double PrefService::GetDouble(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29146 DCHECK(CalledOnValidThread());
147
148 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29149
[email protected]18038f82012-11-20 13:46:58150 const base::Value* value = GetPreferenceValue(path);
151 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40152 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29153 return result;
154 }
[email protected]18038f82012-11-20 13:46:58155 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29156 DCHECK(rv);
157 return result;
158}
159
georgesak7da6e9d2014-12-03 01:10:29160std::string PrefService::GetString(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29161 DCHECK(CalledOnValidThread());
162
[email protected]ddd231e2010-06-29 20:35:19163 std::string result;
[email protected]8e50b602009-03-03 22:59:43164
[email protected]18038f82012-11-20 13:46:58165 const base::Value* value = GetPreferenceValue(path);
166 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40167 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29168 return result;
169 }
[email protected]18038f82012-11-20 13:46:58170 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29171 DCHECK(rv);
172 return result;
173}
174
georgesak7da6e9d2014-12-03 01:10:29175base::FilePath PrefService::GetFilePath(const std::string& path) const {
[email protected]b9636002009-03-04 00:05:25176 DCHECK(CalledOnValidThread());
177
[email protected]650b2d52013-02-10 03:41:45178 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25179
[email protected]18038f82012-11-20 13:46:58180 const base::Value* value = GetPreferenceValue(path);
181 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40182 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45183 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25184 }
[email protected]18038f82012-11-20 13:46:58185 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25186 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04187 return result;
[email protected]b9636002009-03-04 00:05:25188}
189
georgesak7da6e9d2014-12-03 01:10:29190bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33191 const Preference* pref = FindPreference(path);
192 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29193}
194
[email protected]ddf421c32013-11-01 00:52:35195scoped_ptr<base::DictionaryValue> PrefService::GetPreferenceValues() const {
[email protected]ebd0b022011-01-27 13:24:14196 DCHECK(CalledOnValidThread());
[email protected]ddf421c32013-11-01 00:52:35197 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18198 for (const auto& it : *pref_registry_) {
estadea68b0442015-05-12 18:11:50199 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
asvitkine36ff0c5822014-11-25 22:58:18200 }
danakj0c8d4aa2015-11-25 05:29:58201 return out;
asvitkine36ff0c5822014-11-25 22:58:18202}
203
204scoped_ptr<base::DictionaryValue> PrefService::GetPreferenceValuesOmitDefaults()
205 const {
206 DCHECK(CalledOnValidThread());
207 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
208 for (const auto& it : *pref_registry_) {
georgesak7da6e9d2014-12-03 01:10:29209 const Preference* pref = FindPreference(it.first);
asvitkine36ff0c5822014-11-25 22:58:18210 if (pref->IsDefaultValue())
211 continue;
estadea68b0442015-05-12 18:11:50212 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
[email protected]ebd0b022011-01-27 13:24:14213 }
danakj0c8d4aa2015-11-25 05:29:58214 return out;
[email protected]ebd0b022011-01-27 13:24:14215}
216
[email protected]ddf421c32013-11-01 00:52:35217scoped_ptr<base::DictionaryValue>
218PrefService::GetPreferenceValuesWithoutPathExpansion() const {
[email protected]2a1965c2013-10-02 16:07:01219 DCHECK(CalledOnValidThread());
[email protected]ddf421c32013-11-01 00:52:35220 scoped_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18221 for (const auto& it : *pref_registry_) {
222 const base::Value* value = GetPreferenceValue(it.first);
[email protected]2a1965c2013-10-02 16:07:01223 DCHECK(value);
estadea68b0442015-05-12 18:11:50224 out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
[email protected]2a1965c2013-10-02 16:07:01225 }
danakj0c8d4aa2015-11-25 05:29:58226 return out;
[email protected]2a1965c2013-10-02 16:07:01227}
228
initial.commit09911bf2008-07-26 23:55:29229const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29230 const std::string& pref_name) const {
initial.commit09911bf2008-07-26 23:55:29231 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42232 PreferenceMap::iterator it = prefs_map_.find(pref_name);
233 if (it != prefs_map_.end())
234 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47235 const base::Value* default_value = NULL;
236 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33237 return NULL;
[email protected]d15d5682012-10-23 17:50:42238 it = prefs_map_.insert(
[email protected]b1de2c72013-02-06 02:45:47239 std::make_pair(pref_name, Preference(
240 this, pref_name, default_value->GetType()))).first;
[email protected]d15d5682012-10-23 17:50:42241 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29242}
243
[email protected]acd78969c2010-12-08 09:49:11244bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17245 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11246}
247
[email protected]59c10712012-03-13 02:10:34248PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
249 const {
250 if (!user_pref_store_->IsInitializationComplete())
251 return INITIALIZATION_STATUS_WAITING;
252
253 switch (user_pref_store_->GetReadError()) {
254 case PersistentPrefStore::PREF_READ_ERROR_NONE:
255 return INITIALIZATION_STATUS_SUCCESS;
256 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18257 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34258 default:
259 return INITIALIZATION_STATUS_ERROR;
260 }
261}
262
georgesak7da6e9d2014-12-03 01:10:29263bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48264 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33265 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48266}
267
khannansb2025b72014-12-19 16:04:25268bool PrefService::IsPreferenceManagedByCustodian(
269 const std::string& pref_name) const {
270 const Preference* pref = FindPreference(pref_name);
271 return pref && pref->IsManagedByCustodian();
272}
273
georgesak7da6e9d2014-12-03 01:10:29274bool PrefService::IsUserModifiablePreference(
275 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07276 const Preference* pref = FindPreference(pref_name);
277 return pref && pref->IsUserModifiable();
278}
279
[email protected]a43a667b2013-06-14 17:56:08280const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29281 const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29282 DCHECK(CalledOnValidThread());
283
[email protected]a43a667b2013-06-14 17:56:08284 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58285 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40286 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29287 return NULL;
288 }
[email protected]a43a667b2013-06-14 17:56:08289 if (value->GetType() != base::Value::TYPE_DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25290 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29291 return NULL;
[email protected]11b040b2011-02-02 12:42:25292 }
[email protected]a43a667b2013-06-14 17:56:08293 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29294}
295
georgesak7da6e9d2014-12-03 01:10:29296const base::Value* PrefService::GetUserPrefValue(
297 const std::string& path) const {
[email protected]1a5a31f2012-04-26 20:21:34298 DCHECK(CalledOnValidThread());
299
300 const Preference* pref = FindPreference(path);
301 if (!pref) {
302 NOTREACHED() << "Trying to get an unregistered pref: " << path;
303 return NULL;
304 }
305
306 // Look for an existing preference in the user store. If it doesn't
307 // exist, return NULL.
308 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34309 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34310 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34311
312 if (!value->IsType(pref->GetType())) {
313 NOTREACHED() << "Pref value type doesn't match registered type.";
314 return NULL;
315 }
316
317 return value;
318}
319
georgesak7da6e9d2014-12-03 01:10:29320void PrefService::SetDefaultPrefValue(const std::string& path,
[email protected]5879cef2013-03-02 17:02:25321 base::Value* value) {
322 DCHECK(CalledOnValidThread());
323 pref_registry_->SetDefaultPrefValue(path, value);
324}
325
georgesak7da6e9d2014-12-03 01:10:29326const base::Value* PrefService::GetDefaultPrefValue(
327 const std::string& path) const {
[email protected]35a6fd12012-05-28 18:08:08328 DCHECK(CalledOnValidThread());
329 // Lookup the preference in the default store.
330 const base::Value* value = NULL;
[email protected]b1de2c72013-02-06 02:45:47331 if (!pref_registry_->defaults()->GetValue(path, &value)) {
[email protected]35a6fd12012-05-28 18:08:08332 NOTREACHED() << "Default value missing for pref: " << path;
333 return NULL;
334 }
335 return value;
336}
337
georgesak7da6e9d2014-12-03 01:10:29338const base::ListValue* PrefService::GetList(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29339 DCHECK(CalledOnValidThread());
340
[email protected]a43a667b2013-06-14 17:56:08341 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58342 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40343 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29344 return NULL;
345 }
[email protected]a43a667b2013-06-14 17:56:08346 if (value->GetType() != base::Value::TYPE_LIST) {
[email protected]11b040b2011-02-02 12:42:25347 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29348 return NULL;
[email protected]11b040b2011-02-02 12:42:25349 }
[email protected]a43a667b2013-06-14 17:56:08350 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29351}
352
georgesak7da6e9d2014-12-03 01:10:29353void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50354 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29355}
356
georgesak7da6e9d2014-12-03 01:10:29357void PrefService::RemovePrefObserver(const std::string& path,
358 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50359 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29360}
361
[email protected]a6a7ced2012-11-01 17:24:18362void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
363 pref_notifier_->AddInitObserver(obs);
364}
365
[email protected]b1de2c72013-02-06 02:45:47366PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
367 return pref_registry_.get();
368}
369
georgesak7da6e9d2014-12-03 01:10:29370void PrefService::ClearPref(const std::string& path) {
initial.commit09911bf2008-07-26 23:55:29371 DCHECK(CalledOnValidThread());
372
373 const Preference* pref = FindPreference(path);
374 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40375 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29376 return;
377 }
raymesf3a929b02015-05-07 03:54:45378 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29379}
380
georgesak7da6e9d2014-12-03 01:10:29381void PrefService::Set(const std::string& path, const base::Value& value) {
[email protected]b99c41c2011-04-27 15:18:48382 SetUserPrefValue(path, value.DeepCopy());
[email protected]a048d7e42009-12-01 01:02:39383}
384
georgesak7da6e9d2014-12-03 01:10:29385void PrefService::SetBoolean(const std::string& path, bool value) {
[email protected]b54e6252014-01-30 10:32:41386 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29387}
388
georgesak7da6e9d2014-12-03 01:10:29389void PrefService::SetInteger(const std::string& path, int value) {
[email protected]b54e6252014-01-30 10:32:41390 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29391}
392
georgesak7da6e9d2014-12-03 01:10:29393void PrefService::SetDouble(const std::string& path, double value) {
[email protected]b54e6252014-01-30 10:32:41394 SetUserPrefValue(path, new base::FundamentalValue(value));
initial.commit09911bf2008-07-26 23:55:29395}
396
georgesak7da6e9d2014-12-03 01:10:29397void PrefService::SetString(const std::string& path, const std::string& value) {
[email protected]b54e6252014-01-30 10:32:41398 SetUserPrefValue(path, new base::StringValue(value));
initial.commit09911bf2008-07-26 23:55:29399}
400
georgesak7da6e9d2014-12-03 01:10:29401void PrefService::SetFilePath(const std::string& path,
402 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50403 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25404}
405
avi9ef8bb02015-12-24 05:29:36406void PrefService::SetInt64(const std::string& path, int64_t value) {
[email protected]b54e6252014-01-30 10:32:41407 SetUserPrefValue(path, new base::StringValue(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32408}
409
avi9ef8bb02015-12-24 05:29:36410int64_t PrefService::GetInt64(const std::string& path) const {
[email protected]0bb1a622009-03-04 03:22:32411 DCHECK(CalledOnValidThread());
412
[email protected]a43a667b2013-06-14 17:56:08413 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58414 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40415 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08416 return 0;
[email protected]0bb1a622009-03-04 03:22:32417 }
[email protected]dc9a6762010-08-16 07:13:53418 std::string result("0");
[email protected]18038f82012-11-20 13:46:58419 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32420 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25421
avi9ef8bb02015-12-24 05:29:36422 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53423 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25424 return val;
[email protected]0bb1a622009-03-04 03:22:32425}
426
avi9ef8bb02015-12-24 05:29:36427void PrefService::SetUint64(const std::string& path, uint64_t value) {
[email protected]b54e6252014-01-30 10:32:41428 SetUserPrefValue(path, new base::StringValue(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43429}
430
avi9ef8bb02015-12-24 05:29:36431uint64_t PrefService::GetUint64(const std::string& path) const {
[email protected]3cbe0812012-07-03 02:51:43432 DCHECK(CalledOnValidThread());
433
[email protected]a43a667b2013-06-14 17:56:08434 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58435 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43436 NOTREACHED() << "Trying to read an unregistered pref: " << path;
437 return 0;
438 }
439 std::string result("0");
[email protected]18038f82012-11-20 13:46:58440 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43441 DCHECK(rv);
442
avi9ef8bb02015-12-24 05:29:36443 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43444 base::StringToUint64(result, &val);
445 return val;
446}
447
georgesak7da6e9d2014-12-03 01:10:29448base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08449 base::Value::Type type) {
450 CHECK(type == base::Value::TYPE_DICTIONARY || type == base::Value::TYPE_LIST);
initial.commit09911bf2008-07-26 23:55:29451 DCHECK(CalledOnValidThread());
452
453 const Preference* pref = FindPreference(path);
454 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40455 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29456 return NULL;
457 }
[email protected]26418b72011-03-30 14:07:39458 if (pref->GetType() != type) {
459 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29460 return NULL;
461 }
462
[email protected]e0250892010-10-01 18:57:53463 // Look for an existing preference in the user store. If it doesn't
464 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08465 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34466 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39467 !value->IsType(type)) {
[email protected]a43a667b2013-06-14 17:56:08468 if (type == base::Value::TYPE_DICTIONARY) {
469 value = new base::DictionaryValue;
470 } else if (type == base::Value::TYPE_LIST) {
471 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39472 } else {
473 NOTREACHED();
474 }
estade0bd407f2015-06-26 18:16:18475 user_pref_store_->SetValueSilently(path, make_scoped_ptr(value),
476 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29477 }
[email protected]26418b72011-03-30 14:07:39478 return value;
479}
480
[email protected]68bf41a2011-03-25 16:38:31481void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]86bb4e652014-07-10 17:09:51482 DCHECK(CalledOnValidThread());
raymesf3a929b02015-05-07 03:54:45483 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27484}
485
georgesak7da6e9d2014-12-03 01:10:29486void PrefService::SetUserPrefValue(const std::string& path,
487 base::Value* new_value) {
[email protected]a43a667b2013-06-14 17:56:08488 scoped_ptr<base::Value> owned_value(new_value);
[email protected]c3b54f372010-09-14 08:25:07489 DCHECK(CalledOnValidThread());
490
491 const Preference* pref = FindPreference(path);
492 if (!pref) {
493 NOTREACHED() << "Trying to write an unregistered pref: " << path;
494 return;
495 }
[email protected]99cc9a02010-09-17 07:53:28496 if (pref->GetType() != new_value->GetType()) {
497 NOTREACHED() << "Trying to set pref " << path
498 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07499 << " to value of type " << new_value->GetType();
500 return;
501 }
502
danakj0c8d4aa2015-11-25 05:29:58503 user_pref_store_->SetValue(path, std::move(owned_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43504}
505
[email protected]5b199522012-12-22 17:24:44506void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
507 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05508}
509
initial.commit09911bf2008-07-26 23:55:29510///////////////////////////////////////////////////////////////////////////////
511// PrefService::Preference
512
[email protected]c3b54f372010-09-14 08:25:07513PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29514 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02515 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29516 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07517 DCHECK(service);
raymes76de1af2015-05-06 03:22:21518 // Cache the registration flags at creation time to avoid multiple map lookups
519 // later.
520 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28521}
522
[email protected]fb8fdf12012-08-21 16:28:20523const std::string PrefService::Preference::name() const {
524 return name_;
525}
526
[email protected]bab1c13f2011-08-12 20:59:02527base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33528 return type_;
initial.commit09911bf2008-07-26 23:55:29529}
530
[email protected]a43a667b2013-06-14 17:56:08531const base::Value* PrefService::Preference::GetValue() const {
532 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58533 DCHECK(result) << "Must register pref before getting its value";
534 return result;
[email protected]40a47c162010-09-09 11:14:01535}
536
[email protected]a43a667b2013-06-14 17:56:08537const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29538 DCHECK(pref_service_->FindPreference(name_))
539 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03540
[email protected]a43a667b2013-06-14 17:56:08541 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03542 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
543 DCHECK(found_value->IsType(type_));
544 return found_value;
545 }
546
547 // The pref has no recommended value.
548 return NULL;
549}
550
[email protected]40a47c162010-09-09 11:14:01551bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29552 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01553}
554
khannansb2025b72014-12-19 16:04:25555bool PrefService::Preference::IsManagedByCustodian() const {
556 return pref_value_store()->PrefValueInSupervisedStore(name_.c_str());
557}
558
[email protected]a5437282011-12-12 12:33:21559bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29560 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21561}
562
[email protected]40a47c162010-09-09 11:14:01563bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29564 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01565}
566
567bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29568 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01569}
570
571bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29572 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01573}
574
575bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29576 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07577}
578
579bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29580 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35581}
[email protected]74379bc52010-07-21 13:54:08582
583bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29584 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08585}
[email protected]9a28f132011-02-24 21:15:16586
587bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29588 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16589}
[email protected]18038f82012-11-20 13:46:58590
591const base::Value* PrefService::GetPreferenceValue(
592 const std::string& path) const {
593 DCHECK(CalledOnValidThread());
battre0a69def2015-01-05 18:50:19594
595 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
596 // crash dumps it looks like the PrefService is accessed even though it has
597 // been cleared already.
598 CHECK(pref_registry_);
599 CHECK(pref_registry_->defaults());
600 CHECK(pref_value_store_);
601
[email protected]a43a667b2013-06-14 17:56:08602 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47603 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08604 const base::Value* found_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47605 base::Value::Type default_type = default_value->GetType();
606 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
607 DCHECK(found_value->IsType(default_type));
608 return found_value;
609 } else {
610 // Every registered preference has at least a default value.
611 NOTREACHED() << "no valid value found for registered pref " << path;
612 }
[email protected]18038f82012-11-20 13:46:58613 }
614
[email protected]18038f82012-11-20 13:46:58615 return NULL;
616}