Flutter Engine
The Flutter Engine
platform_configuration_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
5#define FML_USED_ON_EMBEDDER
6
7#include "flutter/lib/ui/window/platform_configuration.h"
8
9#include <memory>
10
11#include "flutter/common/task_runners.h"
12#include "flutter/fml/synchronization/waitable_event.h"
13#include "flutter/lib/ui/painting/vertices.h"
14#include "flutter/runtime/dart_vm.h"
15#include "flutter/shell/common/shell_test.h"
16#include "flutter/shell/common/thread_host.h"
17#include "flutter/testing/testing.h"
18
19namespace flutter {
20namespace testing {
21
23
25 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
26
27 auto nativeValidateConfiguration =
28 [message_latch](Dart_NativeArguments args) {
29 PlatformConfiguration* configuration =
31 ASSERT_NE(configuration->GetMetrics(0), nullptr);
32 ASSERT_EQ(configuration->GetMetrics(0)->device_pixel_ratio, 1.0);
33 ASSERT_EQ(configuration->GetMetrics(0)->physical_width, 0.0);
34 ASSERT_EQ(configuration->GetMetrics(0)->physical_height, 0.0);
35
36 message_latch->Signal();
37 };
38
39 Settings settings = CreateSettingsForFixture();
40 TaskRunners task_runners("test", // label
41 GetCurrentTaskRunner(), // platform
42 CreateNewThread(), // raster
43 CreateNewThread(), // ui
44 CreateNewThread() // io
45 );
46
47 AddNativeCallback("ValidateConfiguration",
48 CREATE_NATIVE_ENTRY(nativeValidateConfiguration));
49
50 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
51
52 ASSERT_TRUE(shell->IsSetup());
53 auto run_configuration = RunConfiguration::InferFromSettings(settings);
54 run_configuration.SetEntrypoint("validateConfiguration");
55
56 shell->RunEngine(std::move(run_configuration), [&](auto result) {
58 });
59
60 message_latch->Wait();
61 DestroyShell(std::move(shell), task_runners);
62}
63
64TEST_F(PlatformConfigurationTest, WindowMetricsUpdate) {
65 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
66
67 auto nativeValidateConfiguration =
68 [message_latch](Dart_NativeArguments args) {
69 PlatformConfiguration* configuration =
71
72 ASSERT_NE(configuration->GetMetrics(0), nullptr);
73 bool has_view = configuration->UpdateViewMetrics(
74 0, ViewportMetrics{2.0, 10.0, 20.0, 22, 0});
75 ASSERT_TRUE(has_view);
76 ASSERT_EQ(configuration->GetMetrics(0)->device_pixel_ratio, 2.0);
77 ASSERT_EQ(configuration->GetMetrics(0)->physical_width, 10.0);
78 ASSERT_EQ(configuration->GetMetrics(0)->physical_height, 20.0);
79 ASSERT_EQ(configuration->GetMetrics(0)->physical_touch_slop, 22);
80
81 message_latch->Signal();
82 };
83
84 Settings settings = CreateSettingsForFixture();
85 TaskRunners task_runners("test", // label
86 GetCurrentTaskRunner(), // platform
87 CreateNewThread(), // raster
88 CreateNewThread(), // ui
89 CreateNewThread() // io
90 );
91
92 AddNativeCallback("ValidateConfiguration",
93 CREATE_NATIVE_ENTRY(nativeValidateConfiguration));
94
95 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
96
97 ASSERT_TRUE(shell->IsSetup());
98 auto run_configuration = RunConfiguration::InferFromSettings(settings);
99 run_configuration.SetEntrypoint("validateConfiguration");
100
101 shell->RunEngine(std::move(run_configuration), [&](auto result) {
103 });
104
105 message_latch->Wait();
106 DestroyShell(std::move(shell), task_runners);
107}
108
109TEST_F(PlatformConfigurationTest, GetWindowReturnsNullForNonexistentId) {
110 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
111
112 auto nativeValidateConfiguration =
113 [message_latch](Dart_NativeArguments args) {
114 PlatformConfiguration* configuration =
116
117 ASSERT_EQ(configuration->GetMetrics(1), nullptr);
118 ASSERT_EQ(configuration->GetMetrics(2), nullptr);
119
120 message_latch->Signal();
121 };
122
123 Settings settings = CreateSettingsForFixture();
124 TaskRunners task_runners("test", // label
125 GetCurrentTaskRunner(), // platform
126 CreateNewThread(), // raster
127 CreateNewThread(), // ui
128 CreateNewThread() // io
129 );
130
131 AddNativeCallback("ValidateConfiguration",
132 CREATE_NATIVE_ENTRY(nativeValidateConfiguration));
133
134 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
135
136 ASSERT_TRUE(shell->IsSetup());
137 auto run_configuration = RunConfiguration::InferFromSettings(settings);
138 run_configuration.SetEntrypoint("validateConfiguration");
139
140 shell->RunEngine(std::move(run_configuration), [&](auto result) {
142 });
143
144 message_latch->Wait();
145 DestroyShell(std::move(shell), task_runners);
146}
147
148TEST_F(PlatformConfigurationTest, OnErrorHandlesError) {
149 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
150 bool did_throw = false;
151
152 auto finish = [message_latch](Dart_NativeArguments args) {
153 message_latch->Signal();
154 };
155 AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish));
156
157 Settings settings = CreateSettingsForFixture();
158 settings.unhandled_exception_callback =
159 [&did_throw](const std::string& exception,
160 const std::string& stack_trace) -> bool {
161 did_throw = true;
162 return false;
163 };
164
165 TaskRunners task_runners("test", // label
166 GetCurrentTaskRunner(), // platform
167 CreateNewThread(), // raster
168 CreateNewThread(), // ui
169 CreateNewThread() // io
170 );
171
172 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
173
174 ASSERT_TRUE(shell->IsSetup());
175 auto run_configuration = RunConfiguration::InferFromSettings(settings);
176 run_configuration.SetEntrypoint("customOnErrorTrue");
177
178 shell->RunEngine(std::move(run_configuration), [&](auto result) {
180 });
181
182 message_latch->Wait();
183
184 // Flush the UI task runner to make sure errors that were triggered had a turn
185 // to propagate.
186 task_runners.GetUITaskRunner()->PostTask(
187 [&message_latch]() { message_latch->Signal(); });
188 message_latch->Wait();
189
190 ASSERT_FALSE(did_throw);
191 DestroyShell(std::move(shell), task_runners);
192}
193
194TEST_F(PlatformConfigurationTest, OnErrorDoesNotHandleError) {
195 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
196 std::string ex;
197 std::string st;
198 size_t throw_count = 0;
199
200 auto finish = [message_latch](Dart_NativeArguments args) {
201 message_latch->Signal();
202 };
203 AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish));
204
205 Settings settings = CreateSettingsForFixture();
206 settings.unhandled_exception_callback =
207 [&ex, &st, &throw_count](const std::string& exception,
208 const std::string& stack_trace) -> bool {
209 throw_count += 1;
210 ex = exception;
211 st = stack_trace;
212 return true;
213 };
214
215 TaskRunners task_runners("test", // label
216 GetCurrentTaskRunner(), // platform
217 CreateNewThread(), // raster
218 CreateNewThread(), // ui
219 CreateNewThread() // io
220 );
221
222 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
223
224 ASSERT_TRUE(shell->IsSetup());
225 auto run_configuration = RunConfiguration::InferFromSettings(settings);
226 run_configuration.SetEntrypoint("customOnErrorFalse");
227
228 shell->RunEngine(std::move(run_configuration), [&](auto result) {
230 });
231
232 message_latch->Wait();
233
234 // Flush the UI task runner to make sure errors that were triggered had a turn
235 // to propagate.
236 task_runners.GetUITaskRunner()->PostTask(
237 [&message_latch]() { message_latch->Signal(); });
238 message_latch->Wait();
239
240 ASSERT_EQ(throw_count, 1ul);
241 ASSERT_EQ(ex, "Exception: false") << ex;
242 ASSERT_EQ(st.rfind("#0 customOnErrorFalse", 0), 0ul) << st;
243 DestroyShell(std::move(shell), task_runners);
244}
245
247 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
248 std::vector<std::string> errors;
249 size_t throw_count = 0;
250
251 auto finish = [message_latch](Dart_NativeArguments args) {
252 message_latch->Signal();
253 };
254 AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish));
255
256 Settings settings = CreateSettingsForFixture();
257 settings.unhandled_exception_callback =
258 [&errors, &throw_count](const std::string& exception,
259 const std::string& stack_trace) -> bool {
260 throw_count += 1;
261 errors.push_back(exception);
262 errors.push_back(stack_trace);
263 return true;
264 };
265
266 TaskRunners task_runners("test", // label
267 GetCurrentTaskRunner(), // platform
268 CreateNewThread(), // raster
269 CreateNewThread(), // ui
270 CreateNewThread() // io
271 );
272
273 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
274
275 ASSERT_TRUE(shell->IsSetup());
276 auto run_configuration = RunConfiguration::InferFromSettings(settings);
277 run_configuration.SetEntrypoint("customOnErrorThrow");
278
279 shell->RunEngine(std::move(run_configuration), [&](auto result) {
281 });
282
283 message_latch->Wait();
284
285 // Flush the UI task runner to make sure errors that were triggered had a turn
286 // to propagate.
287 task_runners.GetUITaskRunner()->PostTask(
288 [&message_latch]() { message_latch->Signal(); });
289 message_latch->Wait();
290
291 ASSERT_EQ(throw_count, 2ul);
292 ASSERT_EQ(errors.size(), 4ul);
293 ASSERT_EQ(errors[0], "Exception: throw2") << errors[0];
294 ASSERT_EQ(errors[1].rfind("#0 customOnErrorThrow"), 0ul) << errors[1];
295 ASSERT_EQ(errors[2], "Exception: throw1") << errors[2];
296 ASSERT_EQ(errors[3].rfind("#0 customOnErrorThrow"), 0ul) << errors[3];
297
298 DestroyShell(std::move(shell), task_runners);
299}
300
301TEST_F(PlatformConfigurationTest, SetDartPerformanceMode) {
302 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
303 auto finish = [message_latch](Dart_NativeArguments args) {
304 // call needs to happen on the UI thread.
308 message_latch->Signal();
309 };
310 AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish));
311
312 Settings settings = CreateSettingsForFixture();
313
314 TaskRunners task_runners("test", // label
315 GetCurrentTaskRunner(), // platform
316 CreateNewThread(), // raster
317 CreateNewThread(), // ui
318 CreateNewThread() // io
319 );
320
321 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
322
323 ASSERT_TRUE(shell->IsSetup());
324 auto run_configuration = RunConfiguration::InferFromSettings(settings);
325 run_configuration.SetEntrypoint("setLatencyPerformanceMode");
326
327 shell->RunEngine(std::move(run_configuration), [&](auto result) {
329 });
330
331 message_latch->Wait();
332 DestroyShell(std::move(shell), task_runners);
333}
334
335} // namespace testing
336} // namespace flutter
static float prev(float f)
A class for holding and distributing platform-level information to and from the Dart code in Flutter'...
const ViewportMetrics * GetMetrics(int view_id)
Retrieves the viewport metrics with the given ID managed by the PlatformConfiguration.
bool UpdateViewMetrics(int64_t view_id, const ViewportMetrics &metrics)
Update the view metrics for the specified view.
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
PlatformConfiguration * platform_configuration() const
static UIDartState * Current()
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
Dart_PerformanceMode
Definition: dart_api.h:1369
@ Dart_PerformanceMode_Default
Definition: dart_api.h:1373
@ Dart_PerformanceMode_Latency
Definition: dart_api.h:1380
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
DART_EXPORT Dart_PerformanceMode Dart_SetPerformanceMode(Dart_PerformanceMode mode)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
fml::RefPtr< fml::TaskRunner > GetCurrentTaskRunner()
TEST_F(DisplayListTest, Defaults)
#define CREATE_NATIVE_ENTRY(native_entry)