blob: a03daa0470915ac7853bc46a7b2aa52e7a5d1385 [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"
dcheng5f043bc2016-04-22 19:09:0614#include "base/memory/ptr_util.h"
[email protected]835d7c82010-10-14 04:38:3815#include "base/metrics/histogram.h"
skyostil054861d2015-04-30 19:06:1516#include "base/single_thread_task_runner.h"
[email protected]7286e3fc2011-07-19 22:13:2417#include "base/stl_util.h"
[email protected]3ea1b182013-02-08 22:38:4118#include "base/strings/string_number_conversions.h"
[email protected]d529cb02013-06-10 19:06:5719#include "base/strings/string_util.h"
gab7966d312016-05-11 20:35:0120#include "base/threading/thread_task_runner_handle.h"
[email protected]8703b2b2011-03-15 09:51:5021#include "base/value_conversions.h"
[email protected]66de4f092009-09-04 23:59:4022#include "build/build_config.h"
brettwf00b9b42016-02-01 22:11:3823#include "components/prefs/default_pref_store.h"
24#include "components/prefs/pref_notifier_impl.h"
25#include "components/prefs/pref_registry.h"
26#include "components/prefs/pref_value_store.h"
initial.commit09911bf2008-07-26 23:55:2927
28namespace {
29
[email protected]845b43a82011-05-11 10:14:4330class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate {
31 public:
[email protected]70a317a2012-12-19 20:59:3332 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb)
33 : callback_(cb) {}
[email protected]845b43a82011-05-11 10:14:4334
dcheng56488182014-10-21 10:54:5135 void OnError(PersistentPrefStore::PrefReadError error) override {
[email protected]70a317a2012-12-19 20:59:3336 callback_.Run(error);
[email protected]845b43a82011-05-11 10:14:4337 }
[email protected]70a317a2012-12-19 20:59:3338
39 private:
40 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_;
[email protected]845b43a82011-05-11 10:14:4341};
42
raymes76de1af2015-05-06 03:22:2143// Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
44// |path|.
avi9ef8bb02015-12-24 05:29:3645uint32_t GetWriteFlags(const PrefService::Preference* pref) {
46 uint32_t write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
raymesf3a929b02015-05-07 03:54:4547
48 if (!pref)
49 return write_flags;
50
raymes76de1af2015-05-06 03:22:2151 if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
raymesf3a929b02015-05-07 03:54:4552 write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
raymes76de1af2015-05-06 03:22:2153 return write_flags;
54}
55
initial.commit09911bf2008-07-26 23:55:2956} // namespace
57
[email protected]70a317a2012-12-19 20:59:3358PrefService::PrefService(
59 PrefNotifierImpl* pref_notifier,
60 PrefValueStore* pref_value_store,
61 PersistentPrefStore* user_prefs,
[email protected]b1de2c72013-02-06 02:45:4762 PrefRegistry* pref_registry,
[email protected]70a317a2012-12-19 20:59:3363 base::Callback<void(PersistentPrefStore::PrefReadError)>
64 read_error_callback,
65 bool async)
[email protected]361d37f62011-11-22 10:37:0266 : pref_notifier_(pref_notifier),
67 pref_value_store_(pref_value_store),
[email protected]b1de2c72013-02-06 02:45:4768 pref_registry_(pref_registry),
[email protected]361d37f62011-11-22 10:37:0269 user_pref_store_(user_prefs),
[email protected]5b199522012-12-22 17:24:4470 read_error_callback_(read_error_callback) {
[email protected]361d37f62011-11-22 10:37:0271 pref_notifier_->SetPrefService(this);
[email protected]b1de2c72013-02-06 02:45:4772
battre0a69def2015-01-05 18:50:1973 // TODO(battre): This is a check for crbug.com/435208 to make sure that
74 // access violations are caused by a use-after-free bug and not by an
75 // initialization bug.
76 CHECK(pref_registry_);
77 CHECK(pref_value_store_);
78
[email protected]361d37f62011-11-22 10:37:0279 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:3380}
81
initial.commit09911bf2008-07-26 23:55:2982PrefService::~PrefService() {
gab6e1fb5352017-05-31 18:27:1283 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]a98ce1262011-01-28 13:20:2384
85 // Reset pointers so accesses after destruction reliably crash.
86 pref_value_store_.reset();
[email protected]b1de2c72013-02-06 02:45:4787 pref_registry_ = NULL;
[email protected]a98ce1262011-01-28 13:20:2388 user_pref_store_ = NULL;
[email protected]42f23782012-06-08 19:11:5389 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:2990}
91
[email protected]845b43a82011-05-11 10:14:4392void PrefService::InitFromStorage(bool async) {
[email protected]38d1aab2014-03-29 17:48:4993 if (user_pref_store_->IsInitializationComplete()) {
94 read_error_callback_.Run(user_pref_store_->GetReadError());
95 } else if (!async) {
[email protected]70a317a2012-12-19 20:59:3396 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:2197 } else {
[email protected]845b43a82011-05-11 10:14:4398 // Guarantee that initialization happens after this function returned.
skyostil054861d2015-04-30 19:06:1599 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]845b43a82011-05-11 10:14:43100 FROM_HERE,
tzik07cace42016-09-01 04:21:25101 base::Bind(&PersistentPrefStore::ReadPrefsAsync, user_pref_store_,
[email protected]70a317a2012-12-19 20:59:33102 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:21103 }
[email protected]ba399672010-04-06 15:42:39104}
105
[email protected]3826fed2011-03-25 10:59:56106void PrefService::CommitPendingWrite() {
gab6e1fb5352017-05-31 18:27:12107 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]3826fed2011-03-25 10:59:56108 user_pref_store_->CommitPendingWrite();
109}
110
benwells26730592015-05-28 13:08:08111void PrefService::SchedulePendingLossyWrites() {
gab6e1fb5352017-05-31 18:27:12112 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
benwells26730592015-05-28 13:08:08113 user_pref_store_->SchedulePendingLossyWrites();
114}
115
georgesak7da6e9d2014-12-03 01:10:29116bool PrefService::GetBoolean(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12117 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29118
119 bool result = false;
initial.commit09911bf2008-07-26 23:55:29120
[email protected]18038f82012-11-20 13:46:58121 const base::Value* value = GetPreferenceValue(path);
122 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40123 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29124 return result;
125 }
[email protected]18038f82012-11-20 13:46:58126 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29127 DCHECK(rv);
128 return result;
129}
130
georgesak7da6e9d2014-12-03 01:10:29131int PrefService::GetInteger(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12132 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29133
134 int result = 0;
initial.commit09911bf2008-07-26 23:55:29135
[email protected]18038f82012-11-20 13:46:58136 const base::Value* value = GetPreferenceValue(path);
137 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40138 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29139 return result;
140 }
[email protected]18038f82012-11-20 13:46:58141 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29142 DCHECK(rv);
143 return result;
144}
145
georgesak7da6e9d2014-12-03 01:10:29146double PrefService::GetDouble(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12147 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29148
149 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29150
[email protected]18038f82012-11-20 13:46:58151 const base::Value* value = GetPreferenceValue(path);
152 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40153 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29154 return result;
155 }
[email protected]18038f82012-11-20 13:46:58156 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29157 DCHECK(rv);
158 return result;
159}
160
georgesak7da6e9d2014-12-03 01:10:29161std::string PrefService::GetString(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12162 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29163
[email protected]ddd231e2010-06-29 20:35:19164 std::string result;
[email protected]8e50b602009-03-03 22:59:43165
[email protected]18038f82012-11-20 13:46:58166 const base::Value* value = GetPreferenceValue(path);
167 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40168 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29169 return result;
170 }
[email protected]18038f82012-11-20 13:46:58171 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29172 DCHECK(rv);
173 return result;
174}
175
georgesak7da6e9d2014-12-03 01:10:29176base::FilePath PrefService::GetFilePath(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12177 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]b9636002009-03-04 00:05:25178
[email protected]650b2d52013-02-10 03:41:45179 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25180
[email protected]18038f82012-11-20 13:46:58181 const base::Value* value = GetPreferenceValue(path);
182 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40183 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45184 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25185 }
[email protected]18038f82012-11-20 13:46:58186 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25187 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04188 return result;
[email protected]b9636002009-03-04 00:05:25189}
190
georgesak7da6e9d2014-12-03 01:10:29191bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33192 const Preference* pref = FindPreference(path);
193 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29194}
195
brettwebf7184f2017-04-18 21:10:53196void PrefService::IteratePreferenceValues(
197 base::RepeatingCallback<void(const std::string& key,
198 const base::Value& value)> callback) const {
gab6e1fb5352017-05-31 18:27:12199 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
brettwebf7184f2017-04-18 21:10:53200 for (const auto& it : *pref_registry_)
201 callback.Run(it.first, *GetPreferenceValue(it.first));
asvitkine36ff0c5822014-11-25 22:58:18202}
203
brettwebf7184f2017-04-18 21:10:53204std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
205 IncludeDefaults include_defaults) const {
gab6e1fb5352017-05-31 18:27:12206 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dcheng5f043bc2016-04-22 19:09:06207 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18208 for (const auto& it : *pref_registry_) {
brettwebf7184f2017-04-18 21:10:53209 if (include_defaults == INCLUDE_DEFAULTS) {
210 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
211 } else {
212 const Preference* pref = FindPreference(it.first);
213 if (pref->IsDefaultValue())
214 continue;
215 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
216 }
[email protected]2a1965c2013-10-02 16:07:01217 }
danakj0c8d4aa2015-11-25 05:29:58218 return out;
[email protected]2a1965c2013-10-02 16:07:01219}
220
initial.commit09911bf2008-07-26 23:55:29221const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29222 const std::string& pref_name) const {
gab6e1fb5352017-05-31 18:27:12223 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]d15d5682012-10-23 17:50:42224 PreferenceMap::iterator it = prefs_map_.find(pref_name);
225 if (it != prefs_map_.end())
226 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47227 const base::Value* default_value = NULL;
228 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33229 return NULL;
[email protected]d15d5682012-10-23 17:50:42230 it = prefs_map_.insert(
[email protected]b1de2c72013-02-06 02:45:47231 std::make_pair(pref_name, Preference(
232 this, pref_name, default_value->GetType()))).first;
[email protected]d15d5682012-10-23 17:50:42233 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29234}
235
[email protected]acd78969c2010-12-08 09:49:11236bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17237 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11238}
239
[email protected]59c10712012-03-13 02:10:34240PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
241 const {
242 if (!user_pref_store_->IsInitializationComplete())
243 return INITIALIZATION_STATUS_WAITING;
244
245 switch (user_pref_store_->GetReadError()) {
246 case PersistentPrefStore::PREF_READ_ERROR_NONE:
247 return INITIALIZATION_STATUS_SUCCESS;
248 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18249 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34250 default:
251 return INITIALIZATION_STATUS_ERROR;
252 }
253}
254
Sam McNallyf4dab612017-08-16 03:06:33255PrefService::PrefInitializationStatus
256PrefService::GetAllPrefStoresInitializationStatus() const {
257 if (!pref_value_store_->IsInitializationComplete())
258 return INITIALIZATION_STATUS_WAITING;
259
260 return GetInitializationStatus();
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 {
gab6e1fb5352017-05-31 18:27:12282 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29283
[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 }
jdoerriedc72ee942016-12-07 15:43:28289 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 {
gab6e1fb5352017-05-31 18:27:12298 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]1a5a31f2012-04-26 20:21:34299
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) {
gab6e1fb5352017-05-31 18:27:12322 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]5879cef2013-03-02 17:02:25323 pref_registry_->SetDefaultPrefValue(path, value);
324}
325
georgesak7da6e9d2014-12-03 01:10:29326const base::Value* PrefService::GetDefaultPrefValue(
327 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12328 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]35a6fd12012-05-28 18:08:08329 // 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 {
gab6e1fb5352017-05-31 18:27:12339 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29340
[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 }
jdoerriedc72ee942016-12-07 15:43:28346 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) {
gab6e1fb5352017-05-31 18:27:12371 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29372
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
dvadym53fc0d42016-02-05 13:34:57381void PrefService::ClearMutableValues() {
382 user_pref_store_->ClearMutableValues();
383}
384
proberge45e347282017-08-16 21:24:05385void PrefService::OnStoreDeletionFromDisk() {
386 user_pref_store_->OnStoreDeletionFromDisk();
387}
388
georgesak7da6e9d2014-12-03 01:10:29389void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43390 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39391}
392
georgesak7da6e9d2014-12-03 01:10:29393void PrefService::SetBoolean(const std::string& path, bool value) {
vabrbce355c2017-03-23 18:52:43394 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29395}
396
georgesak7da6e9d2014-12-03 01:10:29397void PrefService::SetInteger(const std::string& path, int value) {
vabrbce355c2017-03-23 18:52:43398 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29399}
400
georgesak7da6e9d2014-12-03 01:10:29401void PrefService::SetDouble(const std::string& path, double value) {
vabrbce355c2017-03-23 18:52:43402 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29403}
404
georgesak7da6e9d2014-12-03 01:10:29405void PrefService::SetString(const std::string& path, const std::string& value) {
vabrbce355c2017-03-23 18:52:43406 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29407}
408
georgesak7da6e9d2014-12-03 01:10:29409void PrefService::SetFilePath(const std::string& path,
410 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50411 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25412}
413
avi9ef8bb02015-12-24 05:29:36414void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43415 SetUserPrefValue(path,
416 base::MakeUnique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32417}
418
avi9ef8bb02015-12-24 05:29:36419int64_t PrefService::GetInt64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12420 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]0bb1a622009-03-04 03:22:32421
[email protected]a43a667b2013-06-14 17:56:08422 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58423 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40424 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08425 return 0;
[email protected]0bb1a622009-03-04 03:22:32426 }
[email protected]dc9a6762010-08-16 07:13:53427 std::string result("0");
[email protected]18038f82012-11-20 13:46:58428 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32429 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25430
avi9ef8bb02015-12-24 05:29:36431 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53432 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25433 return val;
[email protected]0bb1a622009-03-04 03:22:32434}
435
avi9ef8bb02015-12-24 05:29:36436void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43437 SetUserPrefValue(path,
438 base::MakeUnique<base::Value>(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43439}
440
avi9ef8bb02015-12-24 05:29:36441uint64_t PrefService::GetUint64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12442 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]3cbe0812012-07-03 02:51:43443
[email protected]a43a667b2013-06-14 17:56:08444 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58445 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43446 NOTREACHED() << "Trying to read an unregistered pref: " << path;
447 return 0;
448 }
449 std::string result("0");
[email protected]18038f82012-11-20 13:46:58450 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43451 DCHECK(rv);
452
avi9ef8bb02015-12-24 05:29:36453 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43454 base::StringToUint64(result, &val);
455 return val;
456}
457
georgesak7da6e9d2014-12-03 01:10:29458base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08459 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28460 CHECK(type == base::Value::Type::DICTIONARY ||
461 type == base::Value::Type::LIST);
gab6e1fb5352017-05-31 18:27:12462 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29463
464 const Preference* pref = FindPreference(path);
465 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40466 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29467 return NULL;
468 }
[email protected]26418b72011-03-30 14:07:39469 if (pref->GetType() != type) {
470 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29471 return NULL;
472 }
473
[email protected]e0250892010-10-01 18:57:53474 // Look for an existing preference in the user store. If it doesn't
475 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08476 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34477 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39478 !value->IsType(type)) {
jdoerriedc72ee942016-12-07 15:43:28479 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08480 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28481 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08482 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39483 } else {
484 NOTREACHED();
485 }
dcheng5f043bc2016-04-22 19:09:06486 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18487 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29488 }
[email protected]26418b72011-03-30 14:07:39489 return value;
490}
491
[email protected]68bf41a2011-03-25 16:38:31492void PrefService::ReportUserPrefChanged(const std::string& key) {
gab6e1fb5352017-05-31 18:27:12493 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
raymesf3a929b02015-05-07 03:54:45494 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27495}
496
Sam McNally69572322017-05-01 00:41:38497void PrefService::ReportUserPrefChanged(
498 const std::string& key,
499 std::set<std::vector<std::string>> path_components) {
gab6e1fb5352017-05-31 18:27:12500 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam McNally69572322017-05-01 00:41:38501 user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
502 GetWriteFlags(FindPreference(key)));
503}
504
georgesak7da6e9d2014-12-03 01:10:29505void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43506 std::unique_ptr<base::Value> new_value) {
gab6e1fb5352017-05-31 18:27:12507 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]c3b54f372010-09-14 08:25:07508
509 const Preference* pref = FindPreference(path);
510 if (!pref) {
511 NOTREACHED() << "Trying to write an unregistered pref: " << path;
512 return;
513 }
[email protected]99cc9a02010-09-17 07:53:28514 if (pref->GetType() != new_value->GetType()) {
515 NOTREACHED() << "Trying to set pref " << path
516 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07517 << " to value of type " << new_value->GetType();
518 return;
519 }
520
vabrbce355c2017-03-23 18:52:43521 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43522}
523
[email protected]5b199522012-12-22 17:24:44524void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
525 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05526}
527
initial.commit09911bf2008-07-26 23:55:29528///////////////////////////////////////////////////////////////////////////////
529// PrefService::Preference
530
[email protected]c3b54f372010-09-14 08:25:07531PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29532 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02533 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29534 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07535 DCHECK(service);
raymes76de1af2015-05-06 03:22:21536 // Cache the registration flags at creation time to avoid multiple map lookups
537 // later.
538 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28539}
540
[email protected]fb8fdf12012-08-21 16:28:20541const std::string PrefService::Preference::name() const {
542 return name_;
543}
544
[email protected]bab1c13f2011-08-12 20:59:02545base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33546 return type_;
initial.commit09911bf2008-07-26 23:55:29547}
548
[email protected]a43a667b2013-06-14 17:56:08549const base::Value* PrefService::Preference::GetValue() const {
550 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58551 DCHECK(result) << "Must register pref before getting its value";
552 return result;
[email protected]40a47c162010-09-09 11:14:01553}
554
[email protected]a43a667b2013-06-14 17:56:08555const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29556 DCHECK(pref_service_->FindPreference(name_))
557 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03558
[email protected]a43a667b2013-06-14 17:56:08559 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03560 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
561 DCHECK(found_value->IsType(type_));
562 return found_value;
563 }
564
565 // The pref has no recommended value.
566 return NULL;
567}
568
[email protected]40a47c162010-09-09 11:14:01569bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29570 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01571}
572
khannansb2025b72014-12-19 16:04:25573bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09574 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25575}
576
[email protected]a5437282011-12-12 12:33:21577bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29578 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21579}
580
[email protected]40a47c162010-09-09 11:14:01581bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29582 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01583}
584
585bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29586 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01587}
588
589bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29590 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01591}
592
593bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29594 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07595}
596
597bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29598 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35599}
[email protected]74379bc52010-07-21 13:54:08600
601bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29602 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08603}
[email protected]9a28f132011-02-24 21:15:16604
605bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29606 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16607}
[email protected]18038f82012-11-20 13:46:58608
609const base::Value* PrefService::GetPreferenceValue(
610 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12611 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
battre0a69def2015-01-05 18:50:19612
613 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
614 // crash dumps it looks like the PrefService is accessed even though it has
615 // been cleared already.
616 CHECK(pref_registry_);
617 CHECK(pref_registry_->defaults());
618 CHECK(pref_value_store_);
619
[email protected]a43a667b2013-06-14 17:56:08620 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47621 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08622 const base::Value* found_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47623 base::Value::Type default_type = default_value->GetType();
624 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
625 DCHECK(found_value->IsType(default_type));
626 return found_value;
627 } else {
628 // Every registered preference has at least a default value.
629 NOTREACHED() << "no valid value found for registered pref " << path;
630 }
[email protected]18038f82012-11-20 13:46:58631 }
632
[email protected]18038f82012-11-20 13:46:58633 return NULL;
634}