OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/prefs/profile_pref_store_manager.h" | 5 #include "chrome/browser/prefs/profile_pref_store_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/callback.h" |
9 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
10 #include "base/json/json_file_value_serializer.h" | 12 #include "base/json/json_file_value_serializer.h" |
11 #include "base/logging.h" | 13 #include "base/logging.h" |
12 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
13 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
14 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
15 #include "build/build_config.h" | 17 #include "build/build_config.h" |
16 #include "chrome/common/chrome_constants.h" | 18 #include "chrome/common/chrome_constants.h" |
17 #include "chrome/common/chrome_features.h" | 19 #include "chrome/common/chrome_features.h" |
18 #include "components/pref_registry/pref_registry_syncable.h" | 20 #include "components/pref_registry/pref_registry_syncable.h" |
19 #include "components/prefs/json_pref_store.h" | 21 #include "components/prefs/json_pref_store.h" |
20 #include "components/prefs/persistent_pref_store.h" | 22 #include "components/prefs/persistent_pref_store.h" |
21 #include "components/prefs/pref_registry_simple.h" | 23 #include "components/prefs/pref_registry_simple.h" |
22 #include "services/preferences/public/cpp/persistent_pref_store_client.h" | 24 #include "services/preferences/public/cpp/persistent_pref_store_client.h" |
23 #include "services/preferences/public/interfaces/preferences.mojom.h" | 25 #include "services/preferences/public/interfaces/preferences.mojom.h" |
24 #include "services/preferences/tracked/pref_hash_filter.h" | 26 #include "services/preferences/tracked/pref_hash_filter.h" |
25 #include "services/preferences/tracked/tracked_persistent_pref_store_factory.h" | 27 #include "services/preferences/tracked/pref_hash_store_impl.h" |
| 28 #include "services/preferences/tracked/segregated_pref_store.h" |
| 29 #include "services/preferences/tracked/tracked_preferences_migration.h" |
26 #include "services/service_manager/public/cpp/connector.h" | 30 #include "services/service_manager/public/cpp/connector.h" |
27 | 31 |
28 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
29 #include "chrome/install_static/install_util.h" | 33 #include "chrome/install_static/install_util.h" |
| 34 #include "services/preferences/tracked/registry_hash_store_contents_win.h" |
30 #endif | 35 #endif |
31 | 36 |
32 namespace { | 37 namespace { |
33 | 38 |
| 39 using EnforcementLevel = |
| 40 prefs::mojom::TrackedPreferenceMetadata::EnforcementLevel; |
| 41 |
| 42 void RemoveValueSilently(const base::WeakPtr<JsonPrefStore> pref_store, |
| 43 const std::string& key) { |
| 44 if (pref_store) { |
| 45 pref_store->RemoveValueSilently( |
| 46 key, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
| 47 } |
| 48 } |
| 49 |
34 #if defined(OS_WIN) | 50 #if defined(OS_WIN) |
35 // Forces a different registry key to be used for storing preference validation | 51 // Forces a different registry key to be used for storing preference validation |
36 // MACs. See |SetPreferenceValidationRegistryPathForTesting|. | 52 // MACs. See |SetPreferenceValidationRegistryPathForTesting|. |
37 const base::string16* g_preference_validation_registry_path_for_testing = | 53 const base::string16* g_preference_validation_registry_path_for_testing = |
38 nullptr; | 54 nullptr; |
39 #endif // OS_WIN | 55 #endif // OS_WIN |
40 | 56 |
41 } // namespace | 57 } // namespace |
42 | 58 |
43 // Preference tracking and protection is not required on platforms where other | 59 // Preference tracking and protection is not required on platforms where other |
44 // apps do not have access to chrome's persistent storage. | 60 // apps do not have access to chrome's persistent storage. |
45 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = | 61 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = |
46 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 62 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
47 false; | 63 false; |
48 #else | 64 #else |
49 true; | 65 true; |
50 #endif | 66 #endif |
51 | 67 |
52 ProfilePrefStoreManager::ProfilePrefStoreManager( | 68 ProfilePrefStoreManager::ProfilePrefStoreManager( |
53 const base::FilePath& profile_path, | 69 const base::FilePath& profile_path, |
| 70 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> |
| 71 tracking_configuration, |
| 72 size_t reporting_ids_count, |
54 const std::string& seed, | 73 const std::string& seed, |
55 const std::string& legacy_device_id) | 74 const std::string& legacy_device_id, |
| 75 PrefService* local_state) |
56 : profile_path_(profile_path), | 76 : profile_path_(profile_path), |
| 77 tracking_configuration_(std::move(tracking_configuration)), |
| 78 reporting_ids_count_(reporting_ids_count), |
57 seed_(seed), | 79 seed_(seed), |
58 legacy_device_id_(legacy_device_id) {} | 80 legacy_device_id_(legacy_device_id), |
| 81 local_state_(local_state) {} |
59 | 82 |
60 ProfilePrefStoreManager::~ProfilePrefStoreManager() {} | 83 ProfilePrefStoreManager::~ProfilePrefStoreManager() {} |
61 | 84 |
62 // static | 85 // static |
63 void ProfilePrefStoreManager::RegisterProfilePrefs( | 86 void ProfilePrefStoreManager::RegisterProfilePrefs( |
64 user_prefs::PrefRegistrySyncable* registry) { | 87 user_prefs::PrefRegistrySyncable* registry) { |
65 PrefHashFilter::RegisterProfilePrefs(registry); | 88 PrefHashFilter::RegisterProfilePrefs(registry); |
66 } | 89 } |
67 | 90 |
68 // static | 91 // static |
69 base::Time ProfilePrefStoreManager::GetResetTime(PrefService* pref_service) { | 92 base::Time ProfilePrefStoreManager::GetResetTime(PrefService* pref_service) { |
70 return PrefHashFilter::GetResetTime(pref_service); | 93 return PrefHashFilter::GetResetTime(pref_service); |
71 } | 94 } |
72 | 95 |
73 // static | 96 // static |
74 void ProfilePrefStoreManager::ClearResetTime(PrefService* pref_service) { | 97 void ProfilePrefStoreManager::ClearResetTime(PrefService* pref_service) { |
75 PrefHashFilter::ClearResetTime(pref_service); | 98 PrefHashFilter::ClearResetTime(pref_service); |
76 } | 99 } |
77 | 100 |
78 #if defined(OS_WIN) | 101 #if defined(OS_WIN) |
79 // static | 102 // static |
80 void ProfilePrefStoreManager::SetPreferenceValidationRegistryPathForTesting( | 103 void ProfilePrefStoreManager::SetPreferenceValidationRegistryPathForTesting( |
81 const base::string16* path) { | 104 const base::string16* path) { |
82 DCHECK(!path->empty()); | 105 DCHECK(!path->empty()); |
83 g_preference_validation_registry_path_for_testing = path; | 106 g_preference_validation_registry_path_for_testing = path; |
84 } | 107 } |
85 #endif // OS_WIN | 108 #endif // OS_WIN |
86 | 109 |
87 PersistentPrefStore* ProfilePrefStoreManager::CreateProfilePrefStore( | 110 PersistentPrefStore* ProfilePrefStoreManager::CreateProfilePrefStore( |
88 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> | 111 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, |
89 tracking_configuration, | 112 const base::Closure& on_reset_on_load, |
90 size_t reporting_ids_count, | 113 prefs::mojom::TrackedPreferenceValidationDelegate* validation_delegate, |
91 base::SequencedWorkerPool* worker_pool, | |
92 prefs::mojom::ResetOnLoadObserverPtr reset_on_load_observer, | |
93 prefs::mojom::TrackedPreferenceValidationDelegatePtr validation_delegate, | |
94 service_manager::Connector* connector, | 114 service_manager::Connector* connector, |
95 scoped_refptr<PrefRegistry> pref_registry) { | 115 scoped_refptr<PrefRegistry> pref_registry) { |
96 if (features::PrefServiceEnabled()) { | 116 if (features::PrefServiceEnabled()) { |
97 ConfigurePrefService(std::move(tracking_configuration), reporting_ids_count, | 117 ConfigurePrefService(on_reset_on_load, connector); |
98 std::move(reset_on_load_observer), | |
99 std::move(validation_delegate), connector); | |
100 prefs::mojom::PrefStoreConnectorPtr pref_connector; | 118 prefs::mojom::PrefStoreConnectorPtr pref_connector; |
101 connector->BindInterface(prefs::mojom::kServiceName, &pref_connector); | 119 connector->BindInterface(prefs::mojom::kServiceName, &pref_connector); |
102 return new prefs::PersistentPrefStoreClient(std::move(pref_connector), | 120 return new prefs::PersistentPrefStoreClient(std::move(pref_connector), |
103 std::move(pref_registry)); | 121 std::move(pref_registry)); |
104 } | 122 } |
105 if (!kPlatformSupportsPreferenceTracking) { | 123 if (!kPlatformSupportsPreferenceTracking) { |
106 return new JsonPrefStore( | 124 return new JsonPrefStore(profile_path_.Append(chrome::kPreferencesFilename), |
107 profile_path_.Append(chrome::kPreferencesFilename), | 125 io_task_runner.get(), |
108 JsonPrefStore::GetTaskRunnerForFile(profile_path_, worker_pool), | 126 std::unique_ptr<PrefFilter>()); |
109 nullptr); | |
110 } | 127 } |
111 return CreateTrackedPersistentPrefStore( | 128 |
112 CreateTrackedPrefStoreConfiguration( | 129 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> |
113 std::move(tracking_configuration), reporting_ids_count, | 130 unprotected_configuration; |
114 std::move(reset_on_load_observer), std::move(validation_delegate)), | 131 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> |
115 worker_pool); | 132 protected_configuration; |
| 133 std::set<std::string> protected_pref_names; |
| 134 std::set<std::string> unprotected_pref_names; |
| 135 for (auto& metadata : tracking_configuration_) { |
| 136 if (metadata->enforcement_level > EnforcementLevel::NO_ENFORCEMENT) { |
| 137 protected_pref_names.insert(metadata->name); |
| 138 protected_configuration.push_back(std::move(metadata)); |
| 139 } else { |
| 140 unprotected_pref_names.insert(metadata->name); |
| 141 unprotected_configuration.push_back(std::move(metadata)); |
| 142 } |
| 143 } |
| 144 tracking_configuration_.clear(); |
| 145 |
| 146 std::unique_ptr<PrefHashFilter> unprotected_pref_hash_filter( |
| 147 new PrefHashFilter(GetPrefHashStore(false), |
| 148 GetExternalVerificationPrefHashStorePair(), |
| 149 unprotected_configuration, base::Closure(), |
| 150 validation_delegate, reporting_ids_count_, false)); |
| 151 std::unique_ptr<PrefHashFilter> protected_pref_hash_filter(new PrefHashFilter( |
| 152 GetPrefHashStore(true), GetExternalVerificationPrefHashStorePair(), |
| 153 protected_configuration, on_reset_on_load, validation_delegate, |
| 154 reporting_ids_count_, true)); |
| 155 |
| 156 PrefHashFilter* raw_unprotected_pref_hash_filter = |
| 157 unprotected_pref_hash_filter.get(); |
| 158 PrefHashFilter* raw_protected_pref_hash_filter = |
| 159 protected_pref_hash_filter.get(); |
| 160 |
| 161 scoped_refptr<JsonPrefStore> unprotected_pref_store(new JsonPrefStore( |
| 162 profile_path_.Append(chrome::kPreferencesFilename), io_task_runner.get(), |
| 163 std::move(unprotected_pref_hash_filter))); |
| 164 scoped_refptr<JsonPrefStore> protected_pref_store(new JsonPrefStore( |
| 165 profile_path_.Append(chrome::kSecurePreferencesFilename), |
| 166 io_task_runner.get(), std::move(protected_pref_hash_filter))); |
| 167 |
| 168 SetupTrackedPreferencesMigration( |
| 169 unprotected_pref_names, protected_pref_names, |
| 170 base::Bind(&RemoveValueSilently, unprotected_pref_store->AsWeakPtr()), |
| 171 base::Bind(&RemoveValueSilently, protected_pref_store->AsWeakPtr()), |
| 172 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply, |
| 173 unprotected_pref_store->AsWeakPtr()), |
| 174 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteReply, |
| 175 protected_pref_store->AsWeakPtr()), |
| 176 GetPrefHashStore(false), GetPrefHashStore(true), |
| 177 raw_unprotected_pref_hash_filter, raw_protected_pref_hash_filter); |
| 178 |
| 179 return new SegregatedPrefStore(unprotected_pref_store, protected_pref_store, |
| 180 protected_pref_names); |
116 } | 181 } |
117 | 182 |
118 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs( | 183 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs( |
119 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> | |
120 tracking_configuration, | |
121 size_t reporting_ids_count, | |
122 std::unique_ptr<base::DictionaryValue> master_prefs) { | 184 std::unique_ptr<base::DictionaryValue> master_prefs) { |
123 // Create the profile directory if it doesn't exist yet (very possible on | 185 // Create the profile directory if it doesn't exist yet (very possible on |
124 // first run). | 186 // first run). |
125 if (!base::CreateDirectory(profile_path_)) | 187 if (!base::CreateDirectory(profile_path_)) |
126 return false; | 188 return false; |
127 | 189 |
128 if (kPlatformSupportsPreferenceTracking) { | 190 if (kPlatformSupportsPreferenceTracking) { |
129 InitializeMasterPrefsTracking( | 191 PrefHashFilter(GetPrefHashStore(false), |
130 CreateTrackedPrefStoreConfiguration(std::move(tracking_configuration), | 192 GetExternalVerificationPrefHashStorePair(), |
131 reporting_ids_count, {}, nullptr), | 193 tracking_configuration_, base::Closure(), NULL, |
132 master_prefs.get()); | 194 reporting_ids_count_, false) |
| 195 .Initialize(master_prefs.get()); |
133 } | 196 } |
134 | 197 |
135 // This will write out to a single combined file which will be immediately | 198 // This will write out to a single combined file which will be immediately |
136 // migrated to two files on load. | 199 // migrated to two files on load. |
137 JSONFileValueSerializer serializer( | 200 JSONFileValueSerializer serializer( |
138 profile_path_.Append(chrome::kPreferencesFilename)); | 201 profile_path_.Append(chrome::kPreferencesFilename)); |
139 | 202 |
140 // Call Serialize (which does IO) on the main thread, which would _normally_ | 203 // Call Serialize (which does IO) on the main thread, which would _normally_ |
141 // be verboten. In this case however, we require this IO to synchronously | 204 // be verboten. In this case however, we require this IO to synchronously |
142 // complete before Chrome can start (as master preferences seed the Local | 205 // complete before Chrome can start (as master preferences seed the Local |
143 // State and Preferences files). This won't trip ThreadIORestrictions as they | 206 // State and Preferences files). This won't trip ThreadIORestrictions as they |
144 // won't have kicked in yet on the main thread. | 207 // won't have kicked in yet on the main thread. |
145 bool success = serializer.Serialize(*master_prefs); | 208 bool success = serializer.Serialize(*master_prefs); |
146 | 209 |
147 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); | 210 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); |
148 return success; | 211 return success; |
149 } | 212 } |
150 | 213 |
| 214 std::unique_ptr<PrefHashStore> ProfilePrefStoreManager::GetPrefHashStore( |
| 215 bool use_super_mac) { |
| 216 DCHECK(kPlatformSupportsPreferenceTracking); |
| 217 |
| 218 return std::unique_ptr<PrefHashStore>( |
| 219 new PrefHashStoreImpl(seed_, legacy_device_id_, use_super_mac)); |
| 220 } |
| 221 |
| 222 std::pair<std::unique_ptr<PrefHashStore>, std::unique_ptr<HashStoreContents>> |
| 223 ProfilePrefStoreManager::GetExternalVerificationPrefHashStorePair() { |
| 224 DCHECK(kPlatformSupportsPreferenceTracking); |
| 225 #if defined(OS_WIN) |
| 226 return std::make_pair( |
| 227 base::MakeUnique<PrefHashStoreImpl>( |
| 228 "ChromeRegistryHashStoreValidationSeed", legacy_device_id_, |
| 229 false /* use_super_mac */), |
| 230 g_preference_validation_registry_path_for_testing |
| 231 ? base::MakeUnique<RegistryHashStoreContentsWin>( |
| 232 *g_preference_validation_registry_path_for_testing, |
| 233 profile_path_.BaseName().LossyDisplayName()) |
| 234 : base::MakeUnique<RegistryHashStoreContentsWin>( |
| 235 install_static::GetRegistryPath(), |
| 236 profile_path_.BaseName().LossyDisplayName())); |
| 237 #else |
| 238 return std::make_pair(nullptr, nullptr); |
| 239 #endif |
| 240 } |
| 241 |
151 void ProfilePrefStoreManager::ConfigurePrefService( | 242 void ProfilePrefStoreManager::ConfigurePrefService( |
152 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> | 243 const base::Closure& on_reset_on_load, |
153 tracking_configuration, | |
154 size_t reporting_ids_count, | |
155 prefs::mojom::ResetOnLoadObserverPtr reset_on_load_observer, | |
156 prefs::mojom::TrackedPreferenceValidationDelegatePtr validation_delegate, | |
157 service_manager::Connector* connector) { | 244 service_manager::Connector* connector) { |
158 auto config = prefs::mojom::PersistentPrefStoreConfiguration::New(); | 245 auto config = prefs::mojom::PersistentPrefStoreConfiguration::New(); |
159 if (!kPlatformSupportsPreferenceTracking) { | 246 config->set_simple_configuration( |
160 config->set_simple_configuration( | 247 prefs::mojom::SimplePersistentPrefStoreConfiguration::New( |
161 prefs::mojom::SimplePersistentPrefStoreConfiguration::New( | 248 profile_path_.Append(chrome::kPreferencesFilename))); |
162 profile_path_.Append(chrome::kPreferencesFilename))); | |
163 } else { | |
164 config->set_tracked_configuration(CreateTrackedPrefStoreConfiguration( | |
165 std::move(tracking_configuration), reporting_ids_count, | |
166 std::move(reset_on_load_observer), std::move(validation_delegate))); | |
167 } | |
168 prefs::mojom::PrefServiceControlPtr control; | 249 prefs::mojom::PrefServiceControlPtr control; |
169 connector->BindInterface(prefs::mojom::kServiceName, &control); | 250 connector->BindInterface(prefs::mojom::kServiceName, &control); |
170 control->Init(std::move(config)); | 251 control->Init(std::move(config)); |
171 } | 252 } |
172 | |
173 prefs::mojom::TrackedPersistentPrefStoreConfigurationPtr | |
174 ProfilePrefStoreManager::CreateTrackedPrefStoreConfiguration( | |
175 std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> | |
176 tracking_configuration, | |
177 size_t reporting_ids_count, | |
178 prefs::mojom::ResetOnLoadObserverPtr reset_on_load_observer, | |
179 prefs::mojom::TrackedPreferenceValidationDelegatePtr validation_delegate) { | |
180 return prefs::mojom::TrackedPersistentPrefStoreConfiguration::New( | |
181 profile_path_.Append(chrome::kPreferencesFilename), | |
182 profile_path_.Append(chrome::kSecurePreferencesFilename), | |
183 std::move(tracking_configuration), reporting_ids_count, seed_, | |
184 legacy_device_id_, "ChromeRegistryHashStoreValidationSeed", | |
185 #if defined(OS_WIN) | |
186 g_preference_validation_registry_path_for_testing | |
187 ? *g_preference_validation_registry_path_for_testing | |
188 : install_static::GetRegistryPath(), | |
189 #else | |
190 base::string16(), | |
191 #endif | |
192 std::move(validation_delegate), std::move(reset_on_load_observer)); | |
193 } | |
OLD | NEW |