Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: chrome/browser/prefs/pref_hash_store_impl.cc

Issue 114223002: Multi-strategy based tracking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge up to r248367 Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/prefs/pref_hash_store_impl.h ('k') | chrome/browser/prefs/pref_hash_store_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 f4fb145c4e30da3410c32a563e54298dadb23868..205102cecc4a70c3fd6667aa700a73fd7f83f714 100644
--- a/chrome/browser/prefs/pref_hash_store_impl.cc
+++ b/chrome/browser/prefs/pref_hash_store_impl.cc
@@ -8,7 +8,6 @@
#include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
-#include "base/prefs/scoped_user_pref_update.h"
#include "base/values.h"
#include "chrome/common/pref_names.h"
@@ -80,26 +79,135 @@ PrefHashStore::ValueState PrefHashStoreImpl::CheckValue(
void PrefHashStoreImpl::StoreHash(
const std::string& path, const base::Value* new_value) {
DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes);
+ StoreHashInternal(path, new_value, &update);
+}
- // Get the dictionary corresponding to the profile name, which may have a
- // '.'
+PrefHashStore::ValueState PrefHashStoreImpl::CheckSplitValue(
+ const std::string& path,
+ const base::DictionaryValue* initial_split_value,
+ std::vector<std::string>* invalid_keys) const {
+ DCHECK(invalid_keys && invalid_keys->empty());
+
+ const bool has_hashes = HasSplitHashesAtPath(path);
+
+ // Treat NULL and empty the same; otherwise we would need to store a hash
+ // for the entire dictionary (or some other special beacon) to
+ // differentiate these two cases which are really the same for
+ // dictionaries.
+ if (!initial_split_value || initial_split_value->empty())
+ return has_hashes ? CLEARED : UNCHANGED;
+
+ if (!has_hashes) {
+ return initial_hashes_dictionary_trusted_ ?
+ TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
+ }
+
+ std::string keyed_path(path);
+ keyed_path.push_back('.');
+ const size_t common_part_length = keyed_path.length();
+ for (base::DictionaryValue::Iterator it(*initial_split_value); !it.IsAtEnd();
+ it.Advance()) {
+ // Keep the common part from the old |keyed_path| and replace the key to
+ // get the new |keyed_path|.
+ keyed_path.replace(common_part_length, std::string::npos, it.key());
+ ValueState value_state = CheckValue(keyed_path, &it.value());
+ switch (value_state) {
+ case CLEARED:
+ // CLEARED doesn't make sense as a NULL value would never be sampled
+ // by the DictionaryValue::Iterator; in fact it is a known weakness of
+ // this current algorithm to not detect the case where a single key is
+ // cleared entirely from the dictionary pref.
+ NOTREACHED();
+ break;
+ case MIGRATED:
+ // Split tracked preferences were introduced after the migration started
+ // so no migration is expected, but declare it invalid in Release builds
+ // anyways.
+ NOTREACHED();
+ invalid_keys->push_back(it.key());
+ break;
+ case UNCHANGED:
+ break;
+ case CHANGED: // Falls through.
+ case UNTRUSTED_UNKNOWN_VALUE: // Falls through.
+ case TRUSTED_UNKNOWN_VALUE:
+ // Declare this value invalid, whether it was changed or never seen
+ // before (note that the initial hashes being trusted is irrelevant for
+ // individual entries in this scenario).
+ invalid_keys->push_back(it.key());
+ break;
+ }
+ }
+ return invalid_keys->empty() ? UNCHANGED : CHANGED;
+}
+
+void PrefHashStoreImpl::StoreSplitHash(
+ const std::string& path,
+ const base::DictionaryValue* split_value) {
+ DictionaryPrefUpdate update(local_state_, prefs::kProfilePreferenceHashes);
+ ClearPath(path, &update);
+
+ if (split_value) {
+ std::string keyed_path(path);
+ keyed_path.push_back('.');
+ const size_t common_part_length = keyed_path.length();
+ for (base::DictionaryValue::Iterator it(*split_value); !it.IsAtEnd();
+ it.Advance()) {
+ // Keep the common part from the old |keyed_path| and replace the key to
+ // get the new |keyed_path|.
+ keyed_path.replace(common_part_length, std::string::npos, it.key());
+ StoreHashInternal(keyed_path, &it.value(), &update);
+ }
+ }
+}
+
+void PrefHashStoreImpl::ClearPath(const std::string& path,
+ DictionaryPrefUpdate* update) {
base::DictionaryValue* hashes_dict = NULL;
- if (!update->GetDictionaryWithoutPathExpansion(hash_store_id_,
- &hashes_dict)) {
- hashes_dict = new base::DictionaryValue;
- update->SetWithoutPathExpansion(hash_store_id_, hashes_dict);
+ if (update->Get()->GetDictionaryWithoutPathExpansion(hash_store_id_,
+ &hashes_dict)) {
+ hashes_dict->Remove(path, NULL);
}
+ UpdateHashOfHashes(hashes_dict, update);
+}
+
+bool PrefHashStoreImpl::HasSplitHashesAtPath(const std::string& path) const {
+ const base::DictionaryValue* pref_hash_dicts =
+ local_state_->GetDictionary(prefs::kProfilePreferenceHashes);
+ const base::DictionaryValue* hashed_prefs = NULL;
+ pref_hash_dicts->GetDictionaryWithoutPathExpansion(hash_store_id_,
+ &hashed_prefs);
+ return hashed_prefs && hashed_prefs->GetDictionary(path, NULL);
+}
+void PrefHashStoreImpl::StoreHashInternal(const std::string& path,
+ const base::Value* new_value,
+ DictionaryPrefUpdate* update) {
+ base::DictionaryValue* hashes_dict = NULL;
+
+ // Get the dictionary corresponding to the profile name, which may have a '.'
+ if (!update->Get()->GetDictionaryWithoutPathExpansion(hash_store_id_,
+ &hashes_dict)) {
+ hashes_dict = new base::DictionaryValue;
+ update->Get()->SetWithoutPathExpansion(hash_store_id_, hashes_dict);
+ }
hashes_dict->SetString(
path, pref_hash_calculator_.Calculate(path, new_value));
+ UpdateHashOfHashes(hashes_dict, update);
+}
+
+void PrefHashStoreImpl::UpdateHashOfHashes(
+ const base::DictionaryValue* hashes_dict,
+ DictionaryPrefUpdate* update) {
+
// Get the dictionary where the hash of hashes are stored.
base::DictionaryValue* hash_of_hashes_dict = NULL;
- if (!update->GetDictionaryWithoutPathExpansion(internals::kHashOfHashesPref,
- &hash_of_hashes_dict)) {
+ if (!update->Get()->GetDictionaryWithoutPathExpansion(
+ internals::kHashOfHashesPref, &hash_of_hashes_dict)) {
hash_of_hashes_dict = new base::DictionaryValue;
- update->SetWithoutPathExpansion(internals::kHashOfHashesPref,
- hash_of_hashes_dict);
+ update->Get()->SetWithoutPathExpansion(internals::kHashOfHashesPref,
+ hash_of_hashes_dict);
}
// Use the |hash_store_id_| as the hashed path to avoid having the hash
// depend on kProfilePreferenceHashes.
« no previous file with comments | « chrome/browser/prefs/pref_hash_store_impl.h ('k') | chrome/browser/prefs/pref_hash_store_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698