Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
14namespace flutter {
15namespace testing {
16
17namespace {
18class 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
44uint64_t MockGetCurrentTime() {
45 return 10000;
46}
47} // namespace
48
49TEST(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
72TEST(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
95TEST(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
123
124TEST(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;
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)
GLFWwindow * window
Definition main.cc:60
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
TEST(NativeAssetsManagerTest, NoAvailableAssets)
uint64_t(* CurrentTimeProc)()
Definition task_runner.h:21
uint64_t task
Definition embedder.h:1850
struct tagMSG MSG
#define DispatchMessage