|  | // 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. | 
|  |  | 
|  | #ifndef COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_ | 
|  | #define COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/macros.h" | 
|  |  | 
|  | class PrefRegistrySimple; | 
|  | class PrefService; | 
|  |  | 
|  | namespace base { | 
|  | class Clock; | 
|  | }  // namespace base | 
|  |  | 
|  | namespace ntp_snippets { | 
|  |  | 
|  | // Collects data about user usage patterns of content suggestions, computes | 
|  | // long-term user metrics locally using pref, and reports the metrics to UMA. | 
|  | // Based on these long-term user metrics, it classifies the user in a UserClass. | 
|  | class UserClassifier { | 
|  | public: | 
|  | // Enumeration listing user classes | 
|  | enum class UserClass { | 
|  | RARE_NTP_USER, | 
|  | ACTIVE_NTP_USER, | 
|  | ACTIVE_SUGGESTIONS_CONSUMER, | 
|  | }; | 
|  |  | 
|  | // For estimating the average length of the intervals between two successive | 
|  | // events, we keep a simple frequency model, a single value that we call | 
|  | // "metric" below. | 
|  | // We track exponentially-discounted rate of the given event per hour where | 
|  | // the continuous utility function between two successive events (e.g. opening | 
|  | // a NTP) at times t1 < t2 is 1 / (t2-t1), i.e. intuitively the rate of this | 
|  | // event in this time interval. | 
|  | // See https://en.wikipedia.org/wiki/Exponential_discounting for more details. | 
|  | // We keep track of the following events. | 
|  | // NOTE: if you add any element, add it also in the static arrays in .cc and | 
|  | // create another histogram. | 
|  | enum class Metric { | 
|  | NTP_OPENED,  // When the user opens a new NTP - this indicates potential | 
|  | // use of content suggestions. | 
|  | // TODO(jkrcal): Remove the following metric as for condensed NTP / Chrome | 
|  | // Home, this coincides with NTP_OPENED. | 
|  | SUGGESTIONS_SHOWN,  // When the content suggestions are shown to the user - | 
|  | // in the current implementation when the user scrolls | 
|  | // below the fold. | 
|  | SUGGESTIONS_USED,   // When the user clicks on some suggestions or on some | 
|  | // "More" button. | 
|  | COUNT               // Keep this as the last element. | 
|  | }; | 
|  |  | 
|  | // The provided |pref_service| may be nullptr in unit-tests. | 
|  | UserClassifier(PrefService* pref_service, base::Clock* clock); | 
|  | ~UserClassifier(); | 
|  |  | 
|  | // Registers profile prefs for all metrics. Called from browser_prefs.cc. | 
|  | static void RegisterProfilePrefs(PrefRegistrySimple* registry); | 
|  |  | 
|  | // Informs the UserClassifier about a new event for |metric|. The | 
|  | // classification is based on these calls. | 
|  | void OnEvent(Metric metric); | 
|  |  | 
|  | // Get the estimate average length of the interval between two successive | 
|  | // events of the given type. | 
|  | double GetEstimatedAvgTime(Metric metric) const; | 
|  |  | 
|  | // Return the classification of the current user. | 
|  | UserClass GetUserClass() const; | 
|  | std::string GetUserClassDescriptionForDebugging() const; | 
|  |  | 
|  | // Resets the classification (emulates a fresh upgrade / install). | 
|  | void ClearClassificationForDebugging(); | 
|  |  | 
|  | private: | 
|  | // The event has happened, recompute the metric accordingly. Then store and | 
|  | // return the new value. | 
|  | double UpdateMetricOnEvent(Metric metric); | 
|  | // No event has happened but we need to get up-to-date metric, recompute and | 
|  | // return the new value. This function does not store the recomputed metric. | 
|  | double GetUpToDateMetricValue(Metric metric) const; | 
|  |  | 
|  | // Returns the number of hours since the last event of the same type. | 
|  | // If there is no last event of that type, assume it happened just now and | 
|  | // return 0. | 
|  | double GetHoursSinceLastTime(Metric metric) const; | 
|  | bool HasLastTime(Metric metric) const; | 
|  | void SetLastTimeToNow(Metric metric); | 
|  |  | 
|  | double GetMetricValue(Metric metric) const; | 
|  | void SetMetricValue(Metric metric, double metric_value); | 
|  | void ClearMetricValue(Metric metric); | 
|  |  | 
|  | PrefService* pref_service_; | 
|  | base::Clock* clock_; | 
|  |  | 
|  | // Params of the metric. | 
|  | const double discount_rate_per_hour_; | 
|  | const double min_hours_; | 
|  | const double max_hours_; | 
|  |  | 
|  | // Params of the classification. | 
|  | const double active_consumer_clicks_at_least_once_per_hours_; | 
|  | const double rare_user_opens_ntp_at_most_once_per_hours_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(UserClassifier); | 
|  | }; | 
|  |  | 
|  | }  // namespace ntp_snippets | 
|  |  | 
|  | #endif  // COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_ |