Flutter Windows Embedder
task_runner_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <atomic>
8 #include <chrono>
9 
10 #include "flutter/fml/macros.h"
12 #include "gtest/gtest.h"
13 
14 namespace flutter {
15 namespace testing {
16 
17 namespace {
18 class MockTaskRunner : public TaskRunner {
19  public:
20  MockTaskRunner(CurrentTimeProc get_current_time,
21  const TaskExpiredCallback& on_task_expired)
22  : TaskRunner(get_current_time, on_task_expired) {}
23 
24  virtual bool RunsTasksOnCurrentThread() const override { return true; }
25 
26  void SimulateTimerAwake() { ProcessTasks(); }
27 
28  protected:
29  virtual void WakeUp() override {
30  // Do nothing to avoid processing tasks immediately after the tasks is
31  // posted.
32  }
33 
34  virtual TaskTimePoint GetCurrentTimeForTask() const override {
35  return TaskTimePoint(
36  std::chrono::duration_cast<std::chrono::steady_clock::duration>(
37  std::chrono::nanoseconds(10000)));
38  }
39 
40  private:
41  FML_DISALLOW_COPY_AND_ASSIGN(MockTaskRunner);
42 };
43 
44 uint64_t MockGetCurrentTime() {
45  return 10000;
46 }
47 } // namespace
48 
49 TEST(TaskRunnerTest, MaybeExecuteTaskWithExactOrder) {
50  std::vector<uint64_t> executed_task_order;
51  auto runner =
52  MockTaskRunner(MockGetCurrentTime,
53  [&executed_task_order](const FlutterTask* expired_task) {
54  executed_task_order.push_back(expired_task->task);
55  });
56 
57  uint64_t time_now = MockGetCurrentTime();
58 
59  runner.PostFlutterTask(FlutterTask{nullptr, 1}, time_now);
60  runner.PostFlutterTask(FlutterTask{nullptr, 2}, time_now);
61  runner.PostTask(
62  [&executed_task_order]() { executed_task_order.push_back(3); });
63  runner.PostTask(
64  [&executed_task_order]() { executed_task_order.push_back(4); });
65 
66  runner.SimulateTimerAwake();
67 
68  std::vector<uint64_t> posted_task_order{1, 2, 3, 4};
69  EXPECT_EQ(executed_task_order, posted_task_order);
70 }
71 
72 TEST(TaskRunnerTest, MaybeExecuteTaskOnlyExpired) {
73  std::set<uint64_t> executed_task;
74  auto runner = MockTaskRunner(
75  MockGetCurrentTime, [&executed_task](const FlutterTask* expired_task) {
76  executed_task.insert(expired_task->task);
77  });
78 
79  uint64_t task_expired_before_now = 1;
80  uint64_t time_before_now = 0;
81  runner.PostFlutterTask(FlutterTask{nullptr, task_expired_before_now},
82  time_before_now);
83 
84  uint64_t task_expired_after_now = 2;
85  uint64_t time_after_now = MockGetCurrentTime() * 2;
86  runner.PostFlutterTask(FlutterTask{nullptr, task_expired_after_now},
87  time_after_now);
88 
89  runner.SimulateTimerAwake();
90 
91  std::set<uint64_t> only_task_expired_before_now{task_expired_before_now};
92  EXPECT_EQ(executed_task, only_task_expired_before_now);
93 }
94 
95 TEST(TaskRunnerTest, TimerThreadDoesNotCancelEarlierScheduledTasks) {
96  std::atomic_bool signaled = false;
97  std::optional<std::chrono::high_resolution_clock::time_point> callback_time;
98  TimerThread timer_thread([&]() {
99  callback_time = std::chrono::high_resolution_clock::now();
100  signaled = true;
101  });
102  timer_thread.Start();
103  auto now = std::chrono::high_resolution_clock::now();
104  // Make sure that subsequent call to schedule does not cancel earlier task
105  // as documented in TimerThread::ScheduleAt.
106  timer_thread.ScheduleAt(now + std::chrono::milliseconds(20));
107  timer_thread.ScheduleAt(now + std::chrono::seconds(10));
108 
109  while (!signaled.load()) {
110  std::this_thread::sleep_for(std::chrono::milliseconds(5));
111  }
112 
113  EXPECT_TRUE(callback_time.has_value());
114  EXPECT_GE(*callback_time, now + std::chrono::milliseconds(20));
115 
116  timer_thread.Stop();
117 }
118 
120  public:
122 };
123 
124 TEST(TaskRunnerTest, TaskRunnerWindowCoalescesWakeUpMessages) {
125  class Delegate : public TaskRunnerWindow::Delegate {
126  public:
127  Delegate() {}
128 
129  std::chrono::nanoseconds ProcessTasks() override {
130  process_tasks_call_count_++;
131  return std::chrono::nanoseconds::max();
132  }
133 
134  int process_tasks_call_count_ = 0;
135  };
136 
137  Delegate delegate;
138  TestTaskRunnerWindow window;
139 
140  window.AddDelegate(&delegate);
141 
142  window.WakeUp();
143  window.WakeUp();
144 
145  ::MSG msg;
146  while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
147  TranslateMessage(&msg);
148  DispatchMessage(&msg);
149  }
150 
151  EXPECT_EQ(delegate.process_tasks_call_count_, 1);
152 }
153 
154 } // namespace testing
155 } // namespace flutter
void AddDelegate(Delegate *delegate)
TEST(AccessibilityBridgeWindows, GetParent)
uint64_t(* CurrentTimeProc)()
Definition: task_runner.h:21