• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
6 
7 #include <queue>
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/functional/bind.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/scoped_refptr.h"
15 #include "base/task/sequence_manager/task_queue.h"
16 #include "base/task/sequence_manager/thread_controller_power_monitor.h"
17 #include "base/task/single_thread_task_runner.h"
18 #include "base/task/task_features.h"
19 #include "base/test/bind.h"
20 #include "base/test/mock_callback.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/simple_test_tick_clock.h"
23 #include "base/time/time.h"
24 #include "build/build_config.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/abseil-cpp/absl/types/optional.h"
28 
29 using testing::_;
30 using testing::Invoke;
31 using testing::ElementsAre;
32 
33 namespace base::sequence_manager::internal {
34 
35 namespace {
36 
37 class ThreadControllerForTest : public ThreadControllerWithMessagePumpImpl {
38  public:
ThreadControllerForTest(std::unique_ptr<MessagePump> pump,const SequenceManager::Settings & settings)39   ThreadControllerForTest(std::unique_ptr<MessagePump> pump,
40                           const SequenceManager::Settings& settings)
41       : ThreadControllerWithMessagePumpImpl(std::move(pump), settings) {}
42 
~ThreadControllerForTest()43   ~ThreadControllerForTest() override {
44     if (trace_observer_)
45       RunLevelTracker::SetTraceObserverForTesting(nullptr);
46   }
47 
48   using ThreadControllerWithMessagePumpImpl::BeforeWait;
49   using ThreadControllerWithMessagePumpImpl::DoIdleWork;
50   using ThreadControllerWithMessagePumpImpl::DoWork;
51   using ThreadControllerWithMessagePumpImpl::EnsureWorkScheduled;
52   using ThreadControllerWithMessagePumpImpl::OnBeginWorkItem;
53   using ThreadControllerWithMessagePumpImpl::OnEndWorkItem;
54   using ThreadControllerWithMessagePumpImpl::Quit;
55   using ThreadControllerWithMessagePumpImpl::Run;
56 
57   using ThreadControllerWithMessagePumpImpl::MainThreadOnlyForTesting;
58   using ThreadControllerWithMessagePumpImpl::
59       ThreadControllerPowerMonitorForTesting;
60 
61   class MockTraceObserver
62       : public ThreadController::RunLevelTracker::TraceObserverForTesting {
63    public:
64     MOCK_METHOD0(OnThreadControllerActiveBegin, void());
65     MOCK_METHOD0(OnThreadControllerActiveEnd, void());
66     MOCK_METHOD1(OnPhaseRecorded, void(Phase));
67   };
68 
InstallTraceObserver()69   void InstallTraceObserver() {
70     trace_observer_.emplace();
71     RunLevelTracker::SetTraceObserverForTesting(&trace_observer_.value());
72 
73     // EnableMessagePumpTimeKeeperMetrics is a no-op on hardware which lacks
74     // high-res clocks.
75     ASSERT_TRUE(TimeTicks::IsHighResolution());
76     EnableMessagePumpTimeKeeperMetrics("TestMainThread");
77   }
78 
79   // Optionally emplaced, strict from then on.
80   absl::optional<testing::StrictMock<MockTraceObserver>> trace_observer_;
81 };
82 
83 class MockMessagePump : public MessagePump {
84  public:
MockMessagePump()85   MockMessagePump() {}
~MockMessagePump()86   ~MockMessagePump() override {}
87 
88   MOCK_METHOD1(Run, void(MessagePump::Delegate*));
89   MOCK_METHOD0(Quit, void());
90   MOCK_METHOD0(ScheduleWork, void());
91   MOCK_METHOD1(ScheduleDelayedWork_TimeTicks, void(const TimeTicks&));
92 
ScheduleDelayedWork(const MessagePump::Delegate::NextWorkInfo & next_work_info)93   void ScheduleDelayedWork(
94       const MessagePump::Delegate::NextWorkInfo& next_work_info) override {
95     ScheduleDelayedWork_TimeTicks(next_work_info.delayed_run_time);
96   }
97 };
98 
99 // TODO(crbug.com/901373): Deduplicate FakeTaskRunners.
100 class FakeTaskRunner : public SingleThreadTaskRunner {
101  public:
PostDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)102   bool PostDelayedTask(const Location& from_here,
103                        OnceClosure task,
104                        TimeDelta delay) override {
105     return true;
106   }
107 
PostNonNestableDelayedTask(const Location & from_here,OnceClosure task,TimeDelta delay)108   bool PostNonNestableDelayedTask(const Location& from_here,
109                                   OnceClosure task,
110                                   TimeDelta delay) override {
111     return true;
112   }
113 
RunsTasksInCurrentSequence() const114   bool RunsTasksInCurrentSequence() const override { return true; }
115 
116  protected:
117   ~FakeTaskRunner() override = default;
118 };
119 
120 class FakeSequencedTaskSource : public SequencedTaskSource {
121  public:
FakeSequencedTaskSource(TickClock * clock)122   explicit FakeSequencedTaskSource(TickClock* clock) : clock_(clock) {}
123   ~FakeSequencedTaskSource() override = default;
124 
SelectNextTask(LazyNow & lazy_now,SelectTaskOption option)125   absl::optional<SelectedTask> SelectNextTask(
126       LazyNow& lazy_now,
127       SelectTaskOption option) override {
128     if (tasks_.empty())
129       return absl::nullopt;
130     if (tasks_.front().delayed_run_time > clock_->NowTicks())
131       return absl::nullopt;
132     if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
133         !tasks_.front().delayed_run_time.is_null()) {
134       return absl::nullopt;
135     }
136     task_execution_stack_.push_back(std::move(tasks_.front()));
137     tasks_.pop();
138     return SelectedTask(task_execution_stack_.back(),
139                         TaskExecutionTraceLogger(),
140                         static_cast<TaskQueue::QueuePriority>(
141                             TaskQueue::DefaultQueuePriority::kNormalPriority),
142                         QueueName::TEST_TQ);
143   }
144 
DidRunTask(LazyNow & lazy_now)145   void DidRunTask(LazyNow& lazy_now) override {
146     task_execution_stack_.pop_back();
147   }
148 
GetPendingWakeUp(LazyNow * lazy_now,SelectTaskOption option)149   absl::optional<WakeUp> GetPendingWakeUp(LazyNow* lazy_now,
150                                           SelectTaskOption option) override {
151     if (tasks_.empty())
152       return absl::nullopt;
153     if (option == SequencedTaskSource::SelectTaskOption::kSkipDelayedTask &&
154         !tasks_.front().delayed_run_time.is_null()) {
155       return absl::nullopt;
156     }
157     if (tasks_.front().delayed_run_time.is_null())
158       return WakeUp{};
159     if (lazy_now->Now() > tasks_.front().delayed_run_time)
160       return WakeUp{};
161     return WakeUp{tasks_.front().delayed_run_time};
162   }
163 
AddTask(Location posted_from,OnceClosure task,TimeTicks delayed_run_time=TimeTicks (),TimeTicks queue_time=TimeTicks ())164   void AddTask(Location posted_from,
165                OnceClosure task,
166                TimeTicks delayed_run_time = TimeTicks(),
167                TimeTicks queue_time = TimeTicks()) {
168     DCHECK(tasks_.empty() || delayed_run_time.is_null() ||
169            tasks_.back().delayed_run_time < delayed_run_time);
170     tasks_.push(
171         Task(PostedTask(nullptr, std::move(task), posted_from, delayed_run_time,
172                         base::subtle::DelayPolicy::kFlexibleNoSooner),
173              EnqueueOrder::FromIntForTesting(13), EnqueueOrder(), queue_time));
174   }
175 
HasPendingHighResolutionTasks()176   bool HasPendingHighResolutionTasks() override {
177     return has_pending_high_resolution_tasks;
178   }
179 
SetHasPendingHighResolutionTasks(bool state)180   void SetHasPendingHighResolutionTasks(bool state) {
181     has_pending_high_resolution_tasks = state;
182   }
183 
OnSystemIdle()184   bool OnSystemIdle() override { return false; }
185 
MaybeEmitTaskDetails(perfetto::EventContext & ctx,const SelectedTask & selected_task) const186   void MaybeEmitTaskDetails(perfetto::EventContext& ctx,
187                             const SelectedTask& selected_task) const override {}
188 
189  private:
190   raw_ptr<TickClock> clock_;
191   std::queue<Task> tasks_;
192   // Use std::deque() so that references returned by SelectNextTask() remain
193   // valid until the matching call to DidRunTask(), even when nested RunLoops
194   // cause tasks to be pushed on the stack in-between. This is needed because
195   // references are kept in local variables by calling code between
196   // SelectNextTask()/DidRunTask().
197   //
198   // See also `SequenceManagerImpl::MainThreadOnly::task_execution_stack`.
199   std::deque<Task> task_execution_stack_;
200   bool has_pending_high_resolution_tasks = false;
201 };
202 
203 }  // namespace
204 
205 class ThreadControllerWithMessagePumpTestBase : public testing::Test {
206  public:
ThreadControllerWithMessagePumpTestBase(bool can_run_tasks_by_batches)207   explicit ThreadControllerWithMessagePumpTestBase(
208       bool can_run_tasks_by_batches)
209       : settings_(SequenceManager::Settings::Builder()
210                       .SetTickClock(&clock_)
211                       .SetCanRunTasksByBatches(can_run_tasks_by_batches)
212                       .Build()),
213         thread_controller_(
214             std::make_unique<testing::StrictMock<MockMessagePump>>(),
215             settings_),
216         message_pump_(static_cast<MockMessagePump*>(
217             thread_controller_.GetBoundMessagePump())),
218         task_source_(&clock_) {
219     // SimpleTestTickClock starts at zero, but that also satisfies
220     // TimeTicks::is_null() and that throws off some ThreadController state.
221     // Move away from 0. All ThreadControllerWithMessagePumpTests should favor
222     // Advance() over SetNowTicks() for this reason.
223     clock_.Advance(Seconds(1000));
224 
225     thread_controller_.SetWorkBatchSize(1);
226     thread_controller_.SetSequencedTaskSource(&task_source_);
227   }
228 
SetUp()229   void SetUp() override {
230     ThreadControllerPowerMonitor::OverrideUsePowerMonitorForTesting(true);
231   }
232 
TearDown()233   void TearDown() override { ThreadControllerPowerMonitor::ResetForTesting(); }
234 
FromNow(TimeDelta delta)235   TimeTicks FromNow(TimeDelta delta) { return clock_.NowTicks() + delta; }
236 
237  protected:
238   SimpleTestTickClock clock_;
239   SequenceManager::Settings settings_;
240   ThreadControllerForTest thread_controller_;
241   raw_ptr<MockMessagePump> message_pump_;
242   FakeSequencedTaskSource task_source_;
243 };
244 
245 class ThreadControllerWithMessagePumpTest
246     : public ThreadControllerWithMessagePumpTestBase {
247  public:
ThreadControllerWithMessagePumpTest()248   ThreadControllerWithMessagePumpTest()
249       : ThreadControllerWithMessagePumpTestBase(
250             /* can_run_tasks_by_batches=*/true) {}
251 };
252 
253 class ThreadControllerWithMessagePumpNoBatchesTest
254     : public ThreadControllerWithMessagePumpTestBase {
255  public:
ThreadControllerWithMessagePumpNoBatchesTest()256   ThreadControllerWithMessagePumpNoBatchesTest()
257       : ThreadControllerWithMessagePumpTestBase(
258             /* can_run_tasks_by_batches=*/false) {}
259 };
260 
TEST_F(ThreadControllerWithMessagePumpTest,ScheduleDelayedWork)261 TEST_F(ThreadControllerWithMessagePumpTest, ScheduleDelayedWork) {
262   MockCallback<OnceClosure> task1;
263   task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
264                        clock_.NowTicks());
265   MockCallback<OnceClosure> task2;
266   task_source_.AddTask(FROM_HERE, task2.Get());
267   MockCallback<OnceClosure> task3;
268   task_source_.AddTask(FROM_HERE, task3.Get(), FromNow(Seconds(20)),
269                        clock_.NowTicks());
270 
271   // Call a no-op DoWork. Expect that it doesn't do any work.
272   clock_.Advance(Seconds(5));
273   EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(_)).Times(0);
274   {
275     auto next_work_info = thread_controller_.DoWork();
276     EXPECT_FALSE(next_work_info.is_immediate());
277     EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(5)));
278   }
279   testing::Mock::VerifyAndClearExpectations(message_pump_);
280 
281   // Call DoWork after the expiration of the delay.
282   // Expect that |task1| runs and the return value indicates that |task2| can
283   // run immediately.
284   clock_.Advance(Seconds(6));
285   EXPECT_CALL(task1, Run()).Times(1);
286   {
287     auto next_work_info = thread_controller_.DoWork();
288     EXPECT_TRUE(next_work_info.is_immediate());
289   }
290   testing::Mock::VerifyAndClearExpectations(&task1);
291 
292   // Call DoWork. Expect |task2| to be run and the delayed run time of
293   // |task3| to be returned.
294   EXPECT_CALL(task2, Run()).Times(1);
295   {
296     auto next_work_info = thread_controller_.DoWork();
297     EXPECT_FALSE(next_work_info.is_immediate());
298     EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(9)));
299   }
300   testing::Mock::VerifyAndClearExpectations(&task2);
301 
302   // Call DoWork for the last task and expect to be told
303   // about the lack of further delayed work (next run time being TimeTicks()).
304   clock_.Advance(Seconds(10));
305   EXPECT_CALL(task3, Run()).Times(1);
306   {
307     auto next_work_info = thread_controller_.DoWork();
308     EXPECT_FALSE(next_work_info.is_immediate());
309     EXPECT_EQ(next_work_info.delayed_run_time, TimeTicks::Max());
310   }
311   testing::Mock::VerifyAndClearExpectations(&task3);
312 }
313 
TEST_F(ThreadControllerWithMessagePumpTest,SetNextDelayedDoWork)314 TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork) {
315   EXPECT_CALL(*message_pump_,
316               ScheduleDelayedWork_TimeTicks(FromNow(Seconds(123))));
317 
318   LazyNow lazy_now(&clock_);
319   thread_controller_.SetNextDelayedDoWork(&lazy_now,
320                                           WakeUp{FromNow(Seconds(123))});
321 }
322 
TEST_F(ThreadControllerWithMessagePumpTest,SetNextDelayedDoWork_CapAtOneDay)323 TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork_CapAtOneDay) {
324   EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(FromNow(Days(1))));
325 
326   LazyNow lazy_now(&clock_);
327   thread_controller_.SetNextDelayedDoWork(&lazy_now, WakeUp{FromNow(Days(2))});
328 }
329 
TEST_F(ThreadControllerWithMessagePumpTest,DelayedWork_CapAtOneDay)330 TEST_F(ThreadControllerWithMessagePumpTest, DelayedWork_CapAtOneDay) {
331   MockCallback<OnceClosure> task1;
332   task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Days(10)),
333                        clock_.NowTicks());
334 
335   auto next_work_info = thread_controller_.DoWork();
336   EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Days(1)));
337 }
338 
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkDoesntScheduleDelayedWork)339 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkDoesntScheduleDelayedWork) {
340   MockCallback<OnceClosure> task1;
341   task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
342                        clock_.NowTicks());
343 
344   EXPECT_CALL(*message_pump_, ScheduleDelayedWork_TimeTicks(_)).Times(0);
345   auto next_work_info = thread_controller_.DoWork();
346   EXPECT_EQ(next_work_info.delayed_run_time, FromNow(Seconds(10)));
347 }
348 
TEST_F(ThreadControllerWithMessagePumpTest,NestedExecution)349 TEST_F(ThreadControllerWithMessagePumpTest, NestedExecution) {
350   // This test posts three immediate tasks. The first creates a nested RunLoop
351   // and the test expects that the second and third tasks are run outside of
352   // the nested loop.
353   std::vector<std::string> log;
354 
355   SingleThreadTaskRunner::CurrentDefaultHandle handle(
356       MakeRefCounted<FakeTaskRunner>());
357 
358   EXPECT_CALL(*message_pump_, Run(_))
359       .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
360         log.push_back("entering top-level runloop");
361         EXPECT_EQ(delegate, &thread_controller_);
362         EXPECT_TRUE(delegate->DoWork().is_immediate());
363         EXPECT_TRUE(delegate->DoWork().is_immediate());
364         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
365         log.push_back("exiting top-level runloop");
366       }))
367       .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
368         log.push_back("entering nested runloop");
369         EXPECT_EQ(delegate, &thread_controller_);
370         EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
371         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
372         log.push_back("exiting nested runloop");
373       }));
374 
375   task_source_.AddTask(FROM_HERE,
376                        base::BindOnce(
377                            [](std::vector<std::string>* log,
378                               ThreadControllerForTest* controller) {
379                              EXPECT_FALSE(controller->IsTaskExecutionAllowed());
380                              log->push_back("task1");
381                              RunLoop().Run();
382                            },
383                            &log, &thread_controller_),
384                        TimeTicks());
385   task_source_.AddTask(FROM_HERE,
386                        base::BindOnce(
387                            [](std::vector<std::string>* log,
388                               ThreadControllerForTest* controller) {
389                              EXPECT_FALSE(controller->IsTaskExecutionAllowed());
390                              log->push_back("task2");
391                            },
392                            &log, &thread_controller_),
393                        TimeTicks());
394   task_source_.AddTask(FROM_HERE,
395                        base::BindOnce(
396                            [](std::vector<std::string>* log,
397                               ThreadControllerForTest* controller) {
398                              EXPECT_FALSE(controller->IsTaskExecutionAllowed());
399                              log->push_back("task3");
400                            },
401                            &log, &thread_controller_),
402                        TimeTicks());
403 
404   EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
405   RunLoop().Run();
406 
407   EXPECT_THAT(log,
408               ElementsAre("entering top-level runloop", "task1",
409                           "entering nested runloop", "exiting nested runloop",
410                           "task2", "task3", "exiting top-level runloop"));
411   testing::Mock::VerifyAndClearExpectations(message_pump_);
412 }
413 
TEST_F(ThreadControllerWithMessagePumpTest,NestedExecutionWithApplicationTasks)414 TEST_F(ThreadControllerWithMessagePumpTest,
415        NestedExecutionWithApplicationTasks) {
416   // This test is similar to the previous one, but execution is explicitly
417   // allowed (by specifying appropriate RunLoop type), and tasks are run inside
418   // nested runloop.
419   std::vector<std::string> log;
420 
421   SingleThreadTaskRunner::CurrentDefaultHandle handle(
422       MakeRefCounted<FakeTaskRunner>());
423 
424   EXPECT_CALL(*message_pump_, Run(_))
425       .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
426         log.push_back("entering top-level runloop");
427         EXPECT_EQ(delegate, &thread_controller_);
428         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
429         log.push_back("exiting top-level runloop");
430       }))
431       .WillOnce(Invoke([&log, this](MessagePump::Delegate* delegate) {
432         log.push_back("entering nested runloop");
433         EXPECT_EQ(delegate, &thread_controller_);
434         EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
435         EXPECT_TRUE(delegate->DoWork().is_immediate());
436         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
437         log.push_back("exiting nested runloop");
438       }));
439 
440   task_source_.AddTask(
441       FROM_HERE,
442       base::BindOnce(
443           [](std::vector<std::string>* log,
444              ThreadControllerForTest* controller) {
445             EXPECT_FALSE(controller->IsTaskExecutionAllowed());
446             log->push_back("task1");
447             RunLoop(RunLoop::Type::kNestableTasksAllowed).Run();
448           },
449           &log, &thread_controller_),
450       TimeTicks());
451   task_source_.AddTask(FROM_HERE,
452                        base::BindOnce(
453                            [](std::vector<std::string>* log,
454                               ThreadControllerForTest* controller) {
455                              EXPECT_FALSE(controller->IsTaskExecutionAllowed());
456                              log->push_back("task2");
457                            },
458                            &log, &thread_controller_),
459                        TimeTicks());
460   task_source_.AddTask(FROM_HERE,
461                        base::BindOnce(
462                            [](std::vector<std::string>* log,
463                               ThreadControllerForTest* controller) {
464                              EXPECT_FALSE(controller->IsTaskExecutionAllowed());
465                              log->push_back("task3");
466                            },
467                            &log, &thread_controller_),
468                        TimeTicks());
469 
470   EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
471   RunLoop().Run();
472 
473   EXPECT_THAT(
474       log, ElementsAre("entering top-level runloop", "task1",
475                        "entering nested runloop", "task2", "task3",
476                        "exiting nested runloop", "exiting top-level runloop"));
477   testing::Mock::VerifyAndClearExpectations(message_pump_);
478 }
479 
TEST_F(ThreadControllerWithMessagePumpTest,SetDefaultTaskRunner)480 TEST_F(ThreadControllerWithMessagePumpTest, SetDefaultTaskRunner) {
481   scoped_refptr<SingleThreadTaskRunner> task_runner1 =
482       MakeRefCounted<FakeTaskRunner>();
483   thread_controller_.SetDefaultTaskRunner(task_runner1);
484   EXPECT_EQ(task_runner1, SingleThreadTaskRunner::GetCurrentDefault());
485 
486   // Check that we are correctly supporting overriding.
487   scoped_refptr<SingleThreadTaskRunner> task_runner2 =
488       MakeRefCounted<FakeTaskRunner>();
489   thread_controller_.SetDefaultTaskRunner(task_runner2);
490   EXPECT_EQ(task_runner2, SingleThreadTaskRunner::GetCurrentDefault());
491 }
492 
TEST_F(ThreadControllerWithMessagePumpTest,EnsureWorkScheduled)493 TEST_F(ThreadControllerWithMessagePumpTest, EnsureWorkScheduled) {
494   task_source_.AddTask(FROM_HERE, DoNothing());
495 
496   // Ensure that the first ScheduleWork() call results in the pump being called.
497   EXPECT_CALL(*message_pump_, ScheduleWork());
498   thread_controller_.ScheduleWork();
499   testing::Mock::VerifyAndClearExpectations(message_pump_);
500 
501   // Ensure that the subsequent ScheduleWork() does not call the pump.
502   thread_controller_.ScheduleWork();
503   testing::Mock::VerifyAndClearExpectations(message_pump_);
504 
505   // EnsureWorkScheduled() doesn't need to do anything because there's a pending
506   // DoWork.
507   EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
508   thread_controller_.EnsureWorkScheduled();
509   testing::Mock::VerifyAndClearExpectations(message_pump_);
510 
511   EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
512 
513   // EnsureWorkScheduled() calls the pump because there's no pending DoWork.
514   EXPECT_CALL(*message_pump_, ScheduleWork()).Times(1);
515   thread_controller_.EnsureWorkScheduled();
516   testing::Mock::VerifyAndClearExpectations(message_pump_);
517 }
518 
TEST_F(ThreadControllerWithMessagePumpTest,WorkBatching)519 TEST_F(ThreadControllerWithMessagePumpTest, WorkBatching) {
520   SingleThreadTaskRunner::CurrentDefaultHandle handle(
521       MakeRefCounted<FakeTaskRunner>());
522 
523   const int kBatchSize = 5;
524   thread_controller_.SetWorkBatchSize(kBatchSize);
525 
526   int task_count = 0;
527   EXPECT_CALL(*message_pump_, Run(_))
528       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
529         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
530         EXPECT_EQ(5, task_count);
531       }));
532 
533   for (int i = 0; i < kBatchSize; i++) {
534     task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] { task_count++; }),
535                          TimeTicks());
536   }
537 
538   RunLoop run_loop;
539   run_loop.Run();
540   testing::Mock::VerifyAndClearExpectations(message_pump_);
541 }
542 
TEST_F(ThreadControllerWithMessagePumpTest,QuitInterruptsBatch)543 TEST_F(ThreadControllerWithMessagePumpTest, QuitInterruptsBatch) {
544   // This check ensures that RunLoop::Quit() makes us drop back to a work batch
545   // size of 1.
546   SingleThreadTaskRunner::CurrentDefaultHandle handle(
547       MakeRefCounted<FakeTaskRunner>());
548 
549   const int kBatchSize = 5;
550   thread_controller_.SetWorkBatchSize(kBatchSize);
551 
552   int task_count = 0;
553   EXPECT_CALL(*message_pump_, Run(_))
554       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
555         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
556         EXPECT_EQ(1, task_count);
557 
558         // Somewhat counter-intuitive, but if the pump keeps calling us after
559         // Quit(), the delegate should still run tasks as normally. This is
560         // needed to support nested OS-level runloops that still pump
561         // application tasks (e.g., showing a popup menu on Mac).
562         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
563         EXPECT_EQ(2, task_count);
564         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
565         EXPECT_EQ(3, task_count);
566       }));
567   EXPECT_CALL(*message_pump_, Quit());
568 
569   RunLoop run_loop;
570   for (int i = 0; i < kBatchSize; i++) {
571     task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] {
572                            if (!task_count++)
573                              run_loop.Quit();
574                          }),
575                          TimeTicks());
576   }
577 
578   run_loop.Run();
579   testing::Mock::VerifyAndClearExpectations(message_pump_);
580 }
581 
TEST_F(ThreadControllerWithMessagePumpTest,PrioritizeYieldingToNative)582 TEST_F(ThreadControllerWithMessagePumpTest, PrioritizeYieldingToNative) {
583   SingleThreadTaskRunner::CurrentDefaultHandle handle(
584       MakeRefCounted<FakeTaskRunner>());
585 
586   testing::InSequence sequence;
587 
588   RunLoop run_loop;
589   const auto delayed_time = FromNow(Seconds(10));
590   EXPECT_CALL(*message_pump_, Run(_))
591       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
592         clock_.Advance(Seconds(5));
593         MockCallback<OnceClosure> tasks[5];
594 
595         // A: Post 5 application tasks, 4 immediate 1 delayed.
596         // B: Run one of them (enter active)
597         //   C: Expect we return immediate work item without yield_to_native
598         //      (default behaviour).
599         // D: Set PrioritizeYieldingToNative until 8 seconds and run second
600         //    task.
601         //   E: Expect we return immediate work item with yield_to_native.
602         // F: Exceed the PrioritizeYieldingToNative deadline and run third task.
603         //   G: Expect we return immediate work item without yield_to_native.
604         // H: Set PrioritizeYieldingToNative to Max() and run third of them
605         //   I: Expect we return a delayed work item with yield_to_native.
606 
607         // A:
608         task_source_.AddTask(FROM_HERE, tasks[0].Get(),
609                              /* delayed_run_time=*/base::TimeTicks(),
610                              /* queue_time=*/clock_.NowTicks());
611         task_source_.AddTask(FROM_HERE, tasks[1].Get(),
612                              /* delayed_run_time=*/base::TimeTicks(),
613                              /* queue_time=*/clock_.NowTicks());
614         task_source_.AddTask(FROM_HERE, tasks[2].Get(),
615                              /* delayed_run_time=*/base::TimeTicks(),
616                              /* queue_time=*/clock_.NowTicks());
617         task_source_.AddTask(FROM_HERE, tasks[3].Get(),
618                              /* delayed_run_time=*/base::TimeTicks(),
619                              /* queue_time=*/clock_.NowTicks());
620         task_source_.AddTask(FROM_HERE, tasks[4].Get(),
621                              /* delayed_run_time=*/delayed_time,
622                              /* queue_time=*/clock_.NowTicks());
623 
624         // B:
625         EXPECT_CALL(tasks[0], Run());
626         auto next_work_item = thread_controller_.DoWork();
627         // C:
628         EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
629         EXPECT_FALSE(next_work_item.yield_to_native);
630 
631         // D:
632         thread_controller_.PrioritizeYieldingToNative(FromNow(Seconds(3)));
633         EXPECT_CALL(tasks[1], Run());
634         next_work_item = thread_controller_.DoWork();
635         // E:
636         EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
637         EXPECT_TRUE(next_work_item.yield_to_native);
638 
639         // F:
640         clock_.Advance(Seconds(3));
641         EXPECT_CALL(tasks[2], Run());
642         next_work_item = thread_controller_.DoWork();
643         // G:
644         EXPECT_EQ(next_work_item.delayed_run_time, TimeTicks());
645         EXPECT_FALSE(next_work_item.yield_to_native);
646 
647         // H:
648         thread_controller_.PrioritizeYieldingToNative(base::TimeTicks::Max());
649         EXPECT_CALL(tasks[3], Run());
650         next_work_item = thread_controller_.DoWork();
651 
652         // I:
653         EXPECT_EQ(next_work_item.delayed_run_time, delayed_time);
654         EXPECT_TRUE(next_work_item.yield_to_native);
655 
656         EXPECT_FALSE(thread_controller_.DoIdleWork());
657       }));
658 
659   run_loop.Run();
660   testing::Mock::VerifyAndClearExpectations(message_pump_);
661 }
662 
TEST_F(ThreadControllerWithMessagePumpTest,EarlyQuit)663 TEST_F(ThreadControllerWithMessagePumpTest, EarlyQuit) {
664   // This test ensures that a opt-of-runloop Quit() (which is possible with some
665   // pump implementations) doesn't affect the next RunLoop::Run call.
666 
667   SingleThreadTaskRunner::CurrentDefaultHandle handle(
668       MakeRefCounted<FakeTaskRunner>());
669 
670   std::vector<std::string> log;
671 
672   // This quit should be a no-op for future calls.
673   EXPECT_CALL(*message_pump_, Quit());
674   thread_controller_.Quit();
675   testing::Mock::VerifyAndClearExpectations(message_pump_);
676 
677   EXPECT_CALL(*message_pump_, Run(_))
678       .WillOnce(Invoke([this](MessagePump::Delegate* delegate) {
679         EXPECT_EQ(delegate, &thread_controller_);
680         EXPECT_TRUE(delegate->DoWork().is_immediate());
681         EXPECT_EQ(delegate->DoWork().delayed_run_time, TimeTicks::Max());
682       }));
683 
684   RunLoop run_loop;
685 
686   task_source_.AddTask(
687       FROM_HERE,
688       base::BindOnce(
689           [](std::vector<std::string>* log) { log->push_back("task1"); }, &log),
690       TimeTicks());
691   task_source_.AddTask(
692       FROM_HERE,
693       base::BindOnce(
694           [](std::vector<std::string>* log) { log->push_back("task2"); }, &log),
695       TimeTicks());
696 
697   run_loop.RunUntilIdle();
698 
699   EXPECT_THAT(log, ElementsAre("task1", "task2"));
700   testing::Mock::VerifyAndClearExpectations(message_pump_);
701 }
702 
TEST_F(ThreadControllerWithMessagePumpTest,NativeNestedMessageLoop)703 TEST_F(ThreadControllerWithMessagePumpTest, NativeNestedMessageLoop) {
704   bool did_run = false;
705   task_source_.AddTask(
706       FROM_HERE, BindLambdaForTesting([&] {
707         // Clear expectation set for the non-nested PostTask.
708         testing::Mock::VerifyAndClearExpectations(message_pump_);
709 
710         EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
711         // SetTaskExecutionAllowed(true) should ScheduleWork.
712         EXPECT_CALL(*message_pump_, ScheduleWork());
713         thread_controller_.SetTaskExecutionAllowed(true);
714         testing::Mock::VerifyAndClearExpectations(message_pump_);
715 
716         // There's no pending work so the native loop should go
717         // idle.
718         EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
719         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
720                   TimeTicks::Max());
721         testing::Mock::VerifyAndClearExpectations(message_pump_);
722 
723         // Simulate a native callback which posts a task, this
724         // should now ask the pump to ScheduleWork();
725         task_source_.AddTask(FROM_HERE, DoNothing());
726         EXPECT_CALL(*message_pump_, ScheduleWork());
727         thread_controller_.ScheduleWork();
728         testing::Mock::VerifyAndClearExpectations(message_pump_);
729 
730         thread_controller_.SetTaskExecutionAllowed(false);
731 
732         // Simulate a subsequent PostTask by the chromium task after
733         // we've left the native loop. This should not ScheduleWork
734         // on the pump because the ThreadController will do that
735         // after this task finishes.
736         task_source_.AddTask(FROM_HERE, DoNothing());
737         EXPECT_CALL(*message_pump_, ScheduleWork()).Times(0);
738         thread_controller_.ScheduleWork();
739 
740         did_run = true;
741       }),
742       TimeTicks());
743 
744   // Simulate a PostTask that enters a native nested message loop.
745   EXPECT_CALL(*message_pump_, ScheduleWork());
746   thread_controller_.ScheduleWork();
747   EXPECT_TRUE(thread_controller_.DoWork().is_immediate());
748   EXPECT_TRUE(did_run);
749 }
750 
TEST_F(ThreadControllerWithMessagePumpTest,RunWithTimeout)751 TEST_F(ThreadControllerWithMessagePumpTest, RunWithTimeout) {
752   MockCallback<OnceClosure> task1;
753   task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(5)),
754                        clock_.NowTicks());
755   MockCallback<OnceClosure> task2;
756   task_source_.AddTask(FROM_HERE, task2.Get(), FromNow(Seconds(10)),
757                        clock_.NowTicks());
758   MockCallback<OnceClosure> task3;
759   task_source_.AddTask(FROM_HERE, task3.Get(), FromNow(Seconds(20)),
760                        clock_.NowTicks());
761 
762   EXPECT_CALL(*message_pump_, Run(_))
763       .WillOnce(Invoke([&](MessagePump::Delegate*) {
764         clock_.Advance(Seconds(5));
765         EXPECT_CALL(task1, Run()).Times(1);
766         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
767                   FromNow(Seconds(5)));
768 
769         clock_.Advance(Seconds(5));
770         EXPECT_CALL(task2, Run()).Times(1);
771         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
772                   FromNow(Seconds(5)));
773 
774         clock_.Advance(Seconds(5));
775         EXPECT_CALL(task3, Run()).Times(0);
776         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
777                   TimeTicks::Max());
778 
779         EXPECT_CALL(*message_pump_, Quit());
780         EXPECT_FALSE(thread_controller_.DoIdleWork());
781       }));
782   thread_controller_.Run(true, Seconds(15));
783 }
784 
785 #if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest,SetHighResolutionTimer)786 TEST_F(ThreadControllerWithMessagePumpTest, SetHighResolutionTimer) {
787   MockCallback<OnceClosure> task;
788   task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
789                        clock_.NowTicks());
790 
791   SingleThreadTaskRunner::CurrentDefaultHandle handle(
792       MakeRefCounted<FakeTaskRunner>());
793 
794   EXPECT_CALL(*message_pump_, Run(_))
795       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
796         // Should initially not be in high resolution.
797         EXPECT_FALSE(
798             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
799 
800         // Ensures timer resolution is set to high resolution.
801         task_source_.SetHasPendingHighResolutionTasks(true);
802         EXPECT_FALSE(delegate->DoIdleWork());
803         EXPECT_TRUE(
804             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
805 
806         // Ensures time resolution is set back to low resolution.
807         task_source_.SetHasPendingHighResolutionTasks(false);
808         EXPECT_FALSE(delegate->DoIdleWork());
809         EXPECT_FALSE(
810             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
811 
812         EXPECT_CALL(*message_pump_, Quit());
813         thread_controller_.Quit();
814       }));
815 
816   RunLoop run_loop;
817   run_loop.Run();
818 }
819 #endif  // BUILDFLAG(IS_WIN)
820 
821 #if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest,SetHighResolutionTimerWithPowerSuspend)822 TEST_F(ThreadControllerWithMessagePumpTest,
823        SetHighResolutionTimerWithPowerSuspend) {
824   MockCallback<OnceClosure> task;
825   task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
826                        clock_.NowTicks());
827 
828   SingleThreadTaskRunner::CurrentDefaultHandle handle(
829       MakeRefCounted<FakeTaskRunner>());
830 
831   EXPECT_CALL(*message_pump_, Run(_))
832       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
833         // Should initially not be in high resolution.
834         EXPECT_FALSE(
835             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
836 
837         // The power suspend notification is sent.
838         thread_controller_.ThreadControllerPowerMonitorForTesting()
839             ->OnSuspend();
840 
841         // The timer resolution should NOT be updated during power suspend.
842         task_source_.SetHasPendingHighResolutionTasks(true);
843         EXPECT_FALSE(delegate->DoIdleWork());
844         EXPECT_FALSE(
845             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
846 
847         // The power resume notification is sent.
848         thread_controller_.ThreadControllerPowerMonitorForTesting()->OnResume();
849 
850         // Ensures timer resolution is set to high resolution.
851         EXPECT_FALSE(delegate->DoIdleWork());
852         EXPECT_TRUE(
853             thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
854 
855         EXPECT_CALL(*message_pump_, Quit());
856         thread_controller_.Quit();
857       }));
858 
859   RunLoop run_loop;
860   run_loop.Run();
861 }
862 #endif  // BUILDFLAG(IS_WIN)
863 
TEST_F(ThreadControllerWithMessagePumpTest,ScheduleDelayedWorkWithPowerSuspend)864 TEST_F(ThreadControllerWithMessagePumpTest,
865        ScheduleDelayedWorkWithPowerSuspend) {
866   SingleThreadTaskRunner::CurrentDefaultHandle handle(
867       MakeRefCounted<FakeTaskRunner>());
868 
869   MockCallback<OnceClosure> task1;
870   task_source_.AddTask(FROM_HERE, task1.Get(), FromNow(Seconds(10)),
871                        clock_.NowTicks());
872   MockCallback<OnceClosure> task2;
873   task_source_.AddTask(FROM_HERE, task2.Get(), FromNow(Seconds(15)),
874                        clock_.NowTicks());
875 
876   clock_.Advance(Seconds(5));
877 
878   // Call a no-op DoWork. Expect that it doesn't do any work.
879   EXPECT_CALL(task1, Run()).Times(0);
880   EXPECT_CALL(task2, Run()).Times(0);
881   EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, FromNow(Seconds(5)));
882   testing::Mock::VerifyAndClearExpectations(&task1);
883   testing::Mock::VerifyAndClearExpectations(&task2);
884 
885   // Simulate a power suspend.
886   thread_controller_.ThreadControllerPowerMonitorForTesting()->OnSuspend();
887 
888   // Delayed task is not yet ready to be executed.
889   EXPECT_CALL(task1, Run()).Times(0);
890   EXPECT_CALL(task2, Run()).Times(0);
891   EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
892   testing::Mock::VerifyAndClearExpectations(&task1);
893   testing::Mock::VerifyAndClearExpectations(&task2);
894 
895   // Move time after the expiration delay of tasks.
896   clock_.Advance(Seconds(42));
897 
898   // Should not process delayed tasks. The process is still in suspended power
899   // state.
900   EXPECT_CALL(task1, Run()).Times(0);
901   EXPECT_CALL(task2, Run()).Times(0);
902   EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
903   testing::Mock::VerifyAndClearExpectations(&task1);
904   testing::Mock::VerifyAndClearExpectations(&task2);
905 
906   // Simulate a power resume.
907   thread_controller_.ThreadControllerPowerMonitorForTesting()->OnResume();
908 
909   // No longer in suspended state. Controller should process both delayed tasks.
910   EXPECT_CALL(task1, Run()).Times(1);
911   EXPECT_CALL(task2, Run()).Times(1);
912   EXPECT_TRUE(thread_controller_.DoWork().is_immediate());
913   EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks::Max());
914   testing::Mock::VerifyAndClearExpectations(&task1);
915   testing::Mock::VerifyAndClearExpectations(&task2);
916 }
917 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveSingleApplicationTask)918 TEST_F(ThreadControllerWithMessagePumpTest,
919        ThreadControllerActiveSingleApplicationTask) {
920   SingleThreadTaskRunner::CurrentDefaultHandle handle(
921       MakeRefCounted<FakeTaskRunner>());
922 
923   thread_controller_.InstallTraceObserver();
924 
925   testing::InSequence sequence;
926 
927   RunLoop run_loop;
928   EXPECT_CALL(*thread_controller_.trace_observer_,
929               OnThreadControllerActiveBegin);
930   EXPECT_CALL(*message_pump_, Run(_))
931       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
932         // Don't expect a call to OnThreadControllerActiveBegin on the first
933         // pass as the Run() call already triggered the active state.
934         bool first_pass = true;
935 
936         // Post 1 task, run it, go idle, repeat 5 times. Expected to enter/exit
937         // "ThreadController active" state 5 consecutive times.
938         for (int i = 0; i < 5; ++i, first_pass = false) {
939           MockCallback<OnceClosure> task;
940           task_source_.AddTask(FROM_HERE, task.Get());
941 
942           if (!first_pass) {
943             EXPECT_CALL(*thread_controller_.trace_observer_,
944                         OnThreadControllerActiveBegin);
945           } else {
946             // The first pass begins with a kPumpOverhead phase as the
947             // RunLoop::Run() begins active. Subsequent passes begin idle and
948             // thus start with a kSelectingApplicationTask phase.
949             EXPECT_CALL(*thread_controller_.trace_observer_,
950                         OnPhaseRecorded(ThreadController::kPumpOverhead));
951           }
952           EXPECT_CALL(
953               *thread_controller_.trace_observer_,
954               OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
955           EXPECT_CALL(task, Run());
956           EXPECT_CALL(*thread_controller_.trace_observer_,
957                       OnPhaseRecorded(ThreadController::kApplicationTask));
958           EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
959                     TimeTicks::Max());
960 
961           testing::Mock::VerifyAndClearExpectations(
962               &*thread_controller_.trace_observer_);
963 
964           EXPECT_CALL(*thread_controller_.trace_observer_,
965                       OnPhaseRecorded(ThreadController::kIdleWork));
966           EXPECT_CALL(*thread_controller_.trace_observer_,
967                       OnThreadControllerActiveEnd);
968           EXPECT_FALSE(thread_controller_.DoIdleWork());
969 
970           testing::Mock::VerifyAndClearExpectations(
971               &*thread_controller_.trace_observer_);
972         }
973       }));
974 
975   RunLoop().Run();
976 }
977 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveMultipleApplicationTasks)978 TEST_F(ThreadControllerWithMessagePumpTest,
979        ThreadControllerActiveMultipleApplicationTasks) {
980   SingleThreadTaskRunner::CurrentDefaultHandle handle(
981       MakeRefCounted<FakeTaskRunner>());
982 
983   thread_controller_.InstallTraceObserver();
984 
985   testing::InSequence sequence;
986 
987   RunLoop run_loop;
988   EXPECT_CALL(*thread_controller_.trace_observer_,
989               OnThreadControllerActiveBegin);
990   EXPECT_CALL(*message_pump_, Run(_))
991       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
992         MockCallback<OnceClosure> tasks[5];
993         // Post 5 tasks, run them, go idle. Expected to only exit
994         // "ThreadController active" state at the end.
995         for (auto& t : tasks)
996           task_source_.AddTask(FROM_HERE, t.Get());
997         for (size_t i = 0; i < std::size(tasks); ++i) {
998           const TimeTicks expected_delayed_run_time =
999               i < std::size(tasks) - 1 ? TimeTicks() : TimeTicks::Max();
1000 
1001           // The first pass begins with a kPumpOverhead phase as the
1002           // RunLoop::Run() begins active and the subsequent ones also do
1003           // (between the end of the last kChromeTask and the next
1004           // kSelectingApplicationTask).
1005           EXPECT_CALL(*thread_controller_.trace_observer_,
1006                       OnPhaseRecorded(ThreadController::kPumpOverhead));
1007 
1008           EXPECT_CALL(
1009               *thread_controller_.trace_observer_,
1010               OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1011           EXPECT_CALL(tasks[i], Run());
1012           EXPECT_CALL(*thread_controller_.trace_observer_,
1013                       OnPhaseRecorded(ThreadController::kApplicationTask));
1014           EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1015                     expected_delayed_run_time);
1016         }
1017 
1018         EXPECT_CALL(*thread_controller_.trace_observer_,
1019                     OnPhaseRecorded(ThreadController::kIdleWork));
1020         EXPECT_CALL(*thread_controller_.trace_observer_,
1021                     OnThreadControllerActiveEnd);
1022         EXPECT_FALSE(thread_controller_.DoIdleWork());
1023       }));
1024 
1025   RunLoop().Run();
1026 }
1027 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveWakeUpForNothing)1028 TEST_F(ThreadControllerWithMessagePumpTest,
1029        ThreadControllerActiveWakeUpForNothing) {
1030   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1031       MakeRefCounted<FakeTaskRunner>());
1032 
1033   thread_controller_.InstallTraceObserver();
1034 
1035   testing::InSequence sequence;
1036 
1037   RunLoop run_loop;
1038   EXPECT_CALL(*thread_controller_.trace_observer_,
1039               OnThreadControllerActiveBegin);
1040   EXPECT_CALL(*message_pump_, Run(_))
1041       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1042         // Don't expect a call to OnThreadControllerActiveBegin on the first
1043         // pass as the Run() call already triggered the active state.
1044         bool first_pass = true;
1045 
1046         // Invoke DoWork with no pending work, go idle, repeat 5 times. Expected
1047         // to enter/exit "ThreadController active" state 5 consecutive times.
1048         for (int i = 0; i < 5; ++i, first_pass = false) {
1049           if (!first_pass) {
1050             EXPECT_CALL(*thread_controller_.trace_observer_,
1051                         OnThreadControllerActiveBegin);
1052           } else {
1053             // As-in ThreadControllerActiveSingleApplicationTask.
1054             EXPECT_CALL(*thread_controller_.trace_observer_,
1055                         OnPhaseRecorded(ThreadController::kPumpOverhead));
1056           }
1057           EXPECT_CALL(
1058               *thread_controller_.trace_observer_,
1059               OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1060           EXPECT_CALL(*thread_controller_.trace_observer_,
1061                       OnPhaseRecorded(ThreadController::kApplicationTask));
1062           EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1063                     TimeTicks::Max());
1064 
1065           testing::Mock::VerifyAndClearExpectations(
1066               &*thread_controller_.trace_observer_);
1067 
1068           EXPECT_CALL(*thread_controller_.trace_observer_,
1069                       OnPhaseRecorded(ThreadController::kIdleWork));
1070           EXPECT_CALL(*thread_controller_.trace_observer_,
1071                       OnThreadControllerActiveEnd);
1072           EXPECT_FALSE(thread_controller_.DoIdleWork());
1073 
1074           testing::Mock::VerifyAndClearExpectations(
1075               &*thread_controller_.trace_observer_);
1076         }
1077       }));
1078 
1079   RunLoop().Run();
1080 }
1081 
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkBatches)1082 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatches) {
1083   base::test::ScopedFeatureList scoped_feature_list;
1084 
1085   scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1086   ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1087   MessagePump::InitializeFeatures();
1088 
1089   int task_counter = 0;
1090   for (int i = 0; i < 2; i++) {
1091     task_source_.AddTask(
1092         FROM_HERE, BindLambdaForTesting([&] { task_counter++; }), TimeTicks());
1093   }
1094   thread_controller_.DoWork();
1095 
1096   EXPECT_EQ(task_counter, 2);
1097   ThreadControllerWithMessagePumpImpl::ResetFeatures();
1098 }
1099 
TEST_F(ThreadControllerWithMessagePumpNoBatchesTest,DoWorkBatches)1100 TEST_F(ThreadControllerWithMessagePumpNoBatchesTest, DoWorkBatches) {
1101   base::test::ScopedFeatureList scoped_feature_list;
1102 
1103   scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1104   ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1105   MessagePump::InitializeFeatures();
1106 
1107   int task_counter = 0;
1108   for (int i = 0; i < 2; i++) {
1109     task_source_.AddTask(
1110         FROM_HERE, BindLambdaForTesting([&] { task_counter++; }), TimeTicks());
1111   }
1112   thread_controller_.DoWork();
1113 
1114   // Only one task should run because the SequenceManager was configured to
1115   // disallow batches.
1116   EXPECT_EQ(task_counter, 1);
1117   ThreadControllerWithMessagePumpImpl::ResetFeatures();
1118 }
1119 
TEST_F(ThreadControllerWithMessagePumpTest,DoWorkBatchesForSetTime)1120 TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatchesForSetTime) {
1121   base::test::ScopedFeatureList scoped_feature_list;
1122 
1123   scoped_feature_list.InitAndEnableFeature(kRunTasksByBatches);
1124   ThreadControllerWithMessagePumpImpl::InitializeFeatures();
1125   MessagePump::InitializeFeatures();
1126 
1127   int task_counter = 0;
1128 
1129   for (int i = 0; i < 4; i++) {
1130     task_source_.AddTask(FROM_HERE, BindLambdaForTesting([&] {
1131                            clock_.Advance(Milliseconds(4));
1132                            task_counter++;
1133                          }));
1134   }
1135   thread_controller_.DoWork();
1136 
1137   EXPECT_EQ(task_counter, 2);
1138   ThreadControllerWithMessagePumpImpl::ResetFeatures();
1139 }
1140 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveAdvancedNesting)1141 TEST_F(ThreadControllerWithMessagePumpTest,
1142        ThreadControllerActiveAdvancedNesting) {
1143   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1144       MakeRefCounted<FakeTaskRunner>());
1145 
1146   thread_controller_.InstallTraceObserver();
1147 
1148   testing::InSequence sequence;
1149 
1150   RunLoop run_loop;
1151   EXPECT_CALL(*thread_controller_.trace_observer_,
1152               OnThreadControllerActiveBegin);
1153   EXPECT_CALL(*message_pump_, Run(_))
1154       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1155         MockCallback<OnceClosure> tasks[5];
1156 
1157         // A: Post 2 tasks
1158         // B: Run one of them (enter active)
1159         //   C: Enter a nested loop (enter nested active)
1160         //     D: Run the next task (remain nested active)
1161         //     E: Go idle (exit active)
1162         //     F: Post 2 tasks
1163         //     G: Run one (enter nested active)
1164         //     H: exit nested loop (exit nested active)
1165         // I: Run the next one, go idle (remain active, exit active)
1166         // J: Post/run one more task, go idle (enter active, exit active)
1167         // ��
1168 
1169         // A:
1170         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1171         task_source_.AddTask(FROM_HERE, tasks[1].Get());
1172 
1173         EXPECT_CALL(*thread_controller_.trace_observer_,
1174                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1175         EXPECT_CALL(
1176             *thread_controller_.trace_observer_,
1177             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1178         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1179           // C:
1180           // kChromeTask phase is suspended when the nested loop is entered.
1181           EXPECT_CALL(*thread_controller_.trace_observer_,
1182                       OnPhaseRecorded(ThreadController::kApplicationTask));
1183           EXPECT_CALL(*thread_controller_.trace_observer_,
1184                       OnThreadControllerActiveBegin);
1185           EXPECT_CALL(*message_pump_, Run(_))
1186               .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1187                 // D:
1188                 EXPECT_CALL(tasks[1], Run());
1189                 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1190                           TimeTicks::Max());
1191                 testing::Mock::VerifyAndClearExpectations(
1192                     &*thread_controller_.trace_observer_);
1193 
1194                 // E:
1195                 EXPECT_CALL(*thread_controller_.trace_observer_,
1196                             OnThreadControllerActiveEnd);
1197                 EXPECT_FALSE(thread_controller_.DoIdleWork());
1198                 testing::Mock::VerifyAndClearExpectations(
1199                     &*thread_controller_.trace_observer_);
1200 
1201                 // F:
1202                 task_source_.AddTask(FROM_HERE, tasks[2].Get());
1203                 task_source_.AddTask(FROM_HERE, tasks[3].Get());
1204 
1205                 // G:
1206                 EXPECT_CALL(*thread_controller_.trace_observer_,
1207                             OnThreadControllerActiveBegin);
1208                 EXPECT_CALL(tasks[2], Run());
1209                 EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1210                           TimeTicks());
1211                 testing::Mock::VerifyAndClearExpectations(
1212                     &*thread_controller_.trace_observer_);
1213 
1214                 // H:
1215                 EXPECT_CALL(*thread_controller_.trace_observer_,
1216                             OnThreadControllerActiveEnd);
1217                 // The kNested phase (C) ends when the RunLoop exits...
1218                 EXPECT_CALL(*thread_controller_.trace_observer_,
1219                             OnPhaseRecorded(ThreadController::kNested));
1220                 // ... and then the calling task (B) ends.
1221                 EXPECT_CALL(
1222                     *thread_controller_.trace_observer_,
1223                     OnPhaseRecorded(ThreadController::kApplicationTask));
1224               }));
1225           RunLoop(RunLoop::Type::kNestableTasksAllowed).Run();
1226         }));
1227 
1228         // B:
1229         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1230         testing::Mock::VerifyAndClearExpectations(
1231             &*thread_controller_.trace_observer_);
1232 
1233         // I:
1234         EXPECT_CALL(*thread_controller_.trace_observer_,
1235                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1236         EXPECT_CALL(
1237             *thread_controller_.trace_observer_,
1238             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1239         EXPECT_CALL(tasks[3], Run());
1240         EXPECT_CALL(*thread_controller_.trace_observer_,
1241                     OnPhaseRecorded(ThreadController::kApplicationTask));
1242         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1243                   TimeTicks::Max());
1244         testing::Mock::VerifyAndClearExpectations(
1245             &*thread_controller_.trace_observer_);
1246 
1247         EXPECT_CALL(*thread_controller_.trace_observer_,
1248                     OnPhaseRecorded(ThreadController::kIdleWork));
1249         EXPECT_CALL(*thread_controller_.trace_observer_,
1250                     OnThreadControllerActiveEnd);
1251         EXPECT_FALSE(thread_controller_.DoIdleWork());
1252         testing::Mock::VerifyAndClearExpectations(
1253             &*thread_controller_.trace_observer_);
1254 
1255         // J:
1256         task_source_.AddTask(FROM_HERE, tasks[4].Get());
1257         EXPECT_CALL(*thread_controller_.trace_observer_,
1258                     OnThreadControllerActiveBegin);
1259         EXPECT_CALL(
1260             *thread_controller_.trace_observer_,
1261             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1262         EXPECT_CALL(tasks[4], Run());
1263         EXPECT_CALL(*thread_controller_.trace_observer_,
1264                     OnPhaseRecorded(ThreadController::kApplicationTask));
1265         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1266                   TimeTicks::Max());
1267         testing::Mock::VerifyAndClearExpectations(
1268             &*thread_controller_.trace_observer_);
1269 
1270         EXPECT_CALL(*thread_controller_.trace_observer_,
1271                     OnPhaseRecorded(ThreadController::kIdleWork));
1272         EXPECT_CALL(*thread_controller_.trace_observer_,
1273                     OnThreadControllerActiveEnd);
1274         EXPECT_FALSE(thread_controller_.DoIdleWork());
1275         testing::Mock::VerifyAndClearExpectations(
1276             &*thread_controller_.trace_observer_);
1277       }));
1278 
1279   RunLoop().Run();
1280 }
1281 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedNativeLoop)1282 TEST_F(ThreadControllerWithMessagePumpTest,
1283        ThreadControllerActiveNestedNativeLoop) {
1284   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1285       MakeRefCounted<FakeTaskRunner>());
1286 
1287   thread_controller_.InstallTraceObserver();
1288 
1289   testing::InSequence sequence;
1290 
1291   RunLoop run_loop;
1292   EXPECT_CALL(*thread_controller_.trace_observer_,
1293               OnThreadControllerActiveBegin);
1294   EXPECT_CALL(*message_pump_, Run(_))
1295       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1296         MockCallback<OnceClosure> tasks[2];
1297         size_t run_level_depth = delegate->RunDepth();
1298 
1299         // A: Post 2 application tasks
1300         // B: Run one of them which allows nested application tasks (enter
1301         //    active)
1302         //   C: Enter a native nested loop
1303         //     D: Run a native task (enter nested active)
1304         //     E: Run an application task (remain nested active)
1305         //     F: Go idle (exit nested active)
1306         //     G: Run a native task (enter nested active)
1307         //     H: Exit native nested loop (end nested active)
1308         // I: Go idle (exit active)
1309 
1310         // A:
1311         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1312         task_source_.AddTask(FROM_HERE, tasks[1].Get());
1313 
1314         EXPECT_CALL(*thread_controller_.trace_observer_,
1315                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1316         EXPECT_CALL(
1317             *thread_controller_.trace_observer_,
1318             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1319         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1320           // C:
1321           EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1322           EXPECT_CALL(*message_pump_, ScheduleWork());
1323           thread_controller_.SetTaskExecutionAllowed(true);
1324           // i.e. simulate that something runs code within the scope of a
1325           // ScopedAllowApplicationTasksInNativeNestedLoop and ends up entering
1326           // a nested native loop which would invoke OnBeginWorkItem()
1327 
1328           // D:
1329 
1330           // kChromeTask phase is suspended when the nested native loop is
1331           // entered.
1332           EXPECT_CALL(*thread_controller_.trace_observer_,
1333                       OnPhaseRecorded(ThreadController::kApplicationTask));
1334           EXPECT_CALL(*thread_controller_.trace_observer_,
1335                       OnThreadControllerActiveBegin);
1336           thread_controller_.OnBeginWorkItem();
1337           testing::Mock::VerifyAndClearExpectations(
1338               &*thread_controller_.trace_observer_);
1339           thread_controller_.OnEndWorkItem(run_level_depth + 1);
1340 
1341           // E:
1342           EXPECT_CALL(tasks[1], Run());
1343           EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1344                     TimeTicks::Max());
1345           testing::Mock::VerifyAndClearExpectations(
1346               &*thread_controller_.trace_observer_);
1347 
1348           // F:
1349           EXPECT_CALL(*thread_controller_.trace_observer_,
1350                       OnThreadControllerActiveEnd);
1351           EXPECT_FALSE(thread_controller_.DoIdleWork());
1352           testing::Mock::VerifyAndClearExpectations(
1353               &*thread_controller_.trace_observer_);
1354 
1355           // G:
1356           EXPECT_CALL(*thread_controller_.trace_observer_,
1357                       OnThreadControllerActiveBegin);
1358           thread_controller_.OnBeginWorkItem();
1359           testing::Mock::VerifyAndClearExpectations(
1360               &*thread_controller_.trace_observer_);
1361           thread_controller_.OnEndWorkItem(run_level_depth + 1);
1362 
1363           // H:
1364           EXPECT_CALL(*thread_controller_.trace_observer_,
1365                       OnThreadControllerActiveEnd);
1366           // The kNested phase (C) ends when the RunLoop exits and kChromeTask
1367           // doesn't resume as task (B) is done.
1368           EXPECT_CALL(*thread_controller_.trace_observer_,
1369                       OnPhaseRecorded(ThreadController::kNested));
1370           thread_controller_.SetTaskExecutionAllowed(false);
1371         }));
1372 
1373         // B:
1374         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1375                   TimeTicks::Max());
1376         testing::Mock::VerifyAndClearExpectations(
1377             &*thread_controller_.trace_observer_);
1378 
1379         // I:
1380         EXPECT_CALL(*thread_controller_.trace_observer_,
1381                     OnPhaseRecorded(ThreadController::kIdleWork));
1382         EXPECT_CALL(*thread_controller_.trace_observer_,
1383                     OnThreadControllerActiveEnd);
1384         EXPECT_FALSE(thread_controller_.DoIdleWork());
1385         testing::Mock::VerifyAndClearExpectations(
1386             &*thread_controller_.trace_observer_);
1387       }));
1388 
1389   RunLoop().Run();
1390 }
1391 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveUnusedNativeLoop)1392 TEST_F(ThreadControllerWithMessagePumpTest,
1393        ThreadControllerActiveUnusedNativeLoop) {
1394   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1395       MakeRefCounted<FakeTaskRunner>());
1396 
1397   thread_controller_.InstallTraceObserver();
1398 
1399   testing::InSequence sequence;
1400 
1401   RunLoop run_loop;
1402   EXPECT_CALL(*thread_controller_.trace_observer_,
1403               OnThreadControllerActiveBegin);
1404   EXPECT_CALL(*message_pump_, Run(_))
1405       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1406         MockCallback<OnceClosure> tasks[2];
1407 
1408         // A: Post 2 application tasks
1409         // B: Run one of them (enter active)
1410         //   C: Allow entering a native loop but don't enter one (no-op)
1411         //   D: Complete the task without having entered a native loop (no-op)
1412         // E: Run an application task (remain nested active)
1413         // F: Go idle (exit active)
1414 
1415         // A:
1416         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1417         task_source_.AddTask(FROM_HERE, tasks[1].Get());
1418 
1419         EXPECT_CALL(*thread_controller_.trace_observer_,
1420                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1421         EXPECT_CALL(
1422             *thread_controller_.trace_observer_,
1423             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1424         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1425           // C:
1426           EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1427           EXPECT_CALL(*message_pump_, ScheduleWork());
1428           thread_controller_.SetTaskExecutionAllowed(true);
1429 
1430           // D:
1431           thread_controller_.SetTaskExecutionAllowed(false);
1432           EXPECT_CALL(*thread_controller_.trace_observer_,
1433                       OnPhaseRecorded(ThreadController::kApplicationTask));
1434         }));
1435 
1436         // B:
1437         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1438         testing::Mock::VerifyAndClearExpectations(
1439             &*thread_controller_.trace_observer_);
1440 
1441         // E:
1442         EXPECT_CALL(*thread_controller_.trace_observer_,
1443                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1444         EXPECT_CALL(
1445             *thread_controller_.trace_observer_,
1446             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1447         EXPECT_CALL(tasks[1], Run());
1448         EXPECT_CALL(*thread_controller_.trace_observer_,
1449                     OnPhaseRecorded(ThreadController::kApplicationTask));
1450         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1451                   TimeTicks::Max());
1452         testing::Mock::VerifyAndClearExpectations(
1453             &*thread_controller_.trace_observer_);
1454 
1455         // F:
1456         EXPECT_CALL(*thread_controller_.trace_observer_,
1457                     OnPhaseRecorded(ThreadController::kIdleWork));
1458         EXPECT_CALL(*thread_controller_.trace_observer_,
1459                     OnThreadControllerActiveEnd);
1460         EXPECT_FALSE(thread_controller_.DoIdleWork());
1461         testing::Mock::VerifyAndClearExpectations(
1462             &*thread_controller_.trace_observer_);
1463       }));
1464 
1465   RunLoop().Run();
1466 }
1467 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedNativeLoopWithoutAllowance)1468 TEST_F(ThreadControllerWithMessagePumpTest,
1469        ThreadControllerActiveNestedNativeLoopWithoutAllowance) {
1470   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1471       MakeRefCounted<FakeTaskRunner>());
1472 
1473   thread_controller_.InstallTraceObserver();
1474 
1475   testing::InSequence sequence;
1476 
1477   RunLoop run_loop;
1478   EXPECT_CALL(*thread_controller_.trace_observer_,
1479               OnThreadControllerActiveBegin);
1480   EXPECT_CALL(*message_pump_, Run(_))
1481       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1482         MockCallback<OnceClosure> tasks[2];
1483         size_t run_level_depth = delegate->RunDepth();
1484 
1485         // A: Post 2 application tasks
1486         // B: Run one of them (enter active)
1487         //   C: Enter a native nested loop (without having allowed nested
1488         //      application tasks in B.)
1489         //     D: Run a native task (enter nested active)
1490         // E: End task C. (which implicitly means the native loop is over).
1491         // F: Run an application task (remain active)
1492         // G: Go idle (exit active)
1493 
1494         // A:
1495         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1496         task_source_.AddTask(FROM_HERE, tasks[1].Get());
1497 
1498         EXPECT_CALL(*thread_controller_.trace_observer_,
1499                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1500         EXPECT_CALL(
1501             *thread_controller_.trace_observer_,
1502             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1503         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1504           // C:
1505           // D:
1506           // kChromeTask phase is suspended when the nested loop is entered.
1507           EXPECT_CALL(*thread_controller_.trace_observer_,
1508                       OnPhaseRecorded(ThreadController::kApplicationTask));
1509           EXPECT_CALL(*thread_controller_.trace_observer_,
1510                       OnThreadControllerActiveBegin);
1511           thread_controller_.OnBeginWorkItem();
1512           testing::Mock::VerifyAndClearExpectations(
1513               &*thread_controller_.trace_observer_);
1514           thread_controller_.OnEndWorkItem(run_level_depth + 1);
1515 
1516           // E:
1517           EXPECT_CALL(*thread_controller_.trace_observer_,
1518                       OnThreadControllerActiveEnd);
1519           EXPECT_CALL(*thread_controller_.trace_observer_,
1520                       OnPhaseRecorded(ThreadController::kNested));
1521         }));
1522 
1523         // B:
1524         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
1525         testing::Mock::VerifyAndClearExpectations(
1526             &*thread_controller_.trace_observer_);
1527 
1528         // F:
1529         EXPECT_CALL(*thread_controller_.trace_observer_,
1530                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1531         EXPECT_CALL(
1532             *thread_controller_.trace_observer_,
1533             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1534         EXPECT_CALL(tasks[1], Run());
1535         EXPECT_CALL(*thread_controller_.trace_observer_,
1536                     OnPhaseRecorded(ThreadController::kApplicationTask));
1537         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1538                   TimeTicks::Max());
1539 
1540         // G:
1541         EXPECT_CALL(*thread_controller_.trace_observer_,
1542                     OnPhaseRecorded(ThreadController::kIdleWork));
1543         EXPECT_CALL(*thread_controller_.trace_observer_,
1544                     OnThreadControllerActiveEnd);
1545         EXPECT_FALSE(thread_controller_.DoIdleWork());
1546         testing::Mock::VerifyAndClearExpectations(
1547             &*thread_controller_.trace_observer_);
1548       }));
1549 
1550   RunLoop().Run();
1551 }
1552 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveMultipleNativeLoopsUnderOneApplicationTask)1553 TEST_F(ThreadControllerWithMessagePumpTest,
1554        ThreadControllerActiveMultipleNativeLoopsUnderOneApplicationTask) {
1555   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1556       MakeRefCounted<FakeTaskRunner>());
1557 
1558   thread_controller_.InstallTraceObserver();
1559 
1560   testing::InSequence sequence;
1561 
1562   RunLoop run_loop;
1563   EXPECT_CALL(*thread_controller_.trace_observer_,
1564               OnThreadControllerActiveBegin);
1565   EXPECT_CALL(*message_pump_, Run(_))
1566       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1567         MockCallback<OnceClosure> tasks[2];
1568         size_t run_level_depth = delegate->RunDepth();
1569 
1570         // A: Post 1 application task
1571         // B: Run it
1572         //   C: Enter a native nested loop (application tasks allowed)
1573         //     D: Run a native task (enter nested active)
1574         //     E: Exit nested loop (missed by RunLevelTracker -- no-op)
1575         //   F: Enter another native nested loop (application tasks allowed)
1576         //     G: Run a native task (no-op)
1577         //     H: Exit nested loop (no-op)
1578         //   I: End task (exit nested active)
1579         // J: Go idle (exit active)
1580 
1581         // A:
1582         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1583 
1584         EXPECT_CALL(*thread_controller_.trace_observer_,
1585                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1586         EXPECT_CALL(
1587             *thread_controller_.trace_observer_,
1588             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1589         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1590           for (int i = 0; i < 2; ++i) {
1591             // C & F:
1592             EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1593             EXPECT_CALL(*message_pump_, ScheduleWork());
1594             thread_controller_.SetTaskExecutionAllowed(true);
1595 
1596             // D & G:
1597             if (i == 0) {
1598               // kChromeTask phase is suspended when the nested loop is entered.
1599               EXPECT_CALL(*thread_controller_.trace_observer_,
1600                           OnPhaseRecorded(ThreadController::kApplicationTask));
1601               EXPECT_CALL(*thread_controller_.trace_observer_,
1602                           OnThreadControllerActiveBegin);
1603             }
1604             thread_controller_.OnBeginWorkItem();
1605             testing::Mock::VerifyAndClearExpectations(
1606                 &*thread_controller_.trace_observer_);
1607             thread_controller_.OnEndWorkItem(run_level_depth + 1);
1608 
1609             // E & H:
1610             thread_controller_.SetTaskExecutionAllowed(false);
1611             testing::Mock::VerifyAndClearExpectations(
1612                 &*thread_controller_.trace_observer_);
1613           }
1614 
1615           // I:
1616           EXPECT_CALL(*thread_controller_.trace_observer_,
1617                       OnThreadControllerActiveEnd);
1618           EXPECT_CALL(*thread_controller_.trace_observer_,
1619                       OnPhaseRecorded(ThreadController::kNested));
1620         }));
1621 
1622         // B:
1623         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1624                   TimeTicks::Max());
1625         testing::Mock::VerifyAndClearExpectations(
1626             &*thread_controller_.trace_observer_);
1627 
1628         // J:
1629         EXPECT_CALL(*thread_controller_.trace_observer_,
1630                     OnPhaseRecorded(ThreadController::kIdleWork));
1631         EXPECT_CALL(*thread_controller_.trace_observer_,
1632                     OnThreadControllerActiveEnd);
1633         EXPECT_FALSE(thread_controller_.DoIdleWork());
1634         testing::Mock::VerifyAndClearExpectations(
1635             &*thread_controller_.trace_observer_);
1636       }));
1637 
1638   RunLoop().Run();
1639 }
1640 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNativeLoopsReachingIdle)1641 TEST_F(ThreadControllerWithMessagePumpTest,
1642        ThreadControllerActiveNativeLoopsReachingIdle) {
1643   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1644       MakeRefCounted<FakeTaskRunner>());
1645 
1646   thread_controller_.InstallTraceObserver();
1647 
1648   testing::InSequence sequence;
1649 
1650   RunLoop run_loop;
1651   EXPECT_CALL(*thread_controller_.trace_observer_,
1652               OnThreadControllerActiveBegin);
1653   EXPECT_CALL(*message_pump_, Run(_))
1654       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1655         MockCallback<OnceClosure> task;
1656         size_t run_level_depth = delegate->RunDepth();
1657 
1658         // A: Post 1 application task
1659         // B: Run it
1660         //   C: Enter a native nested loop (application tasks allowed)
1661         //     D: Run a native task (enter nested active)
1662         //     E: Reach idle (nested inactive)
1663         //     F: Run another task (nested active)
1664         //     G: Exit nested loop (missed by RunLevelTracker -- no-op)
1665         //   H: End task B (exit nested active)
1666         // I: Go idle (exit active)
1667         //
1668         // This exercises the heuristic in
1669         // ThreadControllerWithMessagePumpImpl::SetTaskExecutionAllowed() to
1670         // detect the end of a nested native loop before the end of the task
1671         // that triggered it. When application tasks are not allowed however,
1672         // there's nothing we can do detect and two native nested loops in a
1673         // row. They may look like a single one if the first one is quit before
1674         // it reaches idle.
1675 
1676         // A:
1677         task_source_.AddTask(FROM_HERE, task.Get());
1678 
1679         EXPECT_CALL(*thread_controller_.trace_observer_,
1680                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1681         EXPECT_CALL(
1682             *thread_controller_.trace_observer_,
1683             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1684         EXPECT_CALL(task, Run()).WillOnce(Invoke([&]() {
1685           // C:
1686           EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1687           EXPECT_CALL(*message_pump_, ScheduleWork());
1688           thread_controller_.SetTaskExecutionAllowed(true);
1689 
1690           // D:
1691           // kChromeTask phase is suspended when the nested loop is entered.
1692           EXPECT_CALL(*thread_controller_.trace_observer_,
1693                       OnPhaseRecorded(ThreadController::kApplicationTask));
1694           EXPECT_CALL(*thread_controller_.trace_observer_,
1695                       OnThreadControllerActiveBegin);
1696           thread_controller_.OnBeginWorkItem();
1697           testing::Mock::VerifyAndClearExpectations(
1698               &*thread_controller_.trace_observer_);
1699           thread_controller_.OnEndWorkItem(run_level_depth + 1);
1700 
1701           // E:
1702           EXPECT_CALL(*thread_controller_.trace_observer_,
1703                       OnThreadControllerActiveEnd);
1704           thread_controller_.BeforeWait();
1705           testing::Mock::VerifyAndClearExpectations(
1706               &*thread_controller_.trace_observer_);
1707 
1708           // F:
1709           EXPECT_CALL(*thread_controller_.trace_observer_,
1710                       OnThreadControllerActiveBegin);
1711           thread_controller_.OnBeginWorkItem();
1712           testing::Mock::VerifyAndClearExpectations(
1713               &*thread_controller_.trace_observer_);
1714           thread_controller_.OnEndWorkItem(run_level_depth + 1);
1715 
1716           // G:
1717           thread_controller_.SetTaskExecutionAllowed(false);
1718 
1719           // H:
1720           EXPECT_CALL(*thread_controller_.trace_observer_,
1721                       OnThreadControllerActiveEnd);
1722           EXPECT_CALL(*thread_controller_.trace_observer_,
1723                       OnPhaseRecorded(ThreadController::kNested));
1724         }));
1725 
1726         // B:
1727         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1728                   TimeTicks::Max());
1729         testing::Mock::VerifyAndClearExpectations(
1730             &*thread_controller_.trace_observer_);
1731 
1732         // I:
1733         EXPECT_CALL(*thread_controller_.trace_observer_,
1734                     OnPhaseRecorded(ThreadController::kIdleWork));
1735         EXPECT_CALL(*thread_controller_.trace_observer_,
1736                     OnThreadControllerActiveEnd);
1737         EXPECT_FALSE(thread_controller_.DoIdleWork());
1738         testing::Mock::VerifyAndClearExpectations(
1739             &*thread_controller_.trace_observer_);
1740       }));
1741 
1742   RunLoop().Run();
1743 }
1744 
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveQuitNestedWhileApplicationIdle)1745 TEST_F(ThreadControllerWithMessagePumpTest,
1746        ThreadControllerActiveQuitNestedWhileApplicationIdle) {
1747   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1748       MakeRefCounted<FakeTaskRunner>());
1749 
1750   thread_controller_.InstallTraceObserver();
1751 
1752   testing::InSequence sequence;
1753 
1754   RunLoop run_loop;
1755   EXPECT_CALL(*thread_controller_.trace_observer_,
1756               OnThreadControllerActiveBegin);
1757   EXPECT_CALL(*message_pump_, Run(_))
1758       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1759         MockCallback<OnceClosure> tasks[2];
1760 
1761         // A: Post 2 application tasks
1762         // B: Run the first task
1763         //   C: Enter a native nested loop (application tasks allowed)
1764         //     D: Run the second task (enter nested active)
1765         //     E: Reach idle
1766         //     F: Run a native task (not visible to RunLevelTracker)
1767         //     G: F quits the native nested loop (no-op)
1768         //   H: End task B (exit nested active)
1769         // I: Go idle (exit active)
1770 
1771         // A:
1772         task_source_.AddTask(FROM_HERE, tasks[0].Get());
1773         task_source_.AddTask(FROM_HERE, tasks[1].Get());
1774 
1775         EXPECT_CALL(*thread_controller_.trace_observer_,
1776                     OnPhaseRecorded(ThreadController::kPumpOverhead));
1777         EXPECT_CALL(
1778             *thread_controller_.trace_observer_,
1779             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
1780         EXPECT_CALL(tasks[0], Run()).WillOnce(Invoke([&]() {
1781           // C:
1782           EXPECT_FALSE(thread_controller_.IsTaskExecutionAllowed());
1783           EXPECT_CALL(*message_pump_, ScheduleWork());
1784           thread_controller_.SetTaskExecutionAllowed(true);
1785 
1786           // D:
1787           // kChromeTask phase is suspended when the nested loop is entered.
1788           EXPECT_CALL(*thread_controller_.trace_observer_,
1789                       OnPhaseRecorded(ThreadController::kApplicationTask));
1790           EXPECT_CALL(*thread_controller_.trace_observer_,
1791                       OnThreadControllerActiveBegin);
1792           EXPECT_CALL(tasks[1], Run());
1793           EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1794                     TimeTicks::Max());
1795           testing::Mock::VerifyAndClearExpectations(
1796               &*thread_controller_.trace_observer_);
1797 
1798           // E:
1799           EXPECT_CALL(*thread_controller_.trace_observer_,
1800                       OnThreadControllerActiveEnd);
1801           thread_controller_.BeforeWait();
1802           testing::Mock::VerifyAndClearExpectations(
1803               &*thread_controller_.trace_observer_);
1804 
1805           // F + G:
1806           thread_controller_.SetTaskExecutionAllowed(false);
1807 
1808           // H:
1809           EXPECT_CALL(*thread_controller_.trace_observer_,
1810                       OnPhaseRecorded(ThreadController::kNested));
1811         }));
1812 
1813         // B:
1814         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1815                   TimeTicks::Max());
1816         testing::Mock::VerifyAndClearExpectations(
1817             &*thread_controller_.trace_observer_);
1818 
1819         // I:
1820         EXPECT_CALL(*thread_controller_.trace_observer_,
1821                     OnPhaseRecorded(ThreadController::kIdleWork));
1822         EXPECT_CALL(*thread_controller_.trace_observer_,
1823                     OnThreadControllerActiveEnd);
1824         EXPECT_FALSE(thread_controller_.DoIdleWork());
1825         testing::Mock::VerifyAndClearExpectations(
1826             &*thread_controller_.trace_observer_);
1827       }));
1828 
1829   RunLoop().Run();
1830 }
1831 
1832 // This test verifies the edge case where the first task on the stack is native
1833 // task which spins a native nested loop. That inner-loop should be allowed to
1834 // execute application tasks as the outer-loop didn't consume
1835 // |task_execution_allowed == true|. RunLevelTracker should support this use
1836 // case as well.
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks)1837 TEST_F(ThreadControllerWithMessagePumpTest,
1838        ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks) {
1839   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1840       MakeRefCounted<FakeTaskRunner>());
1841 
1842   thread_controller_.InstallTraceObserver();
1843 
1844   testing::InSequence sequence;
1845 
1846   RunLoop run_loop;
1847   EXPECT_CALL(*thread_controller_.trace_observer_,
1848               OnThreadControllerActiveBegin);
1849   EXPECT_CALL(*message_pump_, Run(_))
1850       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1851         // Start this test idle for a change.
1852         EXPECT_CALL(*thread_controller_.trace_observer_,
1853                     OnPhaseRecorded(ThreadController::kIdleWork));
1854         EXPECT_CALL(*thread_controller_.trace_observer_,
1855                     OnThreadControllerActiveEnd);
1856         EXPECT_FALSE(thread_controller_.DoIdleWork());
1857         testing::Mock::VerifyAndClearExpectations(
1858             &*thread_controller_.trace_observer_);
1859 
1860         MockCallback<OnceClosure> task;
1861         size_t run_level_depth = delegate->RunDepth();
1862 
1863         // A: Post 1 application task
1864         // B: Run a native task
1865         //   C: Enter a native nested loop (application tasks still allowed)
1866         //     D: Run the application task (enter nested active)
1867         // E: End the native task (exit nested active)
1868         // F: Go idle (exit active)
1869 
1870         // A:
1871         task_source_.AddTask(FROM_HERE, task.Get());
1872 
1873         EXPECT_CALL(*thread_controller_.trace_observer_,
1874                     OnThreadControllerActiveBegin)
1875             .WillOnce(Invoke([&]() {
1876               // C:
1877               EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
1878 
1879               // D:
1880               // kNativeWork phase is suspended when the nested loop is entered.
1881               EXPECT_CALL(*thread_controller_.trace_observer_,
1882                           OnPhaseRecorded(ThreadController::kNativeWork));
1883               EXPECT_CALL(*thread_controller_.trace_observer_,
1884                           OnThreadControllerActiveBegin);
1885               EXPECT_CALL(task, Run());
1886               EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1887                         TimeTicks::Max());
1888               testing::Mock::VerifyAndClearExpectations(
1889                   &*thread_controller_.trace_observer_);
1890             }));
1891 
1892         // B:
1893         thread_controller_.OnBeginWorkItem();
1894         testing::Mock::VerifyAndClearExpectations(
1895             &*thread_controller_.trace_observer_);
1896 
1897         // E:
1898         EXPECT_CALL(*thread_controller_.trace_observer_,
1899                     OnThreadControllerActiveEnd);
1900         EXPECT_CALL(*thread_controller_.trace_observer_,
1901                     OnPhaseRecorded(ThreadController::kNested));
1902         thread_controller_.OnEndWorkItem(run_level_depth);
1903 
1904         // F:
1905         EXPECT_CALL(*thread_controller_.trace_observer_,
1906                     OnPhaseRecorded(ThreadController::kIdleWork));
1907         EXPECT_CALL(*thread_controller_.trace_observer_,
1908                     OnThreadControllerActiveEnd);
1909         EXPECT_FALSE(thread_controller_.DoIdleWork());
1910         testing::Mock::VerifyAndClearExpectations(
1911             &*thread_controller_.trace_observer_);
1912       }));
1913 
1914   RunLoop().Run();
1915 }
1916 
1917 // Same as ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks but
1918 // with a dummy ScopedAllowApplicationTasksInNativeNestedLoop that is a
1919 // true=>true no-op for SetTaskExecutionAllowed(). This is a regression test
1920 // against another discussed implementation for RunLevelTracker which
1921 // would have used ScopedAllowApplicationTasksInNativeNestedLoop as a hint of
1922 // nested native loops. Doing so would have been incorrect because it assumes
1923 // that ScopedAllowApplicationTasksInNativeNestedLoop always toggles the
1924 // allowance away-from and back-to |false|.
TEST_F(ThreadControllerWithMessagePumpTest,ThreadControllerActiveDummyScopedAllowApplicationTasks)1925 TEST_F(ThreadControllerWithMessagePumpTest,
1926        ThreadControllerActiveDummyScopedAllowApplicationTasks) {
1927   SingleThreadTaskRunner::CurrentDefaultHandle handle(
1928       MakeRefCounted<FakeTaskRunner>());
1929 
1930   thread_controller_.InstallTraceObserver();
1931 
1932   testing::InSequence sequence;
1933 
1934   RunLoop run_loop;
1935   EXPECT_CALL(*thread_controller_.trace_observer_,
1936               OnThreadControllerActiveBegin);
1937   EXPECT_CALL(*message_pump_, Run(_))
1938       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
1939         // Start this test idle for a change.
1940         EXPECT_CALL(*thread_controller_.trace_observer_,
1941                     OnPhaseRecorded(ThreadController::kIdleWork));
1942         EXPECT_CALL(*thread_controller_.trace_observer_,
1943                     OnThreadControllerActiveEnd);
1944         EXPECT_FALSE(thread_controller_.DoIdleWork());
1945         testing::Mock::VerifyAndClearExpectations(
1946             &*thread_controller_.trace_observer_);
1947 
1948         MockCallback<OnceClosure> task;
1949         size_t run_level_depth = delegate->RunDepth();
1950 
1951         // A: Post 1 application task
1952         // B: Run a native task
1953         //   C: Enter dummy ScopedAllowApplicationTasksInNativeNestedLoop
1954         //   D: Enter a native nested loop (application tasks still allowed)
1955         //     E: Run the application task (enter nested active)
1956         //   F: Exit dummy scope (SetTaskExecutionAllowed(true)).
1957         // G: End the native task (exit nested active)
1958         // H: Go idle (exit active)
1959 
1960         // A:
1961         task_source_.AddTask(FROM_HERE, task.Get());
1962 
1963         EXPECT_CALL(*thread_controller_.trace_observer_,
1964                     OnThreadControllerActiveBegin)
1965             .WillOnce(Invoke([&]() {
1966               // C + D:
1967               EXPECT_TRUE(thread_controller_.IsTaskExecutionAllowed());
1968               EXPECT_CALL(*message_pump_, ScheduleWork());
1969               thread_controller_.SetTaskExecutionAllowed(true);
1970               testing::Mock::VerifyAndClearExpectations(
1971                   &*thread_controller_.trace_observer_);
1972 
1973               // E:
1974               // kNativeWork phase is suspended when the nested loop is entered.
1975               EXPECT_CALL(*thread_controller_.trace_observer_,
1976                           OnPhaseRecorded(ThreadController::kNativeWork));
1977               EXPECT_CALL(*thread_controller_.trace_observer_,
1978                           OnThreadControllerActiveBegin);
1979               EXPECT_CALL(task, Run());
1980               EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
1981                         TimeTicks::Max());
1982               testing::Mock::VerifyAndClearExpectations(
1983                   &*thread_controller_.trace_observer_);
1984 
1985               // F:
1986               EXPECT_CALL(*message_pump_, ScheduleWork());
1987               thread_controller_.SetTaskExecutionAllowed(true);
1988             }));
1989 
1990         // B:
1991         thread_controller_.OnBeginWorkItem();
1992         testing::Mock::VerifyAndClearExpectations(
1993             &*thread_controller_.trace_observer_);
1994 
1995         // G:
1996         EXPECT_CALL(*thread_controller_.trace_observer_,
1997                     OnThreadControllerActiveEnd);
1998         EXPECT_CALL(*thread_controller_.trace_observer_,
1999                     OnPhaseRecorded(ThreadController::kNested));
2000         thread_controller_.OnEndWorkItem(run_level_depth);
2001 
2002         // H:
2003         EXPECT_CALL(*thread_controller_.trace_observer_,
2004                     OnPhaseRecorded(ThreadController::kIdleWork));
2005         EXPECT_CALL(*thread_controller_.trace_observer_,
2006                     OnThreadControllerActiveEnd);
2007         EXPECT_FALSE(thread_controller_.DoIdleWork());
2008         testing::Mock::VerifyAndClearExpectations(
2009             &*thread_controller_.trace_observer_);
2010       }));
2011 
2012   RunLoop().Run();
2013 }
2014 
2015 // Verify that the kScheduled phase is emitted when coming out of idle and
2016 // `queue_time` is set on PendingTasks.
TEST_F(ThreadControllerWithMessagePumpTest,MessagePumpPhasesWithQueuingTime)2017 TEST_F(ThreadControllerWithMessagePumpTest, MessagePumpPhasesWithQueuingTime) {
2018   SingleThreadTaskRunner::CurrentDefaultHandle handle(
2019       MakeRefCounted<FakeTaskRunner>());
2020 
2021   thread_controller_.InstallTraceObserver();
2022 
2023   testing::InSequence sequence;
2024 
2025   RunLoop run_loop;
2026   EXPECT_CALL(*thread_controller_.trace_observer_,
2027               OnThreadControllerActiveBegin);
2028   EXPECT_CALL(*message_pump_, Run(_))
2029       .WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
2030         // Start this test idle.
2031         EXPECT_CALL(*thread_controller_.trace_observer_,
2032                     OnPhaseRecorded(ThreadController::kIdleWork));
2033         EXPECT_CALL(*thread_controller_.trace_observer_,
2034                     OnThreadControllerActiveEnd);
2035         EXPECT_FALSE(thread_controller_.DoIdleWork());
2036         testing::Mock::VerifyAndClearExpectations(
2037             &*thread_controller_.trace_observer_);
2038 
2039         MockCallback<OnceClosure> task1;
2040         task_source_.AddTask(FROM_HERE, task1.Get(),
2041                              /*delayed_run_time=*/TimeTicks(),
2042                              /*queue_time=*/clock_.NowTicks());
2043         MockCallback<OnceClosure> task2;
2044         task_source_.AddTask(FROM_HERE, task2.Get(),
2045                              /*delayed_run_time=*/TimeTicks(),
2046                              /*queue_time=*/clock_.NowTicks());
2047         // kScheduled is only emitted if in past.
2048         clock_.Advance(Milliseconds(1));
2049 
2050         EXPECT_CALL(*thread_controller_.trace_observer_,
2051                     OnThreadControllerActiveBegin);
2052         EXPECT_CALL(*thread_controller_.trace_observer_,
2053                     OnPhaseRecorded(ThreadController::kScheduled));
2054         EXPECT_CALL(
2055             *thread_controller_.trace_observer_,
2056             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
2057         EXPECT_CALL(task1, Run());
2058         EXPECT_CALL(*thread_controller_.trace_observer_,
2059                     OnPhaseRecorded(ThreadController::kApplicationTask));
2060         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time, TimeTicks());
2061 
2062         EXPECT_CALL(*thread_controller_.trace_observer_,
2063                     OnPhaseRecorded(ThreadController::kPumpOverhead));
2064         EXPECT_CALL(
2065             *thread_controller_.trace_observer_,
2066             OnPhaseRecorded(ThreadController::kSelectingApplicationTask));
2067         EXPECT_CALL(task2, Run());
2068         EXPECT_CALL(*thread_controller_.trace_observer_,
2069                     OnPhaseRecorded(ThreadController::kApplicationTask));
2070         EXPECT_EQ(thread_controller_.DoWork().delayed_run_time,
2071                   TimeTicks::Max());
2072 
2073         testing::Mock::VerifyAndClearExpectations(
2074             &*thread_controller_.trace_observer_);
2075 
2076         EXPECT_CALL(*thread_controller_.trace_observer_,
2077                     OnPhaseRecorded(ThreadController::kIdleWork));
2078         EXPECT_CALL(*thread_controller_.trace_observer_,
2079                     OnThreadControllerActiveEnd);
2080         EXPECT_FALSE(thread_controller_.DoIdleWork());
2081 
2082         testing::Mock::VerifyAndClearExpectations(
2083             &*thread_controller_.trace_observer_);
2084       }));
2085 
2086   RunLoop().Run();
2087 }
2088 
2089 }  // namespace base::sequence_manager::internal
2090