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