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_builder.h" 22 #include "chrome/browser/ui/profile_error_dialog.h" 23 #include "components/user_prefs/pref_registry_syncable.h" 24 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_thread.h" 26 #include "grit/chromium_strings.h" 27 #include "grit/generated_resources.h" 28 29 #if defined(ENABLE_CONFIGURATION_POLICY) 30 #include "chrome/browser/policy/browser_policy_connector.h" 31 #include "chrome/browser/policy/configuration_policy_pref_store.h" 32 #include "chrome/browser/policy/policy_types.h" 33 #endif 34 35 using content::BrowserContext; 36 using content::BrowserThread; 37 38 namespace { 39 40 // Shows notifications which correspond to PersistentPrefStore's reading errors. 41 void HandleReadError(PersistentPrefStore::PrefReadError error) { 42 if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) { 43 // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for 44 // an example problem that this can cause. 45 // Do some diagnosis and try to avoid losing data. 46 int message_id = 0; 47 if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) { 48 message_id = IDS_PREFERENCES_CORRUPT_ERROR; 49 } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) { 50 message_id = IDS_PREFERENCES_UNREADABLE_ERROR; 51 } 52 53 if (message_id) { 54 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 55 base::Bind(&ShowProfileErrorDialog, message_id)); 56 } 57 UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 58 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM); 59 } 60 } 61 62 void PrepareBuilder( 63 PrefServiceSyncableBuilder* builder, 64 const base::FilePath& pref_filename, 65 base::SequencedTaskRunner* pref_io_task_runner, 66 policy::PolicyService* policy_service, 67 const scoped_refptr<PrefStore>& extension_prefs, 68 bool async) { 69 #if defined(OS_LINUX) 70 // We'd like to see what fraction of our users have the preferences 71 // stored on a network file system, as we've had no end of troubles 72 // with NFS/AFS. 73 // TODO(evanm): remove this once we've collected state. 74 file_util::FileSystemType fstype; 75 if (file_util::GetFileSystemType(pref_filename.DirName(), &fstype)) { 76 UMA_HISTOGRAM_ENUMERATION("PrefService.FileSystemType", 77 static_cast<int>(fstype), 78 file_util::FILE_SYSTEM_TYPE_COUNT); 79 } 80 #endif 81 82 #if defined(ENABLE_CONFIGURATION_POLICY) 83 using policy::ConfigurationPolicyPrefStore; 84 builder->WithManagedPrefs(new ConfigurationPolicyPrefStore( 85 policy_service, 86 g_browser_process->browser_policy_connector()->GetHandlerList(), 87 policy::POLICY_LEVEL_MANDATORY)); 88 builder->WithRecommendedPrefs(new ConfigurationPolicyPrefStore( 89 policy_service, 90 g_browser_process->browser_policy_connector()->GetHandlerList(), 91 policy::POLICY_LEVEL_RECOMMENDED)); 92 #endif // ENABLE_CONFIGURATION_POLICY 93 94 builder->WithAsync(async); 95 builder->WithExtensionPrefs(extension_prefs.get()); 96 builder->WithCommandLinePrefs( 97 new CommandLinePrefStore(CommandLine::ForCurrentProcess())); 98 builder->WithReadErrorCallback(base::Bind(&HandleReadError)); 99 builder->WithUserPrefs(new JsonPrefStore(pref_filename, pref_io_task_runner)); 100 } 101 102 } // namespace 103 104 namespace chrome_prefs { 105 106 PrefService* CreateLocalState( 107 const base::FilePath& pref_filename, 108 base::SequencedTaskRunner* pref_io_task_runner, 109 policy::PolicyService* policy_service, 110 const scoped_refptr<PrefStore>& extension_prefs, 111 const scoped_refptr<PrefRegistry>& pref_registry, 112 bool async) { 113 PrefServiceSyncableBuilder builder; 114 PrepareBuilder(&builder, 115 pref_filename, 116 pref_io_task_runner, 117 policy_service, 118 extension_prefs, 119 async); 120 return builder.Create(pref_registry.get()); 121 } 122 123 PrefServiceSyncable* CreateProfilePrefs( 124 const base::FilePath& pref_filename, 125 base::SequencedTaskRunner* pref_io_task_runner, 126 policy::PolicyService* policy_service, 127 const scoped_refptr<PrefStore>& extension_prefs, 128 const scoped_refptr<user_prefs::PrefRegistrySyncable>& pref_registry, 129 bool async) { 130 TRACE_EVENT0("browser", "chrome_prefs::CreateProfilePrefs"); 131 PrefServiceSyncableBuilder builder; 132 PrepareBuilder(&builder, 133 pref_filename, 134 pref_io_task_runner, 135 policy_service, 136 extension_prefs, 137 async); 138 return builder.CreateSyncable(pref_registry.get()); 139 } 140 141 } // namespace chrome_prefs 142