blob: 39552b929e01d560e6554368dd56b1a8aceeab46 [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() {
Pavol Markoe1f238f2017-09-05 18:58:42107 CommitPendingWrite(base::OnceClosure());
108}
109
110void PrefService::CommitPendingWrite(base::OnceClosure done_callback) {
gab6e1fb5352017-05-31 18:27:12111 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Pavol Markoe1f238f2017-09-05 18:58:42112 user_pref_store_->CommitPendingWrite(std::move(done_callback));
[email protected]3826fed2011-03-25 10:59:56113}
114
benwells26730592015-05-28 13:08:08115void PrefService::SchedulePendingLossyWrites() {
gab6e1fb5352017-05-31 18:27:12116 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
benwells26730592015-05-28 13:08:08117 user_pref_store_->SchedulePendingLossyWrites();
118}
119
georgesak7da6e9d2014-12-03 01:10:29120bool PrefService::GetBoolean(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12121 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29122
123 bool result = false;
initial.commit09911bf2008-07-26 23:55:29124
[email protected]18038f82012-11-20 13:46:58125 const base::Value* value = GetPreferenceValue(path);
126 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40127 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29128 return result;
129 }
[email protected]18038f82012-11-20 13:46:58130 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29131 DCHECK(rv);
132 return result;
133}
134
georgesak7da6e9d2014-12-03 01:10:29135int PrefService::GetInteger(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12136 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29137
138 int result = 0;
initial.commit09911bf2008-07-26 23:55:29139
[email protected]18038f82012-11-20 13:46:58140 const base::Value* value = GetPreferenceValue(path);
141 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40142 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29143 return result;
144 }
[email protected]18038f82012-11-20 13:46:58145 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29146 DCHECK(rv);
147 return result;
148}
149
georgesak7da6e9d2014-12-03 01:10:29150double PrefService::GetDouble(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12151 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29152
153 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29154
[email protected]18038f82012-11-20 13:46:58155 const base::Value* value = GetPreferenceValue(path);
156 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40157 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29158 return result;
159 }
[email protected]18038f82012-11-20 13:46:58160 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29161 DCHECK(rv);
162 return result;
163}
164
georgesak7da6e9d2014-12-03 01:10:29165std::string PrefService::GetString(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12166 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29167
[email protected]ddd231e2010-06-29 20:35:19168 std::string result;
[email protected]8e50b602009-03-03 22:59:43169
[email protected]18038f82012-11-20 13:46:58170 const base::Value* value = GetPreferenceValue(path);
171 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40172 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29173 return result;
174 }
[email protected]18038f82012-11-20 13:46:58175 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29176 DCHECK(rv);
177 return result;
178}
179
georgesak7da6e9d2014-12-03 01:10:29180base::FilePath PrefService::GetFilePath(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12181 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]b9636002009-03-04 00:05:25182
[email protected]650b2d52013-02-10 03:41:45183 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25184
[email protected]18038f82012-11-20 13:46:58185 const base::Value* value = GetPreferenceValue(path);
186 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40187 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45188 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25189 }
[email protected]18038f82012-11-20 13:46:58190 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25191 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04192 return result;
[email protected]b9636002009-03-04 00:05:25193}
194
georgesak7da6e9d2014-12-03 01:10:29195bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33196 const Preference* pref = FindPreference(path);
197 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29198}
199
brettwebf7184f2017-04-18 21:10:53200void PrefService::IteratePreferenceValues(
201 base::RepeatingCallback<void(const std::string& key,
202 const base::Value& value)> callback) const {
gab6e1fb5352017-05-31 18:27:12203 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
brettwebf7184f2017-04-18 21:10:53204 for (const auto& it : *pref_registry_)
205 callback.Run(it.first, *GetPreferenceValue(it.first));
asvitkine36ff0c5822014-11-25 22:58:18206}
207
brettwebf7184f2017-04-18 21:10:53208std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
209 IncludeDefaults include_defaults) const {
gab6e1fb5352017-05-31 18:27:12210 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dcheng5f043bc2016-04-22 19:09:06211 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18212 for (const auto& it : *pref_registry_) {
brettwebf7184f2017-04-18 21:10:53213 if (include_defaults == INCLUDE_DEFAULTS) {
214 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
215 } else {
216 const Preference* pref = FindPreference(it.first);
217 if (pref->IsDefaultValue())
218 continue;
219 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
220 }
[email protected]2a1965c2013-10-02 16:07:01221 }
danakj0c8d4aa2015-11-25 05:29:58222 return out;
[email protected]2a1965c2013-10-02 16:07:01223}
224
initial.commit09911bf2008-07-26 23:55:29225const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29226 const std::string& pref_name) const {
gab6e1fb5352017-05-31 18:27:12227 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]d15d5682012-10-23 17:50:42228 PreferenceMap::iterator it = prefs_map_.find(pref_name);
229 if (it != prefs_map_.end())
230 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47231 const base::Value* default_value = NULL;
232 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33233 return NULL;
jdoerrie76cee9c2017-10-06 22:42:42234 it = prefs_map_
235 .insert(std::make_pair(
236 pref_name, Preference(this, pref_name, default_value->type())))
237 .first;
[email protected]d15d5682012-10-23 17:50:42238 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29239}
240
[email protected]acd78969c2010-12-08 09:49:11241bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17242 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11243}
244
[email protected]59c10712012-03-13 02:10:34245PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
246 const {
247 if (!user_pref_store_->IsInitializationComplete())
248 return INITIALIZATION_STATUS_WAITING;
249
250 switch (user_pref_store_->GetReadError()) {
251 case PersistentPrefStore::PREF_READ_ERROR_NONE:
252 return INITIALIZATION_STATUS_SUCCESS;
253 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18254 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34255 default:
256 return INITIALIZATION_STATUS_ERROR;
257 }
258}
259
Sam McNallyf4dab612017-08-16 03:06:33260PrefService::PrefInitializationStatus
261PrefService::GetAllPrefStoresInitializationStatus() const {
262 if (!pref_value_store_->IsInitializationComplete())
263 return INITIALIZATION_STATUS_WAITING;
264
265 return GetInitializationStatus();
266}
267
georgesak7da6e9d2014-12-03 01:10:29268bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48269 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33270 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48271}
272
khannansb2025b72014-12-19 16:04:25273bool PrefService::IsPreferenceManagedByCustodian(
274 const std::string& pref_name) const {
275 const Preference* pref = FindPreference(pref_name);
276 return pref && pref->IsManagedByCustodian();
277}
278
georgesak7da6e9d2014-12-03 01:10:29279bool PrefService::IsUserModifiablePreference(
280 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07281 const Preference* pref = FindPreference(pref_name);
282 return pref && pref->IsUserModifiable();
283}
284
[email protected]a43a667b2013-06-14 17:56:08285const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29286 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12287 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29288
[email protected]a43a667b2013-06-14 17:56:08289 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58290 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40291 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29292 return NULL;
293 }
jdoerrie76cee9c2017-10-06 22:42:42294 if (value->type() != base::Value::Type::DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25295 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29296 return NULL;
[email protected]11b040b2011-02-02 12:42:25297 }
[email protected]a43a667b2013-06-14 17:56:08298 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29299}
300
georgesak7da6e9d2014-12-03 01:10:29301const base::Value* PrefService::GetUserPrefValue(
302 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12303 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]1a5a31f2012-04-26 20:21:34304
305 const Preference* pref = FindPreference(path);
306 if (!pref) {
307 NOTREACHED() << "Trying to get an unregistered pref: " << path;
308 return NULL;
309 }
310
311 // Look for an existing preference in the user store. If it doesn't
312 // exist, return NULL.
313 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34314 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34315 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34316
317 if (!value->IsType(pref->GetType())) {
318 NOTREACHED() << "Pref value type doesn't match registered type.";
319 return NULL;
320 }
321
322 return value;
323}
324
georgesak7da6e9d2014-12-03 01:10:29325void PrefService::SetDefaultPrefValue(const std::string& path,
[email protected]5879cef2013-03-02 17:02:25326 base::Value* value) {
gab6e1fb5352017-05-31 18:27:12327 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]5879cef2013-03-02 17:02:25328 pref_registry_->SetDefaultPrefValue(path, value);
329}
330
georgesak7da6e9d2014-12-03 01:10:29331const base::Value* PrefService::GetDefaultPrefValue(
332 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12333 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]35a6fd12012-05-28 18:08:08334 // Lookup the preference in the default store.
Lei Zhang9e22c8432017-10-17 20:54:28335 const base::Value* value = nullptr;
336 bool has_value = pref_registry_->defaults()->GetValue(path, &value);
337 DCHECK(has_value) << "Default value missing for pref: " << path;
[email protected]35a6fd12012-05-28 18:08:08338 return value;
339}
340
georgesak7da6e9d2014-12-03 01:10:29341const base::ListValue* PrefService::GetList(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12342 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29343
[email protected]a43a667b2013-06-14 17:56:08344 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58345 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40346 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29347 return NULL;
348 }
jdoerrie76cee9c2017-10-06 22:42:42349 if (value->type() != base::Value::Type::LIST) {
[email protected]11b040b2011-02-02 12:42:25350 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29351 return NULL;
[email protected]11b040b2011-02-02 12:42:25352 }
[email protected]a43a667b2013-06-14 17:56:08353 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29354}
355
georgesak7da6e9d2014-12-03 01:10:29356void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50357 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29358}
359
georgesak7da6e9d2014-12-03 01:10:29360void PrefService::RemovePrefObserver(const std::string& path,
361 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50362 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29363}
364
[email protected]a6a7ced2012-11-01 17:24:18365void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
366 pref_notifier_->AddInitObserver(obs);
367}
368
[email protected]b1de2c72013-02-06 02:45:47369PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
370 return pref_registry_.get();
371}
372
georgesak7da6e9d2014-12-03 01:10:29373void PrefService::ClearPref(const std::string& path) {
gab6e1fb5352017-05-31 18:27:12374 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29375
376 const Preference* pref = FindPreference(path);
377 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40378 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29379 return;
380 }
raymesf3a929b02015-05-07 03:54:45381 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29382}
383
dvadym53fc0d42016-02-05 13:34:57384void PrefService::ClearMutableValues() {
385 user_pref_store_->ClearMutableValues();
386}
387
proberge45e347282017-08-16 21:24:05388void PrefService::OnStoreDeletionFromDisk() {
389 user_pref_store_->OnStoreDeletionFromDisk();
390}
391
Brett Wilson21cf626a2017-09-07 00:30:20392void PrefService::AddPrefObserverAllPrefs(PrefObserver* obs) {
393 pref_notifier_->AddPrefObserverAllPrefs(obs);
394}
395
396void PrefService::RemovePrefObserverAllPrefs(PrefObserver* obs) {
397 pref_notifier_->RemovePrefObserverAllPrefs(obs);
398}
399
georgesak7da6e9d2014-12-03 01:10:29400void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43401 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39402}
403
georgesak7da6e9d2014-12-03 01:10:29404void PrefService::SetBoolean(const std::string& path, bool value) {
vabrbce355c2017-03-23 18:52:43405 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29406}
407
georgesak7da6e9d2014-12-03 01:10:29408void PrefService::SetInteger(const std::string& path, int value) {
vabrbce355c2017-03-23 18:52:43409 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29410}
411
georgesak7da6e9d2014-12-03 01:10:29412void PrefService::SetDouble(const std::string& path, double value) {
vabrbce355c2017-03-23 18:52:43413 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29414}
415
georgesak7da6e9d2014-12-03 01:10:29416void PrefService::SetString(const std::string& path, const std::string& value) {
vabrbce355c2017-03-23 18:52:43417 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29418}
419
georgesak7da6e9d2014-12-03 01:10:29420void PrefService::SetFilePath(const std::string& path,
421 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50422 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25423}
424
avi9ef8bb02015-12-24 05:29:36425void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43426 SetUserPrefValue(path,
427 base::MakeUnique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32428}
429
avi9ef8bb02015-12-24 05:29:36430int64_t PrefService::GetInt64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12431 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]0bb1a622009-03-04 03:22:32432
[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]b154e6f2009-03-06 01:52:40435 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08436 return 0;
[email protected]0bb1a622009-03-04 03:22:32437 }
[email protected]dc9a6762010-08-16 07:13:53438 std::string result("0");
[email protected]18038f82012-11-20 13:46:58439 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32440 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25441
avi9ef8bb02015-12-24 05:29:36442 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53443 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25444 return val;
[email protected]0bb1a622009-03-04 03:22:32445}
446
avi9ef8bb02015-12-24 05:29:36447void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43448 SetUserPrefValue(path,
449 base::MakeUnique<base::Value>(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43450}
451
avi9ef8bb02015-12-24 05:29:36452uint64_t PrefService::GetUint64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12453 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]3cbe0812012-07-03 02:51:43454
[email protected]a43a667b2013-06-14 17:56:08455 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58456 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43457 NOTREACHED() << "Trying to read an unregistered pref: " << path;
458 return 0;
459 }
460 std::string result("0");
[email protected]18038f82012-11-20 13:46:58461 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43462 DCHECK(rv);
463
avi9ef8bb02015-12-24 05:29:36464 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43465 base::StringToUint64(result, &val);
466 return val;
467}
468
georgesak7da6e9d2014-12-03 01:10:29469base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08470 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28471 CHECK(type == base::Value::Type::DICTIONARY ||
472 type == base::Value::Type::LIST);
gab6e1fb5352017-05-31 18:27:12473 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29474
475 const Preference* pref = FindPreference(path);
476 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40477 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29478 return NULL;
479 }
[email protected]26418b72011-03-30 14:07:39480 if (pref->GetType() != type) {
481 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29482 return NULL;
483 }
484
[email protected]e0250892010-10-01 18:57:53485 // Look for an existing preference in the user store. If it doesn't
486 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08487 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34488 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39489 !value->IsType(type)) {
jdoerriedc72ee942016-12-07 15:43:28490 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08491 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28492 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08493 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39494 } else {
495 NOTREACHED();
496 }
dcheng5f043bc2016-04-22 19:09:06497 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18498 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29499 }
[email protected]26418b72011-03-30 14:07:39500 return value;
501}
502
[email protected]68bf41a2011-03-25 16:38:31503void PrefService::ReportUserPrefChanged(const std::string& key) {
gab6e1fb5352017-05-31 18:27:12504 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
raymesf3a929b02015-05-07 03:54:45505 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27506}
507
Sam McNally69572322017-05-01 00:41:38508void PrefService::ReportUserPrefChanged(
509 const std::string& key,
510 std::set<std::vector<std::string>> path_components) {
gab6e1fb5352017-05-31 18:27:12511 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam McNally69572322017-05-01 00:41:38512 user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
513 GetWriteFlags(FindPreference(key)));
514}
515
georgesak7da6e9d2014-12-03 01:10:29516void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43517 std::unique_ptr<base::Value> new_value) {
gab6e1fb5352017-05-31 18:27:12518 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]c3b54f372010-09-14 08:25:07519
520 const Preference* pref = FindPreference(path);
521 if (!pref) {
522 NOTREACHED() << "Trying to write an unregistered pref: " << path;
523 return;
524 }
jdoerrie76cee9c2017-10-06 22:42:42525 if (pref->GetType() != new_value->type()) {
526 NOTREACHED() << "Trying to set pref " << path << " of type "
527 << pref->GetType() << " to value of type "
528 << new_value->type();
[email protected]c3b54f372010-09-14 08:25:07529 return;
530 }
531
vabrbce355c2017-03-23 18:52:43532 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43533}
534
[email protected]5b199522012-12-22 17:24:44535void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
536 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05537}
538
initial.commit09911bf2008-07-26 23:55:29539///////////////////////////////////////////////////////////////////////////////
540// PrefService::Preference
541
[email protected]c3b54f372010-09-14 08:25:07542PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29543 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02544 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29545 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07546 DCHECK(service);
raymes76de1af2015-05-06 03:22:21547 // Cache the registration flags at creation time to avoid multiple map lookups
548 // later.
549 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28550}
551
[email protected]fb8fdf12012-08-21 16:28:20552const std::string PrefService::Preference::name() const {
553 return name_;
554}
555
[email protected]bab1c13f2011-08-12 20:59:02556base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33557 return type_;
initial.commit09911bf2008-07-26 23:55:29558}
559
[email protected]a43a667b2013-06-14 17:56:08560const base::Value* PrefService::Preference::GetValue() const {
561 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58562 DCHECK(result) << "Must register pref before getting its value";
563 return result;
[email protected]40a47c162010-09-09 11:14:01564}
565
[email protected]a43a667b2013-06-14 17:56:08566const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29567 DCHECK(pref_service_->FindPreference(name_))
568 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03569
[email protected]a43a667b2013-06-14 17:56:08570 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03571 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
572 DCHECK(found_value->IsType(type_));
573 return found_value;
574 }
575
576 // The pref has no recommended value.
577 return NULL;
578}
579
[email protected]40a47c162010-09-09 11:14:01580bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29581 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01582}
583
khannansb2025b72014-12-19 16:04:25584bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09585 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25586}
587
[email protected]a5437282011-12-12 12:33:21588bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29589 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21590}
591
[email protected]40a47c162010-09-09 11:14:01592bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29593 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01594}
595
596bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29597 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01598}
599
600bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29601 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01602}
603
604bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29605 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07606}
607
608bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29609 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35610}
[email protected]74379bc52010-07-21 13:54:08611
612bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29613 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08614}
[email protected]9a28f132011-02-24 21:15:16615
616bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29617 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16618}
[email protected]18038f82012-11-20 13:46:58619
620const base::Value* PrefService::GetPreferenceValue(
621 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12622 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
battre0a69def2015-01-05 18:50:19623
624 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
625 // crash dumps it looks like the PrefService is accessed even though it has
626 // been cleared already.
627 CHECK(pref_registry_);
628 CHECK(pref_registry_->defaults());
629 CHECK(pref_value_store_);
630
[email protected]a43a667b2013-06-14 17:56:08631 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47632 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08633 const base::Value* found_value = NULL;
jdoerrie76cee9c2017-10-06 22:42:42634 base::Value::Type default_type = default_value->type();
[email protected]b1de2c72013-02-06 02:45:47635 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
636 DCHECK(found_value->IsType(default_type));
637 return found_value;
638 } else {
639 // Every registered preference has at least a default value.
640 NOTREACHED() << "no valid value found for registered pref " << path;
641 }
[email protected]18038f82012-11-20 13:46:58642 }
643
[email protected]18038f82012-11-20 13:46:58644 return NULL;
645}