1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // A "timer" takes care of invoking a callback in the future, once or 6*6777b538SAndroid Build Coastguard Worker // repeatedly. The callback is invoked: 7*6777b538SAndroid Build Coastguard Worker // - OneShotTimer: Once after a `TimeDelta` delay has elapsed. 8*6777b538SAndroid Build Coastguard Worker // - RetainingOneShotTimer: Same as OneShotTimer, but the callback is retained 9*6777b538SAndroid Build Coastguard Worker // after being executed, allowing another invocation to be scheduled with 10*6777b538SAndroid Build Coastguard Worker // Reset() without specifying the callback again. 11*6777b538SAndroid Build Coastguard Worker // - DeadlineTimer: Once at the specified `TimeTicks` time. 12*6777b538SAndroid Build Coastguard Worker // - RepeatingTimer: Repeatedly, with a specified `TimeDelta` delay before the 13*6777b538SAndroid Build Coastguard Worker // first invocation and between invocations. 14*6777b538SAndroid Build Coastguard Worker // - MetronomeTimer: Repeatedly, with a specified `TimeDelta` delay between the 15*6777b538SAndroid Build Coastguard Worker // beginning of each invocations such that a constant phase is respected. 16*6777b538SAndroid Build Coastguard Worker // (Retaining)OneShotTimer and RepeatingTimer automatically apply some leeway to 17*6777b538SAndroid Build Coastguard Worker // the delay whereas DeadlineTimer and MetronomeTimer allow more control over 18*6777b538SAndroid Build Coastguard Worker // the requested time. As a result, the former are generally more 19*6777b538SAndroid Build Coastguard Worker // power-efficient. 20*6777b538SAndroid Build Coastguard Worker // Prefer using (Retaining)OneShotTimer and RepeatingTimer because they 21*6777b538SAndroid Build Coastguard Worker // automatically apply some leeway to the delay which enables power-efficient 22*6777b538SAndroid Build Coastguard Worker // scheduling. 23*6777b538SAndroid Build Coastguard Worker 24*6777b538SAndroid Build Coastguard Worker // Scheduled invocations can be cancelled with Stop() or by deleting the 25*6777b538SAndroid Build Coastguard Worker // Timer. The latter makes it easy to ensure that an object is not accessed by a 26*6777b538SAndroid Build Coastguard Worker // Timer after it has been deleted: just make the Timer a member of the object 27*6777b538SAndroid Build Coastguard Worker // which receives Timer events (see example below). 28*6777b538SAndroid Build Coastguard Worker // 29*6777b538SAndroid Build Coastguard Worker // Sample RepeatingTimer usage: 30*6777b538SAndroid Build Coastguard Worker // 31*6777b538SAndroid Build Coastguard Worker // class MyClass { 32*6777b538SAndroid Build Coastguard Worker // public: 33*6777b538SAndroid Build Coastguard Worker // void StartDoingStuff() { 34*6777b538SAndroid Build Coastguard Worker // timer_.Start(FROM_HERE, base::Seconds(1), 35*6777b538SAndroid Build Coastguard Worker // this, &MyClass::DoStuff); 36*6777b538SAndroid Build Coastguard Worker // // Alternative form if the callback is not bound to `this` or 37*6777b538SAndroid Build Coastguard Worker // // requires arguments: 38*6777b538SAndroid Build Coastguard Worker // // timer_.Start(FROM_HERE, base::Seconds(1), 39*6777b538SAndroid Build Coastguard Worker // // base::BindRepeating(&MyFunction, 42)); 40*6777b538SAndroid Build Coastguard Worker // } 41*6777b538SAndroid Build Coastguard Worker // void StopDoingStuff() { 42*6777b538SAndroid Build Coastguard Worker // timer_.Stop(); 43*6777b538SAndroid Build Coastguard Worker // } 44*6777b538SAndroid Build Coastguard Worker // private: 45*6777b538SAndroid Build Coastguard Worker // void DoStuff() { 46*6777b538SAndroid Build Coastguard Worker // // This method is called every second to do stuff. 47*6777b538SAndroid Build Coastguard Worker // ... 48*6777b538SAndroid Build Coastguard Worker // } 49*6777b538SAndroid Build Coastguard Worker // base::RepeatingTimer timer_; 50*6777b538SAndroid Build Coastguard Worker // }; 51*6777b538SAndroid Build Coastguard Worker // 52*6777b538SAndroid Build Coastguard Worker // These APIs are not thread safe. When a method is called (except the 53*6777b538SAndroid Build Coastguard Worker // constructor), all further method calls must be on the same sequence until 54*6777b538SAndroid Build Coastguard Worker // Stop(). Once stopped, it may be destroyed or restarted on another sequence. 55*6777b538SAndroid Build Coastguard Worker // 56*6777b538SAndroid Build Coastguard Worker // By default, the scheduled tasks will be run on the same sequence that the 57*6777b538SAndroid Build Coastguard Worker // Timer was *started on*. To mock time in unit tests, some old tests used 58*6777b538SAndroid Build Coastguard Worker // SetTaskRunner() to schedule the delay on a test-controlled TaskRunner. The 59*6777b538SAndroid Build Coastguard Worker // modern and preferred approach to mock time is to use TaskEnvironment's 60*6777b538SAndroid Build Coastguard Worker // MOCK_TIME mode. 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TIMER_TIMER_H_ 63*6777b538SAndroid Build Coastguard Worker #define BASE_TIMER_TIMER_H_ 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // IMPORTANT: If you change timer code, make sure that all tests (including 66*6777b538SAndroid Build Coastguard Worker // disabled ones) from timer_unittests.cc pass locally. Some are disabled 67*6777b538SAndroid Build Coastguard Worker // because they're flaky on the buildbot, but when you run them locally you 68*6777b538SAndroid Build Coastguard Worker // should be able to tell the difference. 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 71*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h" 72*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 73*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h" 74*6777b538SAndroid Build Coastguard Worker #include "base/location.h" 75*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 76*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 77*6777b538SAndroid Build Coastguard Worker #include "base/task/delayed_task_handle.h" 78*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h" 79*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 80*6777b538SAndroid Build Coastguard Worker #include "base/types/strong_alias.h" 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker namespace base { 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker class TickClock; 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker namespace internal { 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker // This class wraps logic shared by all timers. 89*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT TimerBase { 90*6777b538SAndroid Build Coastguard Worker public: 91*6777b538SAndroid Build Coastguard Worker TimerBase(const TimerBase&) = delete; 92*6777b538SAndroid Build Coastguard Worker TimerBase& operator=(const TimerBase&) = delete; 93*6777b538SAndroid Build Coastguard Worker 94*6777b538SAndroid Build Coastguard Worker virtual ~TimerBase(); 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // Returns true if the timer is running (i.e., not stopped). 97*6777b538SAndroid Build Coastguard Worker bool IsRunning() const; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker // Sets the task runner on which the delayed task should be scheduled when 100*6777b538SAndroid Build Coastguard Worker // this Timer is running. This method can only be called while this Timer 101*6777b538SAndroid Build Coastguard Worker // isn't running. If this is used to mock time in tests, the modern and 102*6777b538SAndroid Build Coastguard Worker // preferred approach is to use TaskEnvironment::TimeSource::MOCK_TIME. To 103*6777b538SAndroid Build Coastguard Worker // avoid racy usage of Timer, |task_runner| must run tasks on the same 104*6777b538SAndroid Build Coastguard Worker // sequence which this Timer is bound to (started from). TODO(gab): Migrate 105*6777b538SAndroid Build Coastguard Worker // callers using this as a test seam to 106*6777b538SAndroid Build Coastguard Worker // TaskEnvironment::TimeSource::MOCK_TIME. 107*6777b538SAndroid Build Coastguard Worker virtual void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner); 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker // Call this method to stop the timer and cancel all previously scheduled 110*6777b538SAndroid Build Coastguard Worker // tasks. It is a no-op if the timer is not running. 111*6777b538SAndroid Build Coastguard Worker virtual void Stop(); 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker protected: 114*6777b538SAndroid Build Coastguard Worker // Constructs a timer. Start must be called later to set task info. 115*6777b538SAndroid Build Coastguard Worker explicit TimerBase(const Location& posted_from = Location()); 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker virtual void OnStop() = 0; 118*6777b538SAndroid Build Coastguard Worker 119*6777b538SAndroid Build Coastguard Worker // Disables the scheduled task and abandons it so that it no longer refers 120*6777b538SAndroid Build Coastguard Worker // back to this object. 121*6777b538SAndroid Build Coastguard Worker void AbandonScheduledTask(); 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker // Returns the task runner on which the task should be scheduled. If the 124*6777b538SAndroid Build Coastguard Worker // corresponding |task_runner_| field is null, the task runner for the current 125*6777b538SAndroid Build Coastguard Worker // sequence is returned. 126*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> GetTaskRunner(); 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker // The task runner on which the task should be scheduled. If it is null, the 129*6777b538SAndroid Build Coastguard Worker // task runner for the current sequence will be used. 130*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner_; 131*6777b538SAndroid Build Coastguard Worker 132*6777b538SAndroid Build Coastguard Worker // Timer isn't thread-safe and while it is running, it must only be used on 133*6777b538SAndroid Build Coastguard Worker // the same sequence until fully Stop()'ed. Once stopped, it may be destroyed 134*6777b538SAndroid Build Coastguard Worker // or restarted on another sequence. 135*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(sequence_checker_); 136*6777b538SAndroid Build Coastguard Worker 137*6777b538SAndroid Build Coastguard Worker // Location in user code. 138*6777b538SAndroid Build Coastguard Worker Location posted_from_ GUARDED_BY_CONTEXT(sequence_checker_); 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker // The handle to the posted delayed task. 141*6777b538SAndroid Build Coastguard Worker DelayedTaskHandle delayed_task_handle_ GUARDED_BY_CONTEXT(sequence_checker_); 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker // Callback invoked when the timer is ready. This is saved as a member to 144*6777b538SAndroid Build Coastguard Worker // avoid rebinding every time the Timer fires. Lazy initialized the first time 145*6777b538SAndroid Build Coastguard Worker // the Timer is started. 146*6777b538SAndroid Build Coastguard Worker RepeatingClosure timer_callback_; 147*6777b538SAndroid Build Coastguard Worker }; 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 150*6777b538SAndroid Build Coastguard Worker // This class wraps logic shared by (Retaining)OneShotTimer and RepeatingTimer. 151*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DelayTimerBase : public TimerBase { 152*6777b538SAndroid Build Coastguard Worker public: 153*6777b538SAndroid Build Coastguard Worker DelayTimerBase(const DelayTimerBase&) = delete; 154*6777b538SAndroid Build Coastguard Worker DelayTimerBase& operator=(const DelayTimerBase&) = delete; 155*6777b538SAndroid Build Coastguard Worker 156*6777b538SAndroid Build Coastguard Worker ~DelayTimerBase() override; 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker // Returns the current delay for this timer. 159*6777b538SAndroid Build Coastguard Worker TimeDelta GetCurrentDelay() const; 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker // Call this method to reset the timer delay. The user task must be set. If 162*6777b538SAndroid Build Coastguard Worker // the timer is not running, this will start it by posting a task. 163*6777b538SAndroid Build Coastguard Worker virtual void Reset(); 164*6777b538SAndroid Build Coastguard Worker 165*6777b538SAndroid Build Coastguard Worker // DEPRECATED. Call Stop() instead. 166*6777b538SAndroid Build Coastguard Worker // TODO(1262205): Remove this method and all callers. 167*6777b538SAndroid Build Coastguard Worker void AbandonAndStop(); 168*6777b538SAndroid Build Coastguard Worker desired_run_time()169*6777b538SAndroid Build Coastguard Worker TimeTicks desired_run_time() const { 170*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 171*6777b538SAndroid Build Coastguard Worker return desired_run_time_; 172*6777b538SAndroid Build Coastguard Worker } 173*6777b538SAndroid Build Coastguard Worker 174*6777b538SAndroid Build Coastguard Worker protected: 175*6777b538SAndroid Build Coastguard Worker // Constructs a timer. Start must be called later to set task info. 176*6777b538SAndroid Build Coastguard Worker // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get 177*6777b538SAndroid Build Coastguard Worker // TimeTicks when scheduling tasks. 178*6777b538SAndroid Build Coastguard Worker explicit DelayTimerBase(const TickClock* tick_clock = nullptr); 179*6777b538SAndroid Build Coastguard Worker 180*6777b538SAndroid Build Coastguard Worker // Construct a timer with task info. 181*6777b538SAndroid Build Coastguard Worker // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get 182*6777b538SAndroid Build Coastguard Worker // TimeTicks when scheduling tasks. 183*6777b538SAndroid Build Coastguard Worker DelayTimerBase(const Location& posted_from, 184*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 185*6777b538SAndroid Build Coastguard Worker const TickClock* tick_clock = nullptr); 186*6777b538SAndroid Build Coastguard Worker 187*6777b538SAndroid Build Coastguard Worker virtual void RunUserTask() = 0; 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker // Schedules |OnScheduledTaskInvoked()| to run on the current sequence with 190*6777b538SAndroid Build Coastguard Worker // the given |delay|. |desired_run_time_| is reset to Now() + delay. 191*6777b538SAndroid Build Coastguard Worker void ScheduleNewTask(TimeDelta delay); 192*6777b538SAndroid Build Coastguard Worker 193*6777b538SAndroid Build Coastguard Worker void StartInternal(const Location& posted_from, TimeDelta delay); 194*6777b538SAndroid Build Coastguard Worker 195*6777b538SAndroid Build Coastguard Worker private: 196*6777b538SAndroid Build Coastguard Worker // DCHECKs that the user task is not null. Used to diagnose a recurring bug 197*6777b538SAndroid Build Coastguard Worker // where Reset() is called on a OneShotTimer that has already fired. 198*6777b538SAndroid Build Coastguard Worker virtual void EnsureNonNullUserTask() = 0; 199*6777b538SAndroid Build Coastguard Worker 200*6777b538SAndroid Build Coastguard Worker // Returns the current tick count. 201*6777b538SAndroid Build Coastguard Worker TimeTicks Now() const; 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Worker // Called when the scheduled task is invoked. Will run the |user_task| if the 204*6777b538SAndroid Build Coastguard Worker // timer is still running and |desired_run_time_| was reached. 205*6777b538SAndroid Build Coastguard Worker void OnScheduledTaskInvoked(); 206*6777b538SAndroid Build Coastguard Worker 207*6777b538SAndroid Build Coastguard Worker // Delay requested by user. 208*6777b538SAndroid Build Coastguard Worker TimeDelta delay_ GUARDED_BY_CONTEXT(sequence_checker_); 209*6777b538SAndroid Build Coastguard Worker 210*6777b538SAndroid Build Coastguard Worker // The desired run time of |user_task_|. The user may update this at any time, 211*6777b538SAndroid Build Coastguard Worker // even if their previous request has not run yet. This time can be a "zero" 212*6777b538SAndroid Build Coastguard Worker // TimeTicks if the task must be run immediately. 213*6777b538SAndroid Build Coastguard Worker TimeTicks desired_run_time_ GUARDED_BY_CONTEXT(sequence_checker_); 214*6777b538SAndroid Build Coastguard Worker 215*6777b538SAndroid Build Coastguard Worker // The tick clock used to calculate the run time for scheduled tasks. 216*6777b538SAndroid Build Coastguard Worker const raw_ptr<const TickClock> tick_clock_ 217*6777b538SAndroid Build Coastguard Worker GUARDED_BY_CONTEXT(sequence_checker_); 218*6777b538SAndroid Build Coastguard Worker }; 219*6777b538SAndroid Build Coastguard Worker 220*6777b538SAndroid Build Coastguard Worker } // namespace internal 221*6777b538SAndroid Build Coastguard Worker 222*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 223*6777b538SAndroid Build Coastguard Worker // A simple, one-shot timer. See usage notes at the top of the file. 224*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT OneShotTimer : public internal::DelayTimerBase { 225*6777b538SAndroid Build Coastguard Worker public: 226*6777b538SAndroid Build Coastguard Worker OneShotTimer(); 227*6777b538SAndroid Build Coastguard Worker explicit OneShotTimer(const TickClock* tick_clock); 228*6777b538SAndroid Build Coastguard Worker 229*6777b538SAndroid Build Coastguard Worker OneShotTimer(const OneShotTimer&) = delete; 230*6777b538SAndroid Build Coastguard Worker OneShotTimer& operator=(const OneShotTimer&) = delete; 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker ~OneShotTimer() override; 233*6777b538SAndroid Build Coastguard Worker 234*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 235*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call the given |user_task|. 236*6777b538SAndroid Build Coastguard Worker virtual void Start(const Location& posted_from, 237*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 238*6777b538SAndroid Build Coastguard Worker OnceClosure user_task); 239*6777b538SAndroid Build Coastguard Worker 240*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 241*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call a task formed from 242*6777b538SAndroid Build Coastguard Worker // |receiver->*method|. 243*6777b538SAndroid Build Coastguard Worker template <class Receiver> Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())244*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 245*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 246*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 247*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)()) { 248*6777b538SAndroid Build Coastguard Worker Start(posted_from, delay, BindOnce(method, Unretained(receiver))); 249*6777b538SAndroid Build Coastguard Worker } 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker // Run the scheduled task immediately, and stop the timer. The timer needs to 252*6777b538SAndroid Build Coastguard Worker // be running. 253*6777b538SAndroid Build Coastguard Worker virtual void FireNow(); 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker private: 256*6777b538SAndroid Build Coastguard Worker void OnStop() final; 257*6777b538SAndroid Build Coastguard Worker void RunUserTask() final; 258*6777b538SAndroid Build Coastguard Worker void EnsureNonNullUserTask() final; 259*6777b538SAndroid Build Coastguard Worker 260*6777b538SAndroid Build Coastguard Worker OnceClosure user_task_; 261*6777b538SAndroid Build Coastguard Worker }; 262*6777b538SAndroid Build Coastguard Worker 263*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 264*6777b538SAndroid Build Coastguard Worker // A simple, repeating timer. See usage notes at the top of the file. 265*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT RepeatingTimer : public internal::DelayTimerBase { 266*6777b538SAndroid Build Coastguard Worker public: 267*6777b538SAndroid Build Coastguard Worker RepeatingTimer(); 268*6777b538SAndroid Build Coastguard Worker explicit RepeatingTimer(const TickClock* tick_clock); 269*6777b538SAndroid Build Coastguard Worker 270*6777b538SAndroid Build Coastguard Worker RepeatingTimer(const RepeatingTimer&) = delete; 271*6777b538SAndroid Build Coastguard Worker RepeatingTimer& operator=(const RepeatingTimer&) = delete; 272*6777b538SAndroid Build Coastguard Worker 273*6777b538SAndroid Build Coastguard Worker ~RepeatingTimer() override; 274*6777b538SAndroid Build Coastguard Worker 275*6777b538SAndroid Build Coastguard Worker RepeatingTimer(const Location& posted_from, 276*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 277*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task); 278*6777b538SAndroid Build Coastguard Worker RepeatingTimer(const Location& posted_from, 279*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 280*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task, 281*6777b538SAndroid Build Coastguard Worker const TickClock* tick_clock); 282*6777b538SAndroid Build Coastguard Worker 283*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 284*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call the given |user_task|. 285*6777b538SAndroid Build Coastguard Worker virtual void Start(const Location& posted_from, 286*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 287*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task); 288*6777b538SAndroid Build Coastguard Worker 289*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 290*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call a task formed from 291*6777b538SAndroid Build Coastguard Worker // |receiver->*method|. 292*6777b538SAndroid Build Coastguard Worker template <class Receiver> Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())293*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 294*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 295*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 296*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)()) { 297*6777b538SAndroid Build Coastguard Worker Start(posted_from, delay, BindRepeating(method, Unretained(receiver))); 298*6777b538SAndroid Build Coastguard Worker } 299*6777b538SAndroid Build Coastguard Worker user_task()300*6777b538SAndroid Build Coastguard Worker const RepeatingClosure& user_task() const { return user_task_; } 301*6777b538SAndroid Build Coastguard Worker 302*6777b538SAndroid Build Coastguard Worker private: 303*6777b538SAndroid Build Coastguard Worker // Mark this final, so that the destructor can call this safely. 304*6777b538SAndroid Build Coastguard Worker void OnStop() final; 305*6777b538SAndroid Build Coastguard Worker void RunUserTask() override; 306*6777b538SAndroid Build Coastguard Worker void EnsureNonNullUserTask() final; 307*6777b538SAndroid Build Coastguard Worker 308*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task_; 309*6777b538SAndroid Build Coastguard Worker }; 310*6777b538SAndroid Build Coastguard Worker 311*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 312*6777b538SAndroid Build Coastguard Worker // A simple, one-shot timer with the retained |user_task| which is reused when 313*6777b538SAndroid Build Coastguard Worker // Reset() is invoked. See usage notes at the top of the file. 314*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT RetainingOneShotTimer : public internal::DelayTimerBase { 315*6777b538SAndroid Build Coastguard Worker public: 316*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer(); 317*6777b538SAndroid Build Coastguard Worker explicit RetainingOneShotTimer(const TickClock* tick_clock); 318*6777b538SAndroid Build Coastguard Worker 319*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer(const RetainingOneShotTimer&) = delete; 320*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer& operator=(const RetainingOneShotTimer&) = delete; 321*6777b538SAndroid Build Coastguard Worker 322*6777b538SAndroid Build Coastguard Worker ~RetainingOneShotTimer() override; 323*6777b538SAndroid Build Coastguard Worker 324*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer(const Location& posted_from, 325*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 326*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task); 327*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer(const Location& posted_from, 328*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 329*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task, 330*6777b538SAndroid Build Coastguard Worker const TickClock* tick_clock); 331*6777b538SAndroid Build Coastguard Worker 332*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 333*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call the given |user_task|. 334*6777b538SAndroid Build Coastguard Worker virtual void Start(const Location& posted_from, 335*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 336*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task); 337*6777b538SAndroid Build Coastguard Worker 338*6777b538SAndroid Build Coastguard Worker // Start the timer to run at the given |delay| from now. If the timer is 339*6777b538SAndroid Build Coastguard Worker // already running, it will be replaced to call a task formed from 340*6777b538SAndroid Build Coastguard Worker // |receiver->*method|. 341*6777b538SAndroid Build Coastguard Worker template <class Receiver> Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())342*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 343*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 344*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 345*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)()) { 346*6777b538SAndroid Build Coastguard Worker Start(posted_from, delay, BindRepeating(method, Unretained(receiver))); 347*6777b538SAndroid Build Coastguard Worker } 348*6777b538SAndroid Build Coastguard Worker user_task()349*6777b538SAndroid Build Coastguard Worker const RepeatingClosure& user_task() const { return user_task_; } 350*6777b538SAndroid Build Coastguard Worker 351*6777b538SAndroid Build Coastguard Worker private: 352*6777b538SAndroid Build Coastguard Worker // Mark this final, so that the destructor can call this safely. 353*6777b538SAndroid Build Coastguard Worker void OnStop() final; 354*6777b538SAndroid Build Coastguard Worker void RunUserTask() override; 355*6777b538SAndroid Build Coastguard Worker void EnsureNonNullUserTask() final; 356*6777b538SAndroid Build Coastguard Worker 357*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task_; 358*6777b538SAndroid Build Coastguard Worker }; 359*6777b538SAndroid Build Coastguard Worker 360*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 361*6777b538SAndroid Build Coastguard Worker // A Delay timer is like The Button from Lost. Once started, you have to keep 362*6777b538SAndroid Build Coastguard Worker // calling Reset otherwise it will call the given method on the sequence it was 363*6777b538SAndroid Build Coastguard Worker // initially Reset() from. 364*6777b538SAndroid Build Coastguard Worker // 365*6777b538SAndroid Build Coastguard Worker // Once created, it is inactive until Reset is called. Once |delay| seconds have 366*6777b538SAndroid Build Coastguard Worker // passed since the last call to Reset, the callback is made. Once the callback 367*6777b538SAndroid Build Coastguard Worker // has been made, it's inactive until Reset is called again. 368*6777b538SAndroid Build Coastguard Worker // 369*6777b538SAndroid Build Coastguard Worker // If destroyed, the timeout is canceled and will not occur even if already 370*6777b538SAndroid Build Coastguard Worker // inflight. 371*6777b538SAndroid Build Coastguard Worker class DelayTimer { 372*6777b538SAndroid Build Coastguard Worker public: 373*6777b538SAndroid Build Coastguard Worker template <class Receiver> DelayTimer(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())374*6777b538SAndroid Build Coastguard Worker DelayTimer(const Location& posted_from, 375*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 376*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 377*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)()) 378*6777b538SAndroid Build Coastguard Worker : DelayTimer(posted_from, delay, receiver, method, nullptr) {} 379*6777b538SAndroid Build Coastguard Worker 380*6777b538SAndroid Build Coastguard Worker template <class Receiver> DelayTimer(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)(),const TickClock * tick_clock)381*6777b538SAndroid Build Coastguard Worker DelayTimer(const Location& posted_from, 382*6777b538SAndroid Build Coastguard Worker TimeDelta delay, 383*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 384*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)(), 385*6777b538SAndroid Build Coastguard Worker const TickClock* tick_clock) 386*6777b538SAndroid Build Coastguard Worker : timer_(posted_from, 387*6777b538SAndroid Build Coastguard Worker delay, 388*6777b538SAndroid Build Coastguard Worker BindRepeating(method, Unretained(receiver)), 389*6777b538SAndroid Build Coastguard Worker tick_clock) {} 390*6777b538SAndroid Build Coastguard Worker 391*6777b538SAndroid Build Coastguard Worker DelayTimer(const DelayTimer&) = delete; 392*6777b538SAndroid Build Coastguard Worker DelayTimer& operator=(const DelayTimer&) = delete; 393*6777b538SAndroid Build Coastguard Worker Reset()394*6777b538SAndroid Build Coastguard Worker void Reset() { timer_.Reset(); } 395*6777b538SAndroid Build Coastguard Worker 396*6777b538SAndroid Build Coastguard Worker private: 397*6777b538SAndroid Build Coastguard Worker RetainingOneShotTimer timer_; 398*6777b538SAndroid Build Coastguard Worker }; 399*6777b538SAndroid Build Coastguard Worker 400*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 401*6777b538SAndroid Build Coastguard Worker // A one-shot timer that attempts to run |user_task| some time near specified 402*6777b538SAndroid Build Coastguard Worker // deadline. See usage notes at the top of the file. 403*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DeadlineTimer : public internal::TimerBase { 404*6777b538SAndroid Build Coastguard Worker public: 405*6777b538SAndroid Build Coastguard Worker DeadlineTimer(); 406*6777b538SAndroid Build Coastguard Worker ~DeadlineTimer() override; 407*6777b538SAndroid Build Coastguard Worker 408*6777b538SAndroid Build Coastguard Worker DeadlineTimer(const DeadlineTimer&) = delete; 409*6777b538SAndroid Build Coastguard Worker DeadlineTimer& operator=(const DeadlineTimer&) = delete; 410*6777b538SAndroid Build Coastguard Worker 411*6777b538SAndroid Build Coastguard Worker // Start the timer to run |user_task| near the specified |deadline| following 412*6777b538SAndroid Build Coastguard Worker // |delay_policy| If the timer is already running, it will be replaced to call 413*6777b538SAndroid Build Coastguard Worker // the given |user_task|. 414*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 415*6777b538SAndroid Build Coastguard Worker TimeTicks deadline, 416*6777b538SAndroid Build Coastguard Worker OnceClosure user_task, 417*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy delay_policy = 418*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy::kFlexiblePreferEarly); 419*6777b538SAndroid Build Coastguard Worker 420*6777b538SAndroid Build Coastguard Worker // Start the timer to run |user_task| near the specified |deadline|. If the 421*6777b538SAndroid Build Coastguard Worker // timer is already running, it will be replaced to call a task formed from 422*6777b538SAndroid Build Coastguard Worker // |receiver->*method|. 423*6777b538SAndroid Build Coastguard Worker template <class Receiver> 424*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 425*6777b538SAndroid Build Coastguard Worker TimeTicks deadline, 426*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 427*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)(), 428*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy delay_policy = 429*6777b538SAndroid Build Coastguard Worker subtle::DelayPolicy::kFlexiblePreferEarly) { 430*6777b538SAndroid Build Coastguard Worker Start(posted_from, deadline, BindOnce(method, Unretained(receiver)), 431*6777b538SAndroid Build Coastguard Worker delay_policy); 432*6777b538SAndroid Build Coastguard Worker } 433*6777b538SAndroid Build Coastguard Worker 434*6777b538SAndroid Build Coastguard Worker protected: 435*6777b538SAndroid Build Coastguard Worker void OnStop() override; 436*6777b538SAndroid Build Coastguard Worker 437*6777b538SAndroid Build Coastguard Worker // Schedules |OnScheduledTaskInvoked()| to run on the current sequence at 438*6777b538SAndroid Build Coastguard Worker // the given |deadline|. 439*6777b538SAndroid Build Coastguard Worker void ScheduleNewTask(TimeTicks deadline, subtle::DelayPolicy delay_policy); 440*6777b538SAndroid Build Coastguard Worker 441*6777b538SAndroid Build Coastguard Worker private: 442*6777b538SAndroid Build Coastguard Worker // Called when the scheduled task is invoked to run the |user_task|. 443*6777b538SAndroid Build Coastguard Worker void OnScheduledTaskInvoked(); 444*6777b538SAndroid Build Coastguard Worker 445*6777b538SAndroid Build Coastguard Worker OnceClosure user_task_; 446*6777b538SAndroid Build Coastguard Worker }; 447*6777b538SAndroid Build Coastguard Worker 448*6777b538SAndroid Build Coastguard Worker //----------------------------------------------------------------------------- 449*6777b538SAndroid Build Coastguard Worker // Repeatedly invokes a callback, waiting for a precise delay between the 450*6777b538SAndroid Build Coastguard Worker // beginning of each invocation. See usage notes at the top of the file. 451*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT MetronomeTimer : public internal::TimerBase { 452*6777b538SAndroid Build Coastguard Worker public: 453*6777b538SAndroid Build Coastguard Worker MetronomeTimer(); 454*6777b538SAndroid Build Coastguard Worker ~MetronomeTimer() override; 455*6777b538SAndroid Build Coastguard Worker 456*6777b538SAndroid Build Coastguard Worker MetronomeTimer(const MetronomeTimer&) = delete; 457*6777b538SAndroid Build Coastguard Worker MetronomeTimer& operator=(const MetronomeTimer&) = delete; 458*6777b538SAndroid Build Coastguard Worker 459*6777b538SAndroid Build Coastguard Worker MetronomeTimer(const Location& posted_from, 460*6777b538SAndroid Build Coastguard Worker TimeDelta interval, 461*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task, 462*6777b538SAndroid Build Coastguard Worker TimeTicks phase = TimeTicks()); 463*6777b538SAndroid Build Coastguard Worker 464*6777b538SAndroid Build Coastguard Worker // Start the timer to repeatedly run |user_task| at the specified |interval|; 465*6777b538SAndroid Build Coastguard Worker // If not specified, the phase is up to the scheduler, otherwise each 466*6777b538SAndroid Build Coastguard Worker // invocation starts as close as possible to `phase + n * delay` for some 467*6777b538SAndroid Build Coastguard Worker // integer n. If the timer is already running, it will be replaced to call the 468*6777b538SAndroid Build Coastguard Worker // given |user_task|. 469*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 470*6777b538SAndroid Build Coastguard Worker TimeDelta interval, 471*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task, 472*6777b538SAndroid Build Coastguard Worker TimeTicks phase = TimeTicks()); 473*6777b538SAndroid Build Coastguard Worker 474*6777b538SAndroid Build Coastguard Worker // Same as the previous overload, except that the user task is specified by 475*6777b538SAndroid Build Coastguard Worker // `receiver` and `method`. 476*6777b538SAndroid Build Coastguard Worker template <class Receiver> 477*6777b538SAndroid Build Coastguard Worker void Start(const Location& posted_from, 478*6777b538SAndroid Build Coastguard Worker TimeDelta interval, 479*6777b538SAndroid Build Coastguard Worker Receiver* receiver, 480*6777b538SAndroid Build Coastguard Worker void (Receiver::*method)(), 481*6777b538SAndroid Build Coastguard Worker TimeTicks phase = TimeTicks()) { 482*6777b538SAndroid Build Coastguard Worker Start(posted_from, interval, BindRepeating(method, Unretained(receiver)), 483*6777b538SAndroid Build Coastguard Worker phase); 484*6777b538SAndroid Build Coastguard Worker } 485*6777b538SAndroid Build Coastguard Worker 486*6777b538SAndroid Build Coastguard Worker // Call this method to reset the timer delay. The user task must be set. If 487*6777b538SAndroid Build Coastguard Worker // the timer is not running, this will start it by posting a task. 488*6777b538SAndroid Build Coastguard Worker void Reset(); 489*6777b538SAndroid Build Coastguard Worker 490*6777b538SAndroid Build Coastguard Worker protected: 491*6777b538SAndroid Build Coastguard Worker void OnStop() override; 492*6777b538SAndroid Build Coastguard Worker 493*6777b538SAndroid Build Coastguard Worker // Schedules |OnScheduledTaskInvoked()| to run on the current sequence at 494*6777b538SAndroid Build Coastguard Worker // the next tick. 495*6777b538SAndroid Build Coastguard Worker void ScheduleNewTask(); 496*6777b538SAndroid Build Coastguard Worker 497*6777b538SAndroid Build Coastguard Worker private: 498*6777b538SAndroid Build Coastguard Worker // Called when the scheduled task is invoked to run the |user_task|. 499*6777b538SAndroid Build Coastguard Worker void OnScheduledTaskInvoked(); 500*6777b538SAndroid Build Coastguard Worker 501*6777b538SAndroid Build Coastguard Worker TimeDelta interval_; 502*6777b538SAndroid Build Coastguard Worker RepeatingClosure user_task_; 503*6777b538SAndroid Build Coastguard Worker TimeTicks phase_; 504*6777b538SAndroid Build Coastguard Worker }; 505*6777b538SAndroid Build Coastguard Worker 506*6777b538SAndroid Build Coastguard Worker } // namespace base 507*6777b538SAndroid Build Coastguard Worker 508*6777b538SAndroid Build Coastguard Worker #endif // BASE_TIMER_TIMER_H_ 509