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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/prefs/json_pref_store.h" | 12 #include "base/prefs/json_pref_store.h" |
13 #include "base/prefs/persistent_pref_store.h" | 13 #include "base/prefs/persistent_pref_store.h" |
14 #include "base/prefs/pref_registry_simple.h" | 14 #include "base/prefs/pref_registry_simple.h" |
15 #include "chrome/browser/prefs/pref_hash_store_impl.h" | 15 #include "chrome/browser/prefs/pref_hash_store_impl.h" |
16 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h" | 16 #include "chrome/browser/prefs/tracked/pref_service_hash_store_contents.h" |
17 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" | 17 #include "chrome/browser/prefs/tracked/segregated_pref_store.h" |
18 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h" | 18 #include "chrome/browser/prefs/tracked/tracked_preferences_migration.h" |
19 #include "chrome/common/chrome_constants.h" | 19 #include "chrome/common/chrome_constants.h" |
20 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
21 #include "components/pref_registry/pref_registry_syncable.h" | 21 #include "components/pref_registry/pref_registry_syncable.h" |
22 | 22 |
23 namespace { | |
24 | |
25 // An in-memory PrefStore backed by an immutable DictionaryValue. | |
26 class DictionaryPrefStore : public PrefStore { | |
27 public: | |
28 explicit DictionaryPrefStore(const base::DictionaryValue* dictionary) | |
29 : dictionary_(dictionary) {} | |
30 | |
31 virtual bool GetValue(const std::string& key, | |
32 const base::Value** result) const OVERRIDE { | |
33 const base::Value* tmp = NULL; | |
34 if (!dictionary_->Get(key, &tmp)) | |
35 return false; | |
36 | |
37 if (result) | |
38 *result = tmp; | |
39 return true; | |
40 } | |
41 | |
42 private: | |
43 virtual ~DictionaryPrefStore() {} | |
44 | |
45 const base::DictionaryValue* dictionary_; | |
46 | |
47 DISALLOW_COPY_AND_ASSIGN(DictionaryPrefStore); | |
48 }; | |
49 | |
50 } // namespace | |
51 | |
52 // TODO(erikwright): Enable this on Chrome OS and Android once MACs are moved | 23 // TODO(erikwright): Enable this on Chrome OS and Android once MACs are moved |
53 // out of Local State. This will resolve a race condition on Android and a | 24 // out of Local State. This will resolve a race condition on Android and a |
54 // privacy issue on ChromeOS. http://crbug.com/349158 | 25 // privacy issue on ChromeOS. http://crbug.com/349158 |
55 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = | 26 const bool ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking = |
56 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 27 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
57 false; | 28 false; |
58 #else | 29 #else |
59 true; | 30 true; |
60 #endif | 31 #endif |
61 | 32 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 if (it->enforcement_level > PrefHashFilter::NO_ENFORCEMENT) { | 102 if (it->enforcement_level > PrefHashFilter::NO_ENFORCEMENT) { |
132 protected_configuration.push_back(*it); | 103 protected_configuration.push_back(*it); |
133 protected_pref_names.insert(it->name); | 104 protected_pref_names.insert(it->name); |
134 } else { | 105 } else { |
135 unprotected_configuration.push_back(*it); | 106 unprotected_configuration.push_back(*it); |
136 unprotected_pref_names.insert(it->name); | 107 unprotected_pref_names.insert(it->name); |
137 } | 108 } |
138 } | 109 } |
139 | 110 |
140 scoped_ptr<PrefHashFilter> unprotected_pref_hash_filter( | 111 scoped_ptr<PrefHashFilter> unprotected_pref_hash_filter( |
141 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 112 new PrefHashFilter(GetPrefHashStore(false), |
142 unprotected_configuration, | 113 unprotected_configuration, |
143 validation_delegate, | 114 validation_delegate, |
144 reporting_ids_count_)); | 115 reporting_ids_count_, |
| 116 false)); |
145 scoped_ptr<PrefHashFilter> protected_pref_hash_filter( | 117 scoped_ptr<PrefHashFilter> protected_pref_hash_filter( |
146 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 118 new PrefHashFilter(GetPrefHashStore(true), |
147 protected_configuration, | 119 protected_configuration, |
148 validation_delegate, | 120 validation_delegate, |
149 reporting_ids_count_)); | 121 reporting_ids_count_, |
| 122 true)); |
150 | 123 |
151 PrefHashFilter* raw_unprotected_pref_hash_filter = | 124 PrefHashFilter* raw_unprotected_pref_hash_filter = |
152 unprotected_pref_hash_filter.get(); | 125 unprotected_pref_hash_filter.get(); |
153 PrefHashFilter* raw_protected_pref_hash_filter = | 126 PrefHashFilter* raw_protected_pref_hash_filter = |
154 protected_pref_hash_filter.get(); | 127 protected_pref_hash_filter.get(); |
155 | 128 |
156 scoped_refptr<JsonPrefStore> unprotected_pref_store( | 129 scoped_refptr<JsonPrefStore> unprotected_pref_store( |
157 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), | 130 new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), |
158 io_task_runner, | 131 io_task_runner, |
159 unprotected_pref_hash_filter.PassAs<PrefFilter>())); | 132 unprotected_pref_hash_filter.PassAs<PrefFilter>())); |
160 scoped_refptr<JsonPrefStore> protected_pref_store(new JsonPrefStore( | 133 scoped_refptr<JsonPrefStore> protected_pref_store(new JsonPrefStore( |
161 profile_path_.Append(chrome::kProtectedPreferencesFilename), | 134 profile_path_.Append(chrome::kProtectedPreferencesFilename), |
162 io_task_runner, | 135 io_task_runner, |
163 protected_pref_hash_filter.PassAs<PrefFilter>())); | 136 protected_pref_hash_filter.PassAs<PrefFilter>())); |
164 | 137 |
165 SetupTrackedPreferencesMigration( | 138 SetupTrackedPreferencesMigration( |
166 unprotected_pref_names, | 139 unprotected_pref_names, |
167 protected_pref_names, | 140 protected_pref_names, |
168 base::Bind(&JsonPrefStore::RemoveValueSilently, | 141 base::Bind(&JsonPrefStore::RemoveValueSilently, |
169 unprotected_pref_store->AsWeakPtr()), | 142 unprotected_pref_store->AsWeakPtr()), |
170 base::Bind(&JsonPrefStore::RemoveValueSilently, | 143 base::Bind(&JsonPrefStore::RemoveValueSilently, |
171 protected_pref_store->AsWeakPtr()), | 144 protected_pref_store->AsWeakPtr()), |
172 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback, | 145 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback, |
173 unprotected_pref_store->AsWeakPtr()), | 146 unprotected_pref_store->AsWeakPtr()), |
174 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback, | 147 base::Bind(&JsonPrefStore::RegisterOnNextSuccessfulWriteCallback, |
175 protected_pref_store->AsWeakPtr()), | 148 protected_pref_store->AsWeakPtr()), |
| 149 GetPrefHashStore(false), |
| 150 GetPrefHashStore(true), |
| 151 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents( |
| 152 profile_path_.AsUTF8Unsafe(), local_state_)), |
176 raw_unprotected_pref_hash_filter, | 153 raw_unprotected_pref_hash_filter, |
177 raw_protected_pref_hash_filter); | 154 raw_protected_pref_hash_filter); |
178 | 155 |
179 return new SegregatedPrefStore(unprotected_pref_store, protected_pref_store, | 156 return new SegregatedPrefStore(unprotected_pref_store, protected_pref_store, |
180 protected_pref_names); | 157 protected_pref_names); |
181 } | 158 } |
182 | 159 |
183 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs( | 160 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs( |
184 const base::DictionaryValue& master_prefs) { | 161 const base::DictionaryValue& master_prefs) { |
185 // Create the profile directory if it doesn't exist yet (very possible on | 162 // Create the profile directory if it doesn't exist yet (very possible on |
186 // first run). | 163 // first run). |
187 if (!base::CreateDirectory(profile_path_)) | 164 if (!base::CreateDirectory(profile_path_)) |
188 return false; | 165 return false; |
189 | 166 |
| 167 const base::DictionaryValue* to_serialize = &master_prefs; |
| 168 scoped_ptr<base::DictionaryValue> copy; |
| 169 |
| 170 if (kPlatformSupportsPreferenceTracking) { |
| 171 copy.reset(master_prefs.DeepCopy()); |
| 172 to_serialize = copy.get(); |
| 173 PrefHashFilter(GetPrefHashStore(false), |
| 174 tracking_configuration_, |
| 175 NULL, |
| 176 reporting_ids_count_, |
| 177 false).Initialize(copy.get()); |
| 178 } |
| 179 |
190 // This will write out to a single combined file which will be immediately | 180 // This will write out to a single combined file which will be immediately |
191 // migrated to two files on load. | 181 // migrated to two files on load. |
192 JSONFileValueSerializer serializer( | 182 JSONFileValueSerializer serializer( |
193 GetPrefFilePathFromProfilePath(profile_path_)); | 183 GetPrefFilePathFromProfilePath(profile_path_)); |
194 | 184 |
195 // Call Serialize (which does IO) on the main thread, which would _normally_ | 185 // Call Serialize (which does IO) on the main thread, which would _normally_ |
196 // be verboten. In this case however, we require this IO to synchronously | 186 // be verboten. In this case however, we require this IO to synchronously |
197 // complete before Chrome can start (as master preferences seed the Local | 187 // complete before Chrome can start (as master preferences seed the Local |
198 // State and Preferences files). This won't trip ThreadIORestrictions as they | 188 // State and Preferences files). This won't trip ThreadIORestrictions as they |
199 // won't have kicked in yet on the main thread. | 189 // won't have kicked in yet on the main thread. |
200 bool success = serializer.Serialize(master_prefs); | 190 bool success = serializer.Serialize(*to_serialize); |
201 | |
202 if (success && kPlatformSupportsPreferenceTracking) { | |
203 scoped_refptr<const PrefStore> pref_store( | |
204 new DictionaryPrefStore(&master_prefs)); | |
205 PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | |
206 tracking_configuration_, | |
207 NULL, | |
208 reporting_ids_count_).Initialize(*pref_store); | |
209 } | |
210 | 191 |
211 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); | 192 UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success); |
212 return success; | 193 return success; |
213 } | 194 } |
214 | 195 |
215 PersistentPrefStore* | 196 PersistentPrefStore* |
216 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore( | 197 ProfilePrefStoreManager::CreateDeprecatedCombinedProfilePrefStore( |
217 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { | 198 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { |
218 scoped_ptr<PrefFilter> pref_filter; | 199 scoped_ptr<PrefFilter> pref_filter; |
219 if (kPlatformSupportsPreferenceTracking) { | 200 if (kPlatformSupportsPreferenceTracking) { |
| 201 scoped_ptr<PrefHashStoreImpl> pref_hash_store_impl( |
| 202 new PrefHashStoreImpl(seed_, device_id_, true)); |
| 203 pref_hash_store_impl->set_legacy_hash_store_contents( |
| 204 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents( |
| 205 profile_path_.AsUTF8Unsafe(), local_state_))); |
220 pref_filter.reset( | 206 pref_filter.reset( |
221 new PrefHashFilter(GetPrefHashStoreImpl().PassAs<PrefHashStore>(), | 207 new PrefHashFilter(pref_hash_store_impl.PassAs<PrefHashStore>(), |
222 tracking_configuration_, | 208 tracking_configuration_, |
223 NULL, | 209 NULL, |
224 reporting_ids_count_)); | 210 reporting_ids_count_, |
| 211 false)); |
225 } | 212 } |
226 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), | 213 return new JsonPrefStore(GetPrefFilePathFromProfilePath(profile_path_), |
227 io_task_runner, | 214 io_task_runner, |
228 pref_filter.Pass()); | 215 pref_filter.Pass()); |
229 } | 216 } |
230 | 217 |
231 scoped_ptr<PrefHashStoreImpl> ProfilePrefStoreManager::GetPrefHashStoreImpl() { | 218 scoped_ptr<PrefHashStore> ProfilePrefStoreManager::GetPrefHashStore( |
| 219 bool use_super_mac) { |
232 DCHECK(kPlatformSupportsPreferenceTracking); | 220 DCHECK(kPlatformSupportsPreferenceTracking); |
233 | 221 |
234 return make_scoped_ptr(new PrefHashStoreImpl( | 222 return scoped_ptr<PrefHashStore>(new PrefHashStoreImpl( |
235 seed_, | 223 seed_, |
236 device_id_, | 224 device_id_, |
237 scoped_ptr<HashStoreContents>(new PrefServiceHashStoreContents( | 225 use_super_mac)); |
238 profile_path_.AsUTF8Unsafe(), local_state_)), | |
239 true)); | |
240 } | 226 } |
OLD | NEW |