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 4f6f6d6754beddc52616934a6156f4cf9dd425fb..afe2dd10c3c372550df362658d2fde9e848accad 100644 |
--- a/chrome/browser/prefs/pref_hash_store_impl.cc |
+++ b/chrome/browser/prefs/pref_hash_store_impl.cc |
@@ -10,29 +10,13 @@ |
#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: |
// Constructs a PrefHashStoreTransactionImpl which can use the private |
// members of its |outer| PrefHashStoreImpl. |
- explicit PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer); |
+ PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer, |
+ scoped_ptr<HashStoreContents> storage); |
virtual ~PrefHashStoreTransactionImpl(); |
// PrefHashStoreTransaction implementation. |
@@ -47,86 +31,110 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl |
virtual void StoreSplitHash( |
const std::string& path, |
const base::DictionaryValue* split_value) OVERRIDE; |
+ virtual bool HasHash(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 IsSuperMACValid() const OVERRIDE; |
+ virtual bool StampSuperMac() OVERRIDE; |
private: |
bool GetSplitMacs(const std::string& path, |
std::map<std::string, std::string>* split_macs) const; |
+ |
+ HashStoreContents* contents() { |
+ return outer_->legacy_hash_store_contents_ |
+ ? outer_->legacy_hash_store_contents_.get() |
+ : contents_.get(); |
+ } |
+ |
+ const HashStoreContents* contents() const { |
+ return outer_->legacy_hash_store_contents_ |
+ ? outer_->legacy_hash_store_contents_.get() |
+ : contents_.get(); |
+ } |
+ |
PrefHashStoreImpl* outer_; |
- bool has_changed_; |
+ scoped_ptr<HashStoreContents> contents_; |
+ |
+ bool super_mac_valid_; |
+ bool super_mac_dirty_; |
DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl); |
}; |
PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed, |
const std::string& device_id, |
- scoped_ptr<HashStoreContents> contents, |
bool use_super_mac) |
: pref_hash_calculator_(seed, device_id), |
- contents_(contents.Pass()), |
- initial_hashes_dictionary_trusted_( |
- use_super_mac |
- ? IsHashDictionaryTrusted(pref_hash_calculator_, *contents_) |
- : false), |
- use_super_mac_(use_super_mac), |
- has_pending_write_(false) { |
- DCHECK(contents_); |
- UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted", |
- initial_hashes_dictionary_trusted_); |
+ use_super_mac_(use_super_mac) { |
} |
-PrefHashStoreImpl::~PrefHashStoreImpl() {} |
- |
-void PrefHashStoreImpl::Reset() { |
- contents_->Reset(); |
+PrefHashStoreImpl::~PrefHashStoreImpl() { |
} |
-scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction() { |
- return scoped_ptr<PrefHashStoreTransaction>( |
- new PrefHashStoreTransactionImpl(this)); |
+void PrefHashStoreImpl::set_legacy_hash_store_contents( |
+ scoped_ptr<HashStoreContents> legacy_hash_store_contents) { |
+ legacy_hash_store_contents_ = legacy_hash_store_contents.Pass(); |
} |
-void PrefHashStoreImpl::CommitPendingWrite() { |
- if (has_pending_write_) { |
- contents_->CommitPendingWrite(); |
- has_pending_write_ = false; |
- } |
+scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction( |
+ scoped_ptr<HashStoreContents> storage) { |
+ return scoped_ptr<PrefHashStoreTransaction>( |
+ new PrefHashStoreTransactionImpl(this, storage.Pass())); |
} |
PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl( |
- PrefHashStoreImpl* outer) : outer_(outer), has_changed_(false) { |
+ PrefHashStoreImpl* outer, |
+ scoped_ptr<HashStoreContents> storage) |
+ : outer_(outer), |
+ contents_(storage.Pass()), |
+ super_mac_valid_(false), |
+ super_mac_dirty_(false) { |
+ if (!outer_->use_super_mac_) |
+ return; |
+ |
+ // The store must be initialized and have a valid super MAC to be trusted. |
+ |
+ const base::DictionaryValue* store_contents = contents()->GetContents(); |
+ if (!store_contents) |
+ return; |
+ |
+ std::string super_mac = contents()->GetSuperMac(); |
+ if (super_mac.empty()) |
+ return; |
+ |
+ super_mac_valid_ = |
+ outer_->pref_hash_calculator_.Validate( |
+ contents()->hash_store_id(), store_contents, super_mac) == |
+ PrefHashCalculator::VALID; |
} |
PrefHashStoreImpl::PrefHashStoreTransactionImpl:: |
~PrefHashStoreTransactionImpl() { |
- // Update the super MAC if and only if the hashes dictionary has been |
- // modified in this transaction. |
- if (has_changed_) { |
- if (outer_->use_super_mac_) { |
- // 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; |
+ if (super_mac_dirty_ && outer_->use_super_mac_) { |
+ // Get the dictionary of hashes (or NULL if it doesn't exist). |
+ const base::DictionaryValue* hashes_dict = contents()->GetContents(); |
+ contents()->SetSuperMac(outer_->pref_hash_calculator_.Calculate( |
+ contents()->hash_store_id(), hashes_dict)); |
} |
- |
} |
PrefHashStoreTransaction::ValueState |
PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue( |
- const std::string& path, const base::Value* initial_value) const { |
- const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents(); |
+ const std::string& path, |
+ const base::Value* initial_value) const { |
+ const base::DictionaryValue* hashes_dict = contents()->GetContents(); |
std::string last_hash; |
- if (hashed_prefs) |
- hashed_prefs->GetString(path, &last_hash); |
+ if (hashes_dict) |
+ hashes_dict->GetString(path, &last_hash); |
if (last_hash.empty()) { |
// In the absence of a hash for this pref, always trust a NULL value, but |
// only trust an existing value if the initial hashes dictionary is trusted. |
- return (!initial_value || outer_->initial_hashes_dictionary_trusted_) ? |
- TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE; |
+ return (!initial_value || super_mac_valid_) ? TRUSTED_UNKNOWN_VALUE |
+ : UNTRUSTED_UNKNOWN_VALUE; |
} |
PrefHashCalculator::ValidationResult validation_result = |
@@ -147,11 +155,12 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue( |
} |
void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash( |
- const std::string& path, const base::Value* new_value) { |
+ const std::string& path, |
+ const base::Value* new_value) { |
const std::string mac = |
outer_->pref_hash_calculator_.Calculate(path, new_value); |
- (*outer_->contents_->GetMutableContents())->SetString(path, mac); |
- has_changed_ = true; |
+ (*contents()->GetMutableContents())->SetString(path, mac); |
+ super_mac_dirty_ = true; |
} |
PrefHashStoreTransaction::ValueState |
@@ -171,10 +180,8 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue( |
if (!initial_split_value || initial_split_value->empty()) |
return has_hashes ? CLEARED : UNCHANGED; |
- if (!has_hashes) { |
- return outer_->initial_hashes_dictionary_trusted_ ? |
- TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE; |
- } |
+ if (!has_hashes) |
+ return super_mac_valid_ ? TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE; |
bool has_secure_legacy_id_hashes = false; |
std::string keyed_path(path); |
@@ -226,15 +233,15 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue( |
} |
return invalid_keys->empty() |
- ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED) |
- : CHANGED; |
+ ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED) |
+ : CHANGED; |
} |
void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash( |
const std::string& path, |
const base::DictionaryValue* split_value) { |
scoped_ptr<HashStoreContents::MutableDictionary> mutable_dictionary = |
- outer_->contents_->GetMutableContents(); |
+ contents()->GetMutableContents(); |
(*mutable_dictionary)->Remove(path, NULL); |
if (split_value) { |
@@ -251,7 +258,7 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash( |
outer_->pref_hash_calculator_.Calculate(keyed_path, &it.value())); |
} |
} |
- has_changed_ = true; |
+ super_mac_dirty_ = true; |
} |
bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( |
@@ -260,9 +267,9 @@ bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( |
DCHECK(split_macs); |
DCHECK(split_macs->empty()); |
- const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents(); |
+ const base::DictionaryValue* hashes_dict = contents()->GetContents(); |
const base::DictionaryValue* split_mac_dictionary = NULL; |
- if (!hashed_prefs || !hashed_prefs->GetDictionary(key, &split_mac_dictionary)) |
+ if (!hashes_dict || !hashes_dict->GetDictionary(key, &split_mac_dictionary)) |
return false; |
for (base::DictionaryValue::Iterator it(*split_mac_dictionary); !it.IsAtEnd(); |
it.Advance()) { |
@@ -275,3 +282,39 @@ bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs( |
} |
return true; |
} |
+ |
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::HasHash( |
+ const std::string& path) const { |
+ const base::DictionaryValue* hashes_dict = contents()->GetContents(); |
+ return hashes_dict && hashes_dict->Get(path, NULL); |
+} |
+ |
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash( |
+ const std::string& path, |
+ const base::Value* hash) { |
+ DCHECK(hash); |
+ |
+ (*contents()->GetMutableContents())->Set(path, hash->DeepCopy()); |
+ |
+ if (super_mac_valid_) |
+ super_mac_dirty_ = true; |
+} |
+ |
+void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash( |
+ const std::string& path) { |
+ if ((*contents()->GetMutableContents())->RemovePath(path, NULL) && |
+ super_mac_valid_) { |
+ super_mac_dirty_ = true; |
+ } |
+} |
+ |
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::IsSuperMACValid() const { |
+ return super_mac_valid_; |
+} |
+ |
+bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() { |
+ if (!outer_->use_super_mac_ || super_mac_valid_) |
+ return false; |
+ super_mac_dirty_ = true; |
+ return true; |
+} |