| /* | 
 |  * Copyright (C) 2015 The Android Open Source Project | 
 |  * | 
 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 |  * you may not use this file except in compliance with the License. | 
 |  * You may obtain a copy of the License at | 
 |  * | 
 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, software | 
 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |  * See the License for the specific language governing permissions and | 
 |  * limitations under the License. | 
 |  */ | 
 |  | 
 | // Timer - class that provides timer tracking. | 
 |  | 
 | #ifndef METRICS_TIMER_H_ | 
 | #define METRICS_TIMER_H_ | 
 |  | 
 | #include <string> | 
 |  | 
 | #include <base/macros.h> | 
 | #include <base/memory/scoped_ptr.h> | 
 | #include <base/time/time.h> | 
 | #include <gtest/gtest_prod.h>  // for FRIEND_TEST | 
 |  | 
 | class MetricsLibraryInterface; | 
 |  | 
 | namespace chromeos_metrics { | 
 |  | 
 | class TimerInterface { | 
 |  public: | 
 |   virtual ~TimerInterface() {} | 
 |  | 
 |   virtual bool Start() = 0; | 
 |   virtual bool Stop() = 0; | 
 |   virtual bool Reset() = 0; | 
 |   virtual bool HasStarted() const = 0; | 
 | }; | 
 |  | 
 | // Wrapper for calls to the system clock. | 
 | class ClockWrapper { | 
 |  public: | 
 |   ClockWrapper() {} | 
 |   virtual ~ClockWrapper() {} | 
 |  | 
 |   // Returns the current time from the system. | 
 |   virtual base::TimeTicks GetCurrentTime() const; | 
 |  | 
 |  private: | 
 |   DISALLOW_COPY_AND_ASSIGN(ClockWrapper); | 
 | }; | 
 |  | 
 | // Implements a Timer. | 
 | class Timer : public TimerInterface { | 
 |  public: | 
 |   Timer(); | 
 |   virtual ~Timer() {} | 
 |  | 
 |   // Starts the timer. If a timer is already running, also resets current | 
 |   // timer. Always returns true. | 
 |   virtual bool Start(); | 
 |  | 
 |   // Stops the timer and calculates the total time elapsed between now and when | 
 |   // Start() was called. Note that this method needs a prior call to Start(). | 
 |   // Otherwise, it fails (returns false). | 
 |   virtual bool Stop(); | 
 |  | 
 |   // Pauses a timer.  If the timer is stopped, this call starts the timer in | 
 |   // the paused state. Fails (returns false) if the timer is already paused. | 
 |   virtual bool Pause(); | 
 |  | 
 |   // Restarts a paused timer (or starts a stopped timer). This method fails | 
 |   // (returns false) if the timer is already running; otherwise, returns true. | 
 |   virtual bool Resume(); | 
 |  | 
 |   // Resets the timer, erasing the current duration being tracked. Always | 
 |   // returns true. | 
 |   virtual bool Reset(); | 
 |  | 
 |   // Returns whether the timer has started or not. | 
 |   virtual bool HasStarted() const; | 
 |  | 
 |   // Stores the current elapsed time in |elapsed_time|. If timer is stopped, | 
 |   // stores the elapsed time from when Stop() was last called. Otherwise, | 
 |   // calculates and stores the elapsed time since the last Start(). | 
 |   // Returns false if the timer was never Start()'ed or if called with a null | 
 |   // pointer argument. | 
 |   virtual bool GetElapsedTime(base::TimeDelta* elapsed_time) const; | 
 |  | 
 |  private: | 
 |   enum TimerState { kTimerStopped, kTimerRunning, kTimerPaused }; | 
 |   friend class TimerTest; | 
 |   friend class TimerReporterTest; | 
 |   FRIEND_TEST(TimerReporterTest, StartStopReport); | 
 |   FRIEND_TEST(TimerTest, InvalidElapsedTime); | 
 |   FRIEND_TEST(TimerTest, InvalidStop); | 
 |   FRIEND_TEST(TimerTest, PauseResumeStop); | 
 |   FRIEND_TEST(TimerTest, PauseStartStopResume); | 
 |   FRIEND_TEST(TimerTest, PauseStop); | 
 |   FRIEND_TEST(TimerTest, Reset); | 
 |   FRIEND_TEST(TimerTest, ReStart); | 
 |   FRIEND_TEST(TimerTest, ResumeStartStopPause); | 
 |   FRIEND_TEST(TimerTest, SeparatedTimers); | 
 |   FRIEND_TEST(TimerTest, StartPauseResumePauseResumeStop); | 
 |   FRIEND_TEST(TimerTest, StartPauseResumePauseStop); | 
 |   FRIEND_TEST(TimerTest, StartPauseResumeStop); | 
 |   FRIEND_TEST(TimerTest, StartPauseStop); | 
 |   FRIEND_TEST(TimerTest, StartResumeStop); | 
 |   FRIEND_TEST(TimerTest, StartStop); | 
 |  | 
 |   // Elapsed time of the last use of the timer. | 
 |   base::TimeDelta elapsed_time_; | 
 |  | 
 |   // Starting time value. | 
 |   base::TimeTicks start_time_; | 
 |  | 
 |   // Whether the timer is running, stopped, or paused. | 
 |   TimerState timer_state_; | 
 |  | 
 |   // Wrapper for the calls to the system clock. | 
 |   scoped_ptr<ClockWrapper> clock_wrapper_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(Timer); | 
 | }; | 
 |  | 
 | // Extends the Timer class to report the elapsed time in milliseconds through | 
 | // the UMA metrics library. | 
 | class TimerReporter : public Timer { | 
 |  public: | 
 |   // Initializes the timer by providing a |histogram_name| to report to with | 
 |   // |min|, |max| and |num_buckets| attributes for the histogram. | 
 |   TimerReporter(const std::string& histogram_name, int min, int max, | 
 |                 int num_buckets); | 
 |   virtual ~TimerReporter() {} | 
 |  | 
 |   // Sets the metrics library used by all instances of this class. | 
 |   static void set_metrics_lib(MetricsLibraryInterface* metrics_lib) { | 
 |     metrics_lib_ = metrics_lib; | 
 |   } | 
 |  | 
 |   // Reports the current duration to UMA, in milliseconds. Returns false if | 
 |   // there is nothing to report, e.g. a metrics library is not set. | 
 |   virtual bool ReportMilliseconds() const; | 
 |  | 
 |   // Accessor methods. | 
 |   const std::string& histogram_name() const { return histogram_name_; } | 
 |   int min() const { return min_; } | 
 |   int max() const { return max_; } | 
 |   int num_buckets() const { return num_buckets_; } | 
 |  | 
 |  private: | 
 |   friend class TimerReporterTest; | 
 |   FRIEND_TEST(TimerReporterTest, StartStopReport); | 
 |   FRIEND_TEST(TimerReporterTest, InvalidReport); | 
 |  | 
 |   static MetricsLibraryInterface* metrics_lib_; | 
 |   std::string histogram_name_; | 
 |   int min_; | 
 |   int max_; | 
 |   int num_buckets_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(TimerReporter); | 
 | }; | 
 |  | 
 | }  // namespace chromeos_metrics | 
 |  | 
 | #endif  // METRICS_TIMER_H_ |