Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / prefs / chrome_pref_service_factory.cc
blob5e502ec41885d6525278348a6fdf04bff8fde8b3
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.
5 #include "chrome/browser/prefs/chrome_pref_service_factory.h"
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h"
13 #include "base/prefs/default_pref_store.h"
14 #include "base/prefs/json_pref_store.h"
15 #include "base/prefs/pref_notifier_impl.h"
16 #include "base/prefs/pref_registry.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/prefs/pref_value_store.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/prefs/command_line_pref_store.h"
21 #include "chrome/browser/prefs/pref_hash_filter.h"
22 #include "chrome/browser/prefs/pref_hash_store.h"
23 #include "chrome/browser/prefs/pref_model_associator.h"
24 #include "chrome/browser/prefs/pref_service_syncable.h"
25 #include "chrome/browser/prefs/pref_service_syncable_factory.h"
26 #include "chrome/browser/ui/profile_error_dialog.h"
27 #include "chrome/common/pref_names.h"
28 #include "components/user_prefs/pref_registry_syncable.h"
29 #include "content/public/browser/browser_context.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "extensions/browser/pref_names.h"
32 #include "grit/chromium_strings.h"
33 #include "grit/generated_resources.h"
35 #if defined(ENABLE_CONFIGURATION_POLICY)
36 #include "chrome/browser/policy/browser_policy_connector.h"
37 #include "components/policy/core/browser/configuration_policy_pref_store.h"
38 #include "components/policy/core/common/policy_types.h"
39 #endif
41 #if defined(ENABLE_MANAGED_USERS)
42 #include "chrome/browser/managed_mode/supervised_user_pref_store.h"
43 #endif
45 using content::BrowserContext;
46 using content::BrowserThread;
48 namespace {
50 // These preferences must be kept in sync with the TrackedPreference enum in
51 // tools/metrics/histograms/histograms.xml. To add a new preference, append it
52 // to the array and add a corresponding value to the histogram enum. Each
53 // tracked preference must be given a unique reporting ID.
54 const PrefHashFilter::TrackedPreference kTrackedPrefs[] = {
55 { 0, prefs::kShowHomeButton, true },
56 { 1, prefs::kHomePageIsNewTabPage, true },
57 { 2, prefs::kHomePage, true },
58 { 3, prefs::kRestoreOnStartup, true },
59 { 4, prefs::kURLsToRestoreOnStartup, true },
60 { 5, extensions::pref_names::kExtensions, false },
61 { 6, prefs::kGoogleServicesLastUsername, true },
62 { 7, prefs::kSearchProviderOverrides, true },
63 { 8, prefs::kDefaultSearchProviderSearchURL, true },
64 { 9, prefs::kDefaultSearchProviderKeyword, true },
65 { 10, prefs::kDefaultSearchProviderName, true },
66 #if !defined(OS_ANDROID)
67 { 11, prefs::kPinnedTabs, true },
68 #endif
69 { 12, extensions::pref_names::kKnownDisabled, true },
70 { 13, prefs::kProfileResetPromptMemento, true },
73 // The count of tracked preferences IDs across all platforms.
74 const size_t kTrackedPrefsReportingIDsCount = 14;
75 COMPILE_ASSERT(kTrackedPrefsReportingIDsCount >= arraysize(kTrackedPrefs),
76 need_to_increment_ids_count);
78 PrefHashFilter::EnforcementLevel GetSettingsEnforcementLevel() {
79 static const char kSettingsEnforcementExperiment[] = "SettingsEnforcement";
80 struct {
81 const char* level_name;
82 PrefHashFilter::EnforcementLevel level;
83 } static const kEnforcementLevelMap[] = {
85 "no_enforcement",
86 PrefHashFilter::NO_ENFORCEMENT
89 "enforce",
90 PrefHashFilter::ENFORCE
93 "enforce_no_seeding",
94 PrefHashFilter::ENFORCE_NO_SEEDING
97 "enforce_no_seeding_no_migration",
98 PrefHashFilter::ENFORCE_NO_SEEDING_NO_MIGRATION
102 base::FieldTrial* trial =
103 base::FieldTrialList::Find(kSettingsEnforcementExperiment);
104 if (trial) {
105 const std::string& group_name = trial->group_name();
106 // ARRAYSIZE_UNSAFE must be used since the array is declared locally; it is
107 // only unsafe because it could not trigger a compile error on some
108 // non-array pointer types; this is fine since kEnforcementLevelMap is
109 // clearly an array.
110 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEnforcementLevelMap); ++i) {
111 if (kEnforcementLevelMap[i].level_name == group_name)
112 return kEnforcementLevelMap[i].level;
115 // TODO(gab): Switch default to ENFORCE_ALL when the field trial config is up.
116 return PrefHashFilter::NO_ENFORCEMENT;
119 // Shows notifications which correspond to PersistentPrefStore's reading errors.
120 void HandleReadError(PersistentPrefStore::PrefReadError error) {
121 // Sample the histogram also for the successful case in order to get a
122 // baseline on the success rate in addition to the error distribution.
123 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
124 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
126 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
127 #if !defined(OS_CHROMEOS)
128 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
129 // an example problem that this can cause.
130 // Do some diagnosis and try to avoid losing data.
131 int message_id = 0;
132 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
133 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
134 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
135 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
138 if (message_id) {
139 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
140 base::Bind(&ShowProfileErrorDialog,
141 PROFILE_ERROR_PREFERENCES,
142 message_id));
144 #else
145 // On ChromeOS error screen with message about broken local state
146 // will be displayed.
147 #endif
151 void PrepareBuilder(
152 PrefServiceSyncableFactory* factory,
153 const base::FilePath& pref_filename,
154 base::SequencedTaskRunner* pref_io_task_runner,
155 policy::PolicyService* policy_service,
156 ManagedUserSettingsService* managed_user_settings,
157 scoped_ptr<PrefHashStore> pref_hash_store,
158 const scoped_refptr<PrefStore>& extension_prefs,
159 bool async) {
160 #if defined(OS_LINUX)
161 // We'd like to see what fraction of our users have the preferences
162 // stored on a network file system, as we've had no end of troubles
163 // with NFS/AFS.
164 // TODO(evanm): remove this once we've collected state.
165 file_util::FileSystemType fstype;
166 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
167 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
168 static_cast<int>(fstype),
169 file_util::FILE_SYSTEM_TYPE_COUNT);
171 #endif
173 #if defined(ENABLE_CONFIGURATION_POLICY)
174 using policy::ConfigurationPolicyPrefStore;
175 factory->set_managed_prefs(
176 make_scoped_refptr(new ConfigurationPolicyPrefStore(
177 policy_service,
178 g_browser_process->browser_policy_connector()->GetHandlerList(),
179 policy::POLICY_LEVEL_MANDATORY)));
180 factory->set_recommended_prefs(
181 make_scoped_refptr(new ConfigurationPolicyPrefStore(
182 policy_service,
183 g_browser_process->browser_policy_connector()->GetHandlerList(),
184 policy::POLICY_LEVEL_RECOMMENDED)));
185 #endif // ENABLE_CONFIGURATION_POLICY
187 #if defined(ENABLE_MANAGED_USERS)
188 if (managed_user_settings) {
189 factory->set_supervised_user_prefs(
190 make_scoped_refptr(new SupervisedUserPrefStore(managed_user_settings)));
192 #endif
194 factory->set_async(async);
195 factory->set_extension_prefs(extension_prefs);
196 factory->set_command_line_prefs(
197 make_scoped_refptr(
198 new CommandLinePrefStore(CommandLine::ForCurrentProcess())));
199 factory->set_read_error_callback(base::Bind(&HandleReadError));
200 scoped_ptr<PrefFilter> pref_filter;
201 if (pref_hash_store) {
202 pref_filter.reset(new PrefHashFilter(pref_hash_store.Pass(),
203 kTrackedPrefs,
204 arraysize(kTrackedPrefs),
205 kTrackedPrefsReportingIDsCount,
206 GetSettingsEnforcementLevel()));
208 factory->set_user_prefs(
209 new JsonPrefStore(
210 pref_filename,
211 pref_io_task_runner,
212 pref_filter.Pass()));
215 } // namespace
217 namespace chrome_prefs {
219 scoped_ptr<PrefService> CreateLocalState(
220 const base::FilePath& pref_filename,
221 base::SequencedTaskRunner* pref_io_task_runner,
222 policy::PolicyService* policy_service,
223 const scoped_refptr<PrefRegistry>& pref_registry,
224 bool async) {
225 PrefServiceSyncableFactory factory;
226 PrepareBuilder(&factory,
227 pref_filename,
228 pref_io_task_runner,
229 policy_service,
230 NULL,
231 scoped_ptr<PrefHashStore>(),
232 NULL,
233 async);
234 return factory.Create(pref_registry.get());
237 scoped_ptr<PrefServiceSyncable> CreateProfilePrefs(
238 const base::FilePath& pref_filename,
239 base::SequencedTaskRunner* pref_io_task_runner,
240 policy::PolicyService* policy_service,
241 ManagedUserSettingsService* managed_user_settings,
242 scoped_ptr<PrefHashStore> pref_hash_store,
243 const scoped_refptr<PrefStore>& extension_prefs,
244 const scoped_refptr<user_prefs::PrefRegistrySyncable>& pref_registry,
245 bool async) {
246 TRACE_EVENT0("browser", "chrome_prefs::CreateProfilePrefs");
247 PrefServiceSyncableFactory factory;
248 PrepareBuilder(&factory,
249 pref_filename,
250 pref_io_task_runner,
251 policy_service,
252 managed_user_settings,
253 pref_hash_store.Pass(),
254 extension_prefs,
255 async);
256 return factory.CreateSyncable(pref_registry.get());
259 } // namespace chrome_prefs