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. 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 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 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 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