blob: c1b8edec6341407896ddd85837376ed5774466bf [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
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 */
Bruno Rochabe388f32011-08-02 12:40:17 -070016
17// Timer - class that provides timer tracking.
18
19#ifndef METRICS_TIMER_H_
20#define METRICS_TIMER_H_
21
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080022#include <memory>
Bruno Rochabe388f32011-08-02 12:40:17 -070023#include <string>
24
Ben Chan652d6972014-09-03 17:23:46 -070025#include <base/macros.h>
Ben Chan2e6543d2014-02-05 23:26:25 -080026#include <base/time/time.h>
Bruno Rochabe388f32011-08-02 12:40:17 -070027#include <gtest/gtest_prod.h> // for FRIEND_TEST
28
29class MetricsLibraryInterface;
30
31namespace chromeos_metrics {
32
33class TimerInterface {
34 public:
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.
44class ClockWrapper {
45 public:
46 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.
57class Timer : public TimerInterface {
58 public:
59 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
repo sync06726552013-05-28 14:19:53 -070071 // 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
Bruno Rochabe388f32011-08-02 12:40:17 -070079 // 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:
repo sync06726552013-05-28 14:19:53 -070094 enum TimerState { kTimerStopped, kTimerRunning, kTimerPaused };
Bruno Rochabe388f32011-08-02 12:40:17 -070095 friend class TimerTest;
96 friend class TimerReporterTest;
Bruno Rochabe388f32011-08-02 12:40:17 -070097 FRIEND_TEST(TimerReporterTest, StartStopReport);
repo sync06726552013-05-28 14:19:53 -070098 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);
Bruno Rochabe388f32011-08-02 12:40:17 -0700113
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
repo sync06726552013-05-28 14:19:53 -0700120 // Whether the timer is running, stopped, or paused.
121 TimerState timer_state_;
Bruno Rochabe388f32011-08-02 12:40:17 -0700122
123 // Wrapper for the calls to the system clock.
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -0800124 std::unique_ptr<ClockWrapper> clock_wrapper_;
Bruno Rochabe388f32011-08-02 12:40:17 -0700125
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.
131class 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);
137 virtual ~TimerReporter() {}
138
139 // Sets the metrics library used by all instances of this class.
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
repo sync1bc9ce02013-03-22 17:21:57 -0700145 // there is nothing to report, e.g. a metrics library is not set.
Bruno Rochabe388f32011-08-02 12:40:17 -0700146 virtual bool ReportMilliseconds() const;
147
148 // Accessor methods.
149 const std::string& histogram_name() const { return histogram_name_; }
150 int min() const { return min_; }
151 int max() const { return max_; }
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_