blob: 6858839110b158b139c7e68fed680e5f50ddeb75 [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
dcheng5f043bc2016-04-22 19:09:06196std::unique_ptr<base::DictionaryValue> PrefService::GetPreferenceValues()
197 const {
[email protected]ebd0b022011-01-27 13:24:14198 DCHECK(CalledOnValidThread());
dcheng5f043bc2016-04-22 19:09:06199 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18200 for (const auto& it : *pref_registry_) {
estadea68b0442015-05-12 18:11:50201 out->Set(it.first, GetPreferenceValue(it.first)->CreateDeepCopy());
asvitkine36ff0c5822014-11-25 22:58:18202 }
danakj0c8d4aa2015-11-25 05:29:58203 return out;
asvitkine36ff0c5822014-11-25 22:58:18204}
205
dcheng5f043bc2016-04-22 19:09:06206std::unique_ptr<base::DictionaryValue>
207PrefService::GetPreferenceValuesOmitDefaults() const {
asvitkine36ff0c5822014-11-25 22:58:18208 DCHECK(CalledOnValidThread());
dcheng5f043bc2016-04-22 19:09:06209 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18210 for (const auto& it : *pref_registry_) {
georgesak7da6e9d2014-12-03 01:10:29211 const Preference* pref = FindPreference(it.first);
asvitkine36ff0c5822014-11-25 22:58:18212 if (pref->IsDefaultValue())
213 continue;
estadea68b0442015-05-12 18:11:50214 out->Set(it.first, pref->GetValue()->CreateDeepCopy());
[email protected]ebd0b022011-01-27 13:24:14215 }
danakj0c8d4aa2015-11-25 05:29:58216 return out;
[email protected]ebd0b022011-01-27 13:24:14217}
218
dcheng5f043bc2016-04-22 19:09:06219std::unique_ptr<base::DictionaryValue>
[email protected]ddf421c32013-11-01 00:52:35220PrefService::GetPreferenceValuesWithoutPathExpansion() const {
[email protected]2a1965c2013-10-02 16:07:01221 DCHECK(CalledOnValidThread());
dcheng5f043bc2016-04-22 19:09:06222 std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue);
asvitkine36ff0c5822014-11-25 22:58:18223 for (const auto& it : *pref_registry_) {
224 const base::Value* value = GetPreferenceValue(it.first);
[email protected]2a1965c2013-10-02 16:07:01225 DCHECK(value);
estadea68b0442015-05-12 18:11:50226 out->SetWithoutPathExpansion(it.first, value->CreateDeepCopy());
[email protected]2a1965c2013-10-02 16:07:01227 }
danakj0c8d4aa2015-11-25 05:29:58228 return out;
[email protected]2a1965c2013-10-02 16:07:01229}
230
initial.commit09911bf2008-07-26 23:55:29231const PrefService::Preference* PrefService::FindPreference(
georgesak7da6e9d2014-12-03 01:10:29232 const std::string& pref_name) const {
initial.commit09911bf2008-07-26 23:55:29233 DCHECK(CalledOnValidThread());
[email protected]d15d5682012-10-23 17:50:42234 PreferenceMap::iterator it = prefs_map_.find(pref_name);
235 if (it != prefs_map_.end())
236 return &(it->second);
[email protected]b1de2c72013-02-06 02:45:47237 const base::Value* default_value = NULL;
238 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
[email protected]9a8c4022011-01-25 14:25:33239 return NULL;
[email protected]d15d5682012-10-23 17:50:42240 it = prefs_map_.insert(
[email protected]b1de2c72013-02-06 02:45:47241 std::make_pair(pref_name, Preference(
242 this, pref_name, default_value->GetType()))).first;
[email protected]d15d5682012-10-23 17:50:42243 return &(it->second);
initial.commit09911bf2008-07-26 23:55:29244}
245
[email protected]acd78969c2010-12-08 09:49:11246bool PrefService::ReadOnly() const {
[email protected]f2d1f612010-12-09 15:10:17247 return user_pref_store_->ReadOnly();
[email protected]acd78969c2010-12-08 09:49:11248}
249
[email protected]59c10712012-03-13 02:10:34250PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
251 const {
252 if (!user_pref_store_->IsInitializationComplete())
253 return INITIALIZATION_STATUS_WAITING;
254
255 switch (user_pref_store_->GetReadError()) {
256 case PersistentPrefStore::PREF_READ_ERROR_NONE:
257 return INITIALIZATION_STATUS_SUCCESS;
258 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
[email protected]88c6fb52013-04-09 10:39:18259 return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
[email protected]59c10712012-03-13 02:10:34260 default:
261 return INITIALIZATION_STATUS_ERROR;
262 }
263}
264
georgesak7da6e9d2014-12-03 01:10:29265bool PrefService::IsManagedPreference(const std::string& pref_name) const {
[email protected]d90de1c02010-07-19 19:50:48266 const Preference* pref = FindPreference(pref_name);
[email protected]9a8c4022011-01-25 14:25:33267 return pref && pref->IsManaged();
[email protected]d90de1c02010-07-19 19:50:48268}
269
khannansb2025b72014-12-19 16:04:25270bool PrefService::IsPreferenceManagedByCustodian(
271 const std::string& pref_name) const {
272 const Preference* pref = FindPreference(pref_name);
273 return pref && pref->IsManagedByCustodian();
274}
275
georgesak7da6e9d2014-12-03 01:10:29276bool PrefService::IsUserModifiablePreference(
277 const std::string& pref_name) const {
[email protected]d6bbd2932012-03-19 17:10:07278 const Preference* pref = FindPreference(pref_name);
279 return pref && pref->IsUserModifiable();
280}
281
[email protected]a43a667b2013-06-14 17:56:08282const base::DictionaryValue* PrefService::GetDictionary(
georgesak7da6e9d2014-12-03 01:10:29283 const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29284 DCHECK(CalledOnValidThread());
285
[email protected]a43a667b2013-06-14 17:56:08286 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58287 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40288 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29289 return NULL;
290 }
jdoerriedc72ee942016-12-07 15:43:28291 if (value->GetType() != base::Value::Type::DICTIONARY) {
[email protected]11b040b2011-02-02 12:42:25292 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29293 return NULL;
[email protected]11b040b2011-02-02 12:42:25294 }
[email protected]a43a667b2013-06-14 17:56:08295 return static_cast<const base::DictionaryValue*>(value);
initial.commit09911bf2008-07-26 23:55:29296}
297
georgesak7da6e9d2014-12-03 01:10:29298const base::Value* PrefService::GetUserPrefValue(
299 const std::string& path) const {
[email protected]1a5a31f2012-04-26 20:21:34300 DCHECK(CalledOnValidThread());
301
302 const Preference* pref = FindPreference(path);
303 if (!pref) {
304 NOTREACHED() << "Trying to get an unregistered pref: " << path;
305 return NULL;
306 }
307
308 // Look for an existing preference in the user store. If it doesn't
309 // exist, return NULL.
310 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34311 if (!user_pref_store_->GetMutableValue(path, &value))
[email protected]1a5a31f2012-04-26 20:21:34312 return NULL;
[email protected]1a5a31f2012-04-26 20:21:34313
314 if (!value->IsType(pref->GetType())) {
315 NOTREACHED() << "Pref value type doesn't match registered type.";
316 return NULL;
317 }
318
319 return value;
320}
321
georgesak7da6e9d2014-12-03 01:10:29322void PrefService::SetDefaultPrefValue(const std::string& path,
[email protected]5879cef2013-03-02 17:02:25323 base::Value* value) {
324 DCHECK(CalledOnValidThread());
325 pref_registry_->SetDefaultPrefValue(path, value);
326}
327
georgesak7da6e9d2014-12-03 01:10:29328const base::Value* PrefService::GetDefaultPrefValue(
329 const std::string& path) const {
[email protected]35a6fd12012-05-28 18:08:08330 DCHECK(CalledOnValidThread());
331 // Lookup the preference in the default store.
332 const base::Value* value = NULL;
[email protected]b1de2c72013-02-06 02:45:47333 if (!pref_registry_->defaults()->GetValue(path, &value)) {
[email protected]35a6fd12012-05-28 18:08:08334 NOTREACHED() << "Default value missing for pref: " << path;
335 return NULL;
336 }
337 return value;
338}
339
georgesak7da6e9d2014-12-03 01:10:29340const base::ListValue* PrefService::GetList(const std::string& path) const {
initial.commit09911bf2008-07-26 23:55:29341 DCHECK(CalledOnValidThread());
342
[email protected]a43a667b2013-06-14 17:56:08343 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58344 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40345 NOTREACHED() << "Trying to read an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29346 return NULL;
347 }
jdoerriedc72ee942016-12-07 15:43:28348 if (value->GetType() != base::Value::Type::LIST) {
[email protected]11b040b2011-02-02 12:42:25349 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29350 return NULL;
[email protected]11b040b2011-02-02 12:42:25351 }
[email protected]a43a667b2013-06-14 17:56:08352 return static_cast<const base::ListValue*>(value);
initial.commit09911bf2008-07-26 23:55:29353}
354
georgesak7da6e9d2014-12-03 01:10:29355void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50356 pref_notifier_->AddPrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29357}
358
georgesak7da6e9d2014-12-03 01:10:29359void PrefService::RemovePrefObserver(const std::string& path,
360 PrefObserver* obs) {
[email protected]d81288a02010-08-18 07:25:50361 pref_notifier_->RemovePrefObserver(path, obs);
initial.commit09911bf2008-07-26 23:55:29362}
363
[email protected]a6a7ced2012-11-01 17:24:18364void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
365 pref_notifier_->AddInitObserver(obs);
366}
367
[email protected]b1de2c72013-02-06 02:45:47368PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
369 return pref_registry_.get();
370}
371
georgesak7da6e9d2014-12-03 01:10:29372void PrefService::ClearPref(const std::string& path) {
initial.commit09911bf2008-07-26 23:55:29373 DCHECK(CalledOnValidThread());
374
375 const Preference* pref = FindPreference(path);
376 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40377 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29378 return;
379 }
raymesf3a929b02015-05-07 03:54:45380 user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29381}
382
dvadym53fc0d42016-02-05 13:34:57383void PrefService::ClearMutableValues() {
384 user_pref_store_->ClearMutableValues();
385}
386
georgesak7da6e9d2014-12-03 01:10:29387void PrefService::Set(const std::string& path, const base::Value& value) {
vabrbce355c2017-03-23 18:52:43388 SetUserPrefValue(path, value.CreateDeepCopy());
[email protected]a048d7e42009-12-01 01:02:39389}
390
georgesak7da6e9d2014-12-03 01:10:29391void PrefService::SetBoolean(const std::string& path, bool value) {
vabrbce355c2017-03-23 18:52:43392 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29393}
394
georgesak7da6e9d2014-12-03 01:10:29395void PrefService::SetInteger(const std::string& path, int value) {
vabrbce355c2017-03-23 18:52:43396 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29397}
398
georgesak7da6e9d2014-12-03 01:10:29399void PrefService::SetDouble(const std::string& path, double value) {
vabrbce355c2017-03-23 18:52:43400 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29401}
402
georgesak7da6e9d2014-12-03 01:10:29403void PrefService::SetString(const std::string& path, const std::string& value) {
vabrbce355c2017-03-23 18:52:43404 SetUserPrefValue(path, base::MakeUnique<base::Value>(value));
initial.commit09911bf2008-07-26 23:55:29405}
406
georgesak7da6e9d2014-12-03 01:10:29407void PrefService::SetFilePath(const std::string& path,
408 const base::FilePath& value) {
[email protected]8703b2b2011-03-15 09:51:50409 SetUserPrefValue(path, base::CreateFilePathValue(value));
[email protected]b9636002009-03-04 00:05:25410}
411
avi9ef8bb02015-12-24 05:29:36412void PrefService::SetInt64(const std::string& path, int64_t value) {
vabrbce355c2017-03-23 18:52:43413 SetUserPrefValue(path,
414 base::MakeUnique<base::Value>(base::Int64ToString(value)));
[email protected]0bb1a622009-03-04 03:22:32415}
416
avi9ef8bb02015-12-24 05:29:36417int64_t PrefService::GetInt64(const std::string& path) const {
[email protected]0bb1a622009-03-04 03:22:32418 DCHECK(CalledOnValidThread());
419
[email protected]a43a667b2013-06-14 17:56:08420 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58421 if (!value) {
[email protected]b154e6f2009-03-06 01:52:40422 NOTREACHED() << "Trying to read an unregistered pref: " << path;
[email protected]c3453302009-12-01 01:33:08423 return 0;
[email protected]0bb1a622009-03-04 03:22:32424 }
[email protected]dc9a6762010-08-16 07:13:53425 std::string result("0");
[email protected]18038f82012-11-20 13:46:58426 bool rv = value->GetAsString(&result);
[email protected]0bb1a622009-03-04 03:22:32427 DCHECK(rv);
[email protected]e83326f2010-07-31 17:29:25428
avi9ef8bb02015-12-24 05:29:36429 int64_t val;
[email protected]dc9a6762010-08-16 07:13:53430 base::StringToInt64(result, &val);
[email protected]e83326f2010-07-31 17:29:25431 return val;
[email protected]0bb1a622009-03-04 03:22:32432}
433
avi9ef8bb02015-12-24 05:29:36434void PrefService::SetUint64(const std::string& path, uint64_t value) {
vabrbce355c2017-03-23 18:52:43435 SetUserPrefValue(path,
436 base::MakeUnique<base::Value>(base::Uint64ToString(value)));
[email protected]3cbe0812012-07-03 02:51:43437}
438
avi9ef8bb02015-12-24 05:29:36439uint64_t PrefService::GetUint64(const std::string& path) const {
[email protected]3cbe0812012-07-03 02:51:43440 DCHECK(CalledOnValidThread());
441
[email protected]a43a667b2013-06-14 17:56:08442 const base::Value* value = GetPreferenceValue(path);
[email protected]18038f82012-11-20 13:46:58443 if (!value) {
[email protected]3cbe0812012-07-03 02:51:43444 NOTREACHED() << "Trying to read an unregistered pref: " << path;
445 return 0;
446 }
447 std::string result("0");
[email protected]18038f82012-11-20 13:46:58448 bool rv = value->GetAsString(&result);
[email protected]3cbe0812012-07-03 02:51:43449 DCHECK(rv);
450
avi9ef8bb02015-12-24 05:29:36451 uint64_t val;
[email protected]3cbe0812012-07-03 02:51:43452 base::StringToUint64(result, &val);
453 return val;
454}
455
georgesak7da6e9d2014-12-03 01:10:29456base::Value* PrefService::GetMutableUserPref(const std::string& path,
[email protected]a43a667b2013-06-14 17:56:08457 base::Value::Type type) {
jdoerriedc72ee942016-12-07 15:43:28458 CHECK(type == base::Value::Type::DICTIONARY ||
459 type == base::Value::Type::LIST);
initial.commit09911bf2008-07-26 23:55:29460 DCHECK(CalledOnValidThread());
461
462 const Preference* pref = FindPreference(path);
463 if (!pref) {
[email protected]b154e6f2009-03-06 01:52:40464 NOTREACHED() << "Trying to get an unregistered pref: " << path;
initial.commit09911bf2008-07-26 23:55:29465 return NULL;
466 }
[email protected]26418b72011-03-30 14:07:39467 if (pref->GetType() != type) {
468 NOTREACHED() << "Wrong type for GetMutableValue: " << path;
initial.commit09911bf2008-07-26 23:55:29469 return NULL;
470 }
471
[email protected]e0250892010-10-01 18:57:53472 // Look for an existing preference in the user store. If it doesn't
473 // exist or isn't the correct type, create a new user preference.
[email protected]a43a667b2013-06-14 17:56:08474 base::Value* value = NULL;
[email protected]892f1d62012-11-08 18:24:34475 if (!user_pref_store_->GetMutableValue(path, &value) ||
[email protected]26418b72011-03-30 14:07:39476 !value->IsType(type)) {
jdoerriedc72ee942016-12-07 15:43:28477 if (type == base::Value::Type::DICTIONARY) {
[email protected]a43a667b2013-06-14 17:56:08478 value = new base::DictionaryValue;
jdoerriedc72ee942016-12-07 15:43:28479 } else if (type == base::Value::Type::LIST) {
[email protected]a43a667b2013-06-14 17:56:08480 value = new base::ListValue;
[email protected]26418b72011-03-30 14:07:39481 } else {
482 NOTREACHED();
483 }
dcheng5f043bc2016-04-22 19:09:06484 user_pref_store_->SetValueSilently(path, base::WrapUnique(value),
estade0bd407f2015-06-26 18:16:18485 GetWriteFlags(pref));
initial.commit09911bf2008-07-26 23:55:29486 }
[email protected]26418b72011-03-30 14:07:39487 return value;
488}
489
[email protected]68bf41a2011-03-25 16:38:31490void PrefService::ReportUserPrefChanged(const std::string& key) {
[email protected]86bb4e652014-07-10 17:09:51491 DCHECK(CalledOnValidThread());
raymesf3a929b02015-05-07 03:54:45492 user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
[email protected]f89ee342011-03-07 09:28:27493}
494
georgesak7da6e9d2014-12-03 01:10:29495void PrefService::SetUserPrefValue(const std::string& path,
vabrbce355c2017-03-23 18:52:43496 std::unique_ptr<base::Value> new_value) {
[email protected]c3b54f372010-09-14 08:25:07497 DCHECK(CalledOnValidThread());
498
499 const Preference* pref = FindPreference(path);
500 if (!pref) {
501 NOTREACHED() << "Trying to write an unregistered pref: " << path;
502 return;
503 }
[email protected]99cc9a02010-09-17 07:53:28504 if (pref->GetType() != new_value->GetType()) {
505 NOTREACHED() << "Trying to set pref " << path
506 << " of type " << pref->GetType()
[email protected]c3b54f372010-09-14 08:25:07507 << " to value of type " << new_value->GetType();
508 return;
509 }
510
vabrbce355c2017-03-23 18:52:43511 user_pref_store_->SetValue(path, std::move(new_value), GetWriteFlags(pref));
[email protected]73c47932010-12-06 18:13:43512}
513
[email protected]5b199522012-12-22 17:24:44514void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
515 pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
[email protected]d3b05ea2012-01-24 22:57:05516}
517
initial.commit09911bf2008-07-26 23:55:29518///////////////////////////////////////////////////////////////////////////////
519// PrefService::Preference
520
[email protected]c3b54f372010-09-14 08:25:07521PrefService::Preference::Preference(const PrefService* service,
georgesak7da6e9d2014-12-03 01:10:29522 const std::string& name,
[email protected]bab1c13f2011-08-12 20:59:02523 base::Value::Type type)
georgesak7da6e9d2014-12-03 01:10:29524 : name_(name), type_(type), pref_service_(service) {
[email protected]c3b54f372010-09-14 08:25:07525 DCHECK(service);
raymes76de1af2015-05-06 03:22:21526 // Cache the registration flags at creation time to avoid multiple map lookups
527 // later.
528 registration_flags_ = service->pref_registry_->GetRegistrationFlags(name_);
[email protected]99cc9a02010-09-17 07:53:28529}
530
[email protected]fb8fdf12012-08-21 16:28:20531const std::string PrefService::Preference::name() const {
532 return name_;
533}
534
[email protected]bab1c13f2011-08-12 20:59:02535base::Value::Type PrefService::Preference::GetType() const {
[email protected]9a8c4022011-01-25 14:25:33536 return type_;
initial.commit09911bf2008-07-26 23:55:29537}
538
[email protected]a43a667b2013-06-14 17:56:08539const base::Value* PrefService::Preference::GetValue() const {
540 const base::Value* result= pref_service_->GetPreferenceValue(name_);
[email protected]18038f82012-11-20 13:46:58541 DCHECK(result) << "Must register pref before getting its value";
542 return result;
[email protected]40a47c162010-09-09 11:14:01543}
544
[email protected]a43a667b2013-06-14 17:56:08545const base::Value* PrefService::Preference::GetRecommendedValue() const {
georgesak7da6e9d2014-12-03 01:10:29546 DCHECK(pref_service_->FindPreference(name_))
547 << "Must register pref before getting its value";
[email protected]7ca0f362012-07-30 10:14:03548
[email protected]a43a667b2013-06-14 17:56:08549 const base::Value* found_value = NULL;
[email protected]7ca0f362012-07-30 10:14:03550 if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
551 DCHECK(found_value->IsType(type_));
552 return found_value;
553 }
554
555 // The pref has no recommended value.
556 return NULL;
557}
558
[email protected]40a47c162010-09-09 11:14:01559bool PrefService::Preference::IsManaged() const {
georgesak7da6e9d2014-12-03 01:10:29560 return pref_value_store()->PrefValueInManagedStore(name_);
[email protected]40a47c162010-09-09 11:14:01561}
562
khannansb2025b72014-12-19 16:04:25563bool PrefService::Preference::IsManagedByCustodian() const {
iceman4179f17c2017-03-29 19:50:09564 return pref_value_store()->PrefValueInSupervisedStore(name_);
khannansb2025b72014-12-19 16:04:25565}
566
[email protected]a5437282011-12-12 12:33:21567bool PrefService::Preference::IsRecommended() const {
georgesak7da6e9d2014-12-03 01:10:29568 return pref_value_store()->PrefValueFromRecommendedStore(name_);
[email protected]a5437282011-12-12 12:33:21569}
570
[email protected]40a47c162010-09-09 11:14:01571bool PrefService::Preference::HasExtensionSetting() const {
georgesak7da6e9d2014-12-03 01:10:29572 return pref_value_store()->PrefValueInExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01573}
574
575bool PrefService::Preference::HasUserSetting() const {
georgesak7da6e9d2014-12-03 01:10:29576 return pref_value_store()->PrefValueInUserStore(name_);
[email protected]40a47c162010-09-09 11:14:01577}
578
579bool PrefService::Preference::IsExtensionControlled() const {
georgesak7da6e9d2014-12-03 01:10:29580 return pref_value_store()->PrefValueFromExtensionStore(name_);
[email protected]40a47c162010-09-09 11:14:01581}
582
583bool PrefService::Preference::IsUserControlled() const {
georgesak7da6e9d2014-12-03 01:10:29584 return pref_value_store()->PrefValueFromUserStore(name_);
[email protected]c3b54f372010-09-14 08:25:07585}
586
587bool PrefService::Preference::IsDefaultValue() const {
georgesak7da6e9d2014-12-03 01:10:29588 return pref_value_store()->PrefValueFromDefaultStore(name_);
[email protected]d7449e82010-07-14 11:42:35589}
[email protected]74379bc52010-07-21 13:54:08590
591bool PrefService::Preference::IsUserModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29592 return pref_value_store()->PrefValueUserModifiable(name_);
[email protected]74379bc52010-07-21 13:54:08593}
[email protected]9a28f132011-02-24 21:15:16594
595bool PrefService::Preference::IsExtensionModifiable() const {
georgesak7da6e9d2014-12-03 01:10:29596 return pref_value_store()->PrefValueExtensionModifiable(name_);
[email protected]9a28f132011-02-24 21:15:16597}
[email protected]18038f82012-11-20 13:46:58598
599const base::Value* PrefService::GetPreferenceValue(
600 const std::string& path) const {
601 DCHECK(CalledOnValidThread());
battre0a69def2015-01-05 18:50:19602
603 // TODO(battre): This is a check for crbug.com/435208. After analyzing some
604 // crash dumps it looks like the PrefService is accessed even though it has
605 // been cleared already.
606 CHECK(pref_registry_);
607 CHECK(pref_registry_->defaults());
608 CHECK(pref_value_store_);
609
[email protected]a43a667b2013-06-14 17:56:08610 const base::Value* default_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47611 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
[email protected]a43a667b2013-06-14 17:56:08612 const base::Value* found_value = NULL;
[email protected]b1de2c72013-02-06 02:45:47613 base::Value::Type default_type = default_value->GetType();
614 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
615 DCHECK(found_value->IsType(default_type));
616 return found_value;
617 } else {
618 // Every registered preference has at least a default value.
619 NOTREACHED() << "no valid value found for registered pref " << path;
620 }
[email protected]18038f82012-11-20 13:46:58621 }
622
[email protected]18038f82012-11-20 13:46:58623 return NULL;
624}