pref_service.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/prefs/pref_service.h"
  5. #include <algorithm>
  6. #include <map>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/check_op.h"
  10. #include "base/debug/alias.h"
  11. #include "base/debug/dump_without_crashing.h"
  12. #include "base/files/file_path.h"
  13. #include "base/json/values_util.h"
  14. #include "base/location.h"
  15. #include "base/memory/ptr_util.h"
  16. #include "base/metrics/histogram.h"
  17. #include "base/notreached.h"
  18. #include "base/strings/string_number_conversions.h"
  19. #include "base/strings/string_util.h"
  20. #include "base/task/sequenced_task_runner.h"
  21. #include "base/threading/sequenced_task_runner_handle.h"
  22. #include "base/values.h"
  23. #include "build/chromeos_buildflags.h"
  24. #include "components/prefs/default_pref_store.h"
  25. #include "components/prefs/json_pref_store.h"
  26. #include "components/prefs/pref_notifier_impl.h"
  27. #include "components/prefs/pref_registry.h"
  28. #if BUILDFLAG(IS_CHROMEOS_ASH)
  29. #include "components/prefs/value_map_pref_store.h"
  30. #endif
  31. #if BUILDFLAG(IS_ANDROID)
  32. #include "components/prefs/android/pref_service_android.h"
  33. #endif
  34. namespace {
  35. // Returns the WriteablePrefStore::PrefWriteFlags for the pref with the given
  36. // |path|.
  37. uint32_t GetWriteFlags(const PrefService::Preference* pref) {
  38. uint32_t write_flags = WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS;
  39. if (!pref)
  40. return write_flags;
  41. if (pref->registration_flags() & PrefRegistry::LOSSY_PREF)
  42. write_flags |= WriteablePrefStore::LOSSY_PREF_WRITE_FLAG;
  43. return write_flags;
  44. }
  45. // For prefs names in |pref_store| that are not presented in |pref_changed_map|,
  46. // check if their values differ from those in pref_service->FindPreference() and
  47. // add the result into |pref_changed_map|.
  48. void CheckForNewPrefChangesInPrefStore(
  49. std::map<std::string, bool>* pref_changed_map,
  50. PrefStore* pref_store,
  51. PrefService* pref_service) {
  52. if (!pref_store)
  53. return;
  54. auto values = pref_store->GetValues();
  55. for (auto item : values) {
  56. // If the key already presents, skip it as a store with higher precedence
  57. // already sets the entry.
  58. if (pref_changed_map->find(item.first) != pref_changed_map->end())
  59. continue;
  60. const PrefService::Preference* pref =
  61. pref_service->FindPreference(item.first);
  62. if (!pref)
  63. continue;
  64. pref_changed_map->emplace(item.first, *(pref->GetValue()) != item.second);
  65. }
  66. }
  67. } // namespace
  68. PrefService::PersistentPrefStoreLoadingObserver::
  69. PersistentPrefStoreLoadingObserver(PrefService* pref_service)
  70. : pref_service_(pref_service) {
  71. DCHECK(pref_service_);
  72. }
  73. void PrefService::PersistentPrefStoreLoadingObserver::OnInitializationCompleted(
  74. bool succeeded) {
  75. pref_service_->CheckPrefsLoaded();
  76. }
  77. PrefService::PrefService(
  78. std::unique_ptr<PrefNotifierImpl> pref_notifier,
  79. std::unique_ptr<PrefValueStore> pref_value_store,
  80. scoped_refptr<PersistentPrefStore> user_prefs,
  81. scoped_refptr<PersistentPrefStore> standalone_browser_prefs,
  82. scoped_refptr<PrefRegistry> pref_registry,
  83. base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>
  84. read_error_callback,
  85. bool async)
  86. : pref_notifier_(std::move(pref_notifier)),
  87. pref_value_store_(std::move(pref_value_store)),
  88. user_pref_store_(std::move(user_prefs)),
  89. standalone_browser_pref_store_(std::move(standalone_browser_prefs)),
  90. read_error_callback_(std::move(read_error_callback)),
  91. pref_registry_(std::move(pref_registry)),
  92. pref_store_observer_(
  93. std::make_unique<PrefService::PersistentPrefStoreLoadingObserver>(
  94. this)) {
  95. pref_notifier_->SetPrefService(this);
  96. DCHECK(pref_registry_);
  97. DCHECK(pref_value_store_);
  98. InitFromStorage(async);
  99. }
  100. PrefService::~PrefService() {
  101. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  102. // Remove observers. This could be necessary if this service is destroyed
  103. // before the prefs are fully loaded.
  104. user_pref_store_->RemoveObserver(pref_store_observer_.get());
  105. if (standalone_browser_pref_store_) {
  106. standalone_browser_pref_store_->RemoveObserver(pref_store_observer_.get());
  107. }
  108. // TODO(crbug.com/942491, 946668, 945772) The following code collects
  109. // augments stack dumps created by ~PrefNotifierImpl() with information
  110. // whether the profile owning the PrefService is an incognito profile.
  111. // Delete this, once the bugs are closed.
  112. const bool is_incognito_profile = user_pref_store_->IsInMemoryPrefStore();
  113. base::debug::Alias(&is_incognito_profile);
  114. // Export value of is_incognito_profile to a string so that `grep`
  115. // is a sufficient tool to analyze crashdumps.
  116. char is_incognito_profile_string[32];
  117. strncpy(is_incognito_profile_string,
  118. is_incognito_profile ? "is_incognito: yes" : "is_incognito: no",
  119. sizeof(is_incognito_profile_string));
  120. base::debug::Alias(&is_incognito_profile_string);
  121. }
  122. void PrefService::InitFromStorage(bool async) {
  123. if (!async) {
  124. if (!user_pref_store_->IsInitializationComplete()) {
  125. user_pref_store_->ReadPrefs();
  126. }
  127. if (standalone_browser_pref_store_ &&
  128. !standalone_browser_pref_store_->IsInitializationComplete()) {
  129. standalone_browser_pref_store_->ReadPrefs();
  130. }
  131. CheckPrefsLoaded();
  132. return;
  133. }
  134. CheckPrefsLoaded();
  135. if (!user_pref_store_->IsInitializationComplete()) {
  136. user_pref_store_->AddObserver(pref_store_observer_.get());
  137. user_pref_store_->ReadPrefsAsync(nullptr);
  138. }
  139. if (standalone_browser_pref_store_ &&
  140. !standalone_browser_pref_store_->IsInitializationComplete()) {
  141. standalone_browser_pref_store_->AddObserver(pref_store_observer_.get());
  142. standalone_browser_pref_store_->ReadPrefsAsync(nullptr);
  143. }
  144. }
  145. void PrefService::CheckPrefsLoaded() {
  146. if (!(user_pref_store_->IsInitializationComplete() &&
  147. (!standalone_browser_pref_store_ ||
  148. standalone_browser_pref_store_->IsInitializationComplete()))) {
  149. // Not done initializing both prefstores.
  150. return;
  151. }
  152. user_pref_store_->RemoveObserver(pref_store_observer_.get());
  153. if (standalone_browser_pref_store_) {
  154. standalone_browser_pref_store_->RemoveObserver(pref_store_observer_.get());
  155. }
  156. // Both prefstores are initialized, get the read errors.
  157. PersistentPrefStore::PrefReadError user_store_error =
  158. user_pref_store_->GetReadError();
  159. if (!standalone_browser_pref_store_) {
  160. read_error_callback_.Run(user_store_error);
  161. return;
  162. }
  163. PersistentPrefStore::PrefReadError standalone_browser_store_error =
  164. standalone_browser_pref_store_->GetReadError();
  165. // If both stores have the same error (or no error), run the callback with
  166. // either one. This avoids double-reporting (either way prefs weren't
  167. // successfully fully loaded)
  168. if (user_store_error == standalone_browser_store_error) {
  169. read_error_callback_.Run(user_store_error);
  170. } else if (user_store_error == PersistentPrefStore::PREF_READ_ERROR_NONE ||
  171. user_store_error == PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
  172. // Prefer to report the standalone_browser_pref_store error if the
  173. // user_pref_store error is not significant.
  174. read_error_callback_.Run(standalone_browser_store_error);
  175. } else {
  176. // Either the user_pref_store error is significant, or
  177. // both stores failed to load but for different reasons.
  178. // The user_store error is more significant in essentially all cases,
  179. // so prefer to report that.
  180. read_error_callback_.Run(user_store_error);
  181. }
  182. }
  183. void PrefService::CommitPendingWrite(
  184. base::OnceClosure reply_callback,
  185. base::OnceClosure synchronous_done_callback) {
  186. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  187. user_pref_store_->CommitPendingWrite(std::move(reply_callback),
  188. std::move(synchronous_done_callback));
  189. }
  190. void PrefService::SchedulePendingLossyWrites() {
  191. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  192. user_pref_store_->SchedulePendingLossyWrites();
  193. }
  194. bool PrefService::GetBoolean(const std::string& path) const {
  195. const base::Value& value = GetValue(path);
  196. if (!value.is_bool())
  197. return false;
  198. return value.GetBool();
  199. }
  200. int PrefService::GetInteger(const std::string& path) const {
  201. const base::Value& value = GetValue(path);
  202. if (!value.is_int())
  203. return 0;
  204. return value.GetInt();
  205. }
  206. double PrefService::GetDouble(const std::string& path) const {
  207. const base::Value& value = GetValue(path);
  208. if (!value.is_double())
  209. return 0.0;
  210. return value.GetDouble();
  211. }
  212. std::string PrefService::GetString(const std::string& path) const {
  213. const base::Value& value = GetValue(path);
  214. if (!value.is_string())
  215. return std::string();
  216. return value.GetString();
  217. }
  218. base::FilePath PrefService::GetFilePath(const std::string& path) const {
  219. const base::Value& value = GetValue(path);
  220. absl::optional<base::FilePath> result = base::ValueToFilePath(value);
  221. DCHECK(result);
  222. return *result;
  223. }
  224. bool PrefService::HasPrefPath(const std::string& path) const {
  225. const Preference* pref = FindPreference(path);
  226. return pref && !pref->IsDefaultValue();
  227. }
  228. void PrefService::IteratePreferenceValues(
  229. base::RepeatingCallback<void(const std::string& key,
  230. const base::Value& value)> callback) const {
  231. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  232. for (const auto& it : *pref_registry_)
  233. callback.Run(it.first, *GetPreferenceValue(it.first));
  234. }
  235. base::Value PrefService::GetPreferenceValues(
  236. IncludeDefaults include_defaults) const {
  237. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  238. base::Value out(base::Value::Type::DICTIONARY);
  239. for (const auto& it : *pref_registry_) {
  240. if (include_defaults == INCLUDE_DEFAULTS) {
  241. out.SetPath(it.first, GetPreferenceValue(it.first)->Clone());
  242. } else {
  243. const Preference* pref = FindPreference(it.first);
  244. if (pref->IsDefaultValue())
  245. continue;
  246. out.SetPath(it.first, pref->GetValue()->Clone());
  247. }
  248. }
  249. return out;
  250. }
  251. const PrefService::Preference* PrefService::FindPreference(
  252. const std::string& pref_name) const {
  253. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  254. auto it = prefs_map_.find(pref_name);
  255. if (it != prefs_map_.end())
  256. return &(it->second);
  257. const base::Value* default_value = nullptr;
  258. if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
  259. return nullptr;
  260. it = prefs_map_
  261. .insert(std::make_pair(
  262. pref_name, Preference(this, pref_name, default_value->type())))
  263. .first;
  264. return &(it->second);
  265. }
  266. bool PrefService::ReadOnly() const {
  267. return user_pref_store_->ReadOnly();
  268. }
  269. PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
  270. const {
  271. if (!user_pref_store_->IsInitializationComplete())
  272. return INITIALIZATION_STATUS_WAITING;
  273. switch (user_pref_store_->GetReadError()) {
  274. case PersistentPrefStore::PREF_READ_ERROR_NONE:
  275. return INITIALIZATION_STATUS_SUCCESS;
  276. case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
  277. return INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE;
  278. default:
  279. return INITIALIZATION_STATUS_ERROR;
  280. }
  281. }
  282. PrefService::PrefInitializationStatus
  283. PrefService::GetAllPrefStoresInitializationStatus() const {
  284. if (!pref_value_store_->IsInitializationComplete())
  285. return INITIALIZATION_STATUS_WAITING;
  286. return GetInitializationStatus();
  287. }
  288. bool PrefService::IsManagedPreference(const std::string& pref_name) const {
  289. const Preference* pref = FindPreference(pref_name);
  290. return pref && pref->IsManaged();
  291. }
  292. bool PrefService::IsPreferenceManagedByCustodian(
  293. const std::string& pref_name) const {
  294. const Preference* pref = FindPreference(pref_name);
  295. return pref && pref->IsManagedByCustodian();
  296. }
  297. bool PrefService::IsUserModifiablePreference(
  298. const std::string& pref_name) const {
  299. const Preference* pref = FindPreference(pref_name);
  300. return pref && pref->IsUserModifiable();
  301. }
  302. const base::Value* PrefService::Get(const std::string& path) const {
  303. return &GetValue(path);
  304. }
  305. const base::Value* PrefService::GetDictionary(const std::string& path) const {
  306. const base::Value& value = GetValue(path);
  307. DCHECK(value.is_dict());
  308. return &value;
  309. }
  310. const base::Value& PrefService::GetValue(const std::string& path) const {
  311. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  312. return *GetPreferenceValueChecked(path);
  313. }
  314. const base::Value::Dict& PrefService::GetValueDict(
  315. const std::string& path) const {
  316. const base::Value& value = GetValue(path);
  317. return value.GetDict();
  318. }
  319. const base::Value::List& PrefService::GetValueList(
  320. const std::string& path) const {
  321. const base::Value& value = GetValue(path);
  322. return value.GetList();
  323. }
  324. const base::Value* PrefService::GetUserPrefValue(
  325. const std::string& path) const {
  326. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  327. const Preference* pref = FindPreference(path);
  328. if (!pref) {
  329. NOTREACHED() << "Trying to get an unregistered pref: " << path;
  330. return nullptr;
  331. }
  332. // Look for an existing preference in the user store. If it doesn't
  333. // exist, return NULL.
  334. base::Value* value = nullptr;
  335. if (!user_pref_store_->GetMutableValue(path, &value))
  336. return nullptr;
  337. if (value->type() != pref->GetType()) {
  338. NOTREACHED() << "Pref value type doesn't match registered type.";
  339. return nullptr;
  340. }
  341. return value;
  342. }
  343. void PrefService::SetDefaultPrefValue(const std::string& path,
  344. base::Value value) {
  345. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  346. pref_registry_->SetDefaultPrefValue(path, std::move(value));
  347. }
  348. const base::Value* PrefService::GetDefaultPrefValue(
  349. const std::string& path) const {
  350. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  351. // Lookup the preference in the default store.
  352. const base::Value* value = nullptr;
  353. bool has_value = pref_registry_->defaults()->GetValue(path, &value);
  354. DCHECK(has_value) << "Default value missing for pref: " << path;
  355. return value;
  356. }
  357. const base::Value* PrefService::GetList(const std::string& path) const {
  358. const base::Value& value = GetValue(path);
  359. DCHECK(value.is_list());
  360. return &value;
  361. }
  362. void PrefService::AddPrefObserver(const std::string& path, PrefObserver* obs) {
  363. pref_notifier_->AddPrefObserver(path, obs);
  364. }
  365. void PrefService::RemovePrefObserver(const std::string& path,
  366. PrefObserver* obs) {
  367. pref_notifier_->RemovePrefObserver(path, obs);
  368. }
  369. void PrefService::AddPrefInitObserver(base::OnceCallback<void(bool)> obs) {
  370. pref_notifier_->AddInitObserver(std::move(obs));
  371. }
  372. PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
  373. return pref_registry_.get();
  374. }
  375. void PrefService::ClearPref(const std::string& path) {
  376. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  377. const Preference* pref = FindPreference(path);
  378. if (!pref) {
  379. NOTREACHED() << "Trying to clear an unregistered pref: " << path;
  380. return;
  381. }
  382. user_pref_store_->RemoveValue(path, GetWriteFlags(pref));
  383. }
  384. void PrefService::ClearPrefsWithPrefixSilently(const std::string& prefix) {
  385. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  386. user_pref_store_->RemoveValuesByPrefixSilently(prefix);
  387. }
  388. void PrefService::ClearMutableValues() {
  389. user_pref_store_->ClearMutableValues();
  390. }
  391. void PrefService::OnStoreDeletionFromDisk() {
  392. user_pref_store_->OnStoreDeletionFromDisk();
  393. }
  394. void PrefService::ChangePrefValueStore(
  395. PrefStore* managed_prefs,
  396. PrefStore* supervised_user_prefs,
  397. PrefStore* extension_prefs,
  398. PrefStore* recommended_prefs,
  399. std::unique_ptr<PrefValueStore::Delegate> delegate) {
  400. // Only adding new pref stores are supported.
  401. DCHECK(!pref_value_store_->HasPrefStore(PrefValueStore::MANAGED_STORE) ||
  402. !managed_prefs);
  403. DCHECK(
  404. !pref_value_store_->HasPrefStore(PrefValueStore::SUPERVISED_USER_STORE) ||
  405. !supervised_user_prefs);
  406. DCHECK(!pref_value_store_->HasPrefStore(PrefValueStore::EXTENSION_STORE) ||
  407. !extension_prefs);
  408. DCHECK(!pref_value_store_->HasPrefStore(PrefValueStore::RECOMMENDED_STORE) ||
  409. !recommended_prefs);
  410. // If some of the stores are already initialized, check for pref value changes
  411. // according to store precedence.
  412. std::map<std::string, bool> pref_changed_map;
  413. CheckForNewPrefChangesInPrefStore(&pref_changed_map, managed_prefs, this);
  414. CheckForNewPrefChangesInPrefStore(&pref_changed_map, supervised_user_prefs,
  415. this);
  416. CheckForNewPrefChangesInPrefStore(&pref_changed_map, extension_prefs, this);
  417. CheckForNewPrefChangesInPrefStore(&pref_changed_map, recommended_prefs, this);
  418. pref_value_store_ = pref_value_store_->CloneAndSpecialize(
  419. managed_prefs, supervised_user_prefs, extension_prefs,
  420. nullptr /* command_line_prefs */, nullptr /* user_prefs */,
  421. nullptr /* standalone_browser_prefs */, recommended_prefs,
  422. nullptr /* default_prefs */, pref_notifier_.get(), std::move(delegate));
  423. // Notify |pref_notifier_| on all changed values.
  424. for (const auto& kv : pref_changed_map) {
  425. if (kv.second)
  426. pref_notifier_.get()->OnPreferenceChanged(kv.first);
  427. }
  428. }
  429. void PrefService::AddPrefObserverAllPrefs(PrefObserver* obs) {
  430. pref_notifier_->AddPrefObserverAllPrefs(obs);
  431. }
  432. void PrefService::RemovePrefObserverAllPrefs(PrefObserver* obs) {
  433. pref_notifier_->RemovePrefObserverAllPrefs(obs);
  434. }
  435. #if BUILDFLAG(IS_ANDROID)
  436. base::android::ScopedJavaLocalRef<jobject> PrefService::GetJavaObject() {
  437. if (!pref_service_android_) {
  438. pref_service_android_ = std::make_unique<PrefServiceAndroid>(this);
  439. }
  440. return pref_service_android_->GetJavaObject();
  441. }
  442. #endif
  443. void PrefService::Set(const std::string& path, const base::Value& value) {
  444. SetUserPrefValue(path, value.Clone());
  445. }
  446. void PrefService::SetBoolean(const std::string& path, bool value) {
  447. SetUserPrefValue(path, base::Value(value));
  448. }
  449. void PrefService::SetInteger(const std::string& path, int value) {
  450. SetUserPrefValue(path, base::Value(value));
  451. }
  452. void PrefService::SetDouble(const std::string& path, double value) {
  453. SetUserPrefValue(path, base::Value(value));
  454. }
  455. void PrefService::SetString(const std::string& path, const std::string& value) {
  456. SetUserPrefValue(path, base::Value(value));
  457. }
  458. void PrefService::SetDict(const std::string& path, base::Value::Dict dict) {
  459. SetUserPrefValue(path, base::Value(std::move(dict)));
  460. }
  461. void PrefService::SetList(const std::string& path, base::Value::List list) {
  462. SetUserPrefValue(path, base::Value(std::move(list)));
  463. }
  464. void PrefService::SetFilePath(const std::string& path,
  465. const base::FilePath& value) {
  466. SetUserPrefValue(path, base::FilePathToValue(value));
  467. }
  468. void PrefService::SetInt64(const std::string& path, int64_t value) {
  469. SetUserPrefValue(path, base::Int64ToValue(value));
  470. }
  471. int64_t PrefService::GetInt64(const std::string& path) const {
  472. const base::Value& value = GetValue(path);
  473. absl::optional<int64_t> integer = base::ValueToInt64(value);
  474. DCHECK(integer);
  475. return integer.value_or(0);
  476. }
  477. void PrefService::SetUint64(const std::string& path, uint64_t value) {
  478. SetUserPrefValue(path, base::Value(base::NumberToString(value)));
  479. }
  480. uint64_t PrefService::GetUint64(const std::string& path) const {
  481. const base::Value& value = GetValue(path);
  482. if (!value.is_string())
  483. return 0;
  484. uint64_t result;
  485. base::StringToUint64(value.GetString(), &result);
  486. return result;
  487. }
  488. void PrefService::SetTime(const std::string& path, base::Time value) {
  489. SetUserPrefValue(path, base::TimeToValue(value));
  490. }
  491. base::Time PrefService::GetTime(const std::string& path) const {
  492. const base::Value& value = GetValue(path);
  493. absl::optional<base::Time> time = base::ValueToTime(value);
  494. DCHECK(time);
  495. return time.value_or(base::Time());
  496. }
  497. void PrefService::SetTimeDelta(const std::string& path, base::TimeDelta value) {
  498. SetUserPrefValue(path, base::TimeDeltaToValue(value));
  499. }
  500. base::TimeDelta PrefService::GetTimeDelta(const std::string& path) const {
  501. const base::Value& value = GetValue(path);
  502. absl::optional<base::TimeDelta> time_delta = base::ValueToTimeDelta(value);
  503. DCHECK(time_delta);
  504. return time_delta.value_or(base::TimeDelta());
  505. }
  506. base::Value* PrefService::GetMutableUserPref(const std::string& path,
  507. base::Value::Type type) {
  508. CHECK(type == base::Value::Type::DICTIONARY ||
  509. type == base::Value::Type::LIST);
  510. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  511. const Preference* pref = FindPreference(path);
  512. if (!pref) {
  513. NOTREACHED() << "Trying to get an unregistered pref: " << path;
  514. return nullptr;
  515. }
  516. if (pref->GetType() != type) {
  517. NOTREACHED() << "Wrong type for GetMutableValue: " << path;
  518. return nullptr;
  519. }
  520. // Look for an existing preference in the user store. Return it in case it
  521. // exists and has the correct type.
  522. base::Value* value = nullptr;
  523. if (user_pref_store_->GetMutableValue(path, &value) &&
  524. value->type() == type) {
  525. return value;
  526. }
  527. // If no user preference of the correct type exists, clone default value.
  528. const base::Value* default_value = nullptr;
  529. pref_registry_->defaults()->GetValue(path, &default_value);
  530. DCHECK_EQ(default_value->type(), type);
  531. user_pref_store_->SetValueSilently(
  532. path, base::Value::ToUniquePtrValue(default_value->Clone()),
  533. GetWriteFlags(pref));
  534. user_pref_store_->GetMutableValue(path, &value);
  535. return value;
  536. }
  537. void PrefService::ReportUserPrefChanged(const std::string& key) {
  538. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  539. user_pref_store_->ReportValueChanged(key, GetWriteFlags(FindPreference(key)));
  540. }
  541. void PrefService::ReportUserPrefChanged(
  542. const std::string& key,
  543. std::set<std::vector<std::string>> path_components) {
  544. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  545. user_pref_store_->ReportSubValuesChanged(key, std::move(path_components),
  546. GetWriteFlags(FindPreference(key)));
  547. }
  548. void PrefService::SetUserPrefValue(const std::string& path,
  549. base::Value new_value) {
  550. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  551. const Preference* pref = FindPreference(path);
  552. if (!pref) {
  553. NOTREACHED() << "Trying to write an unregistered pref: " << path;
  554. return;
  555. }
  556. if (pref->GetType() != new_value.type()) {
  557. NOTREACHED() << "Trying to set pref " << path << " of type "
  558. << pref->GetType() << " to value of type " << new_value.type();
  559. return;
  560. }
  561. user_pref_store_->SetValue(
  562. path, base::Value::ToUniquePtrValue(std::move(new_value)),
  563. GetWriteFlags(pref));
  564. }
  565. void PrefService::UpdateCommandLinePrefStore(PrefStore* command_line_store) {
  566. pref_value_store_->UpdateCommandLinePrefStore(command_line_store);
  567. }
  568. ///////////////////////////////////////////////////////////////////////////////
  569. // PrefService::Preference
  570. PrefService::Preference::Preference(const PrefService* service,
  571. std::string name,
  572. base::Value::Type type)
  573. : name_(std::move(name)),
  574. type_(type),
  575. // Cache the registration flags at creation time to avoid multiple map
  576. // lookups later.
  577. registration_flags_(service->pref_registry_->GetRegistrationFlags(name_)),
  578. pref_service_(service) {}
  579. const base::Value* PrefService::Preference::GetValue() const {
  580. return pref_service_->GetPreferenceValueChecked(name_);
  581. }
  582. const base::Value* PrefService::Preference::GetRecommendedValue() const {
  583. DCHECK(pref_service_->FindPreference(name_))
  584. << "Must register pref before getting its value";
  585. const base::Value* found_value = nullptr;
  586. if (pref_value_store()->GetRecommendedValue(name_, type_, &found_value)) {
  587. DCHECK(found_value->type() == type_);
  588. return found_value;
  589. }
  590. // The pref has no recommended value.
  591. return nullptr;
  592. }
  593. bool PrefService::Preference::IsManaged() const {
  594. return pref_value_store()->PrefValueInManagedStore(name_);
  595. }
  596. bool PrefService::Preference::IsManagedByCustodian() const {
  597. return pref_value_store()->PrefValueInSupervisedStore(name_);
  598. }
  599. bool PrefService::Preference::IsRecommended() const {
  600. return pref_value_store()->PrefValueFromRecommendedStore(name_);
  601. }
  602. bool PrefService::Preference::HasExtensionSetting() const {
  603. return pref_value_store()->PrefValueInExtensionStore(name_);
  604. }
  605. bool PrefService::Preference::HasUserSetting() const {
  606. return pref_value_store()->PrefValueInUserStore(name_);
  607. }
  608. bool PrefService::Preference::IsExtensionControlled() const {
  609. return pref_value_store()->PrefValueFromExtensionStore(name_);
  610. }
  611. bool PrefService::Preference::IsUserControlled() const {
  612. return pref_value_store()->PrefValueFromUserStore(name_);
  613. }
  614. bool PrefService::Preference::IsDefaultValue() const {
  615. return pref_value_store()->PrefValueFromDefaultStore(name_);
  616. }
  617. bool PrefService::Preference::IsUserModifiable() const {
  618. return pref_value_store()->PrefValueUserModifiable(name_);
  619. }
  620. bool PrefService::Preference::IsExtensionModifiable() const {
  621. return pref_value_store()->PrefValueExtensionModifiable(name_);
  622. }
  623. #if BUILDFLAG(IS_CHROMEOS_ASH)
  624. bool PrefService::Preference::IsStandaloneBrowserControlled() const {
  625. return pref_value_store()->PrefValueFromStandaloneBrowserStore(name_);
  626. }
  627. bool PrefService::Preference::IsStandaloneBrowserModifiable() const {
  628. return pref_value_store()->PrefValueStandaloneBrowserModifiable(name_);
  629. }
  630. #endif
  631. const base::Value* PrefService::GetPreferenceValue(
  632. const std::string& path) const {
  633. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  634. // TODO(battre): This is a check for crbug.com/435208. After analyzing some
  635. // crash dumps it looks like the PrefService is accessed even though it has
  636. // been cleared already.
  637. CHECK(pref_registry_);
  638. CHECK(pref_registry_->defaults());
  639. CHECK(pref_value_store_);
  640. const base::Value* default_value = nullptr;
  641. if (!pref_registry_->defaults()->GetValue(path, &default_value))
  642. return nullptr;
  643. const base::Value* found_value = nullptr;
  644. base::Value::Type default_type = default_value->type();
  645. if (!pref_value_store_->GetValue(path, default_type, &found_value)) {
  646. // Every registered preference has at least a default value.
  647. NOTREACHED() << "no valid value found for registered pref " << path;
  648. return nullptr;
  649. }
  650. DCHECK_EQ(found_value->type(), default_type);
  651. return found_value;
  652. }
  653. const base::Value* PrefService::GetPreferenceValueChecked(
  654. const std::string& path) const {
  655. const base::Value* value = GetPreferenceValue(path);
  656. DCHECK(value) << "Trying to read an unregistered pref: " << path;
  657. return value;
  658. }
  659. #if BUILDFLAG(IS_CHROMEOS_ASH)
  660. void PrefService::SetStandaloneBrowserPref(const std::string& path,
  661. const base::Value& value) {
  662. standalone_browser_pref_store_->SetValue(
  663. path, base::Value::ToUniquePtrValue(value.Clone()),
  664. WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  665. }
  666. void PrefService::RemoveStandaloneBrowserPref(const std::string& path) {
  667. standalone_browser_pref_store_->RemoveValue(
  668. path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  669. }
  670. #endif