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

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

Issue 114223002: Multi-strategy based tracking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years 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
Index: chrome/browser/prefs/pref_hash_filter.cc
diff --git a/chrome/browser/prefs/pref_hash_filter.cc b/chrome/browser/prefs/pref_hash_filter.cc
index d50d66c0e550ad3b6cb8f73994592d1b09a321e6..8376b0359e2a9dd2d470bc9383d34a3f7a59b2a7 100644
--- a/chrome/browser/prefs/pref_hash_filter.cc
+++ b/chrome/browser/prefs/pref_hash_filter.cc
@@ -7,90 +7,179 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/values.h"
-#include "chrome/browser/prefs/pref_hash_store.h"
#include "chrome/common/pref_names.h"
namespace {
-// These preferences must be kept in sync with the TrackedPreference enum in
-// tools/metrics/histograms/histograms.xml. To add a new preference, append it
-// to the array and add a corresponding value to the histogram enum. Replace
-// removed preferences with "".
-const char* kTrackedPrefs[] = {
- prefs::kShowHomeButton,
- prefs::kHomePageIsNewTabPage,
- prefs::kHomePage,
- prefs::kRestoreOnStartup,
- prefs::kURLsToRestoreOnStartup,
- prefs::kExtensionsPref,
- prefs::kGoogleServicesLastUsername,
- prefs::kSearchProviderOverrides,
- prefs::kDefaultSearchProviderSearchURL,
- prefs::kDefaultSearchProviderKeyword,
- prefs::kDefaultSearchProviderName,
-#if !defined(OS_ANDROID)
- prefs::kPinnedTabs,
-#else
- "",
-#endif
- prefs::kExtensionKnownDisabled,
- prefs::kProfileResetPromptMemento,
-};
-
void ReportValidationResult(PrefHashStore::ValueState value_state,
- size_t value_index) {
+ size_t value_index,
+ size_t num_values) {
switch (value_state) {
case PrefHashStore::UNCHANGED:
UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceUnchanged",
- value_index, arraysize(kTrackedPrefs));
+ value_index, num_values);
return;
case PrefHashStore::CLEARED:
UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceCleared",
- value_index, arraysize(kTrackedPrefs));
+ value_index, num_values);
return;
case PrefHashStore::MIGRATED:
UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceMigrated",
- value_index, arraysize(kTrackedPrefs));
+ value_index, num_values);
return;
case PrefHashStore::CHANGED:
UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceChanged",
- value_index, arraysize(kTrackedPrefs));
+ value_index, num_values);
return;
case PrefHashStore::UNKNOWN_VALUE:
UMA_HISTOGRAM_ENUMERATION("Settings.TrackedPreferenceInitialized",
- value_index, arraysize(kTrackedPrefs));
+ value_index, num_values);
return;
}
NOTREACHED() << "Unexpected PrefHashStore::ValueState: " << value_state;
}
+void ReportSplitPreferenceChangedCount(const std::string& path, size_t count) {
+ // Handle each known split preference explicitly as UMA macros result in
+ // static blocks which aren't compatible with dynamically generated names.
+ if (path == prefs::kExtensionsPref) {
+ UMA_HISTOGRAM_COUNTS_100(
+ "Settings.TrackedSplitPreferenceChangedCount.kExtensionsPref",
+ count);
+ return;
+ }
+ // All split preferences need to be handled above.
+ NOTREACHED();
+}
+
} // namespace
PrefHashFilter::PrefHashFilter(scoped_ptr<PrefHashStore> pref_hash_store)
- : pref_hash_store_(pref_hash_store.Pass()),
- tracked_paths_(kTrackedPrefs, kTrackedPrefs + arraysize(kTrackedPrefs)) {}
+ : pref_hash_store_(pref_hash_store.Pass()) {
+ // These preferences must be kept in sync with the TrackedPreference enum in
+ // tools/metrics/histograms/histograms.xml. To add a new preference, append it
+ // to the array and add a corresponding value to the histogram enum. New split
+ // preferences must also be added to ReportSplitPreferenceChangedCount above.
+ // The index of each tracked preference must not change; replace removed
+ // preferences' strategies with TRACKING_STRATEGY_NONE rather than removing
+ // them.
+ static const TrackedPreference kTrackedPrefs[] = {
+ { prefs::kShowHomeButton, TRACKING_STRATEGY_ATOMIC },
erikwright (departed) 2013/12/17 02:22:50 Suggestion: Make the 'reporting id' a member of th
gab 2013/12/17 18:08:05 I also considered this, I don't like that it adds
+ { prefs::kHomePageIsNewTabPage, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kHomePage, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kRestoreOnStartup, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kURLsToRestoreOnStartup, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kExtensionsPref, TRACKING_STRATEGY_SPLIT },
+ { prefs::kGoogleServicesLastUsername, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kSearchProviderOverrides, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kDefaultSearchProviderSearchURL, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kDefaultSearchProviderKeyword, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kDefaultSearchProviderName, TRACKING_STRATEGY_ATOMIC },
+ #if !defined(OS_ANDROID)
+ { prefs::kPinnedTabs, TRACKING_STRATEGY_ATOMIC },
+ #else
+ { NULL, TRACKING_STRATEGY_NONE },
+ #endif
+ { prefs::kExtensionKnownDisabled, TRACKING_STRATEGY_ATOMIC },
+ { prefs::kProfileResetPromptMemento, TRACKING_STRATEGY_ATOMIC },
+ };
+
+ InitTrackedPreferences(kTrackedPrefs, arraysize(kTrackedPrefs));
+}
+
+PrefHashFilter::PrefHashFilter(
+ scoped_ptr<PrefHashStore> pref_hash_store,
+ const PrefHashFilter::TrackedPreference tracked_preferences[],
+ size_t tracked_preferences_size)
+ : pref_hash_store_(pref_hash_store.Pass()) {
+ InitTrackedPreferences(tracked_preferences, tracked_preferences_size);
+}
PrefHashFilter::~PrefHashFilter() {}
// Updates the stored hash to correspond to the updated preference value.
void PrefHashFilter::FilterUpdate(const std::string& path,
const base::Value* value) {
- if (tracked_paths_.find(path) != tracked_paths_.end())
- pref_hash_store_->StoreHash(path, value);
+ TrackedPreferencesMap::const_iterator it = tracked_paths_.find(path);
+ if (it != tracked_paths_.end())
+ StoreHashBasedOnStrategy(path, value, it->second.strategy);
}
// Validates loaded preference values according to stored hashes, reports
// validation results via UMA, and updates hashes in case of mismatch.
void PrefHashFilter::FilterOnLoad(base::DictionaryValue* pref_store_contents) {
- for (size_t i = 0; i < arraysize(kTrackedPrefs); ++i) {
- if (kTrackedPrefs[i][0] == '\0')
- continue;
+ for (TrackedPreferencesMap::const_iterator it = tracked_paths_.begin();
+ it != tracked_paths_.end(); ++it) {
+ const std::string& pref_path = it->first;
+ const TrackedPreferenceMetaData& metadata = it->second;
const base::Value* value = NULL;
- pref_store_contents->Get(kTrackedPrefs[i], &value);
+ pref_store_contents->Get(pref_path, &value);
PrefHashStore::ValueState value_state =
- pref_hash_store_->CheckValue(kTrackedPrefs[i], value);
- ReportValidationResult(value_state, i);
+ CheckValueBasedOnStrategy(pref_path, value, metadata.strategy);
+ ReportValidationResult(value_state, metadata.index, tracked_paths_.size());
if (value_state != PrefHashStore::UNCHANGED)
- pref_hash_store_->StoreHash(kTrackedPrefs[i], value);
+ StoreHashBasedOnStrategy(pref_path, value, metadata.strategy);
+ }
+}
+
+void PrefHashFilter::InitTrackedPreferences(
+ const PrefHashFilter::TrackedPreference tracked_preferences[],
erikwright (departed) 2013/12/17 02:22:50 verify whether it's more common to use [] or * in
gab 2013/12/17 18:08:05 Here are 161 cases where an array is passed as the
+ size_t tracked_preferences_size) {
+ for (size_t i = 0; i < tracked_preferences_size; ++i) {
+ if (tracked_preferences[i].strategy == TRACKING_STRATEGY_NONE)
+ continue;
+ bool is_new = tracked_paths_.insert(std::make_pair(
+ std::string(tracked_preferences[i].name),
+ TrackedPreferenceMetaData(i, tracked_preferences[i].strategy))).second;
+ DCHECK(is_new);
+ }
+}
+
+void PrefHashFilter::StoreHashBasedOnStrategy(const std::string& path,
+ const base::Value* value,
+ PrefTrackingStrategy strategy) {
+ switch (strategy) {
+ case TRACKING_STRATEGY_NONE:
+ NOTREACHED();
+ break;
+ case TRACKING_STRATEGY_ATOMIC:
+ pref_hash_store_->StoreHash(path, value);
+ break;
+ case TRACKING_STRATEGY_SPLIT:
+ const base::DictionaryValue* dict_value = NULL;
+ if (value && !value->GetAsDictionary(&dict_value)) {
+ NOTREACHED();
+ break;
erikwright (departed) 2013/12/17 02:22:50 I find this a little foreign (two breaks in a case
gab 2013/12/17 18:08:05 I considered switching the break; for a return; bu
+ }
+ pref_hash_store_->StoreSplitHash(path, dict_value);
+ break;
+ }
erikwright (departed) 2013/12/17 02:22:50 Are unhandled enums handled here too? Or is it onl
gab 2013/12/17 18:08:05 Unhandled enums will throw a couple error on gcc/c
+}
+
+PrefHashStore::ValueState PrefHashFilter::CheckValueBasedOnStrategy(
+ const std::string& path,
+ const base::Value* value,
+ PrefTrackingStrategy strategy) {
+ switch (strategy) {
+ case TRACKING_STRATEGY_NONE:
+ NOTREACHED();
+ return PrefHashStore::UNKNOWN_VALUE;
+ case TRACKING_STRATEGY_ATOMIC:
+ return pref_hash_store_->CheckValue(path, value);
+ case TRACKING_STRATEGY_SPLIT:
+ const base::DictionaryValue* dict_value = NULL;
+ if (value && !value->GetAsDictionary(&dict_value)) {
+ NOTREACHED();
+ return PrefHashStore::UNKNOWN_VALUE;
+ }
+
+ std::vector<std::string> invalid_keys;
+ PrefHashStore::ValueState state =
+ pref_hash_store_->CheckSplitValue(path, dict_value, &invalid_keys);
+ if (state == PrefHashStore::CHANGED)
+ ReportSplitPreferenceChangedCount(path, invalid_keys.size());
+ return state;
}
+ NOTREACHED();
+ return PrefHashStore::UNKNOWN_VALUE;
}

Powered by Google App Engine
This is Rietveld 408576698