Chromium Code Reviews| Index: chrome/browser/prefs/pref_hash_store_impl.cc |
| diff --git a/chrome/browser/prefs/pref_hash_store_impl.cc b/chrome/browser/prefs/pref_hash_store_impl.cc |
| index 096cbd9470b739d71403d929c9c5a1d745db16de..85eb93ed1a8a430adc7d99aebff5737b55c33be5 100644 |
| --- a/chrome/browser/prefs/pref_hash_store_impl.cc |
| +++ b/chrome/browser/prefs/pref_hash_store_impl.cc |
| @@ -10,23 +10,6 @@ |
| #include "chrome/browser/prefs/pref_hash_store_transaction.h" |
| #include "chrome/browser/prefs/tracked/hash_store_contents.h" |
| -namespace { |
| - |
| -// Returns true if the dictionary of hashes stored in |contents| is trusted |
| -// (which implies unknown values can be trusted as newly tracked values). |
| -bool IsHashDictionaryTrusted(const PrefHashCalculator& calculator, |
| - const HashStoreContents& contents) { |
| - const base::DictionaryValue* store_contents = contents.GetContents(); |
| - std::string super_mac = contents.GetSuperMac(); |
| - // The store must be initialized and have a valid super MAC to be trusted. |
| - return store_contents && !super_mac.empty() && |
| - calculator.Validate(contents.hash_store_id(), |
| - store_contents, |
| - super_mac) == PrefHashCalculator::VALID; |
| -} |
| - |
| -} // namespace |
| - |
| class PrefHashStoreImpl::PrefHashStoreTransactionImpl |
| : public PrefHashStoreTransaction { |
| public: |
| @@ -40,6 +23,12 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl |
| const base::Value* value) const OVERRIDE; |
| virtual void StoreHash(const std::string& path, |
| const base::Value* value) OVERRIDE; |
| + virtual const base::Value* GetHash(const std::string& path) const OVERRIDE; |
| + virtual void ImportHash(const std::string& path, |
| + const base::Value* hash) OVERRIDE; |
| + virtual void ClearHash(const std::string& path) OVERRIDE; |
| + virtual bool StampSuperMac() OVERRIDE; |
| + |
| virtual ValueState CheckSplitValue( |
| const std::string& path, |
| const base::DictionaryValue* initial_split_value, |
| @@ -53,25 +42,41 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl |
| std::map<std::string, std::string>* split_macs) const; |
| PrefHashStoreImpl* outer_; |
| bool has_changed_; |
| + bool super_mac_dirty_; |
| DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl); |
| }; |
| PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed, |
| - const std::string& device_id, |
| - scoped_ptr<HashStoreContents> contents) |
| + const std::string& device_id) |
| : pref_hash_calculator_(seed, device_id), |
| - contents_(contents.Pass()), |
| - initial_hashes_dictionary_trusted_( |
| - IsHashDictionaryTrusted(pref_hash_calculator_, *contents_)), |
| + initial_hashes_dictionary_trusted_(false), |
| has_pending_write_(false) { |
| - DCHECK(contents_); |
| UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted", |
| initial_hashes_dictionary_trusted_); |
|
gab
2014/06/06 21:54:59
This histogram should also move.
erikwright (departed)
2014/06/10 20:27:47
Done.
|
| } |
| PrefHashStoreImpl::~PrefHashStoreImpl() {} |
| +void PrefHashStoreImpl::SetHashStoreContents( |
|
gab
2014/06/06 21:54:59
Call this method Init()? And explicitly state that
|
| + scoped_ptr<HashStoreContents> contents) { |
| + contents_ = contents.Pass(); |
| + |
| + const base::DictionaryValue* store_contents = contents_->GetContents(); |
| + std::string super_mac = contents_->GetSuperMac(); |
| + |
| + // The store must be initialized and have a valid super MAC to be trusted. |
| + initial_hashes_dictionary_trusted_ = |
| + store_contents && !super_mac.empty() && |
| + pref_hash_calculator_.Validate(contents_->hash_store_id(), |
| + store_contents, |
| + super_mac) == PrefHashCalculator::VALID; |
| +} |
| + |
| +bool PrefHashStoreImpl::IsInitialized() const { |
| + return contents_->IsInitialized(); |
| +} |
| + |
| void PrefHashStoreImpl::Reset() { |
| contents_->Reset(); |
| } |
| @@ -81,19 +86,6 @@ scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction() { |
| new PrefHashStoreTransactionImpl(this)); |
| } |
| -PrefHashStoreImpl::StoreVersion PrefHashStoreImpl::GetCurrentVersion() const { |
| - if (!contents_->IsInitialized()) |
| - return VERSION_UNINITIALIZED; |
| - |
| - int current_version; |
| - if (!contents_->GetVersion(¤t_version)) { |
| - return VERSION_PRE_MIGRATION; |
| - } |
| - |
| - DCHECK_GT(current_version, VERSION_PRE_MIGRATION); |
| - return static_cast<StoreVersion>(current_version); |
| -} |
| - |
| void PrefHashStoreImpl::CommitPendingWrite() { |
| if (has_pending_write_) { |
| contents_->CommitPendingWrite(); |
| @@ -102,35 +94,36 @@ void PrefHashStoreImpl::CommitPendingWrite() { |
| } |
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl( |
| - PrefHashStoreImpl* outer) : outer_(outer), has_changed_(false) { |
| + PrefHashStoreImpl* outer) |
| + : outer_(outer), has_changed_(false), super_mac_dirty_(false) { |
| } |
| PrefHashStoreImpl::PrefHashStoreTransactionImpl:: |
| ~PrefHashStoreTransactionImpl() { |
| - // Update the super MAC if and only if the hashes dictionary has been |
| - // modified in this transaction. |
| if (has_changed_) { |
| - // Get the dictionary of hashes (or NULL if it doesn't exist). |
| - const base::DictionaryValue* hashes_dict = outer_->contents_->GetContents(); |
| - outer_->contents_->SetSuperMac(outer_->pref_hash_calculator_.Calculate( |
| - outer_->contents_->hash_store_id(), hashes_dict)); |
| + // Update the super MAC if and only if the hashes dictionary has been |
| + // modified in this transaction. Imports do not necessarily affect the super |
| + // MAC (will not transition it from invalid to valid). |
| + if (super_mac_dirty_) { |
| + // Get the dictionary of hashes (or NULL if it doesn't exist). |
| + const base::DictionaryValue* hashes_dict = |
| + outer_->contents_->GetContents(); |
| + outer_->contents_->SetSuperMac(outer_->pref_hash_calculator_.Calculate( |
| + outer_->contents_->hash_store_id(), hashes_dict)); |
| + } |
| outer_->has_pending_write_ = true; |
| } |
| +} |
| - // Mark this hash store has having been updated to the latest version (in |
| - // practice only initialization transactions will actually do this, but |
| - // since they always occur before minor update transaction it's okay |
| - // to unconditionally do this here). Only do this if this store's version |
| - // isn't already at VERSION_LATEST (to avoid scheduling a write when |
| - // unecessary). Note, this is outside of |if (has_changed)| to also seed |
| - // version number of otherwise unchanged profiles. |
| - int current_version; |
| - if (!outer_->contents_->GetVersion(¤t_version) || |
| - current_version != VERSION_LATEST) { |
| - outer_->contents_->SetVersion(VERSION_LATEST); |
| - outer_->has_pending_write_ = true; |
| - } |
| +const base::Value* PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetHash( |
| + const std::string& path) const { |
| + const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents(); |
| + |
| + const base::Value* last_hash = NULL; |
| + if (hashed_prefs) |
| + hashed_prefs->Get(path, &last_hash); |
| + return last_hash; |
| } |
| PrefHashStoreTransaction::ValueState |
| @@ -172,6 +165,35 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash( |
| outer_->pref_hash_calculator_.Calculate(path, new_value); |
| (*outer_->contents_->GetMutableContents())->SetString(path, mac); |
| has_changed_ = true; |
| + super_mac_dirty_ = true; |
| +} |
| + |
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash( |
| + const std::string& path, |
| + const base::Value* hash) { |
|
gab
2014/06/06 21:54:59
I think |hash| should be passed as a std::string.
erikwright (departed)
2014/06/09 18:34:50
That requires separate pairs of methods for atomic
gab
2014/06/09 20:24:33
Duh, of course, passing it via a Value object is f
erikwright (departed)
2014/06/10 20:27:47
I thought about that, but it's consistent with Sto
|
| + if (!hash) |
| + (*outer_->contents_->GetMutableContents())->RemovePath(path, NULL); |
| + else |
| + (*outer_->contents_->GetMutableContents())->Set(path, hash->DeepCopy()); |
| + has_changed_ = true; |
| + super_mac_dirty_ = |
| + super_mac_dirty_ || outer_->initial_hashes_dictionary_trusted_; |
|
gab
2014/06/06 21:54:59
It's incorrect to re-write the super MAC here if t
erikwright (departed)
2014/06/09 18:34:50
We talked about this offline. It's correct to keep
|
| +} |
| + |
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash( |
| + const std::string& path) { |
| + (*outer_->contents_->GetMutableContents())->RemovePath(path, NULL); |
| + has_changed_ = true; |
| + super_mac_dirty_ = |
| + super_mac_dirty_ || outer_->initial_hashes_dictionary_trusted_; |
| +} |
| + |
| +bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() { |
| + if (outer_->initial_hashes_dictionary_trusted_) |
| + return false; |
| + has_changed_ = true; |
| + super_mac_dirty_ = true; |
| + return true; |
| } |
| PrefHashStoreTransaction::ValueState |
| @@ -272,6 +294,7 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash( |
| } |
| } |
| has_changed_ = true; |
| + super_mac_dirty_ = true; |
| } |
| bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( |