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