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