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