user_classifier.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_
  5. #define COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/memory/raw_ptr.h"
  9. class PrefRegistrySimple;
  10. class PrefService;
  11. namespace base {
  12. class Clock;
  13. } // namespace base
  14. namespace ntp_snippets {
  15. // Collects data about user usage patterns of content suggestions, computes
  16. // long-term user metrics locally using pref, and reports the metrics to UMA.
  17. // Based on these long-term user metrics, it classifies the user in a UserClass.
  18. class UserClassifier {
  19. public:
  20. // Enumeration listing user classes
  21. enum class UserClass {
  22. RARE_NTP_USER,
  23. ACTIVE_NTP_USER,
  24. ACTIVE_SUGGESTIONS_CONSUMER,
  25. };
  26. // For estimating the average length of the intervals between two successive
  27. // events, we keep a simple frequency model, a single value that we call
  28. // "metric" below.
  29. // We track exponentially-discounted rate of the given event per hour where
  30. // the continuous utility function between two successive events (e.g. opening
  31. // a NTP) at times t1 < t2 is 1 / (t2-t1), i.e. intuitively the rate of this
  32. // event in this time interval.
  33. // See https://en.wikipedia.org/wiki/Exponential_discounting for more details.
  34. // We keep track of the following events.
  35. // NOTE: if you add any element, add it also in the static arrays in .cc and
  36. // create another histogram.
  37. enum class Metric {
  38. NTP_OPENED, // When the user opens a new NTP - this indicates potential
  39. // use of content suggestions.
  40. // TODO(jkrcal): Remove the following metric as for condensed NTP / Chrome
  41. // Home, this coincides with NTP_OPENED.
  42. SUGGESTIONS_SHOWN, // When the content suggestions are shown to the user -
  43. // in the current implementation when the user scrolls
  44. // below the fold.
  45. SUGGESTIONS_USED, // When the user clicks on some suggestions or on some
  46. // "More" button.
  47. COUNT // Keep this as the last element.
  48. };
  49. // The provided |pref_service| may be nullptr in unit-tests.
  50. UserClassifier(PrefService* pref_service, base::Clock* clock);
  51. UserClassifier(const UserClassifier&) = delete;
  52. UserClassifier& operator=(const UserClassifier&) = delete;
  53. ~UserClassifier();
  54. // Registers profile prefs for all metrics. Called from browser_prefs.cc.
  55. static void RegisterProfilePrefs(PrefRegistrySimple* registry);
  56. // Informs the UserClassifier about a new event for |metric|. The
  57. // classification is based on these calls.
  58. void OnEvent(Metric metric);
  59. // Get the estimate average length of the interval between two successive
  60. // events of the given type.
  61. double GetEstimatedAvgTime(Metric metric) const;
  62. // Return the classification of the current user.
  63. UserClass GetUserClass() const;
  64. std::string GetUserClassDescriptionForDebugging() const;
  65. // Resets the classification (emulates a fresh upgrade / install).
  66. void ClearClassificationForDebugging();
  67. private:
  68. // The event has happened, recompute the metric accordingly. Then store and
  69. // return the new value.
  70. double UpdateMetricOnEvent(Metric metric);
  71. // No event has happened but we need to get up-to-date metric, recompute and
  72. // return the new value. This function does not store the recomputed metric.
  73. double GetUpToDateMetricValue(Metric metric) const;
  74. // Returns the number of hours since the last event of the same type.
  75. // If there is no last event of that type, assume it happened just now and
  76. // return 0.
  77. double GetHoursSinceLastTime(Metric metric) const;
  78. bool HasLastTime(Metric metric) const;
  79. void SetLastTimeToNow(Metric metric);
  80. double GetMetricValue(Metric metric) const;
  81. void SetMetricValue(Metric metric, double metric_value);
  82. void ClearMetricValue(Metric metric);
  83. raw_ptr<PrefService> pref_service_;
  84. raw_ptr<base::Clock> clock_;
  85. // Params of the metric.
  86. const double discount_rate_per_hour_;
  87. const double min_hours_;
  88. const double max_hours_;
  89. // Params of the classification.
  90. const double active_consumer_clicks_at_least_once_per_hours_;
  91. const double rare_user_opens_ntp_at_most_once_per_hours_;
  92. };
  93. } // namespace ntp_snippets
  94. #endif // COMPONENTS_NTP_SNIPPETS_USER_CLASSIFIER_H_