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

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: UNKNOWN_VALUE when going from atomic to split hash for an existing tracked pref 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..535a62d6418ba08edf7b0d1f8070113c848eaac0 100644
--- a/chrome/browser/prefs/pref_hash_filter.cc
+++ b/chrome/browser/prefs/pref_hash_filter.cc
@@ -7,90 +7,177 @@
#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;
}
+// Reports the |count| of items that changed in the split preference at |path|.
+void ReportSplitPreferenceChangedCount(const std::string& path,
+ size_t count) {
+ // The histogram below is an expansion of the UMA_HISTOGRAM_COUNTS_100 macro
+ // adapted to allow for a dynamically suffixed histogram name.
+ // Note: The factory creates and owns the histogram.
+ base::HistogramBase* histogram =
+ base::LinearHistogram::FactoryGet(
+ "Settings.TrackedSplitPreferenceChanged." + path,
+ 1,
+ 100, // Allow counts up to 100.
+ 101,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+ histogram->Add(count);
+}
+
} // 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. Each
+ // tracked preference must be given a unique reporting ID.
+ static const TrackedPreference kTrackedPrefs[] = {
+ { 0, prefs::kShowHomeButton, TRACKING_STRATEGY_ATOMIC },
+ { 1, prefs::kHomePageIsNewTabPage, TRACKING_STRATEGY_ATOMIC },
+ { 2, prefs::kHomePage, TRACKING_STRATEGY_ATOMIC },
+ { 3, prefs::kRestoreOnStartup, TRACKING_STRATEGY_ATOMIC },
+ { 4, prefs::kURLsToRestoreOnStartup, TRACKING_STRATEGY_ATOMIC },
+ { 5, prefs::kExtensionsPref, TRACKING_STRATEGY_SPLIT },
+ { 6, prefs::kGoogleServicesLastUsername, TRACKING_STRATEGY_ATOMIC },
+ { 7, prefs::kSearchProviderOverrides, TRACKING_STRATEGY_ATOMIC },
+ { 8, prefs::kDefaultSearchProviderSearchURL, TRACKING_STRATEGY_ATOMIC },
+ { 9, prefs::kDefaultSearchProviderKeyword, TRACKING_STRATEGY_ATOMIC },
+ { 10, prefs::kDefaultSearchProviderName, TRACKING_STRATEGY_ATOMIC },
+ #if !defined(OS_ANDROID)
+ { 11, prefs::kPinnedTabs, TRACKING_STRATEGY_ATOMIC },
+ #endif
+ { 12, prefs::kExtensionKnownDisabled, TRACKING_STRATEGY_ATOMIC },
+ { 13, 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())
+ StoreHashUsingStrategy(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);
+ CheckValueUsingStrategy(pref_path, value, metadata.strategy);
+ ReportValidationResult(value_state, metadata.reporting_id,
+ tracked_paths_.size());
if (value_state != PrefHashStore::UNCHANGED)
- pref_hash_store_->StoreHash(kTrackedPrefs[i], value);
+ StoreHashUsingStrategy(pref_path, value, metadata.strategy);
+ }
+}
+
+void PrefHashFilter::InitTrackedPreferences(
+ const PrefHashFilter::TrackedPreference tracked_preferences[],
+ size_t tracked_preferences_size) {
+ for (size_t i = 0; i < tracked_preferences_size; ++i) {
+ const TrackedPreferenceMetaData metadata = {
+ tracked_preferences[i].reporting_id,
+ tracked_preferences[i].strategy,
+ };
+ bool is_new = tracked_paths_.insert(std::make_pair(
+ std::string(tracked_preferences[i].name), metadata)).second;
+ DCHECK(is_new);
+ }
+}
+
+void PrefHashFilter::StoreHashUsingStrategy(const std::string& path,
+ const base::Value* value,
+ PrefTrackingStrategy strategy) {
+ switch (strategy) {
+ 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;
+ }
+ pref_hash_store_->StoreSplitHash(path, dict_value);
+ break;
+ }
+ }
+}
+
+PrefHashStore::ValueState PrefHashFilter::CheckValueUsingStrategy(
+ const std::string& path,
+ const base::Value* value,
+ PrefTrackingStrategy strategy) {
+ switch (strategy) {
+ 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());
erikwright (departed) 2013/12/19 15:21:28 It's a little surprising that this "Report" call i
gab 2013/12/20 18:37:06 Done. (I intentionally kept the NOTREACHED() on G
+ return state;
+ }
}
+ NOTREACHED();
+ return PrefHashStore::UNKNOWN_VALUE;
}

Powered by Google App Engine
This is Rietveld 408576698