blob: 7254d0b582e96a5f2b52fc12d7dd0e632be89534 [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 =
François Degrose39cf535e2018-02-07 02:08:3033 base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>;
Lei Zhangc3d77b62017-10-19 03:30:2834 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(
François Degrosee2f030d2017-12-04 00:29:0162 std::unique_ptr<PrefNotifierImpl> pref_notifier,
63 std::unique_ptr<PrefValueStore> pref_value_store,
François Degrose39cf535e2018-02-07 02:08:3064 scoped_refptr<PersistentPrefStore> user_prefs,
65 scoped_refptr<PrefRegistry> pref_registry,
66 base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>
[email protected]70a317a2012-12-19 20:59:3367 read_error_callback,
68 bool async)
François Degrosee2f030d2017-12-04 00:29:0169 : pref_notifier_(std::move(pref_notifier)),
70 pref_value_store_(std::move(pref_value_store)),
François Degrose39cf535e2018-02-07 02:08:3071 pref_registry_(std::move(pref_registry)),
72 user_pref_store_(std::move(user_prefs)),
73 read_error_callback_(std::move(read_error_callback)) {
[email protected]361d37f62011-11-22 10:37:0274 pref_notifier_->SetPrefService(this);
[email protected]b1de2c72013-02-06 02:45:4775
François Degros6783125f2018-02-07 22:43:2476 DCHECK(pref_registry_);
77 DCHECK(pref_value_store_);
battre0a69def2015-01-05 18:50:1978
[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_);
initial.commit09911bf2008-07-26 23:55:2984}
85
[email protected]845b43a82011-05-11 10:14:4386void PrefService::InitFromStorage(bool async) {
[email protected]38d1aab2014-03-29 17:48:4987 if (user_pref_store_->IsInitializationComplete()) {
88 read_error_callback_.Run(user_pref_store_->GetReadError());
89 } else if (!async) {
[email protected]70a317a2012-12-19 20:59:3390 read_error_callback_.Run(user_pref_store_->ReadPrefs());
[email protected]844a1002011-04-19 11:37:2191 } else {
[email protected]845b43a82011-05-11 10:14:4392 // Guarantee that initialization happens after this function returned.
skyostil054861d2015-04-30 19:06:1593 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]845b43a82011-05-11 10:14:4394 FROM_HERE,
tzik07cace42016-09-01 04:21:2595 base::Bind(&PersistentPrefStore::ReadPrefsAsync, user_pref_store_,
[email protected]70a317a2012-12-19 20:59:3396 new ReadErrorHandler(read_error_callback_)));
[email protected]844a1002011-04-19 11:37:2197 }
[email protected]ba399672010-04-06 15:42:3998}
99
[email protected]3826fed2011-03-25 10:59:56100void PrefService::CommitPendingWrite() {
Pavol Markoe1f238f2017-09-05 18:58:42101 CommitPendingWrite(base::OnceClosure());
102}
103
104void PrefService::CommitPendingWrite(base::OnceClosure done_callback) {
gab6e1fb5352017-05-31 18:27:12105 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Pavol Markoe1f238f2017-09-05 18:58:42106 user_pref_store_->CommitPendingWrite(std::move(done_callback));
[email protected]3826fed2011-03-25 10:59:56107}
108
benwells26730592015-05-28 13:08:08109void PrefService::SchedulePendingLossyWrites() {
gab6e1fb5352017-05-31 18:27:12110 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
benwells26730592015-05-28 13:08:08111 user_pref_store_->SchedulePendingLossyWrites();
112}
113
georgesak7da6e9d2014-12-03 01:10:29114bool PrefService::GetBoolean(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12115 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29116
117 bool result = false;
initial.commit09911bf2008-07-26 23:55:29118
[email protected]18038f82012-11-20 13:46:58119 const base::Value* value = GetPreferenceValue(path);
120 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40121 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29122 return result;
123 }
[email protected]18038f82012-11-20 13:46:58124 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29125 DCHECK(rv);
126 return result;
127}
128
georgesak7da6e9d2014-12-03 01:10:29129int PrefService::GetInteger(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12130 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29131
132 int result = 0;
initial.commit09911bf2008-07-26 23:55:29133
[email protected]18038f82012-11-20 13:46:58134 const base::Value* value = GetPreferenceValue(path);
135 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40136 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29137 return result;
138 }
[email protected]18038f82012-11-20 13:46:58139 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29140 DCHECK(rv);
141 return result;
142}
143
georgesak7da6e9d2014-12-03 01:10:29144double PrefService::GetDouble(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12145 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29146
147 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29148
[email protected]18038f82012-11-20 13:46:58149 const base::Value* value = GetPreferenceValue(path);
150 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40151 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29152 return result;
153 }
[email protected]18038f82012-11-20 13:46:58154 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29155 DCHECK(rv);
156 return result;
157}
158
georgesak7da6e9d2014-12-03 01:10:29159std::string PrefService::GetString(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12160 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29161
[email protected]ddd231e2010-06-29 20:35:19162 std::string result;
[email protected]8e50b602009-03-03 22:59:43163
[email protected]18038f82012-11-20 13:46:58164 const base::Value* value = GetPreferenceValue(path);
165 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40166 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29167 return result;
168 }
[email protected]18038f82012-11-20 13:46:58169 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29170 DCHECK(rv);
171 return result;
172}
173
georgesak7da6e9d2014-12-03 01:10:29174base::FilePath PrefService::GetFilePath(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12175 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]b9636002009-03-04 00:05:25176
[email protected]650b2d52013-02-10 03:41:45177 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25178
[email protected]18038f82012-11-20 13:46:58179 const base::Value* value = GetPreferenceValue(path);
180 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40181 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45182 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25183 }
[email protected]18038f82012-11-20 13:46:58184 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25185 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04186 return result;
[email protected]b9636002009-03-04 00:05:25187}
188
georgesak7da6e9d2014-12-03 01:10:29189bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33190 const Preference* pref = FindPreference(path);
191 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29192}
193
brettwebf7184f2017-04-18 21:10:53194void PrefService::IteratePreferenceValues(
195 base::RepeatingCallback<void(const std::string& key,
196 const base::Value& value)> callback) const {
gab6e1fb5352017-05-31 18:27:12197 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
brettwebf7184f2017-04-18 21:10:53198 for (const auto& it : *pref_registry_)
199 callback.Run(it.first, *GetPreferenceValue(it.first));
asvitkine36ff0c5822014-11-25 22:58:18200}
201
brettwebf7184f2017-04-18 21:10:53202std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
203 IncludeDefaults include_defaults) const {
gab6e1fb5352017-05-31 18:27:12204 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dcheng5f043bc2016-04-22 19:09:06205 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18206 for (const auto& it : *pref_registry_) {
brettwebf7184f2017-04-18 21:10:53207 if (include_defaults == INCLUDE_DEFAULTS) {
208 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
209 } else {
210 const Preference* pref = FindPreference(it.first);
211 if (pref->IsDefaultValue())
212 continue;
213 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
214 }
[email protected]2a1965c2013-10-02 16:07:01215 }
danakj0c8d4aa2015-11-25 05:29:58216 return out;
[email protected]2a1965c2013-10-02 16:07:01217}
218
initial.commit09911bf2008-07-26 23:55:29219const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29220 const std::string& pref_name) const {
gab6e1fb5352017-05-31 18:27:12221 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]d15d5682012-10-23 17:50:42222 PreferenceMap::iterator it = prefs_map_.find(pref_name);
223 if (it != prefs_map_.end())
224 return &(it->second);
Ivan Kotenkov75b1c3a2017-10-24 14:47:24225 const base::Value* default_value = nullptr;
[email protected]b1de2c72013-02-06 02:45:47226 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
Ivan Kotenkov75b1c3a2017-10-24 14:47:24227 return nullptr;
jdoerrie76cee9c2017-10-06 22:42:42228 it = prefs_map_
229 .insert(std::make_pair(
230 pref_name, Preference(this, pref_name, default_value->type())))
231 .first;
[email protected]d15d5682012-10-23 17:50:42232 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29233}
234
[email protected]acd78969c2010-12-08 09:49:11235bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17236 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11237}
238
[email protected]59c10712012-03-13 02:10:34239PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
240 const {
241 if (!user_pref_store_->IsInitializationComplete())
242 return INITIALIZATION_STATUS_WAITING;
243
244 switch (user_pref_store_->GetReadError()) {
245 case PersistentPrefStore::PREF_READ_ERROR_NONE:
246 return INITIALIZATION_STATUS_SUCCESS;
247 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18248 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34249 default:
250 return INITIALIZATION_STATUS_ERROR;
251 }
252}
253
Sam McNallyf4dab612017-08-16 03:06:33254PrefService::PrefInitializationStatus
255PrefService::GetAllPrefStoresInitializationStatus() const {
256 if (!pref_value_store_->IsInitializationComplete())
257 return INITIALIZATION_STATUS_WAITING;
258
259 return GetInitializationStatus();
260}
261
georgesak7da6e9d2014-12-03 01:10:29262bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48263 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33264 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48265}
266
khannansb2025b72014-12-19 16:04:25267bool PrefService::IsPreferenceManagedByCustodian(
268 const std::string& pref_name) const {
269 const Preference* pref = FindPreference(pref_name);
270 return pref && pref->IsManagedByCustodian();
271}
272
georgesak7da6e9d2014-12-03 01:10:29273bool PrefService::IsUserModifiablePreference(
274 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07275 const Preference* pref = FindPreference(pref_name);
276 return pref && pref->IsUserModifiable();
277}
278
Steven Bennettsca108512018-05-02 11:05:03279const base::Value* PrefService::Get(const std::string& path) const {
280 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
281
282 const base::Value* value = GetPreferenceValue(path);
283 if (!value) {
284 NOTREACHED() << "Trying to read an unregistered pref: " << path;
285 return nullptr;
286 }
287 return value;
288}
289
[email protected]a43a667b2013-06-14 17:56:08290const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29291 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12292 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29293
[email protected]a43a667b2013-06-14 17:56:08294 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58295 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40296 NOTREACHED() << "Trying to read an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24297 return nullptr;
initial.commit09911bf2008-07-26 23:55:29298 }
jdoerrie76cee9c2017-10-06 22:42:42299 if (value->type() != base::Value::Type::DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25300 NOTREACHED();
Ivan Kotenkov75b1c3a2017-10-24 14:47:24301 return nullptr;
[email protected]11b040b2011-02-02 12:42:25302 }
[email protected]a43a667b2013-06-14 17:56:08303 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29304}
305
georgesak7da6e9d2014-12-03 01:10:29306const base::Value* PrefService::GetUserPrefValue(
307 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12308 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]1a5a31f2012-04-26 20:21:34309
310 const Preference* pref = FindPreference(path);
311 if (!pref) {
312 NOTREACHED() << "Trying to get an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24313 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34314 }
315
316 // Look for an existing preference in the user store. If it doesn't
317 // exist, return NULL.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24318 base::Value* value = nullptr;
[email protected]892f1d62012-11-08 18:24:34319 if (!user_pref_store_->GetMutableValue(path, &value))
Ivan Kotenkov75b1c3a2017-10-24 14:47:24320 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34321
jdoerrief39c2a72017-11-22 10:39:32322 if (value->type() != pref->GetType()) {
[email protected]1a5a31f2012-04-26 20:21:34323 NOTREACHED() << "Pref value type doesn't match registered type.";
Ivan Kotenkov75b1c3a2017-10-24 14:47:24324 return nullptr;
[email protected]1a5a31f2012-04-26 20:21:34325 }
326
327 return value;
328}
329
georgesak7da6e9d2014-12-03 01:10:29330void PrefService::SetDefaultPrefValue(const std::string& path,
Lei Zhangc3d77b62017-10-19 03:30:28331 base::Value value) {
gab6e1fb5352017-05-31 18:27:12332 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Lei Zhangc3d77b62017-10-19 03:30:28333 pref_registry_->SetDefaultPrefValue(path, std::move(value));
[email protected]5879cef2013-03-02 17:02:25334}
335
georgesak7da6e9d2014-12-03 01:10:29336const base::Value* PrefService::GetDefaultPrefValue(
337 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12338 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]35a6fd12012-05-28 18:08:08339 // Lookup the preference in the default store.
Lei Zhang9e22c8432017-10-17 20:54:28340 const base::Value* value = nullptr;
341 bool has_value = pref_registry_->defaults()->GetValue(path, &value);
342 DCHECK(has_value) << "Default value missing for pref: " << path;
[email protected]35a6fd12012-05-28 18:08:08343 return value;
344}
345
georgesak7da6e9d2014-12-03 01:10:29346const base::ListValue* PrefService::GetList(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12347 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29348
[email protected]a43a667b2013-06-14 17:56:08349 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58350 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40351 NOTREACHED() << "Trying to read an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24352 return nullptr;
initial.commit09911bf2008-07-26 23:55:29353 }
jdoerrie76cee9c2017-10-06 22:42:42354 if (value->type() != base::Value::Type::LIST) {
[email protected]11b040b2011-02-02 12:42:25355 NOTREACHED();
Ivan Kotenkov75b1c3a2017-10-24 14:47:24356 return nullptr;
[email protected]11b040b2011-02-02 12:42:25357 }
[email protected]a43a667b2013-06-14 17:56:08358 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29359}
360
georgesak7da6e9d2014-12-03 01:10:29361void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50362 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29363}
364
georgesak7da6e9d2014-12-03 01:10:29365void PrefService::RemovePrefObserver(const std::string& path,
366 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50367 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29368}
369
Kenichi Ishibashif958ad62017-12-19 02:43:14370void PrefService::AddPrefInitObserver(base::OnceCallback<void(bool)> obs) {
371 pref_notifier_->AddInitObserver(std::move(obs));
[email protected]a6a7ced2012-11-01 17:24:18372}
373
[email protected]b1de2c72013-02-06 02:45:47374PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
375 return pref_registry_.get();
376}
377
georgesak7da6e9d2014-12-03 01:10:29378void PrefService::ClearPref(const std::string& path) {
gab6e1fb5352017-05-31 18:27:12379 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29380
381 const Preference* pref = FindPreference(path);
382 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40383 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29384 return;
385 }
raymesf3a929b02015-05-07 03:54:45386 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29387}
388
dvadym53fc0d42016-02-05 13:34:57389void PrefService::ClearMutableValues() {
390 user_pref_store_->ClearMutableValues();
391}
392
proberge45e347282017-08-16 21:24:05393void PrefService::OnStoreDeletionFromDisk() {
394 user_pref_store_->OnStoreDeletionFromDisk();
395}
396
Brett Wilson21cf626a2017-09-07 00:30:20397void PrefService::AddPrefObserverAllPrefs(PrefObserver* obs) {
398 pref_notifier_->AddPrefObserverAllPrefs(obs);
399}
400
401void PrefService::RemovePrefObserverAllPrefs(PrefObserver* obs) {
402 pref_notifier_->RemovePrefObserverAllPrefs(obs);
403}
404
georgesak7da6e9d2014-12-03 01:10:29405void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43406 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39407}
408
georgesak7da6e9d2014-12-03 01:10:29409void PrefService::SetBoolean(const std::string& path, bool value) {
Jinho Bang84b58bd2018-01-01 21:44:48410 SetUserPrefValue(path, std::make_unique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29411}
412
georgesak7da6e9d2014-12-03 01:10:29413void PrefService::SetInteger(const std::string& path, int value) {
Jinho Bang84b58bd2018-01-01 21:44:48414 SetUserPrefValue(path, std::make_unique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29415}
416
georgesak7da6e9d2014-12-03 01:10:29417void PrefService::SetDouble(const std::string& path, double value) {
Jinho Bang84b58bd2018-01-01 21:44:48418 SetUserPrefValue(path, std::make_unique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29419}
420
georgesak7da6e9d2014-12-03 01:10:29421void PrefService::SetString(const std::string& path, const std::string& value) {
Jinho Bang84b58bd2018-01-01 21:44:48422 SetUserPrefValue(path, std::make_unique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29423}
424
georgesak7da6e9d2014-12-03 01:10:29425void PrefService::SetFilePath(const std::string& path,
426 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50427 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25428}
429
avi9ef8bb02015-12-24 05:29:36430void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43431 SetUserPrefValue(path,
Jinho Bang84b58bd2018-01-01 21:44:48432 std::make_unique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32433}
434
avi9ef8bb02015-12-24 05:29:36435int64_t PrefService::GetInt64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12436 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]0bb1a622009-03-04 03:22:32437
[email protected]a43a667b2013-06-14 17:56:08438 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58439 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40440 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08441 return 0;
[email protected]0bb1a622009-03-04 03:22:32442 }
[email protected]dc9a6762010-08-16 07:13:53443 std::string result("0");
[email protected]18038f82012-11-20 13:46:58444 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32445 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25446
avi9ef8bb02015-12-24 05:29:36447 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53448 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25449 return val;
[email protected]0bb1a622009-03-04 03:22:32450}
451
avi9ef8bb02015-12-24 05:29:36452void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43453 SetUserPrefValue(path,
Jinho Bang84b58bd2018-01-01 21:44:48454 std::make_unique<base::Value>(base::NumberToString(value)));
[email protected]3cbe0812012-07-03 02:51:43455}
456
avi9ef8bb02015-12-24 05:29:36457uint64_t PrefService::GetUint64(const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12458 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]3cbe0812012-07-03 02:51:43459
[email protected]a43a667b2013-06-14 17:56:08460 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58461 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43462 NOTREACHED() << "Trying to read an unregistered pref: " << path;
463 return 0;
464 }
465 std::string result("0");
[email protected]18038f82012-11-20 13:46:58466 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43467 DCHECK(rv);
468
avi9ef8bb02015-12-24 05:29:36469 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43470 base::StringToUint64(result, &val);
471 return val;
472}
473
Ilya Sherman557b2de72018-01-18 20:57:17474void PrefService::SetTime(const std::string& path, base::Time value) {
475 SetInt64(path, value.ToDeltaSinceWindowsEpoch().InMicroseconds());
476}
477
478base::Time PrefService::GetTime(const std::string& path) const {
479 return base::Time::FromDeltaSinceWindowsEpoch(
480 base::TimeDelta::FromMicroseconds(GetInt64(path)));
481}
482
georgesak7da6e9d2014-12-03 01:10:29483base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08484 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28485 CHECK(type == base::Value::Type::DICTIONARY ||
486 type == base::Value::Type::LIST);
gab6e1fb5352017-05-31 18:27:12487 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
initial.commit09911bf2008-07-26 23:55:29488
489 const Preference* pref = FindPreference(path);
490 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40491 NOTREACHED() << "Trying to get an unregistered pref: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24492 return nullptr;
initial.commit09911bf2008-07-26 23:55:29493 }
[email protected]26418b72011-03-30 14:07:39494 if (pref->GetType() != type) {
495 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
Ivan Kotenkov75b1c3a2017-10-24 14:47:24496 return nullptr;
initial.commit09911bf2008-07-26 23:55:29497 }
498
[email protected]e0250892010-10-01 18:57:53499 // Look for an existing preference in the user store. If it doesn't
500 // exist or isn't the correct type, create a new user preference.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24501 base::Value* value = nullptr;
[email protected]892f1d62012-11-08 18:24:34502 if (!user_pref_store_->GetMutableValue(path, &value) ||
jdoerrief39c2a72017-11-22 10:39:32503 value->type() != type) {
jdoerriedc72ee942016-12-07 15:43:28504 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08505 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28506 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08507 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39508 } else {
509 NOTREACHED();
510 }
dcheng5f043bc2016-04-22 19:09:06511 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18512 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29513 }
[email protected]26418b72011-03-30 14:07:39514 return value;
515}
516
[email protected]68bf41a2011-03-25 16:38:31517void PrefService::ReportUserPrefChanged(const std::string& key) {
gab6e1fb5352017-05-31 18:27:12518 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
raymesf3a929b02015-05-07 03:54:45519 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27520}
521
Sam McNally69572322017-05-01 00:41:38522void PrefService::ReportUserPrefChanged(
523 const std::string& key,
524 std::set<std::vector<std::string>> path_components) {
gab6e1fb5352017-05-31 18:27:12525 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Sam McNally69572322017-05-01 00:41:38526 user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
527 GetWriteFlags(FindPreference(key)));
528}
529
georgesak7da6e9d2014-12-03 01:10:29530void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43531 std::unique_ptr<base::Value> new_value) {
gab6e1fb5352017-05-31 18:27:12532 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
[email protected]c3b54f372010-09-14 08:25:07533
534 const Preference* pref = FindPreference(path);
535 if (!pref) {
536 NOTREACHED() << "Trying to write an unregistered pref: " << path;
537 return;
538 }
jdoerrie76cee9c2017-10-06 22:42:42539 if (pref->GetType() != new_value->type()) {
540 NOTREACHED() << "Trying to set pref " << path << " of type "
541 << pref->GetType() << " to value of type "
542 << new_value->type();
[email protected]c3b54f372010-09-14 08:25:07543 return;
544 }
545
vabrbce355c2017-03-23 18:52:43546 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43547}
548
[email protected]5b199522012-12-22 17:24:44549void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
550 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05551}
552
initial.commit09911bf2008-07-26 23:55:29553///////////////////////////////////////////////////////////////////////////////
554// PrefService::Preference
555
[email protected]c3b54f372010-09-14 08:25:07556PrefService::Preference::Preference(const PrefService* service,
François Degros484a1332017-11-29 00:47:48557 std::string name,
[email protected]bab1c13f2011-08-12 20:59:02558 base::Value::Type type)
François Degros484a1332017-11-29 00:47:48559 : name_(std::move(name)),
560 type_(type),
561 // Cache the registration flags at creation time to avoid multiple map
562 // lookups later.
563 registration_flags_(service->pref_registry_->GetRegistrationFlags(name_)),
564 pref_service_(service) {}
initial.commit09911bf2008-07-26 23:55:29565
[email protected]a43a667b2013-06-14 17:56:08566const base::Value* PrefService::Preference::GetValue() const {
Lei Zhangc3d77b62017-10-19 03:30:28567 const base::Value* result = pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58568 DCHECK(result) << "Must register pref before getting its value";
569 return result;
[email protected]40a47c162010-09-09 11:14:01570}
571
[email protected]a43a667b2013-06-14 17:56:08572const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29573 DCHECK(pref_service_->FindPreference(name_))
574 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03575
Ivan Kotenkov75b1c3a2017-10-24 14:47:24576 const base::Value* found_value = nullptr;
[email protected]7ca0f362012-07-30 10:14:03577 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
jdoerrief39c2a72017-11-22 10:39:32578 DCHECK(found_value->type() == type_);
[email protected]7ca0f362012-07-30 10:14:03579 return found_value;
580 }
581
582 // The pref has no recommended value.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24583 return nullptr;
[email protected]7ca0f362012-07-30 10:14:03584}
585
[email protected]40a47c162010-09-09 11:14:01586bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29587 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01588}
589
khannansb2025b72014-12-19 16:04:25590bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09591 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25592}
593
[email protected]a5437282011-12-12 12:33:21594bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29595 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21596}
597
[email protected]40a47c162010-09-09 11:14:01598bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29599 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01600}
601
602bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29603 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01604}
605
606bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29607 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01608}
609
610bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29611 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07612}
613
614bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29615 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35616}
[email protected]74379bc52010-07-21 13:54:08617
618bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29619 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08620}
[email protected]9a28f132011-02-24 21:15:16621
622bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29623 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16624}
[email protected]18038f82012-11-20 13:46:58625
626const base::Value* PrefService::GetPreferenceValue(
627 const std::string& path) const {
gab6e1fb5352017-05-31 18:27:12628 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
battre0a69def2015-01-05 18:50:19629
630 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
631 // crash dumps it looks like the PrefService is accessed even though it has
632 // been cleared already.
633 CHECK(pref_registry_);
634 CHECK(pref_registry_->defaults());
635 CHECK(pref_value_store_);
636
Ivan Kotenkov75b1c3a2017-10-24 14:47:24637 const base::Value* default_value = nullptr;
[email protected]b1de2c72013-02-06 02:45:47638 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
Ivan Kotenkov75b1c3a2017-10-24 14:47:24639 const base::Value* found_value = nullptr;
jdoerrie76cee9c2017-10-06 22:42:42640 base::Value::Type default_type = default_value->type();
[email protected]b1de2c72013-02-06 02:45:47641 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
jdoerrief39c2a72017-11-22 10:39:32642 DCHECK(found_value->type() == default_type);
[email protected]b1de2c72013-02-06 02:45:47643 return found_value;
644 } else {
645 // Every registered preference has at least a default value.
646 NOTREACHED() << "no valid value found for registered pref " << path;
647 }
[email protected]18038f82012-11-20 13:46:58648 }
649
Ivan Kotenkov75b1c3a2017-10-24 14:47:24650 return nullptr;
[email protected]18038f82012-11-20 13:46:58651}