xref: /aosp_15_r20/external/cronet/components/metrics/daily_event.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_METRICS_DAILY_EVENT_H_
6 #define COMPONENTS_METRICS_DAILY_EVENT_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/memory/raw_ptr.h"
13 #include "base/time/time.h"
14 
15 class PrefRegistrySimple;
16 class PrefService;
17 
18 namespace metrics {
19 
20 // DailyEvent is used for throttling an event to about once per day, even if
21 // the program is restarted more frequently.  It is based on local machine
22 // time, so it could be fired more often if the clock is changed.
23 //
24 // The service using the DailyEvent should first provide all of the Observers
25 // for the interval, and then arrange for CheckInterval() to be called
26 // periodically to test if the event should be fired.
27 class DailyEvent {
28  public:
29   // Different reasons that Observer::OnDailyEvent() is called.
30   // This enum is used for histograms and must not be renumbered.
31   enum class IntervalType {
32     FIRST_RUN,
33     DAY_ELAPSED,
34     CLOCK_CHANGED,
35     kMaxValue = CLOCK_CHANGED,
36   };
37 
38   // Observer receives notifications from a DailyEvent.
39   // Observers must be added before the DailyEvent begins checking time,
40   // and will be owned by the DailyEvent.
41   class Observer {
42    public:
43     Observer();
44 
45     Observer(const Observer&) = delete;
46     Observer& operator=(const Observer&) = delete;
47 
48     virtual ~Observer();
49 
50     // Called when the daily event is fired.
51     virtual void OnDailyEvent(IntervalType type) = 0;
52   };
53 
54   // Constructs DailyEvent monitor which stores the time it last fired in the
55   // preference |pref_name|. |pref_name| should be registered by calling
56   // RegisterPref before using this object.
57   // Caller is responsible for ensuring that |pref_service| and |pref_name|
58   // outlive the DailyEvent.
59   // |histogram_name| is the name of the UMA metric which record when this
60   // interval fires, and should be registered in histograms.xml. If
61   // |histogram_name| is empty - interval fires are not recorded.
62   DailyEvent(PrefService* pref_service,
63              const char* pref_name,
64              const std::string& histogram_name);
65 
66   DailyEvent(const DailyEvent&) = delete;
67   DailyEvent& operator=(const DailyEvent&) = delete;
68 
69   ~DailyEvent();
70 
71   // Adds a observer to be notified when a day elapses. All observers should
72   // be registered before the the DailyEvent starts checking time.
73   void AddObserver(std::unique_ptr<Observer> observer);
74 
75   // Checks if a day has elapsed. If it has, OnDailyEvent will be called on
76   // all observers.
77   void CheckInterval();
78 
79   // Registers the preference used by this interval.
80   static void RegisterPref(PrefRegistrySimple* registry,
81                            const std::string& pref_name);
82 
83  private:
84   // Handles an interval elapsing because of |type|.
85   void OnInterval(base::Time now, IntervalType type);
86 
87   // A weak pointer to the PrefService object to read and write preferences
88   // from. Calling code should ensure this object continues to exist for the
89   // lifetime of the DailyEvent object.
90   raw_ptr<PrefService, LeakedDanglingUntriaged> pref_service_;
91 
92   // The name of the preference to store the last fired time in.
93   // Calling code should ensure this outlives the DailyEvent.
94   const char* pref_name_;
95 
96   // The name of the histogram to record intervals.
97   std::string histogram_name_;
98 
99   // A list of observers.
100   std::vector<std::unique_ptr<Observer>> observers_;
101 
102   // The time that the daily event was last fired.
103   base::Time last_fired_;
104 };
105 
106 }  // namespace metrics
107 
108 #endif  // COMPONENTS_METRICS_DAILY_EVENT_H_
109