blob: 4ebea533478d97c4b6fa87b0f41abfae99dd0f61 [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() {
83 DCHECK(CalledOnValidThread());
[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() {
107 DCHECK(CalledOnValidThread());
108 user_pref_store_->CommitPendingWrite();
109}
110
benwells26730592015-05-28 13:08:08111void PrefService::SchedulePendingLossyWrites() {
112 DCHECK(CalledOnValidThread());
113 user_pref_store_->SchedulePendingLossyWrites();
114}
115
georgesak7da6e9d2014-12-03 01:10:29116bool PrefService::GetBoolean(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29117 DCHECK(CalledOnValidThread());
118
119 bool result = false;
initial.commit09911bf2008-07-26 23:55:29120
[email protected]18038f82012-11-20 13:46:58121 const base::Value* value = GetPreferenceValue(path);
122 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40123 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29124 return result;
125 }
[email protected]18038f82012-11-20 13:46:58126 bool rv = value->GetAsBoolean(&result);
initial.commit09911bf2008-07-26 23:55:29127 DCHECK(rv);
128 return result;
129}
130
georgesak7da6e9d2014-12-03 01:10:29131int PrefService::GetInteger(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29132 DCHECK(CalledOnValidThread());
133
134 int result = 0;
initial.commit09911bf2008-07-26 23:55:29135
[email protected]18038f82012-11-20 13:46:58136 const base::Value* value = GetPreferenceValue(path);
137 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40138 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29139 return result;
140 }
[email protected]18038f82012-11-20 13:46:58141 bool rv = value->GetAsInteger(&result);
initial.commit09911bf2008-07-26 23:55:29142 DCHECK(rv);
143 return result;
144}
145
georgesak7da6e9d2014-12-03 01:10:29146double PrefService::GetDouble(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29147 DCHECK(CalledOnValidThread());
148
149 double result = 0.0;
initial.commit09911bf2008-07-26 23:55:29150
[email protected]18038f82012-11-20 13:46:58151 const base::Value* value = GetPreferenceValue(path);
152 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40153 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29154 return result;
155 }
[email protected]18038f82012-11-20 13:46:58156 bool rv = value->GetAsDouble(&result);
initial.commit09911bf2008-07-26 23:55:29157 DCHECK(rv);
158 return result;
159}
160
georgesak7da6e9d2014-12-03 01:10:29161std::string PrefService::GetString(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29162 DCHECK(CalledOnValidThread());
163
[email protected]ddd231e2010-06-29 20:35:19164 std::string result;
[email protected]8e50b602009-03-03 22:59:43165
[email protected]18038f82012-11-20 13:46:58166 const base::Value* value = GetPreferenceValue(path);
167 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40168 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29169 return result;
170 }
[email protected]18038f82012-11-20 13:46:58171 bool rv = value->GetAsString(&result);
initial.commit09911bf2008-07-26 23:55:29172 DCHECK(rv);
173 return result;
174}
175
georgesak7da6e9d2014-12-03 01:10:29176base::FilePath PrefService::GetFilePath(const std::string& path) const {
[email protected]b9636002009-03-04 00:05:25177 DCHECK(CalledOnValidThread());
178
[email protected]650b2d52013-02-10 03:41:45179 base::FilePath result;
[email protected]b9636002009-03-04 00:05:25180
[email protected]18038f82012-11-20 13:46:58181 const base::Value* value = GetPreferenceValue(path);
182 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40183 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]650b2d52013-02-10 03:41:45184 return base::FilePath(result);
[email protected]b9636002009-03-04 00:05:25185 }
[email protected]18038f82012-11-20 13:46:58186 bool rv = base::GetValueAsFilePath(*value, &result);
[email protected]b9636002009-03-04 00:05:25187 DCHECK(rv);
[email protected]68d9d352011-02-21 16:35:04188 return result;
[email protected]b9636002009-03-04 00:05:25189}
190
georgesak7da6e9d2014-12-03 01:10:29191bool PrefService::HasPrefPath(const std::string& path) const {
[email protected]9a8c4022011-01-25 14:25:33192 const Preference* pref = FindPreference(path);
193 return pref && !pref->IsDefaultValue();
initial.commit09911bf2008-07-26 23:55:29194}
195
brettwebf7184f2017-04-18 21:10:53196void PrefService::IteratePreferenceValues(
197 base::RepeatingCallback<void(const std::string& key,
198 const base::Value& value)> callback) const {
[email protected]ebd0b022011-01-27 13:24:14199 DCHECK(CalledOnValidThread());
brettwebf7184f2017-04-18 21:10:53200 for (const auto& it : *pref_registry_)
201 callback.Run(it.first, *GetPreferenceValue(it.first));
asvitkine36ff0c5822014-11-25 22:58:18202}
203
brettwebf7184f2017-04-18 21:10:53204std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues(
205 IncludeDefaults include_defaults) const {
asvitkine36ff0c5822014-11-25 22:58:18206 DCHECK(CalledOnValidThread());
dcheng5f043bc2016-04-22 19:09:06207 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18208 for (const auto& it : *pref_registry_) {
brettwebf7184f2017-04-18 21:10:53209 if (include_defaults == INCLUDE_DEFAULTS) {
210 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
211 } else {
212 const Preference* pref = FindPreference(it.first);
213 if (pref->IsDefaultValue())
214 continue;
215 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
216 }
[email protected]2a1965c2013-10-02 16:07:01217 }
danakj0c8d4aa2015-11-25 05:29:58218 return out;
[email protected]2a1965c2013-10-02 16:07:01219}
220
initial.commit09911bf2008-07-26 23:55:29221const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29222 const std::string& pref_name) const {
initial.commit09911bf2008-07-26 23:55:29223 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42224 PreferenceMap::iterator it = prefs_map_.find(pref_name);
225 if (it != prefs_map_.end())
226 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47227 const base::Value* default_value = NULL;
228 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33229 return NULL;
[email protected]d15d5682012-10-23 17:50:42230 it = prefs_map_.insert(
[email protected]b1de2c72013-02-06 02:45:47231 std::make_pair(pref_name, Preference(
232 this, pref_name, default_value->GetType()))).first;
[email protected]d15d5682012-10-23 17:50:42233 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29234}
235
[email protected]acd78969c2010-12-08 09:49:11236bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17237 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11238}
239
[email protected]59c10712012-03-13 02:10:34240PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
241 const {
242 if (!user_pref_store_->IsInitializationComplete())
243 return INITIALIZATION_STATUS_WAITING;
244
245 switch (user_pref_store_->GetReadError()) {
246 case PersistentPrefStore::PREF_READ_ERROR_NONE:
247 return INITIALIZATION_STATUS_SUCCESS;
248 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18249 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34250 default:
251 return INITIALIZATION_STATUS_ERROR;
252 }
253}
254
georgesak7da6e9d2014-12-03 01:10:29255bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48256 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33257 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48258}
259
khannansb2025b72014-12-19 16:04:25260bool PrefService::IsPreferenceManagedByCustodian(
261 const std::string& pref_name) const {
262 const Preference* pref = FindPreference(pref_name);
263 return pref && pref->IsManagedByCustodian();
264}
265
georgesak7da6e9d2014-12-03 01:10:29266bool PrefService::IsUserModifiablePreference(
267 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07268 const Preference* pref = FindPreference(pref_name);
269 return pref && pref->IsUserModifiable();
270}
271
[email protected]a43a667b2013-06-14 17:56:08272const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29273 const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29274 DCHECK(CalledOnValidThread());
275
[email protected]a43a667b2013-06-14 17:56:08276 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58277 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40278 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29279 return NULL;
280 }
jdoerriedc72ee942016-12-07 15:43:28281 if (value->GetType() != base::Value::Type::DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25282 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29283 return NULL;
[email protected]11b040b2011-02-02 12:42:25284 }
[email protected]a43a667b2013-06-14 17:56:08285 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29286}
287
georgesak7da6e9d2014-12-03 01:10:29288const base::Value* PrefService::GetUserPrefValue(
289 const std::string& path) const {
[email protected]1a5a31f2012-04-26 20:21:34290 DCHECK(CalledOnValidThread());
291
292 const Preference* pref = FindPreference(path);
293 if (!pref) {
294 NOTREACHED() << "Trying to get an unregistered pref: " << path;
295 return NULL;
296 }
297
298 // Look for an existing preference in the user store. If it doesn't
299 // exist, return NULL.
300 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34301 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34302 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34303
304 if (!value->IsType(pref->GetType())) {
305 NOTREACHED() << "Pref value type doesn't match registered type.";
306 return NULL;
307 }
308
309 return value;
310}
311
georgesak7da6e9d2014-12-03 01:10:29312void PrefService::SetDefaultPrefValue(const std::string& path,
[email protected]5879cef2013-03-02 17:02:25313 base::Value* value) {
314 DCHECK(CalledOnValidThread());
315 pref_registry_->SetDefaultPrefValue(path, value);
316}
317
georgesak7da6e9d2014-12-03 01:10:29318const base::Value* PrefService::GetDefaultPrefValue(
319 const std::string& path) const {
[email protected]35a6fd12012-05-28 18:08:08320 DCHECK(CalledOnValidThread());
321 // Lookup the preference in the default store.
322 const base::Value* value = NULL;
[email protected]b1de2c72013-02-06 02:45:47323 if (!pref_registry_->defaults()->GetValue(path, &value)) {
[email protected]35a6fd12012-05-28 18:08:08324 NOTREACHED() << "Default value missing for pref: " << path;
325 return NULL;
326 }
327 return value;
328}
329
georgesak7da6e9d2014-12-03 01:10:29330const base::ListValue* PrefService::GetList(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29331 DCHECK(CalledOnValidThread());
332
[email protected]a43a667b2013-06-14 17:56:08333 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58334 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40335 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29336 return NULL;
337 }
jdoerriedc72ee942016-12-07 15:43:28338 if (value->GetType() != base::Value::Type::LIST) {
[email protected]11b040b2011-02-02 12:42:25339 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29340 return NULL;
[email protected]11b040b2011-02-02 12:42:25341 }
[email protected]a43a667b2013-06-14 17:56:08342 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29343}
344
georgesak7da6e9d2014-12-03 01:10:29345void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50346 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29347}
348
georgesak7da6e9d2014-12-03 01:10:29349void PrefService::RemovePrefObserver(const std::string& path,
350 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50351 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29352}
353
[email protected]a6a7ced2012-11-01 17:24:18354void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
355 pref_notifier_->AddInitObserver(obs);
356}
357
[email protected]b1de2c72013-02-06 02:45:47358PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
359 return pref_registry_.get();
360}
361
georgesak7da6e9d2014-12-03 01:10:29362void PrefService::ClearPref(const std::string& path) {
initial.commit09911bf2008-07-26 23:55:29363 DCHECK(CalledOnValidThread());
364
365 const Preference* pref = FindPreference(path);
366 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40367 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29368 return;
369 }
raymesf3a929b02015-05-07 03:54:45370 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29371}
372
dvadym53fc0d42016-02-05 13:34:57373void PrefService::ClearMutableValues() {
374 user_pref_store_->ClearMutableValues();
375}
376
georgesak7da6e9d2014-12-03 01:10:29377void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43378 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39379}
380
georgesak7da6e9d2014-12-03 01:10:29381void PrefService::SetBoolean(const std::string& path, bool value) {
vabrbce355c2017-03-23 18:52:43382 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29383}
384
georgesak7da6e9d2014-12-03 01:10:29385void PrefService::SetInteger(const std::string& path, int value) {
vabrbce355c2017-03-23 18:52:43386 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29387}
388
georgesak7da6e9d2014-12-03 01:10:29389void PrefService::SetDouble(const std::string& path, double value) {
vabrbce355c2017-03-23 18:52:43390 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29391}
392
georgesak7da6e9d2014-12-03 01:10:29393void PrefService::SetString(const std::string& path, const std::string& value) {
vabrbce355c2017-03-23 18:52:43394 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29395}
396
georgesak7da6e9d2014-12-03 01:10:29397void PrefService::SetFilePath(const std::string& path,
398 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50399 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25400}
401
avi9ef8bb02015-12-24 05:29:36402void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43403 SetUserPrefValue(path,
404 base::MakeUnique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32405}
406
avi9ef8bb02015-12-24 05:29:36407int64_t PrefService::GetInt64(const std::string& path) const {
[email protected]0bb1a622009-03-04 03:22:32408 DCHECK(CalledOnValidThread());
409
[email protected]a43a667b2013-06-14 17:56:08410 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58411 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40412 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08413 return 0;
[email protected]0bb1a622009-03-04 03:22:32414 }
[email protected]dc9a6762010-08-16 07:13:53415 std::string result("0");
[email protected]18038f82012-11-20 13:46:58416 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32417 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25418
avi9ef8bb02015-12-24 05:29:36419 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53420 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25421 return val;
[email protected]0bb1a622009-03-04 03:22:32422}
423
avi9ef8bb02015-12-24 05:29:36424void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43425 SetUserPrefValue(path,
426 base::MakeUnique<base::Value>(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43427}
428
avi9ef8bb02015-12-24 05:29:36429uint64_t PrefService::GetUint64(const std::string& path) const {
[email protected]3cbe0812012-07-03 02:51:43430 DCHECK(CalledOnValidThread());
431
[email protected]a43a667b2013-06-14 17:56:08432 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58433 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43434 NOTREACHED() << "Trying to read an unregistered pref: " << path;
435 return 0;
436 }
437 std::string result("0");
[email protected]18038f82012-11-20 13:46:58438 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43439 DCHECK(rv);
440
avi9ef8bb02015-12-24 05:29:36441 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43442 base::StringToUint64(result, &val);
443 return val;
444}
445
georgesak7da6e9d2014-12-03 01:10:29446base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08447 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28448 CHECK(type == base::Value::Type::DICTIONARY ||
449 type == base::Value::Type::LIST);
initial.commit09911bf2008-07-26 23:55:29450 DCHECK(CalledOnValidThread());
451
452 const Preference* pref = FindPreference(path);
453 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40454 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29455 return NULL;
456 }
[email protected]26418b72011-03-30 14:07:39457 if (pref->GetType() != type) {
458 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29459 return NULL;
460 }
461
[email protected]e0250892010-10-01 18:57:53462 // Look for an existing preference in the user store. If it doesn't
463 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08464 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34465 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39466 !value->IsType(type)) {
jdoerriedc72ee942016-12-07 15:43:28467 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08468 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28469 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08470 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39471 } else {
472 NOTREACHED();
473 }
dcheng5f043bc2016-04-22 19:09:06474 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18475 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29476 }
[email protected]26418b72011-03-30 14:07:39477 return value;
478}
479
[email protected]68bf41a2011-03-25 16:38:31480void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]86bb4e652014-07-10 17:09:51481 DCHECK(CalledOnValidThread());
raymesf3a929b02015-05-07 03:54:45482 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27483}
484
georgesak7da6e9d2014-12-03 01:10:29485void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43486 std::unique_ptr<base::Value> new_value) {
[email protected]c3b54f372010-09-14 08:25:07487 DCHECK(CalledOnValidThread());
488
489 const Preference* pref = FindPreference(path);
490 if (!pref) {
491 NOTREACHED() << "Trying to write an unregistered pref: " << path;
492 return;
493 }
[email protected]99cc9a02010-09-17 07:53:28494 if (pref->GetType() != new_value->GetType()) {
495 NOTREACHED() << "Trying to set pref " << path
496 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07497 << " to value of type " << new_value->GetType();
498 return;
499 }
500
vabrbce355c2017-03-23 18:52:43501 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43502}
503
[email protected]5b199522012-12-22 17:24:44504void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
505 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05506}
507
initial.commit09911bf2008-07-26 23:55:29508///////////////////////////////////////////////////////////////////////////////
509// PrefService::Preference
510
[email protected]c3b54f372010-09-14 08:25:07511PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29512 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02513 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29514 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07515 DCHECK(service);
raymes76de1af2015-05-06 03:22:21516 // Cache the registration flags at creation time to avoid multiple map lookups
517 // later.
518 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28519}
520
[email protected]fb8fdf12012-08-21 16:28:20521const std::string PrefService::Preference::name() const {
522 return name_;
523}
524
[email protected]bab1c13f2011-08-12 20:59:02525base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33526 return type_;
initial.commit09911bf2008-07-26 23:55:29527}
528
[email protected]a43a667b2013-06-14 17:56:08529const base::Value* PrefService::Preference::GetValue() const {
530 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58531 DCHECK(result) << "Must register pref before getting its value";
532 return result;
[email protected]40a47c162010-09-09 11:14:01533}
534
[email protected]a43a667b2013-06-14 17:56:08535const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29536 DCHECK(pref_service_->FindPreference(name_))
537 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03538
[email protected]a43a667b2013-06-14 17:56:08539 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03540 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
541 DCHECK(found_value->IsType(type_));
542 return found_value;
543 }
544
545 // The pref has no recommended value.
546 return NULL;
547}
548
[email protected]40a47c162010-09-09 11:14:01549bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29550 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01551}
552
khannansb2025b72014-12-19 16:04:25553bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09554 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25555}
556
[email protected]a5437282011-12-12 12:33:21557bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29558 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21559}
560
[email protected]40a47c162010-09-09 11:14:01561bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29562 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01563}
564
565bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29566 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01567}
568
569bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29570 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01571}
572
573bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29574 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07575}
576
577bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29578 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35579}
[email protected]74379bc52010-07-21 13:54:08580
581bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29582 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08583}
[email protected]9a28f132011-02-24 21:15:16584
585bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29586 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16587}
[email protected]18038f82012-11-20 13:46:58588
589const base::Value* PrefService::GetPreferenceValue(
590 const std::string& path) const {
591 DCHECK(CalledOnValidThread());
battre0a69def2015-01-05 18:50:19592
593 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
594 // crash dumps it looks like the PrefService is accessed even though it has
595 // been cleared already.
596 CHECK(pref_registry_);
597 CHECK(pref_registry_->defaults());
598 CHECK(pref_value_store_);
599
[email protected]a43a667b2013-06-14 17:56:08600 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47601 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08602 const base::Value* found_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47603 base::Value::Type default_type = default_value->GetType();
604 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
605 DCHECK(found_value->IsType(default_type));
606 return found_value;
607 } else {
608 // Every registered preference has at least a default value.
609 NOTREACHED() << "no valid value found for registered pref " << path;
610 }
[email protected]18038f82012-11-20 13:46:58611 }
612
[email protected]18038f82012-11-20 13:46:58613 return NULL;
614}