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 "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/histogram.h"
12 #include "base/prefs/default_pref_store.h"
13 #include "base/prefs/json_pref_store.h"
14 #include "base/prefs/pref_notifier_impl.h"
15 #include "base/prefs/pref_registry.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/prefs/pref_value_store.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/prefs/command_line_pref_store.h"
20 #include "chrome/browser/prefs/pref_model_associator.h"
21 #include "chrome/browser/prefs/pref_service_syncable.h"
22 #include "chrome/browser/prefs/pref_service_syncable_factory.h"
23 #include "chrome/browser/ui/profile_error_dialog.h"
24 #include "components/user_prefs/pref_registry_syncable.h"
25 #include "content/public/browser/browser_context.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "grit/chromium_strings.h"
28 #include "grit/generated_resources.h"
29
30 #if defined(ENABLE_CONFIGURATION_POLICY)
31 #include "chrome/browser/policy/browser_policy_connector.h"
32 #include "components/policy/core/browser/configuration_policy_pref_store.h"
33 #include "components/policy/core/common/policy_types.h"
34 #endif
35
36 #if defined(ENABLE_MANAGED_USERS)
37 #include "chrome/browser/managed_mode/supervised_user_pref_store.h"
38 #endif
39
40 using content::BrowserContext;
41 using content::BrowserThread;
42
43 namespace {
44
45 // Shows notifications which correspond to PersistentPrefStore's reading errors.
HandleReadError(PersistentPrefStore::PrefReadError error)46 void HandleReadError(PersistentPrefStore::PrefReadError error) {
47 // Sample the histogram also for the successful case in order to get a
48 // baseline on the success rate in addition to the error distribution.
49 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error,
50 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
51
52 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
53 #if !defined(OS_CHROMEOS)
54 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
55 // an example problem that this can cause.
56 // Do some diagnosis and try to avoid losing data.
57 int message_id = 0;
58 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
59 message_id = IDS_PREFERENCES_CORRUPT_ERROR;
60 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
61 message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
62 }
63
64 if (message_id) {
65 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
66 base::Bind(&ShowProfileErrorDialog,
67 PROFILE_ERROR_PREFERENCES,
68 message_id));
69 }
70 #else
71 // On ChromeOS error screen with message about broken local state
72 // will be displayed.
73 #endif
74 }
75 }
76
PrepareBuilder(PrefServiceSyncableFactory * factory,const base::FilePath & pref_filename,base::SequencedTaskRunner * pref_io_task_runner,policy::PolicyService * policy_service,ManagedUserSettingsService * managed_user_settings,const scoped_refptr<PrefStore> & extension_prefs,bool async)77 void PrepareBuilder(
78 PrefServiceSyncableFactory* factory,
79 const base::FilePath& pref_filename,
80 base::SequencedTaskRunner* pref_io_task_runner,
81 policy::PolicyService* policy_service,
82 ManagedUserSettingsService* managed_user_settings,
83 const scoped_refptr<PrefStore>& extension_prefs,
84 bool async) {
85 #if defined(OS_LINUX)
86 // We'd like to see what fraction of our users have the preferences
87 // stored on a network file system, as we've had no end of troubles
88 // with NFS/AFS.
89 // TODO(evanm): remove this once we've collected state.
90 file_util::FileSystemType fstype;
91 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) {
92 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType",
93 static_cast<int>(fstype),
94 file_util::FILE_SYSTEM_TYPE_COUNT);
95 }
96 #endif
97
98 #if defined(ENABLE_CONFIGURATION_POLICY)
99 using policy::ConfigurationPolicyPrefStore;
100 factory->set_managed_prefs(
101 make_scoped_refptr(new ConfigurationPolicyPrefStore(
102 policy_service,
103 g_browser_process->browser_policy_connector()->GetHandlerList(),
104 policy::POLICY_LEVEL_MANDATORY)));
105 factory->set_recommended_prefs(
106 make_scoped_refptr(new ConfigurationPolicyPrefStore(
107 policy_service,
108 g_browser_process->browser_policy_connector()->GetHandlerList(),
109 policy::POLICY_LEVEL_RECOMMENDED)));
110 #endif // ENABLE_CONFIGURATION_POLICY
111
112 #if defined(ENABLE_MANAGED_USERS)
113 if (managed_user_settings) {
114 factory->set_supervised_user_prefs(
115 make_scoped_refptr(new SupervisedUserPrefStore(managed_user_settings)));
116 }
117 #endif
118
119 factory->set_async(async);
120 factory->set_extension_prefs(extension_prefs);
121 factory->set_command_line_prefs(
122 make_scoped_refptr(
123 new CommandLinePrefStore(CommandLine::ForCurrentProcess())));
124 factory->set_read_error_callback(base::Bind(&HandleReadError));
125 factory->set_user_prefs(
126 new JsonPrefStore(pref_filename, pref_io_task_runner));
127 }
128
129 } // namespace
130
131 namespace chrome_prefs {
132
CreateLocalState(const base::FilePath & pref_filename,base::SequencedTaskRunner * pref_io_task_runner,policy::PolicyService * policy_service,const scoped_refptr<PrefRegistry> & pref_registry,bool async)133 scoped_ptr<PrefService> CreateLocalState(
134 const base::FilePath& pref_filename,
135 base::SequencedTaskRunner* pref_io_task_runner,
136 policy::PolicyService* policy_service,
137 const scoped_refptr<PrefRegistry>& pref_registry,
138 bool async) {
139 PrefServiceSyncableFactory factory;
140 PrepareBuilder(&factory,
141 pref_filename,
142 pref_io_task_runner,
143 policy_service,
144 NULL,
145 NULL,
146 async);
147 return factory.Create(pref_registry.get());
148 }
149
CreateProfilePrefs(const base::FilePath & pref_filename,base::SequencedTaskRunner * pref_io_task_runner,policy::PolicyService * policy_service,ManagedUserSettingsService * managed_user_settings,const scoped_refptr<PrefStore> & extension_prefs,const scoped_refptr<user_prefs::PrefRegistrySyncable> & pref_registry,bool async)150 scoped_ptr<PrefServiceSyncable> CreateProfilePrefs(
151 const base::FilePath& pref_filename,
152 base::SequencedTaskRunner* pref_io_task_runner,
153 policy::PolicyService* policy_service,
154 ManagedUserSettingsService* managed_user_settings,
155 const scoped_refptr<PrefStore>& extension_prefs,
156 const scoped_refptr<user_prefs::PrefRegistrySyncable>& pref_registry,
157 bool async) {
158 TRACE_EVENT0("browser", "chrome_prefs::CreateProfilePrefs");
159 PrefServiceSyncableFactory factory;
160 PrepareBuilder(&factory,
161 pref_filename,
162 pref_io_task_runner,
163 policy_service,
164 managed_user_settings,
165 extension_prefs,
166 async);
167 return factory.CreateSyncable(pref_registry.get());
168 }
169
170 } // namespace chrome_prefs
171