Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 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/pref_hash_store_impl.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/prefs/pref_service.h" | |
| 9 #include "base/prefs/scoped_user_pref_update.h" | |
| 10 #include "base/values.h" | |
| 11 #include "chrome/browser/prefs/pref_hash_tracker.h" | |
| 12 #include "chrome/common/pref_names.h" | |
| 13 | |
| 14 // Implements PrefHashTracker by storing hashes in a PrefService. | |
| 15 class PrefHashStoreImpl::PrefHashTrackerImpl : public PrefHashTracker { | |
| 16 public: | |
| 17 // Constructs a PrefHashTrackerImpl that calculates hashes of preference | |
| 18 // values using |pref_hash_calculator| and stores them in |local_state|. | |
| 19 // Multiple hash trackers can use the same |local_state| with distinct | |
| 20 // |hash_store_id|s. | |
| 21 // | |
| 22 // Values are stored at kProfilePreferenceHashes / |hash_store_id| / path, | |
|
robertshield
2013/11/28 02:54:26
nit: should this be prefs::kProfilePreferenceHashe
| |
| 23 // where path is the full path of the tracked preference. | |
| 24 // |hash_store_id| is not expanded but path and kProfilePreferenceHashes | |
|
robertshield
2013/11/28 02:54:26
please elaborate slightly on what "expanded" means
| |
| 25 // are. | |
| 26 PrefHashTrackerImpl(PrefService* local_state, | |
| 27 const std::string& hash_store_id, | |
| 28 const PrefHashCalculator& pref_hash_calculator); | |
| 29 | |
| 30 // Adds |path| to the set of preferences for which hashes will be stored. | |
| 31 void Track(const std::string& path); | |
| 32 | |
| 33 // Updates the stored hash for |path|, if |path| has been configured for | |
|
gab
2013/11/27 23:43:27
I think this sentence flows better without the com
| |
| 34 // tracking by calling |Track|. |new_value| may be NULL if there is no value | |
| 35 // |path|. | |
|
gab
2013/11/27 23:43:27
"no value *at* |path|?"
| |
| 36 virtual void OnPrefValueChanged(const std::string& path, | |
| 37 const base::Value* new_value) OVERRIDE; | |
| 38 | |
| 39 private: | |
| 40 std::set<std::string> tracked_paths_; | |
| 41 PrefService* local_state_; | |
| 42 std::string hash_store_id_; | |
| 43 PrefHashCalculator pref_hash_calculator_; | |
| 44 | |
| 45 DISALLOW_COPY_AND_ASSIGN(PrefHashTrackerImpl); | |
| 46 }; | |
| 47 | |
| 48 PrefHashStoreImpl::PrefHashTrackerImpl::PrefHashTrackerImpl( | |
| 49 PrefService* local_state, | |
| 50 const std::string& hash_store_id, | |
| 51 const PrefHashCalculator& pref_hash_calculator) | |
| 52 : local_state_(local_state), | |
| 53 hash_store_id_(hash_store_id), | |
| 54 pref_hash_calculator_(pref_hash_calculator) {} | |
| 55 | |
| 56 void PrefHashStoreImpl::PrefHashTrackerImpl::Track(const std::string& path) { | |
| 57 tracked_paths_.insert(path); | |
|
gab
2013/11/27 23:43:27
Why not use the PrefChangeRegistrar for this? Is i
erikwright (departed)
2013/11/28 17:48:07
We're dealing with a PrefStore, not a PrefService.
| |
| 58 } | |
| 59 | |
| 60 void PrefHashStoreImpl::PrefHashTrackerImpl::OnPrefValueChanged( | |
| 61 const std::string& path, const base::Value* new_value) { | |
| 62 if (tracked_paths_.find(path) == tracked_paths_.end()) | |
| 63 return; | |
| 64 | |
| 65 DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes); | |
| 66 DictionaryValue* child_dictionary = NULL; | |
| 67 | |
| 68 // Get the dictionary corresponding to the profile name, | |
|
gab
2013/11/27 23:43:27
s/profile name/hash store id
| |
| 69 // which may have a '.' | |
| 70 if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_, | |
| 71 &child_dictionary)) { | |
| 72 child_dictionary = new DictionaryValue; | |
| 73 update->SetWithoutPathExpansion(hash_store_id_, child_dictionary); | |
| 74 } | |
| 75 | |
| 76 child_dictionary->SetString( | |
| 77 path, pref_hash_calculator_.Calculate(path, new_value)); | |
| 78 } | |
| 79 | |
| 80 PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed, | |
| 81 PrefService* local_state, | |
| 82 const std::string& hash_store_id) | |
| 83 : local_state_(local_state), | |
| 84 hash_store_id_(hash_store_id), | |
| 85 pref_hash_calculator_(seed), | |
| 86 pref_hash_tracker_(new PrefHashTrackerImpl( | |
| 87 local_state_, hash_store_id, pref_hash_calculator_)) {} | |
| 88 | |
| 89 PrefHashStore::InitializationResult PrefHashStoreImpl::InitializeTrackedValue( | |
| 90 const std::string& path, const base::Value* initial_value) { | |
| 91 DCHECK(pref_hash_tracker_.get()); | |
| 92 if (!pref_hash_tracker_.get()) | |
|
gab
2013/11/27 23:43:27
Why handle this case with silent success? The cont
| |
| 93 return PrefHashStore::UNCHANGED; | |
| 94 | |
| 95 pref_hash_tracker_->Track(path); | |
| 96 | |
| 97 const base::DictionaryValue* pref_hash_dicts = | |
| 98 local_state_->GetDictionary(prefs::kProfilePreferenceHashes); | |
| 99 const base::DictionaryValue* hashed_prefs = NULL; | |
| 100 pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_, | |
| 101 &hashed_prefs); | |
| 102 | |
| 103 std::string last_hash; | |
| 104 // First try to get the stored expected hash... | |
| 105 if (hashed_prefs && hashed_prefs->GetString(path, &last_hash)) { | |
| 106 PrefHashCalculator::ValidationResult validation_result = | |
| 107 pref_hash_calculator_.Validate(path, initial_value, last_hash); | |
| 108 if (validation_result == PrefHashCalculator::VALID) | |
| 109 return PrefHashStore::UNCHANGED; | |
| 110 | |
| 111 // No matter what the reason for the mismatch, we will correct it now. | |
| 112 pref_hash_tracker_->OnPrefValueChanged(path, initial_value); | |
| 113 | |
| 114 switch(validation_result) { | |
| 115 case PrefHashCalculator::VALID_LEGACY: | |
| 116 return PrefHashStore::MIGRATED; | |
| 117 case PrefHashCalculator::INVALID: | |
| 118 return initial_value ? PrefHashStore::CHANGED : PrefHashStore::CLEARED; | |
| 119 default: | |
| 120 NOTREACHED() << "Unexpected PrefHashCalculator::ValidationResult: " | |
| 121 << validation_result; | |
| 122 return PrefHashStore::INITIALIZED; | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 // We haven't tracked this preference yet, or the hash in local state was | |
| 127 // removed. | |
| 128 pref_hash_tracker_->OnPrefValueChanged(path, initial_value); | |
| 129 return PrefHashStore::INITIALIZED; | |
| 130 } | |
| 131 | |
| 132 scoped_ptr<PrefHashTracker> PrefHashStoreImpl::CompleteInitialization() { | |
| 133 return pref_hash_tracker_.Pass(); | |
| 134 } | |
| OLD | NEW |