1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Timer - class that provides timer tracking. 18 19 #ifndef METRICS_TIMER_H_ 20 #define METRICS_TIMER_H_ 21 22 #include <memory> 23 #include <string> 24 25 #include <base/macros.h> 26 #include <base/time/time.h> 27 #include <gtest/gtest_prod.h> // for FRIEND_TEST 28 29 class MetricsLibraryInterface; 30 31 namespace chromeos_metrics { 32 33 class TimerInterface { 34 public: ~TimerInterface()35 virtual ~TimerInterface() {} 36 37 virtual bool Start() = 0; 38 virtual bool Stop() = 0; 39 virtual bool Reset() = 0; 40 virtual bool HasStarted() const = 0; 41 }; 42 43 // Wrapper for calls to the system clock. 44 class ClockWrapper { 45 public: ClockWrapper()46 ClockWrapper() {} ~ClockWrapper()47 virtual ~ClockWrapper() {} 48 49 // Returns the current time from the system. 50 virtual base::TimeTicks GetCurrentTime() const; 51 52 private: 53 DISALLOW_COPY_AND_ASSIGN(ClockWrapper); 54 }; 55 56 // Implements a Timer. 57 class Timer : public TimerInterface { 58 public: 59 Timer(); ~Timer()60 virtual ~Timer() {} 61 62 // Starts the timer. If a timer is already running, also resets current 63 // timer. Always returns true. 64 virtual bool Start(); 65 66 // Stops the timer and calculates the total time elapsed between now and when 67 // Start() was called. Note that this method needs a prior call to Start(). 68 // Otherwise, it fails (returns false). 69 virtual bool Stop(); 70 71 // Pauses a timer. If the timer is stopped, this call starts the timer in 72 // the paused state. Fails (returns false) if the timer is already paused. 73 virtual bool Pause(); 74 75 // Restarts a paused timer (or starts a stopped timer). This method fails 76 // (returns false) if the timer is already running; otherwise, returns true. 77 virtual bool Resume(); 78 79 // Resets the timer, erasing the current duration being tracked. Always 80 // returns true. 81 virtual bool Reset(); 82 83 // Returns whether the timer has started or not. 84 virtual bool HasStarted() const; 85 86 // Stores the current elapsed time in |elapsed_time|. If timer is stopped, 87 // stores the elapsed time from when Stop() was last called. Otherwise, 88 // calculates and stores the elapsed time since the last Start(). 89 // Returns false if the timer was never Start()'ed or if called with a null 90 // pointer argument. 91 virtual bool GetElapsedTime(base::TimeDelta* elapsed_time) const; 92 93 private: 94 enum TimerState { kTimerStopped, kTimerRunning, kTimerPaused }; 95 friend class TimerTest; 96 friend class TimerReporterTest; 97 FRIEND_TEST(TimerReporterTest, StartStopReport); 98 FRIEND_TEST(TimerTest, InvalidElapsedTime); 99 FRIEND_TEST(TimerTest, InvalidStop); 100 FRIEND_TEST(TimerTest, PauseResumeStop); 101 FRIEND_TEST(TimerTest, PauseStartStopResume); 102 FRIEND_TEST(TimerTest, PauseStop); 103 FRIEND_TEST(TimerTest, Reset); 104 FRIEND_TEST(TimerTest, ReStart); 105 FRIEND_TEST(TimerTest, ResumeStartStopPause); 106 FRIEND_TEST(TimerTest, SeparatedTimers); 107 FRIEND_TEST(TimerTest, StartPauseResumePauseResumeStop); 108 FRIEND_TEST(TimerTest, StartPauseResumePauseStop); 109 FRIEND_TEST(TimerTest, StartPauseResumeStop); 110 FRIEND_TEST(TimerTest, StartPauseStop); 111 FRIEND_TEST(TimerTest, StartResumeStop); 112 FRIEND_TEST(TimerTest, StartStop); 113 114 // Elapsed time of the last use of the timer. 115 base::TimeDelta elapsed_time_; 116 117 // Starting time value. 118 base::TimeTicks start_time_; 119 120 // Whether the timer is running, stopped, or paused. 121 TimerState timer_state_; 122 123 // Wrapper for the calls to the system clock. 124 std::unique_ptr<ClockWrapper> clock_wrapper_; 125 126 DISALLOW_COPY_AND_ASSIGN(Timer); 127 }; 128 129 // Extends the Timer class to report the elapsed time in milliseconds through 130 // the UMA metrics library. 131 class TimerReporter : public Timer { 132 public: 133 // Initializes the timer by providing a |histogram_name| to report to with 134 // |min|, |max| and |num_buckets| attributes for the histogram. 135 TimerReporter(const std::string& histogram_name, int min, int max, 136 int num_buckets); ~TimerReporter()137 virtual ~TimerReporter() {} 138 139 // Sets the metrics library used by all instances of this class. set_metrics_lib(MetricsLibraryInterface * metrics_lib)140 static void set_metrics_lib(MetricsLibraryInterface* metrics_lib) { 141 metrics_lib_ = metrics_lib; 142 } 143 144 // Reports the current duration to UMA, in milliseconds. Returns false if 145 // there is nothing to report, e.g. a metrics library is not set. 146 virtual bool ReportMilliseconds() const; 147 148 // Accessor methods. histogram_name()149 const std::string& histogram_name() const { return histogram_name_; } min()150 int min() const { return min_; } max()151 int max() const { return max_; } num_buckets()152 int num_buckets() const { return num_buckets_; } 153 154 private: 155 friend class TimerReporterTest; 156 FRIEND_TEST(TimerReporterTest, StartStopReport); 157 FRIEND_TEST(TimerReporterTest, InvalidReport); 158 159 static MetricsLibraryInterface* metrics_lib_; 160 std::string histogram_name_; 161 int min_; 162 int max_; 163 int num_buckets_; 164 165 DISALLOW_COPY_AND_ASSIGN(TimerReporter); 166 }; 167 168 } // namespace chromeos_metrics 169 170 #endif // METRICS_TIMER_H_ 171