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