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
5 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
6
7 #include <stddef.h>
8
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/compiler_specific.h"
15 #include "base/files/file_path.h"
16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram_macros.h"
18 #include "base/stl_util.h"
19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/time.h"
21 #include "base/trace_event/trace_event.h"
22 #include "build/branding_buildflags.h"
23 #include "build/build_config.h"
24 #include "chrome/browser/browser_process.h"
25 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
26 #include "chrome/browser/prefs/chrome_command_line_pref_store.h"
27 #include "chrome/browser/prefs/chrome_pref_model_associator_client.h"
28 #include "chrome/browser/prefs/profile_pref_store_manager.h"
29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/sync/glue/sync_start_util.h"
31 #include "chrome/browser/ui/profile_error_dialog.h"
32 #include "chrome/common/buildflags.h"
33 #include "chrome/common/chrome_constants.h"
34 #include "chrome/common/pref_names.h"
35 #include "chrome/grit/browser_resources.h"
36 #include "chrome/grit/chromium_strings.h"
37 #include "chrome/grit/generated_resources.h"
38 #include "components/component_updater/pref_names.h"
39 #include "components/policy/core/browser/configuration_policy_pref_store.h"
40 #include "components/pref_registry/pref_registry_syncable.h"
41 #include "components/prefs/default_pref_store.h"
42 #include "components/prefs/json_pref_store.h"
43 #include "components/prefs/pref_filter.h"
44 #include "components/prefs/pref_notifier_impl.h"
45 #include "components/prefs/pref_registry.h"
46 #include "components/prefs/pref_registry_simple.h"
47 #include "components/prefs/pref_service.h"
48 #include "components/prefs/pref_store.h"
49 #include "components/prefs/pref_value_store.h"
50 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
51 #include "components/search_engines/default_search_manager.h"
52 #include "components/search_engines/search_engines_pref_names.h"
53 #include "components/signin/public/base/signin_pref_names.h"
54 #include "components/sync/base/model_type.h"
55 #include "components/sync/base/pref_names.h"
56 #include "components/sync_preferences/pref_model_associator.h"
57 #include "components/sync_preferences/pref_service_syncable.h"
58 #include "components/sync_preferences/pref_service_syncable_factory.h"
59 #include "content/public/browser/browser_context.h"
60 #include "content/public/browser/browser_thread.h"
61 #include "extensions/buildflags/buildflags.h"
62 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
63 #include "rlz/buildflags/buildflags.h"
64 #include "services/preferences/public/cpp/tracked/configuration.h"
65 #include "services/preferences/public/cpp/tracked/pref_names.h"
66 #include "sql/error_delegate_util.h"
67 #include "ui/base/resource/resource_bundle.h"
68
69 #if BUILDFLAG(ENABLE_EXTENSIONS)
70 #include "extensions/browser/pref_names.h"
71 #endif
72
73 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
74 #include "chrome/browser/supervised_user/supervised_user_pref_store.h"
75 #endif
76
77 #if defined(OS_WIN)
78 #include "base/enterprise_util.h"
79 #if BUILDFLAG(ENABLE_RLZ)
80 #include "rlz/lib/machine_id.h"
81 #endif // BUILDFLAG(ENABLE_RLZ)
82 #endif // defined(OS_WIN)
83
84 using content::BrowserContext;
85 using content::BrowserThread;
86
87 using EnforcementLevel =
88 prefs::mojom::TrackedPreferenceMetadata::EnforcementLevel;
89 using PrefTrackingStrategy =
90 prefs::mojom::TrackedPreferenceMetadata::PrefTrackingStrategy;
91 using ValueType = prefs::mojom::TrackedPreferenceMetadata::ValueType;
92
93 namespace {
94
95 #if defined(OS_WIN)
96 // Whether we are in testing mode; can be enabled via
97 // DisableDomainCheckForTesting(). Forces startup checks to ignore the presence
98 // of a domain when determining the active SettingsEnforcement group.
99 bool g_disable_domain_check_for_testing = false;
100 #endif // OS_WIN
101
102 // These preferences must be kept in sync with the TrackedPreference enum in
103 // tools/metrics/histograms/enums.xml. To add a new preference, append it to the
104 // array and add a corresponding value to the histogram enum. Each tracked
105 // preference must be given a unique reporting ID.
106 // See CleanupDeprecatedTrackedPreferences() in pref_hash_filter.cc to remove a
107 // deprecated tracked preference.
108 const prefs::TrackedPreferenceMetadata kTrackedPrefs[] = {
109 {0, prefs::kShowHomeButton, EnforcementLevel::ENFORCE_ON_LOAD,
110 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
111 {1, prefs::kHomePageIsNewTabPage, EnforcementLevel::ENFORCE_ON_LOAD,
112 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
113 {2, prefs::kHomePage, EnforcementLevel::ENFORCE_ON_LOAD,
114 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
115 {3, prefs::kRestoreOnStartup, EnforcementLevel::ENFORCE_ON_LOAD,
116 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
117 {4, prefs::kURLsToRestoreOnStartup, EnforcementLevel::ENFORCE_ON_LOAD,
118 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
119 #if BUILDFLAG(ENABLE_EXTENSIONS)
120 {5, extensions::pref_names::kExtensions, EnforcementLevel::NO_ENFORCEMENT,
121 PrefTrackingStrategy::SPLIT, ValueType::IMPERSONAL},
122 #endif
123 {6, prefs::kGoogleServicesLastUsername, EnforcementLevel::ENFORCE_ON_LOAD,
124 PrefTrackingStrategy::ATOMIC, ValueType::PERSONAL},
125 {7, prefs::kSearchProviderOverrides, EnforcementLevel::ENFORCE_ON_LOAD,
126 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
127 #if !defined(OS_ANDROID)
128 {11, prefs::kPinnedTabs, EnforcementLevel::ENFORCE_ON_LOAD,
129 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
130 #endif
131 {14, DefaultSearchManager::kDefaultSearchProviderDataPrefName,
132 EnforcementLevel::NO_ENFORCEMENT, PrefTrackingStrategy::ATOMIC,
133 ValueType::IMPERSONAL},
134 {// Protecting kPreferenceResetTime does two things:
135 // 1) It ensures this isn't accidently set by someone stomping the pref
136 // file.
137 // 2) More importantly, it declares kPreferenceResetTime as a protected
138 // pref which is required for it to be visible when queried via the
139 // SegregatedPrefStore. This is because it's written directly in the
140 // protected JsonPrefStore by that store's PrefHashFilter if there was
141 // a reset in FilterOnLoad and SegregatedPrefStore will not look for it
142 // in the protected JsonPrefStore unless it's declared as a protected
143 // preference here.
144 15, user_prefs::kPreferenceResetTime, EnforcementLevel::ENFORCE_ON_LOAD,
145 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
146 // kSyncRemainingRollbackTries is deprecated and will be removed a few
147 // releases after M50.
148 {18, prefs::kSafeBrowsingIncidentsSent, EnforcementLevel::ENFORCE_ON_LOAD,
149 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
150 #if defined(OS_WIN)
151 {19, prefs::kSwReporterPromptVersion, EnforcementLevel::ENFORCE_ON_LOAD,
152 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
153 #endif
154 #if defined(OS_WIN)
155 {22, prefs::kSwReporterPromptSeed, EnforcementLevel::ENFORCE_ON_LOAD,
156 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
157 #endif
158 {23, prefs::kGoogleServicesAccountId, EnforcementLevel::ENFORCE_ON_LOAD,
159 PrefTrackingStrategy::ATOMIC, ValueType::PERSONAL},
160 {24, prefs::kGoogleServicesLastAccountId, EnforcementLevel::ENFORCE_ON_LOAD,
161 PrefTrackingStrategy::ATOMIC, ValueType::PERSONAL},
162 #if defined(OS_WIN)
163 {25, prefs::kSettingsResetPromptPromptWave,
164 EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC,
165 ValueType::IMPERSONAL},
166 {26, prefs::kSettingsResetPromptLastTriggeredForDefaultSearch,
167 EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC,
168 ValueType::IMPERSONAL},
169 {27, prefs::kSettingsResetPromptLastTriggeredForStartupUrls,
170 EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC,
171 ValueType::IMPERSONAL},
172 {28, prefs::kSettingsResetPromptLastTriggeredForHomepage,
173 EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC,
174 ValueType::IMPERSONAL},
175 #endif // defined(OS_WIN)
176 {29, prefs::kMediaStorageIdSalt, EnforcementLevel::ENFORCE_ON_LOAD,
177 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
178 #if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
179 {30, prefs::kModuleBlacklistCacheMD5Digest,
180 EnforcementLevel::ENFORCE_ON_LOAD, PrefTrackingStrategy::ATOMIC,
181 ValueType::IMPERSONAL},
182 #endif
183 #if defined(OS_WIN)
184 {31, prefs::kSwReporterReportingEnabled, EnforcementLevel::ENFORCE_ON_LOAD,
185 PrefTrackingStrategy::ATOMIC, ValueType::IMPERSONAL},
186 #endif // defined(OS_WIN)
187
188 // See note at top, new items added here also need to be added to
189 // histograms.xml's TrackedPreference enum.
190 };
191
192 // One more than the last tracked preferences ID above.
193 const size_t kTrackedPrefsReportingIDsCount =
194 kTrackedPrefs[base::size(kTrackedPrefs) - 1].reporting_id + 1;
195
196 // Each group enforces a superset of the protection provided by the previous
197 // one.
198 enum SettingsEnforcementGroup {
199 GROUP_NO_ENFORCEMENT,
200 // Enforce protected settings on profile loads.
201 GROUP_ENFORCE_ALWAYS,
202 // Also enforce extension default search.
203 GROUP_ENFORCE_ALWAYS_WITH_DSE,
204 // Also enforce extension settings and default search.
205 GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE,
206 // The default enforcement group contains all protection features.
207 GROUP_ENFORCE_DEFAULT
208 };
209
GetSettingsEnforcementGroup()210 SettingsEnforcementGroup GetSettingsEnforcementGroup() {
211 # if defined(OS_WIN)
212 if (!g_disable_domain_check_for_testing) {
213 static bool first_call = true;
214 static const bool is_managed = base::IsMachineExternallyManaged();
215 if (first_call) {
216 UMA_HISTOGRAM_BOOLEAN("Settings.TrackedPreferencesNoEnforcementOnDomain",
217 is_managed);
218 first_call = false;
219 }
220 if (is_managed)
221 return GROUP_NO_ENFORCEMENT;
222 }
223 #endif
224
225 struct {
226 const char* group_name;
227 SettingsEnforcementGroup group;
228 } static const kEnforcementLevelMap[] = {
229 { chrome_prefs::internals::kSettingsEnforcementGroupNoEnforcement,
230 GROUP_NO_ENFORCEMENT },
231 { chrome_prefs::internals::kSettingsEnforcementGroupEnforceAlways,
232 GROUP_ENFORCE_ALWAYS },
233 { chrome_prefs::internals::
234 kSettingsEnforcementGroupEnforceAlwaysWithDSE,
235 GROUP_ENFORCE_ALWAYS_WITH_DSE },
236 { chrome_prefs::internals::
237 kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE,
238 GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE },
239 };
240
241 // Use the strongest enforcement setting in the absence of a field trial
242 // config on Windows and MacOS. Remember to update the OFFICIAL_BUILD section
243 // of extension_startup_browsertest.cc and pref_hash_browsertest.cc when
244 // updating the default value below.
245 // TODO(gab): Enforce this on all platforms.
246 SettingsEnforcementGroup enforcement_group =
247 #if defined(OS_WIN) || defined(OS_MACOSX)
248 GROUP_ENFORCE_DEFAULT;
249 #else
250 GROUP_NO_ENFORCEMENT;
251 #endif
252 bool group_determined_from_trial = false;
253 base::FieldTrial* trial =
254 base::FieldTrialList::Find(
255 chrome_prefs::internals::kSettingsEnforcementTrialName);
256 if (trial) {
257 const std::string& group_name = trial->group_name();
258 for (size_t i = 0; i < base::size(kEnforcementLevelMap); ++i) {
259 if (kEnforcementLevelMap[i].group_name == group_name) {
260 enforcement_group = kEnforcementLevelMap[i].group;
261 group_determined_from_trial = true;
262 break;
263 }
264 }
265 }
266 UMA_HISTOGRAM_BOOLEAN("Settings.EnforcementGroupDeterminedFromTrial",
267 group_determined_from_trial);
268 return enforcement_group;
269 }
270
271 // Returns the effective preference tracking configuration.
272 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr>
GetTrackingConfiguration()273 GetTrackingConfiguration() {
274 const SettingsEnforcementGroup enforcement_group =
275 GetSettingsEnforcementGroup();
276
277 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> result;
278 for (size_t i = 0; i < base::size(kTrackedPrefs); ++i) {
279 prefs::mojom::TrackedPreferenceMetadataPtr data =
280 prefs::ConstructTrackedMetadata(kTrackedPrefs[i]);
281
282 if (GROUP_NO_ENFORCEMENT == enforcement_group) {
283 // Remove enforcement for all tracked preferences.
284 data->enforcement_level = EnforcementLevel::NO_ENFORCEMENT;
285 }
286
287 if (enforcement_group >= GROUP_ENFORCE_ALWAYS_WITH_DSE &&
288 data->name ==
289 DefaultSearchManager::kDefaultSearchProviderDataPrefName) {
290 // Specifically enable default search settings enforcement.
291 data->enforcement_level = EnforcementLevel::ENFORCE_ON_LOAD;
292 }
293
294 #if BUILDFLAG(ENABLE_EXTENSIONS)
295 if (enforcement_group >= GROUP_ENFORCE_ALWAYS_WITH_EXTENSIONS_AND_DSE &&
296 data->name == extensions::pref_names::kExtensions) {
297 // Specifically enable extension settings enforcement.
298 data->enforcement_level = EnforcementLevel::ENFORCE_ON_LOAD;
299 }
300 #endif
301
302 result.push_back(std::move(data));
303 }
304 return result;
305 }
306
CreateProfilePrefStoreManager(const base::FilePath & profile_path)307 std::unique_ptr<ProfilePrefStoreManager> CreateProfilePrefStoreManager(
308 const base::FilePath& profile_path) {
309 std::string legacy_device_id;
310 #if defined(OS_WIN) && BUILDFLAG(ENABLE_RLZ)
311 // This is used by
312 // chrome/browser/apps/platform_apps/api/music_manager_private/device_id_win.cc
313 // but that API is private (http://crbug.com/276485) and other platforms are
314 // not available synchronously.
315 // As part of improving pref metrics on other platforms we may want to find
316 // ways to defer preference loading until the device ID can be used.
317 rlz_lib::GetMachineId(&legacy_device_id);
318 #endif
319 std::string seed;
320 CHECK(ui::ResourceBundle::HasSharedInstance());
321 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
322 seed = ui::ResourceBundle::GetSharedInstance()
323 .GetRawDataResource(IDR_PREF_HASH_SEED_BIN)
324 .as_string();
325 #endif
326 return std::make_unique<ProfilePrefStoreManager>(profile_path, seed,
327 legacy_device_id);
328 }
329
PrepareFactory(sync_preferences::PrefServiceSyncableFactory * factory,const base::FilePath & pref_filename,policy::PolicyService * policy_service,SupervisedUserSettingsService * supervised_user_settings,scoped_refptr<PersistentPrefStore> user_pref_store,scoped_refptr<PrefStore> extension_prefs,bool async,policy::BrowserPolicyConnector * policy_connector)330 void PrepareFactory(sync_preferences::PrefServiceSyncableFactory* factory,
331 const base::FilePath& pref_filename,
332 policy::PolicyService* policy_service,
333 SupervisedUserSettingsService* supervised_user_settings,
334 scoped_refptr<PersistentPrefStore> user_pref_store,
335 scoped_refptr<PrefStore> extension_prefs,
336 bool async,
337 policy::BrowserPolicyConnector* policy_connector) {
338 factory->SetManagedPolicies(policy_service, policy_connector);
339 factory->SetRecommendedPolicies(policy_service, policy_connector);
340
341 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
342 if (supervised_user_settings) {
343 scoped_refptr<PrefStore> supervised_user_prefs =
344 base::MakeRefCounted<SupervisedUserPrefStore>(supervised_user_settings);
345 DCHECK(async || supervised_user_prefs->IsInitializationComplete());
346 factory->set_supervised_user_prefs(supervised_user_prefs);
347 }
348 #endif
349
350 factory->set_async(async);
351 factory->set_extension_prefs(std::move(extension_prefs));
352 factory->set_command_line_prefs(
353 base::MakeRefCounted<ChromeCommandLinePrefStore>(
354 base::CommandLine::ForCurrentProcess()));
355 factory->set_read_error_callback(base::BindRepeating(
356 &chrome_prefs::HandlePersistentPrefStoreReadError, pref_filename));
357 factory->set_user_prefs(std::move(user_pref_store));
358 factory->SetPrefModelAssociatorClient(
359 ChromePrefModelAssociatorClient::GetInstance());
360 }
361
362 class ResetOnLoadObserverImpl : public prefs::mojom::ResetOnLoadObserver {
363 public:
ResetOnLoadObserverImpl(const base::FilePath & profile_path)364 explicit ResetOnLoadObserverImpl(const base::FilePath& profile_path)
365 : profile_path_(profile_path) {}
366
OnResetOnLoad()367 void OnResetOnLoad() override {
368 // A StartSyncFlare used to kick sync early in case of a reset event. This
369 // is done since sync may bring back the user's server value post-reset
370 // which could potentially cause a "settings flash" between the factory
371 // default and the re-instantiated server value. Starting sync ASAP
372 // minimizes the window before the server value is re-instantiated (this
373 // window can otherwise be as long as 10 seconds by default).
374 sync_start_util::GetFlareForSyncableService(profile_path_)
375 .Run(syncer::PREFERENCES);
376 }
377
378 private:
379 const base::FilePath profile_path_;
380
381 DISALLOW_COPY_AND_ASSIGN(ResetOnLoadObserverImpl);
382 };
383
384 } // namespace
385
386 namespace chrome_prefs {
387
388 namespace internals {
389
390 // Group modifications should be reflected in first_run_browsertest.cc and
391 // pref_hash_browsertest.cc.
392 const char kSettingsEnforcementTrialName[] = "SettingsEnforcement";
393 const char kSettingsEnforcementGroupNoEnforcement[] = "no_enforcement";
394 const char kSettingsEnforcementGroupEnforceAlways[] = "enforce_always";
395 const char kSettingsEnforcementGroupEnforceAlwaysWithDSE[] =
396 "enforce_always_with_dse";
397 const char kSettingsEnforcementGroupEnforceAlwaysWithExtensionsAndDSE[] =
398 "enforce_always_with_extensions_and_dse";
399
400 } // namespace internals
401
CreateLocalState(const base::FilePath & pref_filename,policy::PolicyService * policy_service,scoped_refptr<PrefRegistry> pref_registry,bool async,policy::BrowserPolicyConnector * policy_connector)402 std::unique_ptr<PrefService> CreateLocalState(
403 const base::FilePath& pref_filename,
404 policy::PolicyService* policy_service,
405 scoped_refptr<PrefRegistry> pref_registry,
406 bool async,
407 policy::BrowserPolicyConnector* policy_connector) {
408 sync_preferences::PrefServiceSyncableFactory factory;
409 PrepareFactory(&factory, pref_filename, policy_service,
410 nullptr, // supervised_user_settings
411 base::MakeRefCounted<JsonPrefStore>(
412 pref_filename, std::unique_ptr<PrefFilter>()),
413 nullptr, // extension_prefs
414 async, policy_connector);
415
416 return factory.Create(std::move(pref_registry));
417 }
418
CreateProfilePrefs(const base::FilePath & profile_path,mojo::PendingRemote<prefs::mojom::TrackedPreferenceValidationDelegate> validation_delegate,policy::PolicyService * policy_service,SupervisedUserSettingsService * supervised_user_settings,scoped_refptr<PrefStore> extension_prefs,scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry,policy::BrowserPolicyConnector * connector,bool async,scoped_refptr<base::SequencedTaskRunner> io_task_runner)419 std::unique_ptr<sync_preferences::PrefServiceSyncable> CreateProfilePrefs(
420 const base::FilePath& profile_path,
421 mojo::PendingRemote<prefs::mojom::TrackedPreferenceValidationDelegate>
422 validation_delegate,
423 policy::PolicyService* policy_service,
424 SupervisedUserSettingsService* supervised_user_settings,
425 scoped_refptr<PrefStore> extension_prefs,
426 scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry,
427 policy::BrowserPolicyConnector* connector,
428 bool async,
429 scoped_refptr<base::SequencedTaskRunner> io_task_runner) {
430 TRACE_EVENT0("browser", "chrome_prefs::CreateProfilePrefs");
431
432 mojo::PendingRemote<prefs::mojom::ResetOnLoadObserver> reset_on_load_observer;
433 mojo::MakeSelfOwnedReceiver(
434 std::make_unique<ResetOnLoadObserverImpl>(profile_path),
435 reset_on_load_observer.InitWithNewPipeAndPassReceiver());
436 sync_preferences::PrefServiceSyncableFactory factory;
437 scoped_refptr<PersistentPrefStore> user_pref_store =
438 CreateProfilePrefStoreManager(profile_path)
439 ->CreateProfilePrefStore(
440 GetTrackingConfiguration(), kTrackedPrefsReportingIDsCount,
441 std::move(io_task_runner), std::move(reset_on_load_observer),
442 std::move(validation_delegate));
443 PrepareFactory(&factory, profile_path, policy_service,
444 supervised_user_settings, std::move(user_pref_store),
445 std::move(extension_prefs), async, connector);
446 return factory.CreateSyncable(std::move(pref_registry));
447 }
448
DisableDomainCheckForTesting()449 void DisableDomainCheckForTesting() {
450 #if defined(OS_WIN)
451 g_disable_domain_check_for_testing = true;
452 #endif // OS_WIN
453 }
454
InitializePrefsFromMasterPrefs(const base::FilePath & profile_path,std::unique_ptr<base::DictionaryValue> master_prefs)455 bool InitializePrefsFromMasterPrefs(
456 const base::FilePath& profile_path,
457 std::unique_ptr<base::DictionaryValue> master_prefs) {
458 return CreateProfilePrefStoreManager(profile_path)
459 ->InitializePrefsFromMasterPrefs(GetTrackingConfiguration(),
460 kTrackedPrefsReportingIDsCount,
461 std::move(master_prefs));
462 }
463
GetResetTime(Profile * profile)464 base::Time GetResetTime(Profile* profile) {
465 return ProfilePrefStoreManager::GetResetTime(profile->GetPrefs());
466 }
467
ClearResetTime(Profile * profile)468 void ClearResetTime(Profile* profile) {
469 ProfilePrefStoreManager::ClearResetTime(profile->GetPrefs());
470 }
471
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)472 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
473 ProfilePrefStoreManager::RegisterProfilePrefs(registry);
474 }
475
HandlePersistentPrefStoreReadError(const base::FilePath & pref_filename,PersistentPrefStore::PrefReadError error)476 void HandlePersistentPrefStoreReadError(
477 const base::FilePath& pref_filename,
478 PersistentPrefStore::PrefReadError error) {
479 // The error callback is always invoked back on the main thread (which is
480 // BrowserThread::UI unless called during early initialization before the main
481 // thread is promoted to BrowserThread::UI).
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
483 !BrowserThread::IsThreadInitialized(BrowserThread::UI));
484
485 // Sample the histogram also for the successful case in order to get a
486 // baseline on the success rate in addition to the error distribution.
487 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
488 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
489
490 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
491 #if !defined(OS_CHROMEOS)
492 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
493 // an example problem that this can cause.
494 // Do some diagnosis and try to avoid losing data.
495 int message_id = 0;
496 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
497 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
498 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
499 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
500 }
501
502 if (message_id) {
503 // Note: ThreadTaskRunnerHandle() is usually BrowserThread::UI but during
504 // early startup it can be ChromeBrowserMainParts::DeferringTaskRunner
505 // which will forward to BrowserThread::UI when it's initialized.
506 base::ThreadTaskRunnerHandle::Get()->PostTask(
507 FROM_HERE,
508 base::BindOnce(&ShowProfileErrorDialog, ProfileErrorType::PREFERENCES,
509 message_id,
510 sql::GetCorruptFileDiagnosticsInfo(pref_filename)));
511 }
512 #else
513 // On ChromeOS error screen with message about broken local state
514 // will be displayed.
515
516 // A supplementary error message about broken local state - is included
517 // in logs and user feedbacks.
518 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE &&
519 error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
520 LOG(ERROR) << "An error happened during prefs loading: " << error;
521 }
522 #endif
523 }
524 }
525
526 } // namespace chrome_prefs
527