Home | History | Annotate | Download | only in metrics
      1 /*
      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  */
     16 
     17 // Timer - class that provides timer tracking.
     18 
     19 #ifndef METRICS_TIMER_H_
     20 #define METRICS_TIMER_H_
     21 
     22 #include <memory>
     23 #include <string>
     24 
     25 #include <base/macros.h>
     26 #include <base/time/time.h>
     27 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     28 
     29 class MetricsLibraryInterface;
     30 
     31 namespace chromeos_metrics {
     32 
     33 class 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.
     44 class 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.
     57 class 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 
     71   // 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 
     79   // 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:
     94   enum TimerState { kTimerStopped, kTimerRunning, kTimerPaused };
     95   friend class TimerTest;
     96   friend class TimerReporterTest;
     97   FRIEND_TEST(TimerReporterTest, StartStopReport);
     98   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);
    113 
    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 
    120   // Whether the timer is running, stopped, or paused.
    121   TimerState timer_state_;
    122 
    123   // Wrapper for the calls to the system clock.
    124   std::unique_ptr<ClockWrapper> clock_wrapper_;
    125 
    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.
    131 class 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
    145   // there is nothing to report, e.g. a metrics library is not set.
    146   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_
    171