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