Index: components/ntp_snippets/user_classifier.cc |
diff --git a/components/ntp_snippets/user_classifier.cc b/components/ntp_snippets/user_classifier.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a7b8995565d643a9f2e2bf62812456359c5abb0e |
--- /dev/null |
+++ b/components/ntp_snippets/user_classifier.cc |
@@ -0,0 +1,123 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/ntp_snippets/user_classifier.h" |
+ |
+#include <algorithm> |
+#include <string> |
+ |
+#include "base/metrics/histogram_macros.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "components/ntp_snippets/pref_names.h" |
+#include "components/prefs/pref_registry_simple.h" |
+#include "components/prefs/pref_service.h" |
+ |
+namespace { |
+ |
+// TODO(jkrcal): Make all of this Finch configurable. |
rkaplow
2016/09/07 13:33:10
nit, variations_service is the external chromium n
jkrcal
2016/09/07 14:19:08
Done.
|
+// Default values to start the discounted-average metrics with. |
+const double kDefaultAverageHoursToOpenNTP = 24; |
+const double kDefaultAverageHoursToShowSuggestions = 48; |
+const double kDefaultAverageHoursToUseSuggestions = 96; |
+// The discount factor for computing the discounted-average metrics. |
+const double kDiscountFactor = 0.25; |
+// Never consider any larger interval than this (so that extreme situations such |
+// as loosing your phone or going for a long offline vacation do not skew the |
Marc Treib
2016/09/07 13:23:48
nit: s/loosing/losing/
Bernhard Bauer
2016/09/07 13:46:45
Nit: "losing"
jkrcal
2016/09/07 14:19:08
Done.
|
+// avg too much). |
+const double kMaxHours = 14*24; |
+ |
+const char kHistogramAverageHoursToOpenNTP[] = |
+ "NewTabPage.UserClassifier.AverageHoursToOpenNTP"; |
+const char kHistogramAverageHoursToShowSuggestions[] = |
+ "NewTabPage.UserClassifier.AverageHoursToShowSuggestions"; |
+const char kHistogramAverageHoursToUseSuggestions[] = |
+ "NewTabPage.UserClassifier.AverageHoursToUseSuggestions"; |
+ |
+} // namespace |
+ |
+namespace ntp_snippets { |
+ |
+UserClassifier::UserClassifier(PrefService* pref_service) |
+ : pref_service_(pref_service) {} |
+ |
+UserClassifier::~UserClassifier() {} |
+ |
+// static |
+void UserClassifier::RegisterProfilePrefs(PrefRegistrySimple* registry) { |
+ registry->RegisterDoublePref(prefs::kUserClassifierAverageHoursToOpenNTP, |
+ kDefaultAverageHoursToOpenNTP); |
+ registry->RegisterDoublePref( |
+ prefs::kUserClassifierAverageHoursToShowSuggestions, |
+ kDefaultAverageHoursToShowSuggestions); |
+ registry->RegisterDoublePref( |
+ prefs::kUserClassifierAverageHoursToUseSuggestions, |
+ kDefaultAverageHoursToUseSuggestions); |
+ |
+ registry->RegisterInt64Pref(prefs::kUserClassifierLastTimeToOpenNTP, 0); |
+ registry->RegisterInt64Pref(prefs::kUserClassifierLastTimeToShowSuggestions, |
+ 0); |
+ registry->RegisterInt64Pref(prefs::kUserClassifierLastTimeToUseSuggestions, |
+ 0); |
+} |
+ |
+void UserClassifier::OnNTPOpened() { |
+ double avg = UpdateMetric(prefs::kUserClassifierAverageHoursToOpenNTP, |
+ prefs::kUserClassifierLastTimeToOpenNTP, |
+ kDefaultAverageHoursToOpenNTP); |
+ UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToOpenNTP, avg, 1, |
+ kMaxHours, 50); |
+} |
+ |
+void UserClassifier::OnSuggestionsShown() { |
+ double avg = UpdateMetric(prefs::kUserClassifierAverageHoursToShowSuggestions, |
+ prefs::kUserClassifierLastTimeToShowSuggestions, |
+ kDefaultAverageHoursToShowSuggestions); |
+ UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToShowSuggestions, avg, 1, |
+ kMaxHours, 50); |
+} |
+ |
+void UserClassifier::OnSuggestionsUsed() { |
+ double avg = UpdateMetric(prefs::kUserClassifierAverageHoursToUseSuggestions, |
+ prefs::kUserClassifierLastTimeToUseSuggestions, |
+ kDefaultAverageHoursToUseSuggestions); |
+ UMA_HISTOGRAM_CUSTOM_COUNTS(kHistogramAverageHoursToUseSuggestions, avg, 1, |
+ kMaxHours, 50); |
+} |
+ |
+double UserClassifier::UpdateMetric(const char* metric_pref_name, |
+ const char* last_time_pref_name, |
Bernhard Bauer
2016/09/07 13:46:45
Nit: Align arguments.
jkrcal
2016/09/07 14:19:08
Done.
|
+ double default_metric_value) { |
rkaplow
2016/09/07 13:33:10
align
jkrcal
2016/09/07 14:19:08
Done.
|
+ if (!pref_service_) |
+ return default_metric_value; |
+ |
+ double hours_since_last_time = std::min( |
+ kMaxHours, |
+ GetHoursSinceLastTime(last_time_pref_name, default_metric_value)); |
+ SetLastTimeToNow(last_time_pref_name); |
+ |
+ double avg = pref_service_->GetDouble(metric_pref_name); |
+ // Compute and store the new discounted average. |
+ avg = hours_since_last_time * kDiscountFactor + avg * (1 - kDiscountFactor); |
rkaplow
2016/09/07 13:33:10
is it best to discount after rounding down to the
jkrcal
2016/09/07 14:19:08
I do not understand. I treat the number always as
|
+ pref_service_->SetDouble(metric_pref_name, avg); |
+ return avg; |
+} |
+ |
+double UserClassifier::GetHoursSinceLastTime( |
+ const char* last_time_pref_name, |
+ double default_hours_since_last_time) { |
+ if (!pref_service_->HasPrefPath(last_time_pref_name)) |
+ return default_hours_since_last_time; |
+ |
+ base::TimeDelta since_last_time = |
+ base::Time::Now() - base::Time::FromInternalValue( |
+ pref_service_->GetInt64(last_time_pref_name)); |
+ return since_last_time.InSecondsF() / 3600; |
+} |
+ |
+void UserClassifier::SetLastTimeToNow(const char* last_time_pref_name) { |
+ pref_service_->SetInt64(last_time_pref_name, |
+ base::Time::Now().ToInternalValue()); |
+} |
+ |
+} // namespace ntp_snippets |