blob: 52cc57892657a8535815f3250d8c874a46b8ba2d [file] [log] [blame]
Bruno Rochabe388f32011-08-02 12:40:17 -07001// Copyright (c) 2011 The Chromium OS 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// Timer - class that provides timer tracking.
6
7#ifndef METRICS_TIMER_H_
8#define METRICS_TIMER_H_
9
10#include <string>
11
Ben Chan652d6972014-09-03 17:23:46 -070012#include <base/macros.h>
Bruno Rochabe388f32011-08-02 12:40:17 -070013#include <base/memory/scoped_ptr.h>
Ben Chan2e6543d2014-02-05 23:26:25 -080014#include <base/time/time.h>
Bruno Rochabe388f32011-08-02 12:40:17 -070015#include <gtest/gtest_prod.h> // for FRIEND_TEST
16
17class MetricsLibraryInterface;
18
19namespace chromeos_metrics {
20
21class TimerInterface {
22 public:
23 virtual ~TimerInterface() {}
24
25 virtual bool Start() = 0;
26 virtual bool Stop() = 0;
27 virtual bool Reset() = 0;
28 virtual bool HasStarted() const = 0;
29};
30
31// Wrapper for calls to the system clock.
32class ClockWrapper {
33 public:
34 ClockWrapper() {}
35 virtual ~ClockWrapper() {}
36
37 // Returns the current time from the system.
38 virtual base::TimeTicks GetCurrentTime() const;
39
40 private:
41 DISALLOW_COPY_AND_ASSIGN(ClockWrapper);
42};
43
44// Implements a Timer.
45class Timer : public TimerInterface {
46 public:
47 Timer();
48 virtual ~Timer() {}
49
50 // Starts the timer. If a timer is already running, also resets current
51 // timer. Always returns true.
52 virtual bool Start();
53
54 // Stops the timer and calculates the total time elapsed between now and when
55 // Start() was called. Note that this method needs a prior call to Start().
56 // Otherwise, it fails (returns false).
57 virtual bool Stop();
58
repo sync06726552013-05-28 14:19:53 -070059 // Pauses a timer. If the timer is stopped, this call starts the timer in
60 // the paused state. Fails (returns false) if the timer is already paused.
61 virtual bool Pause();
62
63 // Restarts a paused timer (or starts a stopped timer). This method fails
64 // (returns false) if the timer is already running; otherwise, returns true.
65 virtual bool Resume();
66
Bruno Rochabe388f32011-08-02 12:40:17 -070067 // Resets the timer, erasing the current duration being tracked. Always
68 // returns true.
69 virtual bool Reset();
70
71 // Returns whether the timer has started or not.
72 virtual bool HasStarted() const;
73
74 // Stores the current elapsed time in |elapsed_time|. If timer is stopped,
75 // stores the elapsed time from when Stop() was last called. Otherwise,
76 // calculates and stores the elapsed time since the last Start().
77 // Returns false if the timer was never Start()'ed or if called with a null
78 // pointer argument.
79 virtual bool GetElapsedTime(base::TimeDelta* elapsed_time) const;
80
81 private:
repo sync06726552013-05-28 14:19:53 -070082 enum TimerState { kTimerStopped, kTimerRunning, kTimerPaused };
Bruno Rochabe388f32011-08-02 12:40:17 -070083 friend class TimerTest;
84 friend class TimerReporterTest;
Bruno Rochabe388f32011-08-02 12:40:17 -070085 FRIEND_TEST(TimerReporterTest, StartStopReport);
repo sync06726552013-05-28 14:19:53 -070086 FRIEND_TEST(TimerTest, InvalidElapsedTime);
87 FRIEND_TEST(TimerTest, InvalidStop);
88 FRIEND_TEST(TimerTest, PauseResumeStop);
89 FRIEND_TEST(TimerTest, PauseStartStopResume);
90 FRIEND_TEST(TimerTest, PauseStop);
91 FRIEND_TEST(TimerTest, Reset);
92 FRIEND_TEST(TimerTest, ReStart);
93 FRIEND_TEST(TimerTest, ResumeStartStopPause);
94 FRIEND_TEST(TimerTest, SeparatedTimers);
95 FRIEND_TEST(TimerTest, StartPauseResumePauseResumeStop);
96 FRIEND_TEST(TimerTest, StartPauseResumePauseStop);
97 FRIEND_TEST(TimerTest, StartPauseResumeStop);
98 FRIEND_TEST(TimerTest, StartPauseStop);
99 FRIEND_TEST(TimerTest, StartResumeStop);
100 FRIEND_TEST(TimerTest, StartStop);
Bruno Rochabe388f32011-08-02 12:40:17 -0700101
102 // Elapsed time of the last use of the timer.
103 base::TimeDelta elapsed_time_;
104
105 // Starting time value.
106 base::TimeTicks start_time_;
107
repo sync06726552013-05-28 14:19:53 -0700108 // Whether the timer is running, stopped, or paused.
109 TimerState timer_state_;
Bruno Rochabe388f32011-08-02 12:40:17 -0700110
111 // Wrapper for the calls to the system clock.
112 scoped_ptr<ClockWrapper> clock_wrapper_;
113
114 DISALLOW_COPY_AND_ASSIGN(Timer);
115};
116
117// Extends the Timer class to report the elapsed time in milliseconds through
118// the UMA metrics library.
119class TimerReporter : public Timer {
120 public:
121 // Initializes the timer by providing a |histogram_name| to report to with
122 // |min|, |max| and |num_buckets| attributes for the histogram.
123 TimerReporter(const std::string& histogram_name, int min, int max,
124 int num_buckets);
125 virtual ~TimerReporter() {}
126
127 // Sets the metrics library used by all instances of this class.
128 static void set_metrics_lib(MetricsLibraryInterface* metrics_lib) {
129 metrics_lib_ = metrics_lib;
130 }
131
132 // Reports the current duration to UMA, in milliseconds. Returns false if
repo sync1bc9ce02013-03-22 17:21:57 -0700133 // there is nothing to report, e.g. a metrics library is not set.
Bruno Rochabe388f32011-08-02 12:40:17 -0700134 virtual bool ReportMilliseconds() const;
135
136 // Accessor methods.
137 const std::string& histogram_name() const { return histogram_name_; }
138 int min() const { return min_; }
139 int max() const { return max_; }
140 int num_buckets() const { return num_buckets_; }
141
142 private:
143 friend class TimerReporterTest;
144 FRIEND_TEST(TimerReporterTest, StartStopReport);
145 FRIEND_TEST(TimerReporterTest, InvalidReport);
146
147 static MetricsLibraryInterface* metrics_lib_;
148 std::string histogram_name_;
149 int min_;
150 int max_;
151 int num_buckets_;
152
153 DISALLOW_COPY_AND_ASSIGN(TimerReporter);
154};
155
156} // namespace chromeos_metrics
157
158#endif // METRICS_TIMER_H_