blob: c4b27676cf6091d1f05243008a6f3e02306c33a0 [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:
Lei Zhangc3d77b62017-10-19 03:30:2832 using ErrorCallback =
33 base::Callback<void(PersistentPrefStore::PrefReadError)>;
34 explicit ReadErrorHandler(ErrorCallback cb) : callback_(cb) {}
[email protected]845b43a82011-05-11 10:14:4335
dcheng56488182014-10-21 10:54:5136 void OnError(PersistentPrefStore::PrefReadError error) override {
[email protected]70a317a2012-12-19 20:59:3337 callback_.Run(error);
[email protected]845b43a82011-05-11 10:14:4338 }
[email protected]70a317a2012-12-19 20:59:3339
40 private:
Lei Zhangc3d77b62017-10-19 03:30:2841 ErrorCallback callback_;
42
43 DISALLOW_COPY_AND_ASSIGN(ReadErrorHandler);
[email protected]845b43a82011-05-11 10:14:4344};
45
raymes76de1af2015-05-06 03:22:2146// Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
47// |path|.
avi9ef8bb02015-12-24 05:29:3648uint32_t GetWriteFlags(const PrefService::Preference* pref) {
49 uint32_t write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
raymesf3a929b02015-05-07 03:54:4550
51 if (!pref)
52 return write_flags;
53
raymes76de1af2015-05-06 03:22:2154 if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
raymesf3a929b02015-05-07 03:54:4555 write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
raymes76de1af2015-05-06 03:22:2156 return write_flags;
57}
58
initial.commit09911bf2008-07-26 23:55:2959} // namespace
60
[email protected]70a317a2012-12-19 20:59:3361PrefService::PrefService(
62 PrefNotifierImpl* pref_notifier,
63 PrefValueStore* pref_value_store,
64 PersistentPrefStore* user_prefs,
[email protected]b1de2c72013-02-06 02:45:4765 PrefRegistry* pref_registry,
[email protected]70a317a2012-12-19 20:59:3366 base::Callback<void(PersistentPrefStore::PrefReadError)>
67 read_error_callback,
68 bool async)
[email protected]361d37f62011-11-22 10:37:0269 : pref_notifier_(pref_notifier),
70 pref_value_store_(pref_value_store),
[email protected]b1de2c72013-02-06 02:45:4771 pref_registry_(pref_registry),
[email protected]361d37f62011-11-22 10:37:0272 user_pref_store_(user_prefs),
[email protected]5b199522012-12-22 17:24:4473 read_error_callback_(read_error_callback) {
[email protected]361d37f62011-11-22 10:37:0274 pref_notifier_->SetPrefService(this);
[email protected]b1de2c72013-02-06 02:45:4775
battre0a69def2015-01-05 18:50:1976 // TODO(battre): This is a check for crbug.com/435208 to make sure that
77 // access violations are caused by a use-after-free bug and not by an
78 // initialization bug.
79 CHECK(pref_registry_);
80 CHECK(pref_value_store_);
81
[email protected]361d37f62011-11-22 10:37:0282 InitFromStorage(async);
[email protected]9a8c4022011-01-25 14:25:3383}
84
initial.commit09911bf2008-07-26 23:55:2985PrefService::~PrefService() {
gab6e1fb5352017-05-31 18:27:1286 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]a98ce1262011-01-28 13:20:2387
88 // Reset pointers so accesses after destruction reliably crash.
89 pref_value_store_.reset();
Ivan Kotenkov75b1c3a2017-10-24 14:47:2490 pref_registry_ = nullptr;
91 user_pref_store_ = nullptr;
[email protected]42f23782012-06-08 19:11:5392 pref_notifier_.reset();
initial.commit09911bf2008-07-26 23:55:2993}
94
[email protected]845b43a82011-05-11 10:14:4395void PrefService::InitFromStorage(bool async) {
[email protected]38d1aab2014-03-29 17:48:4996 if (user_pref_store_->IsInitializationComplete()) {
97 read_error_callback_.Run(user_pref_store_->GetReadError());
98 } else if (!async) {
[email protected]70a317a2012-12-19 20:59:3399 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:21100 } else {
[email protected]845b43a82011-05-11 10:14:43101 // Guarantee that initialization happens after this function returned.
skyostil054861d2015-04-30 19:06:15102 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]845b43a82011-05-11 10:14:43103 FROM_HERE,
tzik07cace42016-09-01 04:21:25104 base::Bind(&PersistentPrefStore::ReadPrefsAsync, user_pref_store_,
[email protected]70a317a2012-12-19 20:59:33105 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:21106 }
[email protected]ba399672010-04-06 15:42:39107}
108
[email protected]3826fed2011-03-25 10:59:56109void PrefService::CommitPendingWrite() {
Pavol Markoe1f238f2017-09-05 18:58:42110 CommitPendingWrite(base::OnceClosure());
111}
112
113void PrefService::CommitPendingWrite(base::OnceClosure done_callback) {
gab6e1fb5352017-05-31 18:27:12114 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Pavol Markoe1f238f2017-09-05 18:58:42115 user_pref_store_->CommitPendingWrite(std::move(done_callback));
[email protected]3826fed2011-03-25 10:59:56116}
117
benwells26730592015-05-28 13:08:08118void PrefService::SchedulePendingLossyWrites() {
gab6e1fb5352017-05-31 18:27:12119 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
benwells26730592015-05-28 13:08:08120 user_pref_store_->SchedulePendingLossyWrites();
121}
122
georgesak7da6e9d2014-12-03 01:10:29123bool PrefService::GetBoolean(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12124 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29125
126 bool result = false;
initial.commit09911bf2008-07-26 23:55:29127
[email protected]18038f82012-11-20 13:46:58128 const base::Value* value = GetPreferenceValue(path);
129 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40130 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29131 return result;
132 }
[email protected]18038f82012-11-20 13:46:58133 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29134 DCHECK(rv);
135 return result;
136}
137
georgesak7da6e9d2014-12-03 01:10:29138int PrefService::GetInteger(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12139 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29140
141 int result = 0;
initial.commit09911bf2008-07-26 23:55:29142
[email protected]18038f82012-11-20 13:46:58143 const base::Value* value = GetPreferenceValue(path);
144 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40145 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29146 return result;
147 }
[email protected]18038f82012-11-20 13:46:58148 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29149 DCHECK(rv);
150 return result;
151}
152
georgesak7da6e9d2014-12-03 01:10:29153double PrefService::GetDouble(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12154 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29155
156 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29157
[email protected]18038f82012-11-20 13:46:58158 const base::Value* value = GetPreferenceValue(path);
159 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40160 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29161 return result;
162 }
[email protected]18038f82012-11-20 13:46:58163 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29164 DCHECK(rv);
165 return result;
166}
167
georgesak7da6e9d2014-12-03 01:10:29168std::string PrefService::GetString(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12169 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29170
[email protected]ddd231e2010-06-29 20:35:19171 std::string result;
[email protected]8e50b602009-03-03 22:59:43172
[email protected]18038f82012-11-20 13:46:58173 const base::Value* value = GetPreferenceValue(path);
174 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40175 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29176 return result;
177 }
[email protected]18038f82012-11-20 13:46:58178 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29179 DCHECK(rv);
180 return result;
181}
182
georgesak7da6e9d2014-12-03 01:10:29183base::FilePath PrefService::GetFilePath(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12184 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]b9636002009-03-04 00:05:25185
[email protected]650b2d52013-02-10 03:41:45186 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25187
[email protected]18038f82012-11-20 13:46:58188 const base::Value* value = GetPreferenceValue(path);
189 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40190 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45191 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25192 }
[email protected]18038f82012-11-20 13:46:58193 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25194 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04195 return result;
[email protected]b9636002009-03-04 00:05:25196}
197
georgesak7da6e9d2014-12-03 01:10:29198bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33199 const Preference* pref = FindPreference(path);
200 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29201}
202
brettwebf7184f2017-04-18 21:10:53203void PrefService::IteratePreferenceValues(
204 base::RepeatingCallback<void(const std::string& key,
205 const base::Value& value)> callback) const {
gab6e1fb5352017-05-31 18:27:12206 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
brettwebf7184f2017-04-18 21:10:53207 for (const auto& it : *pref_registry_)
208 callback.Run(it.first, *GetPreferenceValue(it.first));
asvitkine36ff0c5822014-11-25 22:58:18209}
210
brettwebf7184f2017-04-18 21:10:53211std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
212 IncludeDefaults include_defaults) const {
gab6e1fb5352017-05-31 18:27:12213 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dcheng5f043bc2016-04-22 19:09:06214 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18215 for (const auto& it : *pref_registry_) {
brettwebf7184f2017-04-18 21:10:53216 if (include_defaults == INCLUDE_DEFAULTS) {
217 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
218 } else {
219 const Preference* pref = FindPreference(it.first);
220 if (pref->IsDefaultValue())
221 continue;
222 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
223 }
[email protected]2a1965c2013-10-02 16:07:01224 }
danakj0c8d4aa2015-11-25 05:29:58225 return out;
[email protected]2a1965c2013-10-02 16:07:01226}
227
initial.commit09911bf2008-07-26 23:55:29228const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29229 const std::string& pref_name) const {
gab6e1fb5352017-05-31 18:27:12230 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]d15d5682012-10-23 17:50:42231 PreferenceMap::iterator it = prefs_map_.find(pref_name);
232 if (it != prefs_map_.end())
233 return &(it->second);
Ivan Kotenkov75b1c3a2017-10-24 14:47:24234 const base::Value* default_value = nullptr;
[email protected]b1de2c72013-02-06 02:45:47235 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
Ivan Kotenkov75b1c3a2017-10-24 14:47:24236 return nullptr;
jdoerrie76cee9c2017-10-06 22:42:42237 it = prefs_map_
238 .insert(std::make_pair(
239 pref_name, Preference(this, pref_name, default_value->type())))
240 .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
Sam McNallyf4dab612017-08-16 03:06:33263PrefService::PrefInitializationStatus
264PrefService::GetAllPrefStoresInitializationStatus() const {
265 if (!pref_value_store_->IsInitializationComplete())
266 return INITIALIZATION_STATUS_WAITING;
267
268 return GetInitializationStatus();
269}
270
georgesak7da6e9d2014-12-03 01:10:29271bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48272 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33273 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48274}
275
khannansb2025b72014-12-19 16:04:25276bool PrefService::IsPreferenceManagedByCustodian(
277 const std::string& pref_name) const {
278 const Preference* pref = FindPreference(pref_name);
279 return pref && pref->IsManagedByCustodian();
280}
281
georgesak7da6e9d2014-12-03 01:10:29282bool PrefService::IsUserModifiablePreference(
283 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07284 const Preference* pref = FindPreference(pref_name);
285 return pref && pref->IsUserModifiable();
286}
287
[email protected]a43a667b2013-06-14 17:56:08288const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29289 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12290 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29291
[email protected]a43a667b2013-06-14 17:56:08292 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58293 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40294 NOTREACHED() << "Trying to read an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24295 return nullptr;
initial.commit09911bf2008-07-26 23:55:29296 }
jdoerrie76cee9c2017-10-06 22:42:42297 if (value->type() != base::Value::Type::DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25298 NOTREACHED();
Ivan Kotenkov75b1c3a2017-10-24 14:47:24299 return nullptr;
[email protected]11b040b2011-02-02 12:42:25300 }
[email protected]a43a667b2013-06-14 17:56:08301 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29302}
303
georgesak7da6e9d2014-12-03 01:10:29304const base::Value* PrefService::GetUserPrefValue(
305 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12306 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]1a5a31f2012-04-26 20:21:34307
308 const Preference* pref = FindPreference(path);
309 if (!pref) {
310 NOTREACHED() << "Trying to get an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24311 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34312 }
313
314 // Look for an existing preference in the user store. If it doesn't
315 // exist, return NULL.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24316 base::Value* value = nullptr;
[email protected]892f1d62012-11-08 18:24:34317 if (!user_pref_store_->GetMutableValue(path, &value))
Ivan Kotenkov75b1c3a2017-10-24 14:47:24318 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34319
jdoerrief39c2a72017-11-22 10:39:32320 if (value->type() != pref->GetType()) {
[email protected]1a5a31f2012-04-26 20:21:34321 NOTREACHED() << "Pref value type doesn't match registered type.";
Ivan Kotenkov75b1c3a2017-10-24 14:47:24322 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34323 }
324
325 return value;
326}
327
georgesak7da6e9d2014-12-03 01:10:29328void PrefService::SetDefaultPrefValue(const std::string& path,
Lei Zhangc3d77b62017-10-19 03:30:28329 base::Value value) {
gab6e1fb5352017-05-31 18:27:12330 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Lei Zhangc3d77b62017-10-19 03:30:28331 pref_registry_->SetDefaultPrefValue(path, std::move(value));
[email protected]5879cef2013-03-02 17:02:25332}
333
georgesak7da6e9d2014-12-03 01:10:29334const base::Value* PrefService::GetDefaultPrefValue(
335 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12336 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]35a6fd12012-05-28 18:08:08337 // Lookup the preference in the default store.
Lei Zhang9e22c8432017-10-17 20:54:28338 const base::Value* value = nullptr;
339 bool has_value = pref_registry_->defaults()->GetValue(path, &value);
340 DCHECK(has_value) << "Default value missing for pref: " << path;
[email protected]35a6fd12012-05-28 18:08:08341 return value;
342}
343
georgesak7da6e9d2014-12-03 01:10:29344const base::ListValue* PrefService::GetList(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12345 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29346
[email protected]a43a667b2013-06-14 17:56:08347 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58348 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40349 NOTREACHED() << "Trying to read an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24350 return nullptr;
initial.commit09911bf2008-07-26 23:55:29351 }
jdoerrie76cee9c2017-10-06 22:42:42352 if (value->type() != base::Value::Type::LIST) {
[email protected]11b040b2011-02-02 12:42:25353 NOTREACHED();
Ivan Kotenkov75b1c3a2017-10-24 14:47:24354 return nullptr;
[email protected]11b040b2011-02-02 12:42:25355 }
[email protected]a43a667b2013-06-14 17:56:08356 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29357}
358
georgesak7da6e9d2014-12-03 01:10:29359void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50360 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29361}
362
georgesak7da6e9d2014-12-03 01:10:29363void PrefService::RemovePrefObserver(const std::string& path,
364 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50365 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29366}
367
[email protected]a6a7ced2012-11-01 17:24:18368void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
369 pref_notifier_->AddInitObserver(obs);
370}
371
[email protected]b1de2c72013-02-06 02:45:47372PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
373 return pref_registry_.get();
374}
375
georgesak7da6e9d2014-12-03 01:10:29376void PrefService::ClearPref(const std::string& path) {
gab6e1fb5352017-05-31 18:27:12377 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29378
379 const Preference* pref = FindPreference(path);
380 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40381 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29382 return;
383 }
raymesf3a929b02015-05-07 03:54:45384 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29385}
386
dvadym53fc0d42016-02-05 13:34:57387void PrefService::ClearMutableValues() {
388 user_pref_store_->ClearMutableValues();
389}
390
proberge45e347282017-08-16 21:24:05391void PrefService::OnStoreDeletionFromDisk() {
392 user_pref_store_->OnStoreDeletionFromDisk();
393}
394
Brett Wilson21cf626a2017-09-07 00:30:20395void PrefService::AddPrefObserverAllPrefs(PrefObserver* obs) {
396 pref_notifier_->AddPrefObserverAllPrefs(obs);
397}
398
399void PrefService::RemovePrefObserverAllPrefs(PrefObserver* obs) {
400 pref_notifier_->RemovePrefObserverAllPrefs(obs);
401}
402
georgesak7da6e9d2014-12-03 01:10:29403void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43404 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39405}
406
georgesak7da6e9d2014-12-03 01:10:29407void PrefService::SetBoolean(const std::string& path, bool value) {
vabrbce355c2017-03-23 18:52:43408 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29409}
410
georgesak7da6e9d2014-12-03 01:10:29411void PrefService::SetInteger(const std::string& path, int value) {
vabrbce355c2017-03-23 18:52:43412 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29413}
414
georgesak7da6e9d2014-12-03 01:10:29415void PrefService::SetDouble(const std::string& path, double value) {
vabrbce355c2017-03-23 18:52:43416 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29417}
418
georgesak7da6e9d2014-12-03 01:10:29419void PrefService::SetString(const std::string& path, const std::string& value) {
vabrbce355c2017-03-23 18:52:43420 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29421}
422
georgesak7da6e9d2014-12-03 01:10:29423void PrefService::SetFilePath(const std::string& path,
424 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50425 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25426}
427
avi9ef8bb02015-12-24 05:29:36428void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43429 SetUserPrefValue(path,
430 base::MakeUnique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32431}
432
avi9ef8bb02015-12-24 05:29:36433int64_t PrefService::GetInt64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12434 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]0bb1a622009-03-04 03:22:32435
[email protected]a43a667b2013-06-14 17:56:08436 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58437 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40438 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08439 return 0;
[email protected]0bb1a622009-03-04 03:22:32440 }
[email protected]dc9a6762010-08-16 07:13:53441 std::string result("0");
[email protected]18038f82012-11-20 13:46:58442 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32443 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25444
avi9ef8bb02015-12-24 05:29:36445 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53446 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25447 return val;
[email protected]0bb1a622009-03-04 03:22:32448}
449
avi9ef8bb02015-12-24 05:29:36450void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43451 SetUserPrefValue(path,
452 base::MakeUnique<base::Value>(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43453}
454
avi9ef8bb02015-12-24 05:29:36455uint64_t PrefService::GetUint64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12456 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]3cbe0812012-07-03 02:51:43457
[email protected]a43a667b2013-06-14 17:56:08458 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58459 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43460 NOTREACHED() << "Trying to read an unregistered pref: " << path;
461 return 0;
462 }
463 std::string result("0");
[email protected]18038f82012-11-20 13:46:58464 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43465 DCHECK(rv);
466
avi9ef8bb02015-12-24 05:29:36467 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43468 base::StringToUint64(result, &val);
469 return val;
470}
471
georgesak7da6e9d2014-12-03 01:10:29472base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08473 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28474 CHECK(type == base::Value::Type::DICTIONARY ||
475 type == base::Value::Type::LIST);
gab6e1fb5352017-05-31 18:27:12476 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29477
478 const Preference* pref = FindPreference(path);
479 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40480 NOTREACHED() << "Trying to get an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24481 return nullptr;
initial.commit09911bf2008-07-26 23:55:29482 }
[email protected]26418b72011-03-30 14:07:39483 if (pref->GetType() != type) {
484 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24485 return nullptr;
initial.commit09911bf2008-07-26 23:55:29486 }
487
[email protected]e0250892010-10-01 18:57:53488 // Look for an existing preference in the user store. If it doesn't
489 // exist or isn't the correct type, create a new user preference.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24490 base::Value* value = nullptr;
[email protected]892f1d62012-11-08 18:24:34491 if (!user_pref_store_->GetMutableValue(path, &value) ||
jdoerrief39c2a72017-11-22 10:39:32492 value->type() != type) {
jdoerriedc72ee942016-12-07 15:43:28493 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08494 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28495 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08496 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39497 } else {
498 NOTREACHED();
499 }
dcheng5f043bc2016-04-22 19:09:06500 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18501 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29502 }
[email protected]26418b72011-03-30 14:07:39503 return value;
504}
505
[email protected]68bf41a2011-03-25 16:38:31506void PrefService::ReportUserPrefChanged(const std::string& key) {
gab6e1fb5352017-05-31 18:27:12507 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
raymesf3a929b02015-05-07 03:54:45508 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27509}
510
Sam McNally69572322017-05-01 00:41:38511void PrefService::ReportUserPrefChanged(
512 const std::string& key,
513 std::set<std::vector<std::string>> path_components) {
gab6e1fb5352017-05-31 18:27:12514 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam McNally69572322017-05-01 00:41:38515 user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
516 GetWriteFlags(FindPreference(key)));
517}
518
georgesak7da6e9d2014-12-03 01:10:29519void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43520 std::unique_ptr<base::Value> new_value) {
gab6e1fb5352017-05-31 18:27:12521 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]c3b54f372010-09-14 08:25:07522
523 const Preference* pref = FindPreference(path);
524 if (!pref) {
525 NOTREACHED() << "Trying to write an unregistered pref: " << path;
526 return;
527 }
jdoerrie76cee9c2017-10-06 22:42:42528 if (pref->GetType() != new_value->type()) {
529 NOTREACHED() << "Trying to set pref " << path << " of type "
530 << pref->GetType() << " to value of type "
531 << new_value->type();
[email protected]c3b54f372010-09-14 08:25:07532 return;
533 }
534
vabrbce355c2017-03-23 18:52:43535 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43536}
537
[email protected]5b199522012-12-22 17:24:44538void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
539 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05540}
541
initial.commit09911bf2008-07-26 23:55:29542///////////////////////////////////////////////////////////////////////////////
543// PrefService::Preference
544
[email protected]c3b54f372010-09-14 08:25:07545PrefService::Preference::Preference(const PrefService* service,
François Degros484a1332017-11-29 00:47:48546 std::string name,
[email protected]bab1c13f2011-08-12 20:59:02547 base::Value::Type type)
François Degros484a1332017-11-29 00:47:48548 : name_(std::move(name)),
549 type_(type),
550 // Cache the registration flags at creation time to avoid multiple map
551 // lookups later.
552 registration_flags_(service->pref_registry_->GetRegistrationFlags(name_)),
553 pref_service_(service) {}
initial.commit09911bf2008-07-26 23:55:29554
[email protected]a43a667b2013-06-14 17:56:08555const base::Value* PrefService::Preference::GetValue() const {
Lei Zhangc3d77b62017-10-19 03:30:28556 const base::Value* result = pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58557 DCHECK(result) << "Must register pref before getting its value";
558 return result;
[email protected]40a47c162010-09-09 11:14:01559}
560
[email protected]a43a667b2013-06-14 17:56:08561const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29562 DCHECK(pref_service_->FindPreference(name_))
563 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03564
Ivan Kotenkov75b1c3a2017-10-24 14:47:24565 const base::Value* found_value = nullptr;
[email protected]7ca0f362012-07-30 10:14:03566 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
jdoerrief39c2a72017-11-22 10:39:32567 DCHECK(found_value->type() == type_);
[email protected]7ca0f362012-07-30 10:14:03568 return found_value;
569 }
570
571 // The pref has no recommended value.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24572 return nullptr;
[email protected]7ca0f362012-07-30 10:14:03573}
574
[email protected]40a47c162010-09-09 11:14:01575bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29576 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01577}
578
khannansb2025b72014-12-19 16:04:25579bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09580 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25581}
582
[email protected]a5437282011-12-12 12:33:21583bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29584 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21585}
586
[email protected]40a47c162010-09-09 11:14:01587bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29588 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01589}
590
591bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29592 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01593}
594
595bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29596 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01597}
598
599bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29600 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07601}
602
603bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29604 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35605}
[email protected]74379bc52010-07-21 13:54:08606
607bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29608 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08609}
[email protected]9a28f132011-02-24 21:15:16610
611bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29612 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16613}
[email protected]18038f82012-11-20 13:46:58614
615const base::Value* PrefService::GetPreferenceValue(
616 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12617 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
battre0a69def2015-01-05 18:50:19618
619 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
620 // crash dumps it looks like the PrefService is accessed even though it has
621 // been cleared already.
622 CHECK(pref_registry_);
623 CHECK(pref_registry_->defaults());
624 CHECK(pref_value_store_);
625
Ivan Kotenkov75b1c3a2017-10-24 14:47:24626 const base::Value* default_value = nullptr;
[email protected]b1de2c72013-02-06 02:45:47627 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
Ivan Kotenkov75b1c3a2017-10-24 14:47:24628 const base::Value* found_value = nullptr;
jdoerrie76cee9c2017-10-06 22:42:42629 base::Value::Type default_type = default_value->type();
[email protected]b1de2c72013-02-06 02:45:47630 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
jdoerrief39c2a72017-11-22 10:39:32631 DCHECK(found_value->type() == default_type);
[email protected]b1de2c72013-02-06 02:45:47632 return found_value;
633 } else {
634 // Every registered preference has at least a default value.
635 NOTREACHED() << "no valid value found for registered pref " << path;
636 }
[email protected]18038f82012-11-20 13:46:58637 }
638
Ivan Kotenkov75b1c3a2017-10-24 14:47:24639 return nullptr;
[email protected]18038f82012-11-20 13:46:58640}