xref: /aosp_15_r20/external/libchrome/base/timer/timer_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/timer/timer.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/bind_helpers.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/callback.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/sequenced_task_runner.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/post_task.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/test/scoped_task_environment.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/test/test_mock_time_task_runner.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/threading/sequenced_task_runner_handle.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/time/tick_clock.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
29*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
30*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker namespace base {
33*635a8641SAndroid Build Coastguard Worker 
34*635a8641SAndroid Build Coastguard Worker namespace {
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker // The message loops on which each timer should be tested.
37*635a8641SAndroid Build Coastguard Worker const MessageLoop::Type testing_message_loops[] = {
38*635a8641SAndroid Build Coastguard Worker     MessageLoop::TYPE_DEFAULT, MessageLoop::TYPE_IO,
39*635a8641SAndroid Build Coastguard Worker #if !defined(OS_IOS)  // iOS does not allow direct running of the UI loop.
40*635a8641SAndroid Build Coastguard Worker     MessageLoop::TYPE_UI,
41*635a8641SAndroid Build Coastguard Worker #endif
42*635a8641SAndroid Build Coastguard Worker };
43*635a8641SAndroid Build Coastguard Worker 
44*635a8641SAndroid Build Coastguard Worker const int kNumTestingMessageLoops = arraysize(testing_message_loops);
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker class Receiver {
47*635a8641SAndroid Build Coastguard Worker  public:
Receiver()48*635a8641SAndroid Build Coastguard Worker   Receiver() : count_(0) {}
OnCalled()49*635a8641SAndroid Build Coastguard Worker   void OnCalled() { count_++; }
WasCalled()50*635a8641SAndroid Build Coastguard Worker   bool WasCalled() { return count_ > 0; }
TimesCalled()51*635a8641SAndroid Build Coastguard Worker   int TimesCalled() { return count_; }
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker  private:
54*635a8641SAndroid Build Coastguard Worker   int count_;
55*635a8641SAndroid Build Coastguard Worker };
56*635a8641SAndroid Build Coastguard Worker 
57*635a8641SAndroid Build Coastguard Worker // A basic helper class that can start a one-shot timer and signal a
58*635a8641SAndroid Build Coastguard Worker // WaitableEvent when this timer fires.
59*635a8641SAndroid Build Coastguard Worker class OneShotTimerTesterBase {
60*635a8641SAndroid Build Coastguard Worker  public:
61*635a8641SAndroid Build Coastguard Worker   // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTesterBase(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))62*635a8641SAndroid Build Coastguard Worker   explicit OneShotTimerTesterBase(
63*635a8641SAndroid Build Coastguard Worker       WaitableEvent* did_run = nullptr,
64*635a8641SAndroid Build Coastguard Worker       const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
65*635a8641SAndroid Build Coastguard Worker       : did_run_(did_run), delay_(delay) {}
66*635a8641SAndroid Build Coastguard Worker 
67*635a8641SAndroid Build Coastguard Worker   virtual ~OneShotTimerTesterBase() = default;
68*635a8641SAndroid Build Coastguard Worker 
Start()69*635a8641SAndroid Build Coastguard Worker   void Start() {
70*635a8641SAndroid Build Coastguard Worker     started_time_ = TimeTicks::Now();
71*635a8641SAndroid Build Coastguard Worker     timer_->Start(FROM_HERE, delay_, this, &OneShotTimerTesterBase::Run);
72*635a8641SAndroid Build Coastguard Worker   }
73*635a8641SAndroid Build Coastguard Worker 
IsRunning()74*635a8641SAndroid Build Coastguard Worker   bool IsRunning() { return timer_->IsRunning(); }
75*635a8641SAndroid Build Coastguard Worker 
started_time() const76*635a8641SAndroid Build Coastguard Worker   TimeTicks started_time() const { return started_time_; }
delay() const77*635a8641SAndroid Build Coastguard Worker   TimeDelta delay() const { return delay_; }
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker  protected:
Run()80*635a8641SAndroid Build Coastguard Worker   virtual void Run() {
81*635a8641SAndroid Build Coastguard Worker     if (did_run_) {
82*635a8641SAndroid Build Coastguard Worker       EXPECT_FALSE(did_run_->IsSignaled());
83*635a8641SAndroid Build Coastguard Worker       did_run_->Signal();
84*635a8641SAndroid Build Coastguard Worker     }
85*635a8641SAndroid Build Coastguard Worker   }
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<OneShotTimer> timer_ = std::make_unique<OneShotTimer>();
88*635a8641SAndroid Build Coastguard Worker 
89*635a8641SAndroid Build Coastguard Worker  private:
90*635a8641SAndroid Build Coastguard Worker   WaitableEvent* const did_run_;
91*635a8641SAndroid Build Coastguard Worker   const TimeDelta delay_;
92*635a8641SAndroid Build Coastguard Worker   TimeTicks started_time_;
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(OneShotTimerTesterBase);
95*635a8641SAndroid Build Coastguard Worker };
96*635a8641SAndroid Build Coastguard Worker 
97*635a8641SAndroid Build Coastguard Worker // Extends functionality of OneShotTimerTesterBase with the abilities to wait
98*635a8641SAndroid Build Coastguard Worker // until the timer fires and to change task runner for the timer.
99*635a8641SAndroid Build Coastguard Worker class OneShotTimerTester : public OneShotTimerTesterBase {
100*635a8641SAndroid Build Coastguard Worker  public:
101*635a8641SAndroid Build Coastguard Worker   // |did_run|, if provided, will be signaled when Run() fires.
OneShotTimerTester(WaitableEvent * did_run=nullptr,const TimeDelta & delay=TimeDelta::FromMilliseconds (10))102*635a8641SAndroid Build Coastguard Worker   explicit OneShotTimerTester(
103*635a8641SAndroid Build Coastguard Worker       WaitableEvent* did_run = nullptr,
104*635a8641SAndroid Build Coastguard Worker       const TimeDelta& delay = TimeDelta::FromMilliseconds(10))
105*635a8641SAndroid Build Coastguard Worker       : OneShotTimerTesterBase(did_run, delay),
106*635a8641SAndroid Build Coastguard Worker         quit_closure_(run_loop_.QuitClosure()) {}
107*635a8641SAndroid Build Coastguard Worker 
108*635a8641SAndroid Build Coastguard Worker   ~OneShotTimerTester() override = default;
109*635a8641SAndroid Build Coastguard Worker 
SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner)110*635a8641SAndroid Build Coastguard Worker   void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) {
111*635a8641SAndroid Build Coastguard Worker     timer_->SetTaskRunner(std::move(task_runner));
112*635a8641SAndroid Build Coastguard Worker 
113*635a8641SAndroid Build Coastguard Worker     // Run() will be invoked on |task_runner| but |run_loop_|'s QuitClosure
114*635a8641SAndroid Build Coastguard Worker     // needs to run on this thread (where the MessageLoop lives).
115*635a8641SAndroid Build Coastguard Worker     quit_closure_ = Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
116*635a8641SAndroid Build Coastguard Worker                          SequencedTaskRunnerHandle::Get(), FROM_HERE,
117*635a8641SAndroid Build Coastguard Worker                          run_loop_.QuitClosure());
118*635a8641SAndroid Build Coastguard Worker   }
119*635a8641SAndroid Build Coastguard Worker 
120*635a8641SAndroid Build Coastguard Worker   // Blocks until Run() executes and confirms that Run() didn't fire before
121*635a8641SAndroid Build Coastguard Worker   // |delay_| expired.
WaitAndConfirmTimerFiredAfterDelay()122*635a8641SAndroid Build Coastguard Worker   void WaitAndConfirmTimerFiredAfterDelay() {
123*635a8641SAndroid Build Coastguard Worker     run_loop_.Run();
124*635a8641SAndroid Build Coastguard Worker 
125*635a8641SAndroid Build Coastguard Worker     EXPECT_NE(TimeTicks(), started_time());
126*635a8641SAndroid Build Coastguard Worker     EXPECT_GE(TimeTicks::Now() - started_time(), delay());
127*635a8641SAndroid Build Coastguard Worker   }
128*635a8641SAndroid Build Coastguard Worker 
129*635a8641SAndroid Build Coastguard Worker  protected:
130*635a8641SAndroid Build Coastguard Worker   // Overridable method to do things on Run() before signaling events/closures
131*635a8641SAndroid Build Coastguard Worker   // managed by this helper.
OnRun()132*635a8641SAndroid Build Coastguard Worker   virtual void OnRun() {}
133*635a8641SAndroid Build Coastguard Worker 
134*635a8641SAndroid Build Coastguard Worker  private:
Run()135*635a8641SAndroid Build Coastguard Worker   void Run() override {
136*635a8641SAndroid Build Coastguard Worker     OnRun();
137*635a8641SAndroid Build Coastguard Worker     OneShotTimerTesterBase::Run();
138*635a8641SAndroid Build Coastguard Worker     quit_closure_.Run();
139*635a8641SAndroid Build Coastguard Worker   }
140*635a8641SAndroid Build Coastguard Worker 
141*635a8641SAndroid Build Coastguard Worker   RunLoop run_loop_;
142*635a8641SAndroid Build Coastguard Worker   Closure quit_closure_;
143*635a8641SAndroid Build Coastguard Worker 
144*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(OneShotTimerTester);
145*635a8641SAndroid Build Coastguard Worker };
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker class OneShotSelfDeletingTimerTester : public OneShotTimerTester {
148*635a8641SAndroid Build Coastguard Worker  protected:
OnRun()149*635a8641SAndroid Build Coastguard Worker   void OnRun() override { timer_.reset(); }
150*635a8641SAndroid Build Coastguard Worker };
151*635a8641SAndroid Build Coastguard Worker 
152*635a8641SAndroid Build Coastguard Worker constexpr int kNumRepeats = 10;
153*635a8641SAndroid Build Coastguard Worker 
154*635a8641SAndroid Build Coastguard Worker class RepeatingTimerTester {
155*635a8641SAndroid Build Coastguard Worker  public:
RepeatingTimerTester(WaitableEvent * did_run,const TimeDelta & delay)156*635a8641SAndroid Build Coastguard Worker   explicit RepeatingTimerTester(WaitableEvent* did_run, const TimeDelta& delay)
157*635a8641SAndroid Build Coastguard Worker       : counter_(kNumRepeats),
158*635a8641SAndroid Build Coastguard Worker         quit_closure_(run_loop_.QuitClosure()),
159*635a8641SAndroid Build Coastguard Worker         did_run_(did_run),
160*635a8641SAndroid Build Coastguard Worker         delay_(delay) {}
161*635a8641SAndroid Build Coastguard Worker 
Start()162*635a8641SAndroid Build Coastguard Worker   void Start() {
163*635a8641SAndroid Build Coastguard Worker     started_time_ = TimeTicks::Now();
164*635a8641SAndroid Build Coastguard Worker     timer_.Start(FROM_HERE, delay_, this, &RepeatingTimerTester::Run);
165*635a8641SAndroid Build Coastguard Worker   }
166*635a8641SAndroid Build Coastguard Worker 
WaitAndConfirmTimerFiredRepeatedlyAfterDelay()167*635a8641SAndroid Build Coastguard Worker   void WaitAndConfirmTimerFiredRepeatedlyAfterDelay() {
168*635a8641SAndroid Build Coastguard Worker     run_loop_.Run();
169*635a8641SAndroid Build Coastguard Worker 
170*635a8641SAndroid Build Coastguard Worker     EXPECT_NE(TimeTicks(), started_time_);
171*635a8641SAndroid Build Coastguard Worker     EXPECT_GE(TimeTicks::Now() - started_time_, kNumRepeats * delay_);
172*635a8641SAndroid Build Coastguard Worker   }
173*635a8641SAndroid Build Coastguard Worker 
174*635a8641SAndroid Build Coastguard Worker  private:
Run()175*635a8641SAndroid Build Coastguard Worker   void Run() {
176*635a8641SAndroid Build Coastguard Worker     if (--counter_ == 0) {
177*635a8641SAndroid Build Coastguard Worker       if (did_run_) {
178*635a8641SAndroid Build Coastguard Worker         EXPECT_FALSE(did_run_->IsSignaled());
179*635a8641SAndroid Build Coastguard Worker         did_run_->Signal();
180*635a8641SAndroid Build Coastguard Worker       }
181*635a8641SAndroid Build Coastguard Worker       timer_.Stop();
182*635a8641SAndroid Build Coastguard Worker       quit_closure_.Run();
183*635a8641SAndroid Build Coastguard Worker     }
184*635a8641SAndroid Build Coastguard Worker   }
185*635a8641SAndroid Build Coastguard Worker 
186*635a8641SAndroid Build Coastguard Worker   RepeatingTimer timer_;
187*635a8641SAndroid Build Coastguard Worker   int counter_;
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   RunLoop run_loop_;
190*635a8641SAndroid Build Coastguard Worker   Closure quit_closure_;
191*635a8641SAndroid Build Coastguard Worker   WaitableEvent* const did_run_;
192*635a8641SAndroid Build Coastguard Worker 
193*635a8641SAndroid Build Coastguard Worker   const TimeDelta delay_;
194*635a8641SAndroid Build Coastguard Worker   TimeTicks started_time_;
195*635a8641SAndroid Build Coastguard Worker 
196*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RepeatingTimerTester);
197*635a8641SAndroid Build Coastguard Worker };
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker // Basic test with same setup as RunTest_OneShotTimers_Cancel below to confirm
200*635a8641SAndroid Build Coastguard Worker // that |did_run_a| would be signaled in that test if it wasn't for the
201*635a8641SAndroid Build Coastguard Worker // deletion.
RunTest_OneShotTimers(MessageLoop::Type message_loop_type)202*635a8641SAndroid Build Coastguard Worker void RunTest_OneShotTimers(MessageLoop::Type message_loop_type) {
203*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
206*635a8641SAndroid Build Coastguard Worker                           WaitableEvent::InitialState::NOT_SIGNALED);
207*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester a(&did_run_a);
208*635a8641SAndroid Build Coastguard Worker   a.Start();
209*635a8641SAndroid Build Coastguard Worker 
210*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester b;
211*635a8641SAndroid Build Coastguard Worker   b.Start();
212*635a8641SAndroid Build Coastguard Worker 
213*635a8641SAndroid Build Coastguard Worker   b.WaitAndConfirmTimerFiredAfterDelay();
214*635a8641SAndroid Build Coastguard Worker 
215*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(did_run_a.IsSignaled());
216*635a8641SAndroid Build Coastguard Worker }
217*635a8641SAndroid Build Coastguard Worker 
RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type)218*635a8641SAndroid Build Coastguard Worker void RunTest_OneShotTimers_Cancel(MessageLoop::Type message_loop_type) {
219*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
220*635a8641SAndroid Build Coastguard Worker 
221*635a8641SAndroid Build Coastguard Worker   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
222*635a8641SAndroid Build Coastguard Worker                           WaitableEvent::InitialState::NOT_SIGNALED);
223*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester* a = new OneShotTimerTester(&did_run_a);
224*635a8641SAndroid Build Coastguard Worker 
225*635a8641SAndroid Build Coastguard Worker   // This should run before the timer expires.
226*635a8641SAndroid Build Coastguard Worker   SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
227*635a8641SAndroid Build Coastguard Worker 
228*635a8641SAndroid Build Coastguard Worker   // Now start the timer.
229*635a8641SAndroid Build Coastguard Worker   a->Start();
230*635a8641SAndroid Build Coastguard Worker 
231*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester b;
232*635a8641SAndroid Build Coastguard Worker   b.Start();
233*635a8641SAndroid Build Coastguard Worker 
234*635a8641SAndroid Build Coastguard Worker   b.WaitAndConfirmTimerFiredAfterDelay();
235*635a8641SAndroid Build Coastguard Worker 
236*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(did_run_a.IsSignaled());
237*635a8641SAndroid Build Coastguard Worker }
238*635a8641SAndroid Build Coastguard Worker 
RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type)239*635a8641SAndroid Build Coastguard Worker void RunTest_OneShotSelfDeletingTimer(MessageLoop::Type message_loop_type) {
240*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
241*635a8641SAndroid Build Coastguard Worker 
242*635a8641SAndroid Build Coastguard Worker   OneShotSelfDeletingTimerTester f;
243*635a8641SAndroid Build Coastguard Worker   f.Start();
244*635a8641SAndroid Build Coastguard Worker   f.WaitAndConfirmTimerFiredAfterDelay();
245*635a8641SAndroid Build Coastguard Worker }
246*635a8641SAndroid Build Coastguard Worker 
RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,const TimeDelta & delay)247*635a8641SAndroid Build Coastguard Worker void RunTest_RepeatingTimer(MessageLoop::Type message_loop_type,
248*635a8641SAndroid Build Coastguard Worker                             const TimeDelta& delay) {
249*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
250*635a8641SAndroid Build Coastguard Worker 
251*635a8641SAndroid Build Coastguard Worker   RepeatingTimerTester f(nullptr, delay);
252*635a8641SAndroid Build Coastguard Worker   f.Start();
253*635a8641SAndroid Build Coastguard Worker   f.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
254*635a8641SAndroid Build Coastguard Worker }
255*635a8641SAndroid Build Coastguard Worker 
RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,const TimeDelta & delay)256*635a8641SAndroid Build Coastguard Worker void RunTest_RepeatingTimer_Cancel(MessageLoop::Type message_loop_type,
257*635a8641SAndroid Build Coastguard Worker                                    const TimeDelta& delay) {
258*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
259*635a8641SAndroid Build Coastguard Worker 
260*635a8641SAndroid Build Coastguard Worker   WaitableEvent did_run_a(WaitableEvent::ResetPolicy::MANUAL,
261*635a8641SAndroid Build Coastguard Worker                           WaitableEvent::InitialState::NOT_SIGNALED);
262*635a8641SAndroid Build Coastguard Worker   RepeatingTimerTester* a = new RepeatingTimerTester(&did_run_a, delay);
263*635a8641SAndroid Build Coastguard Worker 
264*635a8641SAndroid Build Coastguard Worker   // This should run before the timer expires.
265*635a8641SAndroid Build Coastguard Worker   SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, a);
266*635a8641SAndroid Build Coastguard Worker 
267*635a8641SAndroid Build Coastguard Worker   // Now start the timer.
268*635a8641SAndroid Build Coastguard Worker   a->Start();
269*635a8641SAndroid Build Coastguard Worker 
270*635a8641SAndroid Build Coastguard Worker   RepeatingTimerTester b(nullptr, delay);
271*635a8641SAndroid Build Coastguard Worker   b.Start();
272*635a8641SAndroid Build Coastguard Worker 
273*635a8641SAndroid Build Coastguard Worker   b.WaitAndConfirmTimerFiredRepeatedlyAfterDelay();
274*635a8641SAndroid Build Coastguard Worker 
275*635a8641SAndroid Build Coastguard Worker   // |a| should not have fired despite |b| starting after it on the same
276*635a8641SAndroid Build Coastguard Worker   // sequence and being complete by now.
277*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(did_run_a.IsSignaled());
278*635a8641SAndroid Build Coastguard Worker }
279*635a8641SAndroid Build Coastguard Worker 
280*635a8641SAndroid Build Coastguard Worker class DelayTimerTarget {
281*635a8641SAndroid Build Coastguard Worker  public:
signaled() const282*635a8641SAndroid Build Coastguard Worker   bool signaled() const { return signaled_; }
283*635a8641SAndroid Build Coastguard Worker 
Signal()284*635a8641SAndroid Build Coastguard Worker   void Signal() {
285*635a8641SAndroid Build Coastguard Worker     ASSERT_FALSE(signaled_);
286*635a8641SAndroid Build Coastguard Worker     signaled_ = true;
287*635a8641SAndroid Build Coastguard Worker   }
288*635a8641SAndroid Build Coastguard Worker 
289*635a8641SAndroid Build Coastguard Worker  private:
290*635a8641SAndroid Build Coastguard Worker   bool signaled_ = false;
291*635a8641SAndroid Build Coastguard Worker };
292*635a8641SAndroid Build Coastguard Worker 
RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type)293*635a8641SAndroid Build Coastguard Worker void RunTest_DelayTimer_NoCall(MessageLoop::Type message_loop_type) {
294*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
295*635a8641SAndroid Build Coastguard Worker 
296*635a8641SAndroid Build Coastguard Worker   // If Delay is never called, the timer shouldn't go off.
297*635a8641SAndroid Build Coastguard Worker   DelayTimerTarget target;
298*635a8641SAndroid Build Coastguard Worker   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
299*635a8641SAndroid Build Coastguard Worker                    &DelayTimerTarget::Signal);
300*635a8641SAndroid Build Coastguard Worker 
301*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester tester;
302*635a8641SAndroid Build Coastguard Worker   tester.Start();
303*635a8641SAndroid Build Coastguard Worker   tester.WaitAndConfirmTimerFiredAfterDelay();
304*635a8641SAndroid Build Coastguard Worker 
305*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(target.signaled());
306*635a8641SAndroid Build Coastguard Worker }
307*635a8641SAndroid Build Coastguard Worker 
RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type)308*635a8641SAndroid Build Coastguard Worker void RunTest_DelayTimer_OneCall(MessageLoop::Type message_loop_type) {
309*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
310*635a8641SAndroid Build Coastguard Worker 
311*635a8641SAndroid Build Coastguard Worker   DelayTimerTarget target;
312*635a8641SAndroid Build Coastguard Worker   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(1), &target,
313*635a8641SAndroid Build Coastguard Worker                    &DelayTimerTarget::Signal);
314*635a8641SAndroid Build Coastguard Worker   timer.Reset();
315*635a8641SAndroid Build Coastguard Worker 
316*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(100));
317*635a8641SAndroid Build Coastguard Worker   tester.Start();
318*635a8641SAndroid Build Coastguard Worker   tester.WaitAndConfirmTimerFiredAfterDelay();
319*635a8641SAndroid Build Coastguard Worker 
320*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(target.signaled());
321*635a8641SAndroid Build Coastguard Worker }
322*635a8641SAndroid Build Coastguard Worker 
323*635a8641SAndroid Build Coastguard Worker struct ResetHelper {
ResetHelperbase::__anon4ee860b90111::ResetHelper324*635a8641SAndroid Build Coastguard Worker   ResetHelper(DelayTimer* timer, DelayTimerTarget* target)
325*635a8641SAndroid Build Coastguard Worker       : timer_(timer), target_(target) {}
326*635a8641SAndroid Build Coastguard Worker 
Resetbase::__anon4ee860b90111::ResetHelper327*635a8641SAndroid Build Coastguard Worker   void Reset() {
328*635a8641SAndroid Build Coastguard Worker     ASSERT_FALSE(target_->signaled());
329*635a8641SAndroid Build Coastguard Worker     timer_->Reset();
330*635a8641SAndroid Build Coastguard Worker   }
331*635a8641SAndroid Build Coastguard Worker 
332*635a8641SAndroid Build Coastguard Worker  private:
333*635a8641SAndroid Build Coastguard Worker   DelayTimer* const timer_;
334*635a8641SAndroid Build Coastguard Worker   DelayTimerTarget* const target_;
335*635a8641SAndroid Build Coastguard Worker };
336*635a8641SAndroid Build Coastguard Worker 
RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type)337*635a8641SAndroid Build Coastguard Worker void RunTest_DelayTimer_Reset(MessageLoop::Type message_loop_type) {
338*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
339*635a8641SAndroid Build Coastguard Worker 
340*635a8641SAndroid Build Coastguard Worker   // If Delay is never called, the timer shouldn't go off.
341*635a8641SAndroid Build Coastguard Worker   DelayTimerTarget target;
342*635a8641SAndroid Build Coastguard Worker   DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
343*635a8641SAndroid Build Coastguard Worker                    &DelayTimerTarget::Signal);
344*635a8641SAndroid Build Coastguard Worker   timer.Reset();
345*635a8641SAndroid Build Coastguard Worker 
346*635a8641SAndroid Build Coastguard Worker   ResetHelper reset_helper(&timer, &target);
347*635a8641SAndroid Build Coastguard Worker 
348*635a8641SAndroid Build Coastguard Worker   OneShotTimer timers[20];
349*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < arraysize(timers); ++i) {
350*635a8641SAndroid Build Coastguard Worker     timers[i].Start(FROM_HERE, TimeDelta::FromMilliseconds(i * 10),
351*635a8641SAndroid Build Coastguard Worker                     &reset_helper, &ResetHelper::Reset);
352*635a8641SAndroid Build Coastguard Worker   }
353*635a8641SAndroid Build Coastguard Worker 
354*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester tester(nullptr, TimeDelta::FromMilliseconds(300));
355*635a8641SAndroid Build Coastguard Worker   tester.Start();
356*635a8641SAndroid Build Coastguard Worker   tester.WaitAndConfirmTimerFiredAfterDelay();
357*635a8641SAndroid Build Coastguard Worker 
358*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(target.signaled());
359*635a8641SAndroid Build Coastguard Worker }
360*635a8641SAndroid Build Coastguard Worker 
361*635a8641SAndroid Build Coastguard Worker class DelayTimerFatalTarget {
362*635a8641SAndroid Build Coastguard Worker  public:
Signal()363*635a8641SAndroid Build Coastguard Worker   void Signal() {
364*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(false);
365*635a8641SAndroid Build Coastguard Worker   }
366*635a8641SAndroid Build Coastguard Worker };
367*635a8641SAndroid Build Coastguard Worker 
RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type)368*635a8641SAndroid Build Coastguard Worker void RunTest_DelayTimer_Deleted(MessageLoop::Type message_loop_type) {
369*635a8641SAndroid Build Coastguard Worker   MessageLoop loop(message_loop_type);
370*635a8641SAndroid Build Coastguard Worker 
371*635a8641SAndroid Build Coastguard Worker   DelayTimerFatalTarget target;
372*635a8641SAndroid Build Coastguard Worker 
373*635a8641SAndroid Build Coastguard Worker   {
374*635a8641SAndroid Build Coastguard Worker     DelayTimer timer(FROM_HERE, TimeDelta::FromMilliseconds(50), &target,
375*635a8641SAndroid Build Coastguard Worker                      &DelayTimerFatalTarget::Signal);
376*635a8641SAndroid Build Coastguard Worker     timer.Reset();
377*635a8641SAndroid Build Coastguard Worker   }
378*635a8641SAndroid Build Coastguard Worker 
379*635a8641SAndroid Build Coastguard Worker   // When the timer is deleted, the DelayTimerFatalTarget should never be
380*635a8641SAndroid Build Coastguard Worker   // called.
381*635a8641SAndroid Build Coastguard Worker   PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
382*635a8641SAndroid Build Coastguard Worker }
383*635a8641SAndroid Build Coastguard Worker 
384*635a8641SAndroid Build Coastguard Worker }  // namespace
385*635a8641SAndroid Build Coastguard Worker 
386*635a8641SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
387*635a8641SAndroid Build Coastguard Worker // Each test is run against each type of MessageLoop.  That way we are sure
388*635a8641SAndroid Build Coastguard Worker // that timers work properly in all configurations.
389*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,OneShotTimers)390*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, OneShotTimers) {
391*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
392*635a8641SAndroid Build Coastguard Worker     RunTest_OneShotTimers(testing_message_loops[i]);
393*635a8641SAndroid Build Coastguard Worker   }
394*635a8641SAndroid Build Coastguard Worker }
395*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,OneShotTimers_Cancel)396*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, OneShotTimers_Cancel) {
397*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
398*635a8641SAndroid Build Coastguard Worker     RunTest_OneShotTimers_Cancel(testing_message_loops[i]);
399*635a8641SAndroid Build Coastguard Worker   }
400*635a8641SAndroid Build Coastguard Worker }
401*635a8641SAndroid Build Coastguard Worker 
402*635a8641SAndroid Build Coastguard Worker // If underline timer does not handle properly, we will crash or fail
403*635a8641SAndroid Build Coastguard Worker // in full page heap environment.
TEST(TimerTest,OneShotSelfDeletingTimer)404*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, OneShotSelfDeletingTimer) {
405*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
406*635a8641SAndroid Build Coastguard Worker     RunTest_OneShotSelfDeletingTimer(testing_message_loops[i]);
407*635a8641SAndroid Build Coastguard Worker   }
408*635a8641SAndroid Build Coastguard Worker }
409*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,OneShotTimer_CustomTaskRunner)410*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, OneShotTimer_CustomTaskRunner) {
411*635a8641SAndroid Build Coastguard Worker   // A MessageLoop is required for the timer events on the other thread to
412*635a8641SAndroid Build Coastguard Worker   // communicate back to the Timer under test.
413*635a8641SAndroid Build Coastguard Worker   MessageLoop loop;
414*635a8641SAndroid Build Coastguard Worker 
415*635a8641SAndroid Build Coastguard Worker   Thread other_thread("OneShotTimer_CustomTaskRunner");
416*635a8641SAndroid Build Coastguard Worker   other_thread.Start();
417*635a8641SAndroid Build Coastguard Worker 
418*635a8641SAndroid Build Coastguard Worker   WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
419*635a8641SAndroid Build Coastguard Worker                         WaitableEvent::InitialState::NOT_SIGNALED);
420*635a8641SAndroid Build Coastguard Worker   OneShotTimerTester f(&did_run);
421*635a8641SAndroid Build Coastguard Worker   f.SetTaskRunner(other_thread.task_runner());
422*635a8641SAndroid Build Coastguard Worker   f.Start();
423*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(f.IsRunning() || did_run.IsSignaled());
424*635a8641SAndroid Build Coastguard Worker 
425*635a8641SAndroid Build Coastguard Worker   f.WaitAndConfirmTimerFiredAfterDelay();
426*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(did_run.IsSignaled());
427*635a8641SAndroid Build Coastguard Worker 
428*635a8641SAndroid Build Coastguard Worker   // |f| should already have communicated back to this |loop| before invoking
429*635a8641SAndroid Build Coastguard Worker   // Run() and as such this thread should already be aware that |f| is no longer
430*635a8641SAndroid Build Coastguard Worker   // running.
431*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(loop.IsIdleForTesting());
432*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(f.IsRunning());
433*635a8641SAndroid Build Coastguard Worker }
434*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,OneShotTimerWithTickClock)435*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, OneShotTimerWithTickClock) {
436*635a8641SAndroid Build Coastguard Worker   scoped_refptr<TestMockTimeTaskRunner> task_runner(
437*635a8641SAndroid Build Coastguard Worker       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
438*635a8641SAndroid Build Coastguard Worker   MessageLoop message_loop;
439*635a8641SAndroid Build Coastguard Worker   message_loop.SetTaskRunner(task_runner);
440*635a8641SAndroid Build Coastguard Worker   Receiver receiver;
441*635a8641SAndroid Build Coastguard Worker   OneShotTimer timer(task_runner->GetMockTickClock());
442*635a8641SAndroid Build Coastguard Worker   timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
443*635a8641SAndroid Build Coastguard Worker               Bind(&Receiver::OnCalled, Unretained(&receiver)));
444*635a8641SAndroid Build Coastguard Worker   task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
445*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(receiver.WasCalled());
446*635a8641SAndroid Build Coastguard Worker }
447*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RepeatingTimer)448*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RepeatingTimer) {
449*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
450*635a8641SAndroid Build Coastguard Worker     RunTest_RepeatingTimer(testing_message_loops[i],
451*635a8641SAndroid Build Coastguard Worker                            TimeDelta::FromMilliseconds(10));
452*635a8641SAndroid Build Coastguard Worker   }
453*635a8641SAndroid Build Coastguard Worker }
454*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RepeatingTimer_Cancel)455*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RepeatingTimer_Cancel) {
456*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
457*635a8641SAndroid Build Coastguard Worker     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
458*635a8641SAndroid Build Coastguard Worker                                   TimeDelta::FromMilliseconds(10));
459*635a8641SAndroid Build Coastguard Worker   }
460*635a8641SAndroid Build Coastguard Worker }
461*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RepeatingTimerZeroDelay)462*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RepeatingTimerZeroDelay) {
463*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
464*635a8641SAndroid Build Coastguard Worker     RunTest_RepeatingTimer(testing_message_loops[i],
465*635a8641SAndroid Build Coastguard Worker                            TimeDelta::FromMilliseconds(0));
466*635a8641SAndroid Build Coastguard Worker   }
467*635a8641SAndroid Build Coastguard Worker }
468*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RepeatingTimerZeroDelay_Cancel)469*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RepeatingTimerZeroDelay_Cancel) {
470*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
471*635a8641SAndroid Build Coastguard Worker     RunTest_RepeatingTimer_Cancel(testing_message_loops[i],
472*635a8641SAndroid Build Coastguard Worker                                   TimeDelta::FromMilliseconds(0));
473*635a8641SAndroid Build Coastguard Worker   }
474*635a8641SAndroid Build Coastguard Worker }
475*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RepeatingTimerWithTickClock)476*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RepeatingTimerWithTickClock) {
477*635a8641SAndroid Build Coastguard Worker   scoped_refptr<TestMockTimeTaskRunner> task_runner(
478*635a8641SAndroid Build Coastguard Worker       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
479*635a8641SAndroid Build Coastguard Worker   MessageLoop message_loop;
480*635a8641SAndroid Build Coastguard Worker   message_loop.SetTaskRunner(task_runner);
481*635a8641SAndroid Build Coastguard Worker   Receiver receiver;
482*635a8641SAndroid Build Coastguard Worker   const int expected_times_called = 10;
483*635a8641SAndroid Build Coastguard Worker   RepeatingTimer timer(task_runner->GetMockTickClock());
484*635a8641SAndroid Build Coastguard Worker   timer.Start(FROM_HERE, TimeDelta::FromSeconds(1),
485*635a8641SAndroid Build Coastguard Worker               Bind(&Receiver::OnCalled, Unretained(&receiver)));
486*635a8641SAndroid Build Coastguard Worker   task_runner->FastForwardBy(TimeDelta::FromSeconds(expected_times_called));
487*635a8641SAndroid Build Coastguard Worker   timer.Stop();
488*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(expected_times_called, receiver.TimesCalled());
489*635a8641SAndroid Build Coastguard Worker }
490*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,DelayTimer_NoCall)491*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, DelayTimer_NoCall) {
492*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
493*635a8641SAndroid Build Coastguard Worker     RunTest_DelayTimer_NoCall(testing_message_loops[i]);
494*635a8641SAndroid Build Coastguard Worker   }
495*635a8641SAndroid Build Coastguard Worker }
496*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,DelayTimer_OneCall)497*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, DelayTimer_OneCall) {
498*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
499*635a8641SAndroid Build Coastguard Worker     RunTest_DelayTimer_OneCall(testing_message_loops[i]);
500*635a8641SAndroid Build Coastguard Worker   }
501*635a8641SAndroid Build Coastguard Worker }
502*635a8641SAndroid Build Coastguard Worker 
503*635a8641SAndroid Build Coastguard Worker // It's flaky on the buildbot, http://crbug.com/25038.
TEST(TimerTest,DISABLED_DelayTimer_Reset)504*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, DISABLED_DelayTimer_Reset) {
505*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
506*635a8641SAndroid Build Coastguard Worker     RunTest_DelayTimer_Reset(testing_message_loops[i]);
507*635a8641SAndroid Build Coastguard Worker   }
508*635a8641SAndroid Build Coastguard Worker }
509*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,DelayTimer_Deleted)510*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, DelayTimer_Deleted) {
511*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kNumTestingMessageLoops; i++) {
512*635a8641SAndroid Build Coastguard Worker     RunTest_DelayTimer_Deleted(testing_message_loops[i]);
513*635a8641SAndroid Build Coastguard Worker   }
514*635a8641SAndroid Build Coastguard Worker }
515*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,DelayTimerWithTickClock)516*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, DelayTimerWithTickClock) {
517*635a8641SAndroid Build Coastguard Worker   scoped_refptr<TestMockTimeTaskRunner> task_runner(
518*635a8641SAndroid Build Coastguard Worker       new TestMockTimeTaskRunner(Time::Now(), TimeTicks::Now()));
519*635a8641SAndroid Build Coastguard Worker   MessageLoop message_loop;
520*635a8641SAndroid Build Coastguard Worker   message_loop.SetTaskRunner(task_runner);
521*635a8641SAndroid Build Coastguard Worker   Receiver receiver;
522*635a8641SAndroid Build Coastguard Worker   DelayTimer timer(FROM_HERE, TimeDelta::FromSeconds(1), &receiver,
523*635a8641SAndroid Build Coastguard Worker                    &Receiver::OnCalled, task_runner->GetMockTickClock());
524*635a8641SAndroid Build Coastguard Worker   task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
525*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(receiver.WasCalled());
526*635a8641SAndroid Build Coastguard Worker   timer.Reset();
527*635a8641SAndroid Build Coastguard Worker   task_runner->FastForwardBy(TimeDelta::FromMilliseconds(999));
528*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(receiver.WasCalled());
529*635a8641SAndroid Build Coastguard Worker   timer.Reset();
530*635a8641SAndroid Build Coastguard Worker   task_runner->FastForwardBy(TimeDelta::FromSeconds(1));
531*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(receiver.WasCalled());
532*635a8641SAndroid Build Coastguard Worker }
533*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,MessageLoopShutdown)534*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, MessageLoopShutdown) {
535*635a8641SAndroid Build Coastguard Worker   // This test is designed to verify that shutdown of the
536*635a8641SAndroid Build Coastguard Worker   // message loop does not cause crashes if there were pending
537*635a8641SAndroid Build Coastguard Worker   // timers not yet fired.  It may only trigger exceptions
538*635a8641SAndroid Build Coastguard Worker   // if debug heap checking is enabled.
539*635a8641SAndroid Build Coastguard Worker   WaitableEvent did_run(WaitableEvent::ResetPolicy::MANUAL,
540*635a8641SAndroid Build Coastguard Worker                         WaitableEvent::InitialState::NOT_SIGNALED);
541*635a8641SAndroid Build Coastguard Worker   {
542*635a8641SAndroid Build Coastguard Worker     OneShotTimerTesterBase a(&did_run);
543*635a8641SAndroid Build Coastguard Worker     OneShotTimerTesterBase b(&did_run);
544*635a8641SAndroid Build Coastguard Worker     OneShotTimerTesterBase c(&did_run);
545*635a8641SAndroid Build Coastguard Worker     OneShotTimerTesterBase d(&did_run);
546*635a8641SAndroid Build Coastguard Worker     {
547*635a8641SAndroid Build Coastguard Worker       MessageLoop loop;
548*635a8641SAndroid Build Coastguard Worker       a.Start();
549*635a8641SAndroid Build Coastguard Worker       b.Start();
550*635a8641SAndroid Build Coastguard Worker     }  // MessageLoop destructs by falling out of scope.
551*635a8641SAndroid Build Coastguard Worker   }  // OneShotTimers destruct.  SHOULD NOT CRASH, of course.
552*635a8641SAndroid Build Coastguard Worker 
553*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(did_run.IsSignaled());
554*635a8641SAndroid Build Coastguard Worker }
555*635a8641SAndroid Build Coastguard Worker 
556*635a8641SAndroid Build Coastguard Worker // Ref counted class which owns a Timer. The class passes a reference to itself
557*635a8641SAndroid Build Coastguard Worker // via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
558*635a8641SAndroid Build Coastguard Worker // end up holding the last reference to the class.
559*635a8641SAndroid Build Coastguard Worker class OneShotSelfOwningTimerTester
560*635a8641SAndroid Build Coastguard Worker     : public RefCounted<OneShotSelfOwningTimerTester> {
561*635a8641SAndroid Build Coastguard Worker  public:
562*635a8641SAndroid Build Coastguard Worker   OneShotSelfOwningTimerTester() = default;
563*635a8641SAndroid Build Coastguard Worker 
StartTimer()564*635a8641SAndroid Build Coastguard Worker   void StartTimer() {
565*635a8641SAndroid Build Coastguard Worker     // Start timer with long delay in order to test the timer getting destroyed
566*635a8641SAndroid Build Coastguard Worker     // while a timer task is still pending.
567*635a8641SAndroid Build Coastguard Worker     timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
568*635a8641SAndroid Build Coastguard Worker                  base::Bind(&OneShotSelfOwningTimerTester::Run, this));
569*635a8641SAndroid Build Coastguard Worker   }
570*635a8641SAndroid Build Coastguard Worker 
571*635a8641SAndroid Build Coastguard Worker  private:
572*635a8641SAndroid Build Coastguard Worker   friend class RefCounted<OneShotSelfOwningTimerTester>;
573*635a8641SAndroid Build Coastguard Worker   ~OneShotSelfOwningTimerTester() = default;
574*635a8641SAndroid Build Coastguard Worker 
Run()575*635a8641SAndroid Build Coastguard Worker   void Run() {
576*635a8641SAndroid Build Coastguard Worker     ADD_FAILURE() << "Timer unexpectedly fired.";
577*635a8641SAndroid Build Coastguard Worker   }
578*635a8641SAndroid Build Coastguard Worker 
579*635a8641SAndroid Build Coastguard Worker   OneShotTimer timer_;
580*635a8641SAndroid Build Coastguard Worker 
581*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
582*635a8641SAndroid Build Coastguard Worker };
583*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,MessageLoopShutdownSelfOwningTimer)584*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
585*635a8641SAndroid Build Coastguard Worker   // This test verifies that shutdown of the message loop does not cause crashes
586*635a8641SAndroid Build Coastguard Worker   // if there is a pending timer not yet fired and |Timer::user_task_| owns the
587*635a8641SAndroid Build Coastguard Worker   // timer. The test may only trigger exceptions if debug heap checking is
588*635a8641SAndroid Build Coastguard Worker   // enabled.
589*635a8641SAndroid Build Coastguard Worker 
590*635a8641SAndroid Build Coastguard Worker   MessageLoop loop;
591*635a8641SAndroid Build Coastguard Worker   scoped_refptr<OneShotSelfOwningTimerTester> tester =
592*635a8641SAndroid Build Coastguard Worker       new OneShotSelfOwningTimerTester();
593*635a8641SAndroid Build Coastguard Worker 
594*635a8641SAndroid Build Coastguard Worker   std::move(tester)->StartTimer();
595*635a8641SAndroid Build Coastguard Worker   // |Timer::user_task_| owns sole reference to |tester|.
596*635a8641SAndroid Build Coastguard Worker 
597*635a8641SAndroid Build Coastguard Worker   // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
598*635a8641SAndroid Build Coastguard Worker }
599*635a8641SAndroid Build Coastguard Worker 
TimerTestCallback()600*635a8641SAndroid Build Coastguard Worker void TimerTestCallback() {
601*635a8641SAndroid Build Coastguard Worker }
602*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,NonRepeatIsRunning)603*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, NonRepeatIsRunning) {
604*635a8641SAndroid Build Coastguard Worker   {
605*635a8641SAndroid Build Coastguard Worker     MessageLoop loop;
606*635a8641SAndroid Build Coastguard Worker     Timer timer(false, false);
607*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer.IsRunning());
608*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
609*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer.IsRunning());
610*635a8641SAndroid Build Coastguard Worker     timer.Stop();
611*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer.IsRunning());
612*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer.user_task().is_null());
613*635a8641SAndroid Build Coastguard Worker   }
614*635a8641SAndroid Build Coastguard Worker 
615*635a8641SAndroid Build Coastguard Worker   {
616*635a8641SAndroid Build Coastguard Worker     Timer timer(true, false);
617*635a8641SAndroid Build Coastguard Worker     MessageLoop loop;
618*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer.IsRunning());
619*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
620*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer.IsRunning());
621*635a8641SAndroid Build Coastguard Worker     timer.Stop();
622*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer.IsRunning());
623*635a8641SAndroid Build Coastguard Worker     ASSERT_FALSE(timer.user_task().is_null());
624*635a8641SAndroid Build Coastguard Worker     timer.Reset();
625*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer.IsRunning());
626*635a8641SAndroid Build Coastguard Worker   }
627*635a8641SAndroid Build Coastguard Worker }
628*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,NonRepeatMessageLoopDeath)629*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, NonRepeatMessageLoopDeath) {
630*635a8641SAndroid Build Coastguard Worker   Timer timer(false, false);
631*635a8641SAndroid Build Coastguard Worker   {
632*635a8641SAndroid Build Coastguard Worker     MessageLoop loop;
633*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer.IsRunning());
634*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback));
635*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer.IsRunning());
636*635a8641SAndroid Build Coastguard Worker   }
637*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(timer.IsRunning());
638*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(timer.user_task().is_null());
639*635a8641SAndroid Build Coastguard Worker }
640*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RetainRepeatIsRunning)641*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RetainRepeatIsRunning) {
642*635a8641SAndroid Build Coastguard Worker   MessageLoop loop;
643*635a8641SAndroid Build Coastguard Worker   Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
644*635a8641SAndroid Build Coastguard Worker               true);
645*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(timer.IsRunning());
646*635a8641SAndroid Build Coastguard Worker   timer.Reset();
647*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(timer.IsRunning());
648*635a8641SAndroid Build Coastguard Worker   timer.Stop();
649*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(timer.IsRunning());
650*635a8641SAndroid Build Coastguard Worker   timer.Reset();
651*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(timer.IsRunning());
652*635a8641SAndroid Build Coastguard Worker }
653*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,RetainNonRepeatIsRunning)654*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, RetainNonRepeatIsRunning) {
655*635a8641SAndroid Build Coastguard Worker   MessageLoop loop;
656*635a8641SAndroid Build Coastguard Worker   Timer timer(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback),
657*635a8641SAndroid Build Coastguard Worker               false);
658*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(timer.IsRunning());
659*635a8641SAndroid Build Coastguard Worker   timer.Reset();
660*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(timer.IsRunning());
661*635a8641SAndroid Build Coastguard Worker   timer.Stop();
662*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(timer.IsRunning());
663*635a8641SAndroid Build Coastguard Worker   timer.Reset();
664*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(timer.IsRunning());
665*635a8641SAndroid Build Coastguard Worker }
666*635a8641SAndroid Build Coastguard Worker 
667*635a8641SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
668*635a8641SAndroid Build Coastguard Worker 
669*635a8641SAndroid Build Coastguard Worker namespace {
670*635a8641SAndroid Build Coastguard Worker 
671*635a8641SAndroid Build Coastguard Worker bool g_callback_happened1 = false;
672*635a8641SAndroid Build Coastguard Worker bool g_callback_happened2 = false;
673*635a8641SAndroid Build Coastguard Worker 
ClearAllCallbackHappened()674*635a8641SAndroid Build Coastguard Worker void ClearAllCallbackHappened() {
675*635a8641SAndroid Build Coastguard Worker   g_callback_happened1 = false;
676*635a8641SAndroid Build Coastguard Worker   g_callback_happened2 = false;
677*635a8641SAndroid Build Coastguard Worker }
678*635a8641SAndroid Build Coastguard Worker 
SetCallbackHappened1()679*635a8641SAndroid Build Coastguard Worker void SetCallbackHappened1() {
680*635a8641SAndroid Build Coastguard Worker   g_callback_happened1 = true;
681*635a8641SAndroid Build Coastguard Worker   RunLoop::QuitCurrentWhenIdleDeprecated();
682*635a8641SAndroid Build Coastguard Worker }
683*635a8641SAndroid Build Coastguard Worker 
SetCallbackHappened2()684*635a8641SAndroid Build Coastguard Worker void SetCallbackHappened2() {
685*635a8641SAndroid Build Coastguard Worker   g_callback_happened2 = true;
686*635a8641SAndroid Build Coastguard Worker   RunLoop::QuitCurrentWhenIdleDeprecated();
687*635a8641SAndroid Build Coastguard Worker }
688*635a8641SAndroid Build Coastguard Worker 
689*635a8641SAndroid Build Coastguard Worker }  // namespace
690*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,ContinuationStopStart)691*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, ContinuationStopStart) {
692*635a8641SAndroid Build Coastguard Worker   {
693*635a8641SAndroid Build Coastguard Worker     ClearAllCallbackHappened();
694*635a8641SAndroid Build Coastguard Worker     MessageLoop loop;
695*635a8641SAndroid Build Coastguard Worker     Timer timer(false, false);
696*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
697*635a8641SAndroid Build Coastguard Worker                 Bind(&SetCallbackHappened1));
698*635a8641SAndroid Build Coastguard Worker     timer.Stop();
699*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(40),
700*635a8641SAndroid Build Coastguard Worker                 Bind(&SetCallbackHappened2));
701*635a8641SAndroid Build Coastguard Worker     RunLoop().Run();
702*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(g_callback_happened1);
703*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(g_callback_happened2);
704*635a8641SAndroid Build Coastguard Worker   }
705*635a8641SAndroid Build Coastguard Worker }
706*635a8641SAndroid Build Coastguard Worker 
TEST(TimerTest,ContinuationReset)707*635a8641SAndroid Build Coastguard Worker TEST(TimerTest, ContinuationReset) {
708*635a8641SAndroid Build Coastguard Worker   {
709*635a8641SAndroid Build Coastguard Worker     ClearAllCallbackHappened();
710*635a8641SAndroid Build Coastguard Worker     MessageLoop loop;
711*635a8641SAndroid Build Coastguard Worker     Timer timer(false, false);
712*635a8641SAndroid Build Coastguard Worker     timer.Start(FROM_HERE, TimeDelta::FromMilliseconds(10),
713*635a8641SAndroid Build Coastguard Worker                 Bind(&SetCallbackHappened1));
714*635a8641SAndroid Build Coastguard Worker     timer.Reset();
715*635a8641SAndroid Build Coastguard Worker     // Since Reset happened before task ran, the user_task must not be cleared:
716*635a8641SAndroid Build Coastguard Worker     ASSERT_FALSE(timer.user_task().is_null());
717*635a8641SAndroid Build Coastguard Worker     RunLoop().Run();
718*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(g_callback_happened1);
719*635a8641SAndroid Build Coastguard Worker   }
720*635a8641SAndroid Build Coastguard Worker }
721*635a8641SAndroid Build Coastguard Worker 
722*635a8641SAndroid Build Coastguard Worker namespace {
723*635a8641SAndroid Build Coastguard Worker 
724*635a8641SAndroid Build Coastguard Worker // Fixture for tests requiring ScopedTaskEnvironment. Includes a WaitableEvent
725*635a8641SAndroid Build Coastguard Worker // so that cases may Wait() on one thread and Signal() (explicitly, or
726*635a8641SAndroid Build Coastguard Worker // implicitly via helper methods) on another.
727*635a8641SAndroid Build Coastguard Worker class TimerSequenceTest : public testing::Test {
728*635a8641SAndroid Build Coastguard Worker  public:
TimerSequenceTest()729*635a8641SAndroid Build Coastguard Worker   TimerSequenceTest()
730*635a8641SAndroid Build Coastguard Worker       : event_(WaitableEvent::ResetPolicy::AUTOMATIC,
731*635a8641SAndroid Build Coastguard Worker                WaitableEvent::InitialState::NOT_SIGNALED) {}
732*635a8641SAndroid Build Coastguard Worker 
733*635a8641SAndroid Build Coastguard Worker   // Block until Signal() is called on another thread.
Wait()734*635a8641SAndroid Build Coastguard Worker   void Wait() { event_.Wait(); }
735*635a8641SAndroid Build Coastguard Worker 
Signal()736*635a8641SAndroid Build Coastguard Worker   void Signal() { event_.Signal(); }
737*635a8641SAndroid Build Coastguard Worker 
738*635a8641SAndroid Build Coastguard Worker   // Helper to augment a task with a subsequent call to Signal().
TaskWithSignal(const Closure & task)739*635a8641SAndroid Build Coastguard Worker   Closure TaskWithSignal(const Closure& task) {
740*635a8641SAndroid Build Coastguard Worker     return Bind(&TimerSequenceTest::RunTaskAndSignal, Unretained(this), task);
741*635a8641SAndroid Build Coastguard Worker   }
742*635a8641SAndroid Build Coastguard Worker 
743*635a8641SAndroid Build Coastguard Worker   // Create the timer.
CreateTimer()744*635a8641SAndroid Build Coastguard Worker   void CreateTimer() { timer_.reset(new OneShotTimer); }
745*635a8641SAndroid Build Coastguard Worker 
746*635a8641SAndroid Build Coastguard Worker   // Schedule an event on the timer.
StartTimer(TimeDelta delay,const Closure & task)747*635a8641SAndroid Build Coastguard Worker   void StartTimer(TimeDelta delay, const Closure& task) {
748*635a8641SAndroid Build Coastguard Worker     timer_->Start(FROM_HERE, delay, task);
749*635a8641SAndroid Build Coastguard Worker   }
750*635a8641SAndroid Build Coastguard Worker 
SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner)751*635a8641SAndroid Build Coastguard Worker   void SetTaskRunnerForTimer(scoped_refptr<SequencedTaskRunner> task_runner) {
752*635a8641SAndroid Build Coastguard Worker     timer_->SetTaskRunner(std::move(task_runner));
753*635a8641SAndroid Build Coastguard Worker   }
754*635a8641SAndroid Build Coastguard Worker 
755*635a8641SAndroid Build Coastguard Worker   // Tell the timer to abandon the task.
AbandonTask()756*635a8641SAndroid Build Coastguard Worker   void AbandonTask() {
757*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer_->IsRunning());
758*635a8641SAndroid Build Coastguard Worker     // Reset() to call Timer::AbandonScheduledTask()
759*635a8641SAndroid Build Coastguard Worker     timer_->Reset();
760*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(timer_->IsRunning());
761*635a8641SAndroid Build Coastguard Worker     timer_->Stop();
762*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(timer_->IsRunning());
763*635a8641SAndroid Build Coastguard Worker   }
764*635a8641SAndroid Build Coastguard Worker 
VerifyAffinity(const SequencedTaskRunner * task_runner)765*635a8641SAndroid Build Coastguard Worker   static void VerifyAffinity(const SequencedTaskRunner* task_runner) {
766*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(task_runner->RunsTasksInCurrentSequence());
767*635a8641SAndroid Build Coastguard Worker   }
768*635a8641SAndroid Build Coastguard Worker 
769*635a8641SAndroid Build Coastguard Worker   // Delete the timer.
DeleteTimer()770*635a8641SAndroid Build Coastguard Worker   void DeleteTimer() { timer_.reset(); }
771*635a8641SAndroid Build Coastguard Worker 
772*635a8641SAndroid Build Coastguard Worker  private:
RunTaskAndSignal(const Closure & task)773*635a8641SAndroid Build Coastguard Worker   void RunTaskAndSignal(const Closure& task) {
774*635a8641SAndroid Build Coastguard Worker     task.Run();
775*635a8641SAndroid Build Coastguard Worker     Signal();
776*635a8641SAndroid Build Coastguard Worker   }
777*635a8641SAndroid Build Coastguard Worker 
778*635a8641SAndroid Build Coastguard Worker   base::test::ScopedTaskEnvironment scoped_task_environment_;
779*635a8641SAndroid Build Coastguard Worker   WaitableEvent event_;
780*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<OneShotTimer> timer_;
781*635a8641SAndroid Build Coastguard Worker 
782*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(TimerSequenceTest);
783*635a8641SAndroid Build Coastguard Worker };
784*635a8641SAndroid Build Coastguard Worker 
785*635a8641SAndroid Build Coastguard Worker }  // namespace
786*635a8641SAndroid Build Coastguard Worker 
TEST_F(TimerSequenceTest,OneShotTimerTaskOnPoolSequence)787*635a8641SAndroid Build Coastguard Worker TEST_F(TimerSequenceTest, OneShotTimerTaskOnPoolSequence) {
788*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner =
789*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
790*635a8641SAndroid Build Coastguard Worker 
791*635a8641SAndroid Build Coastguard Worker   base::RunLoop run_loop_;
792*635a8641SAndroid Build Coastguard Worker 
793*635a8641SAndroid Build Coastguard Worker   // Timer is created on this thread.
794*635a8641SAndroid Build Coastguard Worker   CreateTimer();
795*635a8641SAndroid Build Coastguard Worker 
796*635a8641SAndroid Build Coastguard Worker   // Task will execute on a pool thread.
797*635a8641SAndroid Build Coastguard Worker   SetTaskRunnerForTimer(task_runner);
798*635a8641SAndroid Build Coastguard Worker   StartTimer(TimeDelta::FromMilliseconds(1),
799*635a8641SAndroid Build Coastguard Worker              Bind(IgnoreResult(&SequencedTaskRunner::PostTask),
800*635a8641SAndroid Build Coastguard Worker                   SequencedTaskRunnerHandle::Get(), FROM_HERE,
801*635a8641SAndroid Build Coastguard Worker                   run_loop_.QuitClosure()));
802*635a8641SAndroid Build Coastguard Worker 
803*635a8641SAndroid Build Coastguard Worker   // Spin the loop so that the delayed task fires on it, which will forward it
804*635a8641SAndroid Build Coastguard Worker   // to |task_runner|. And since the Timer's task is one that posts back to this
805*635a8641SAndroid Build Coastguard Worker   // MessageLoop to quit, we finally unblock.
806*635a8641SAndroid Build Coastguard Worker   run_loop_.Run();
807*635a8641SAndroid Build Coastguard Worker 
808*635a8641SAndroid Build Coastguard Worker   // Timer will be destroyed on this thread.
809*635a8641SAndroid Build Coastguard Worker   DeleteTimer();
810*635a8641SAndroid Build Coastguard Worker }
811*635a8641SAndroid Build Coastguard Worker 
TEST_F(TimerSequenceTest,OneShotTimerUsedOnPoolSequence)812*635a8641SAndroid Build Coastguard Worker TEST_F(TimerSequenceTest, OneShotTimerUsedOnPoolSequence) {
813*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner =
814*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
815*635a8641SAndroid Build Coastguard Worker 
816*635a8641SAndroid Build Coastguard Worker   // Timer is created on this thread.
817*635a8641SAndroid Build Coastguard Worker   CreateTimer();
818*635a8641SAndroid Build Coastguard Worker 
819*635a8641SAndroid Build Coastguard Worker   // Task will be scheduled from a pool thread.
820*635a8641SAndroid Build Coastguard Worker   task_runner->PostTask(
821*635a8641SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
822*635a8641SAndroid Build Coastguard Worker                           TimeDelta::FromMilliseconds(1),
823*635a8641SAndroid Build Coastguard Worker                           Bind(&TimerSequenceTest::Signal, Unretained(this))));
824*635a8641SAndroid Build Coastguard Worker   Wait();
825*635a8641SAndroid Build Coastguard Worker 
826*635a8641SAndroid Build Coastguard Worker   // Timer must be destroyed on pool thread, too.
827*635a8641SAndroid Build Coastguard Worker   task_runner->PostTask(
828*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
829*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
830*635a8641SAndroid Build Coastguard Worker   Wait();
831*635a8641SAndroid Build Coastguard Worker }
832*635a8641SAndroid Build Coastguard Worker 
TEST_F(TimerSequenceTest,OneShotTimerTwoSequencesAbandonTask)833*635a8641SAndroid Build Coastguard Worker TEST_F(TimerSequenceTest, OneShotTimerTwoSequencesAbandonTask) {
834*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner1 =
835*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
836*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner2 =
837*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
838*635a8641SAndroid Build Coastguard Worker 
839*635a8641SAndroid Build Coastguard Worker   // Create timer on sequence #1.
840*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
841*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
842*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
843*635a8641SAndroid Build Coastguard Worker   Wait();
844*635a8641SAndroid Build Coastguard Worker 
845*635a8641SAndroid Build Coastguard Worker   // And tell it to execute on a different sequence (#2).
846*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
847*635a8641SAndroid Build Coastguard Worker       FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
848*635a8641SAndroid Build Coastguard Worker                                      Unretained(this), task_runner2)));
849*635a8641SAndroid Build Coastguard Worker   Wait();
850*635a8641SAndroid Build Coastguard Worker 
851*635a8641SAndroid Build Coastguard Worker   // Task will be scheduled from sequence #1.
852*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
853*635a8641SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
854*635a8641SAndroid Build Coastguard Worker                           TimeDelta::FromHours(1), DoNothing()));
855*635a8641SAndroid Build Coastguard Worker 
856*635a8641SAndroid Build Coastguard Worker   // Abandon task - must be called from scheduling sequence (#1).
857*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
858*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
859*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::AbandonTask, Unretained(this))));
860*635a8641SAndroid Build Coastguard Worker   Wait();
861*635a8641SAndroid Build Coastguard Worker 
862*635a8641SAndroid Build Coastguard Worker   // Timer must be destroyed on the sequence it was scheduled from (#1).
863*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
864*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
865*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
866*635a8641SAndroid Build Coastguard Worker   Wait();
867*635a8641SAndroid Build Coastguard Worker }
868*635a8641SAndroid Build Coastguard Worker 
TEST_F(TimerSequenceTest,OneShotTimerUsedAndTaskedOnDifferentSequences)869*635a8641SAndroid Build Coastguard Worker TEST_F(TimerSequenceTest, OneShotTimerUsedAndTaskedOnDifferentSequences) {
870*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner1 =
871*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
872*635a8641SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner2 =
873*635a8641SAndroid Build Coastguard Worker       base::CreateSequencedTaskRunnerWithTraits({});
874*635a8641SAndroid Build Coastguard Worker 
875*635a8641SAndroid Build Coastguard Worker   // Create timer on sequence #1.
876*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
877*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
878*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::CreateTimer, Unretained(this))));
879*635a8641SAndroid Build Coastguard Worker   Wait();
880*635a8641SAndroid Build Coastguard Worker 
881*635a8641SAndroid Build Coastguard Worker   // And tell it to execute on a different sequence (#2).
882*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
883*635a8641SAndroid Build Coastguard Worker       FROM_HERE, TaskWithSignal(Bind(&TimerSequenceTest::SetTaskRunnerForTimer,
884*635a8641SAndroid Build Coastguard Worker                                      Unretained(this), task_runner2)));
885*635a8641SAndroid Build Coastguard Worker   Wait();
886*635a8641SAndroid Build Coastguard Worker 
887*635a8641SAndroid Build Coastguard Worker   // Task will be scheduled from sequence #1.
888*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
889*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
890*635a8641SAndroid Build Coastguard Worker       BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
891*635a8641SAndroid Build Coastguard Worker                TimeDelta::FromMilliseconds(1),
892*635a8641SAndroid Build Coastguard Worker                TaskWithSignal(Bind(&TimerSequenceTest::VerifyAffinity,
893*635a8641SAndroid Build Coastguard Worker                                    Unretained(task_runner2.get())))));
894*635a8641SAndroid Build Coastguard Worker 
895*635a8641SAndroid Build Coastguard Worker   Wait();
896*635a8641SAndroid Build Coastguard Worker 
897*635a8641SAndroid Build Coastguard Worker   // Timer must be destroyed on the sequence it was scheduled from (#1).
898*635a8641SAndroid Build Coastguard Worker   task_runner1->PostTask(
899*635a8641SAndroid Build Coastguard Worker       FROM_HERE,
900*635a8641SAndroid Build Coastguard Worker       TaskWithSignal(Bind(&TimerSequenceTest::DeleteTimer, Unretained(this))));
901*635a8641SAndroid Build Coastguard Worker   Wait();
902*635a8641SAndroid Build Coastguard Worker }
903*635a8641SAndroid Build Coastguard Worker 
904*635a8641SAndroid Build Coastguard Worker }  // namespace base
905