1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TIMER_WALL_CLOCK_TIMER_H_ 6 #define BASE_TIMER_WALL_CLOCK_TIMER_H_ 7 8 #include "base/base_export.h" 9 #include "base/functional/bind.h" 10 #include "base/functional/callback.h" 11 #include "base/location.h" 12 #include "base/memory/raw_ptr.h" 13 #include "base/power_monitor/power_observer.h" 14 #include "base/time/default_clock.h" 15 #include "base/time/time.h" 16 #include "base/timer/timer.h" 17 18 namespace base { 19 class Clock; 20 class TickClock; 21 22 // WallClockTimer is based on OneShotTimer and provides a simple timer API 23 // which is mostly similar to OneShotTimer's API. The main difference is that 24 // WallClockTimer is using Time (which is system-dependent) to schedule task. 25 // WallClockTimer calls you back once scheduled time has come. 26 // 27 // Comparison with OneShotTimer: WallClockTimer runs |user_task_| after |delay_| 28 // expires according to usual time, while OneShotTimer runs |user_task_| after 29 // |delay_| expires according to TimeTicks which may freeze on some platforms 30 // when power suspends (desktop falls asleep). On platforms where TimeTicks 31 // don't freeze, the WallClockTimer has the same behavior as OneShotTimer. 32 // 33 // The API is not thread safe. All methods must be called from the same 34 // sequence (not necessarily the construction sequence), except for the 35 // destructor. 36 // - The destructor may be called from any sequence when the timer is not 37 // running and there is no scheduled task active. 38 class BASE_EXPORT WallClockTimer : public PowerSuspendObserver { 39 public: 40 // Constructs a timer. Start() must be called later to start the timer. 41 // If |clock| is provided, it's used instead of 42 // DefaultClock::GetInstance() to calulate timer's delay. If |tick_clock| 43 // is provided, it's used instead of TimeTicks::Now() to get TimeTicks when 44 // scheduling tasks. 45 WallClockTimer(); 46 WallClockTimer(const Clock* clock, const TickClock* tick_clock); 47 WallClockTimer(const WallClockTimer&) = delete; 48 WallClockTimer& operator=(const WallClockTimer&) = delete; 49 50 ~WallClockTimer() override; 51 52 // Starts the timer to run at the given |desired_run_time|. If the timer is 53 // already running, it will be replaced to call the given |user_task|. 54 virtual void Start(const Location& posted_from, 55 Time desired_run_time, 56 OnceClosure user_task); 57 58 // Starts the timer to run at the given |desired_run_time|. If the timer is 59 // already running, it will be replaced to call a task formed from 60 // |receiver|->*|method|. 61 template <class Receiver> Start(const Location & posted_from,Time desired_run_time,Receiver * receiver,void (Receiver::* method)())62 void Start(const Location& posted_from, 63 Time desired_run_time, 64 Receiver* receiver, 65 void (Receiver::*method)()) { 66 Start(posted_from, desired_run_time, 67 BindOnce(method, Unretained(receiver))); 68 } 69 70 // Stops the timer. It is a no-op if the timer is not running. 71 void Stop(); 72 73 // Returns true if the timer is running. 74 bool IsRunning() const; 75 76 // PowerSuspendObserver: 77 void OnResume() override; 78 desired_run_time()79 Time desired_run_time() const { return desired_run_time_; } 80 81 private: 82 void AddObserver(); 83 84 void RemoveObserver(); 85 86 // Actually run scheduled task 87 void RunUserTask(); 88 89 // Returns the current time count. 90 Time Now() const; 91 92 bool observer_added_ = false; 93 94 // Location in user code. 95 Location posted_from_; 96 97 // The desired run time of |user_task_|. 98 Time desired_run_time_; 99 100 OnceClosure user_task_; 101 102 // Timer which should notify to run task in the period while system awake 103 OneShotTimer timer_; 104 105 // The clock used to calculate the run time for scheduled tasks. 106 const raw_ptr<const Clock> clock_ = DefaultClock::GetInstance(); 107 }; 108 109 } // namespace base 110 111 #endif // BASE_TIMER_WALL_CLOCK_TIMER_H_ 112