5#define FML_USED_ON_EMBEDDER
34#include "third_party/skia/include/core/SkSurface.h"
37#if defined(FML_OS_MACOSX)
46static uint64_t NanosFromEpoch(
int millis_from_now) {
49 return (now + delta).ToEpochDelta().ToNanoseconds();
59TEST(EmbedderTestNoFixture, MustNotRunWithInvalidArgs) {
64 ASSERT_FALSE(
engine.is_valid());
68 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
70 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
74 ASSERT_TRUE(
engine.is_valid());
82 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
85 for (
size_t i = 0;
i < 3; ++
i) {
87 ASSERT_TRUE(
engine.is_valid());
88 FML_LOG(INFO) <<
"Engine launch count: " <<
i + 1;
93 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
95 Dart_NativeFunction entrypoint = [](Dart_NativeArguments
args) {
98 context.AddNativeCallback(
"SayHiFromCustomEntrypoint", entrypoint);
104 ASSERT_TRUE(
engine.is_valid());
108 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
115 auto entry1 = [&latch1](Dart_NativeArguments
args) {
116 FML_LOG(INFO) <<
"In Callback 1";
120 context.AddNativeCallback(
"SayHiFromCustomEntrypoint1", native_entry1);
123 auto entry2 = [&latch2](Dart_NativeArguments
args) {
124 FML_LOG(INFO) <<
"In Callback 2";
127 context.AddNativeCallback(
"SayHiFromCustomEntrypoint2",
131 context.AddNativeCallback(
132 "SayHiFromCustomEntrypoint3",
134 FML_LOG(INFO) <<
"In Callback 3";
145 ASSERT_TRUE(
engine.is_valid());
149 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
154 ASSERT_TRUE(
engine.is_valid());
158 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
163 context.AddNativeCallback(
166 Dart_GetNativeArgument(
args, 0));
167 EXPECT_EQ(
"/path/to/binary", dart_string);
183 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
185 bool implicitViewNotNull =
false;
187 context.AddNativeCallback(
190 Dart_GetNativeArgument(
args, 0));
200 EXPECT_TRUE(implicitViewNotNull);
203std::atomic_size_t EmbedderTestTaskRunner::sEmbedderTaskRunnerIdentifiers = {};
206 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
207 auto ui_task_runner = CreateNewThread(
"test_ui_thread");
208 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
209 static std::mutex engine_mutex;
214 std::scoped_lock lock(engine_mutex);
222 std::scoped_lock lock(engine_mutex);
232 context.AddNativeCallback(
235 ASSERT_TRUE(ui_task_runner->RunsTasksOnCurrentThread());
236 signal_latch_ui.Signal();
239 platform_task_runner->PostTask([&]() {
241 const auto ui_task_runner_description =
242 test_ui_task_runner.GetFlutterTaskRunnerDescription();
243 const auto platform_task_runner_description =
244 test_platform_task_runner.GetFlutterTaskRunnerDescription();
251 ASSERT_TRUE(platform_task_runner->RunsTasksOnCurrentThread());
252 signal_latch_platform.
Signal();
255 std::scoped_lock lock(engine_mutex);
259 ASSERT_TRUE(
engine.is_valid());
261 signal_latch_ui.
Wait();
262 signal_latch_platform.
Wait();
265 platform_task_runner->PostTask([&] {
267 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
273 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
274 auto ui_task_runner = CreateNewThread(
"test_ui_thread");
275 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
276 static std::mutex engine_mutex;
291 std::scoped_lock lock(engine_mutex);
300 platform_task_runner->PostTask([&]() {
302 const auto ui_task_runner_description =
303 test_ui_task_runner.GetFlutterTaskRunnerDescription();
304 const auto platform_task_runner_description =
305 test_platform_task_runner.GetFlutterTaskRunnerDescription();
309 std::scoped_lock lock(engine_mutex);
316 engine_ptr =
engine.get();
326 platform_task_runner->PostTask([&] {
328 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
334 ui_task_runner->PostDelayedTask([&]() { kill_latch.
Signal(); },
340 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
341 auto task_runner = CreateNewThread(
"test_thread");
354 context.AddNativeCallback(
357 ASSERT_TRUE(task_runner->RunsTasksOnCurrentThread());
358 signal_latch_ui.Signal();
361 task_runner->PostTask([&]() {
363 const auto task_runner_description =
364 test_task_runner.GetFlutterTaskRunnerDescription();
371 ASSERT_TRUE(task_runner->RunsTasksOnCurrentThread());
372 signal_latch_platform.
Signal();
375 ASSERT_TRUE(
engine.is_valid());
377 signal_latch_ui.
Wait();
378 signal_latch_platform.
Wait();
381 task_runner->PostTask([&] {
383 task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
389 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
390 auto ui_task_runner = CreateNewThread(
"test_ui_thread");
404 context.AddNativeCallback(
406 ASSERT_TRUE(ui_task_runner->RunsTasksOnCurrentThread());
407 signal_latch.Signal();
410 ui_task_runner->PostTask([&]() {
412 const auto task_runner_description =
413 test_task_runner.GetFlutterTaskRunnerDescription();
418 ASSERT_TRUE(
engine.is_valid());
423 ui_task_runner->PostTask([&] {
425 ui_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
431 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
436 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
437 static std::mutex engine_mutex;
438 static bool signaled_once =
false;
439 static std::atomic<bool> destruction_callback_called =
false;
444 std::scoped_lock lock(engine_mutex);
455 signaled_once =
true;
456 ASSERT_TRUE(
engine.is_valid());
461 [](
void*
user_data) { destruction_callback_called =
true; });
463 platform_task_runner->PostTask([&]() {
465 const auto task_runner_description =
466 test_task_runner.GetFlutterTaskRunnerDescription();
470 std::scoped_lock lock(engine_mutex);
472 ASSERT_TRUE(
engine.is_valid());
477 ASSERT_TRUE(
engine.is_valid());
483 std::scoped_lock lock(engine_mutex);
489 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
493 ASSERT_TRUE(signaled_once);
494 signaled_once =
false;
496 ASSERT_TRUE(destruction_callback_called);
497 destruction_callback_called =
false;
500TEST(EmbedderTestNoFixture, CanGetCurrentTimeInNanoseconds) {
509 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
513 ASSERT_TRUE(
engine.is_valid());
520 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
525 std::string isolate_message;
533 if (strcmp(
message->channel,
"flutter/isolate") == 0) {
534 isolate_message = {reinterpret_cast<const char*>(message->message),
535 message->message_size};
539 engine = builder.LaunchEngine();
540 ASSERT_TRUE(
engine.is_valid());
545 ASSERT_EQ(isolate_message.find(
"isolates/"), 0ul);
550 thread.GetTaskRunner()->PostTask(
563 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
567 context.AddNativeCallback(
572 ASSERT_TRUE(
engine.is_valid());
580 ASSERT_NE(response_handle,
nullptr);
595 std::thread::id thread_id;
600 captures.thread_id = std::this_thread::get_id();
601 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
607 context.AddNativeCallback(
610 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
613 ASSERT_TRUE(
engine.is_valid());
615 static std::string kMessageData =
"Hello from embedder.";
620 ASSERT_EQ(
size, kMessageData.size());
621 ASSERT_EQ(strncmp(
reinterpret_cast<const char*
>(kMessageData.data()),
622 reinterpret_cast<const char*
>(
data),
size),
624 auto captures =
reinterpret_cast<Captures*
>(
user_data);
625 ASSERT_EQ(captures->thread_id, std::this_thread::get_id());
626 captures->latch.Signal();
634 message.channel =
"test_channel";
635 message.message =
reinterpret_cast<const uint8_t*
>(kMessageData.data());
636 message.message_size = kMessageData.size();
637 message.response_handle = response_handle;
648 captures.latch.Wait();
657 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
662 const std::string message_data =
"Hello but don't call me back.";
665 context.AddNativeCallback(
668 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
669 context.AddNativeCallback(
670 "SignalNativeMessage",
672 ([&
message, &message_data](Dart_NativeArguments
args) {
674 Dart_GetNativeArgument(
args, 0));
675 ASSERT_EQ(received_message, message_data);
681 ASSERT_TRUE(
engine.is_valid());
686 platform_message.
channel =
"test_channel";
688 reinterpret_cast<const uint8_t*
>(message_data.data());
702 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
708 context.AddNativeCallback(
711 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
712 context.AddNativeCallback(
713 "SignalNativeMessage",
716 Dart_GetNativeArgument(
args, 0));
717 ASSERT_EQ(
"true", received_message);
723 ASSERT_TRUE(
engine.is_valid());
728 platform_message.
channel =
"test_channel";
729 platform_message.
message =
nullptr;
744 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
749 ASSERT_TRUE(
engine.is_valid());
753 platform_message.
channel =
"test_channel";
754 platform_message.
message =
nullptr;
768 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
772 context.SetLogMessageCallback(
773 [&callback_latch](
const char* tag,
const char*
message) {
774 EXPECT_EQ(std::string(tag),
"flutter");
775 EXPECT_EQ(std::string(
message),
"hello world");
779 ASSERT_TRUE(
engine.is_valid());
780 callback_latch.
Wait();
787 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
792 context.SetLogMessageCallback(
793 [&callback_latch](
const char* tag,
const char*
message) {
794 EXPECT_EQ(std::string(tag),
"butterfly");
795 EXPECT_EQ(std::string(
message),
"hello world");
799 ASSERT_TRUE(
engine.is_valid());
800 callback_latch.
Wait();
808 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
827 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
834 std::vector<std::string> callback_args;
835 auto nativeArgumentsCallback = [&callback_args,
836 &callback_latch](Dart_NativeArguments
args) {
837 Dart_Handle exception =
nullptr;
843 context.AddNativeCallback(
"NativeArgumentsCallback",
846 callback_latch.
Wait();
847 ASSERT_EQ(callback_args[0],
"foo");
848 ASSERT_EQ(callback_args[1],
"bar");
861 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
872 ASSERT_TRUE(
engine.is_valid());
876 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
883 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
887 context.GetCompositor().SetNextPresentCallback(
900 event.pixel_ratio = 1.0;
903 ASSERT_TRUE(
engine.is_valid());
908 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
916 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
920 context.GetCompositor().SetNextPresentCallback(
933 event.pixel_ratio = 1.0;
936 ASSERT_TRUE(
engine.is_valid());
945#if FML_OS_MACOSX && FML_ARCH_CPU_ARM64
947 DISABLED_CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
950 CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
953 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
961 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
965 auto scene_image = context.GetNextSceneImage();
967 context.GetCompositor().SetNextPresentCallback(
985 .rects = paint_region_rects,
989 .paint_region = &paint_region,
1000 ASSERT_EQ(*
layers[0], layer);
1016 ASSERT_EQ(*
layers[1], layer);
1032 .rects = paint_region_rects,
1036 .paint_region = &paint_region,
1047 ASSERT_EQ(*
layers[2], layer);
1063 ASSERT_EQ(*
layers[3], layer);
1079 .rects = paint_region_rects,
1083 .paint_region = &paint_region,
1094 ASSERT_EQ(*
layers[4], layer);
1100 context.GetCompositor().SetPlatformViewRendererCallback(
1102 ) -> sk_sp<SkImage> {
1105 auto canvas =
surface->getCanvas();
1112 paint.setColor(SK_ColorGREEN);
1113 paint.setAlpha(127);
1116 canvas->drawRect(rect, paint);
1122 paint.setColor(SK_ColorMAGENTA);
1123 paint.setAlpha(127);
1126 canvas->drawRect(rect, paint);
1132 <<
"Test was asked to composite an unknown platform view.";
1135 return surface->makeImageSnapshot();
1138 context.AddNativeCallback(
1141 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1150 event.pixel_ratio = 1.0;
1151 event.physical_view_inset_top = 0.0;
1152 event.physical_view_inset_right = 0.0;
1153 event.physical_view_inset_bottom = 0.0;
1154 event.physical_view_inset_left = 0.0;
1157 ASSERT_TRUE(
engine.is_valid());
1164 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1172 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1180 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1184 auto scene_image = context.GetNextSceneImage();
1186 context.GetCompositor().SetNextPresentCallback(
1204 .rects = paint_region_rects,
1208 .paint_region = &paint_region,
1219 ASSERT_EQ(*
layers[0], layer);
1235 ASSERT_EQ(*
layers[1], layer);
1241 context.GetCompositor().SetPlatformViewRendererCallback(
1243 ) -> sk_sp<SkImage> {
1246 auto canvas =
surface->getCanvas();
1253 paint.setColor(SK_ColorGREEN);
1254 paint.setAlpha(127);
1257 canvas->drawRect(rect, paint);
1263 <<
"Test was asked to composite an unknown platform view.";
1266 return surface->makeImageSnapshot();
1269 context.AddNativeCallback(
1272 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1281 event.pixel_ratio = 1.0;
1282 event.physical_view_inset_top = 0.0;
1283 event.physical_view_inset_right = 0.0;
1284 event.physical_view_inset_bottom = 0.0;
1285 event.physical_view_inset_left = 0.0;
1288 ASSERT_TRUE(
engine.is_valid());
1294#if !defined(FML_OS_LINUX)
1295 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1298 "compositor_platform_layer_with_no_overlay.png", scene_image));
1301 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1309 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1317 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1321 auto scene_image = context.GetNextSceneImage();
1323 context.GetCompositor().SetNextPresentCallback(
1341 .rects = paint_region_rects,
1345 .paint_region = &paint_region,
1356 ASSERT_EQ(*
layers[0], layer);
1372 ASSERT_EQ(*
layers[1], layer);
1378 context.GetCompositor().SetPlatformViewRendererCallback(
1380 ) -> sk_sp<SkImage> {
1383 auto canvas =
surface->getCanvas();
1390 paint.setColor(SK_ColorGREEN);
1391 paint.setAlpha(127);
1394 canvas->drawRect(rect, paint);
1400 <<
"Test was asked to composite an unknown platform view.";
1403 return surface->makeImageSnapshot();
1406 context.AddNativeCallback(
1409 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1418 event.pixel_ratio = 1.0;
1419 event.physical_view_inset_top = 0.0;
1420 event.physical_view_inset_right = 0.0;
1421 event.physical_view_inset_bottom = 0.0;
1422 event.physical_view_inset_left = 0.0;
1425 ASSERT_TRUE(
engine.is_valid());
1431#if !defined(FML_OS_LINUX)
1432 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1435 "compositor_platform_layer_with_no_overlay.png", scene_image));
1438 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1445 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1449 ASSERT_TRUE(
engine.is_valid());
1457 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1461 ASSERT_TRUE(
engine.is_valid());
1472 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1476 ASSERT_TRUE(
engine.is_valid());
1489 event.pixel_ratio = 1.0;
1490 event.physical_view_inset_top = 0.0;
1491 event.physical_view_inset_right = 0.0;
1492 event.physical_view_inset_bottom = 0.0;
1493 event.physical_view_inset_left = 0.0;
1503 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1509 context.AddNativeCallback(
1512 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1515 context.AddNativeCallback(
"SignalNativeMessage",
1519 Dart_GetNativeArgument(
args, 0));
1524 ASSERT_TRUE(
engine.is_valid());
1530 metrics.
width = 800;
1540 EXPECT_TRUE(result->added);
1543 message_latch.
Wait();
1544 ASSERT_EQ(
"View IDs: [0, 123]",
message);
1551 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1556 context.AddNativeCallback(
1559 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
1562 context.AddNativeCallback(
1563 "SignalNativeCount",
1565 [&check_latch](Dart_NativeArguments
args) { check_latch.
Signal(); }));
1568 ASSERT_TRUE(
engine.is_valid());
1575 metrics.
width = 800;
1585 EXPECT_TRUE(result->added);
1596 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1602 context.AddNativeCallback(
1605 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1608 context.AddNativeCallback(
"SignalNativeMessage",
1612 Dart_GetNativeArgument(
args, 0));
1617 ASSERT_TRUE(
engine.is_valid());
1624 metrics.
width = 800;
1634 ASSERT_TRUE(result->added);
1637 message_latch.
Wait();
1638 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1645 EXPECT_TRUE(result->removed);
1648 message_latch.
Wait();
1649 ASSERT_EQ(
message,
"View IDs: [0]");
1655 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1657 std::mutex engine_mutex;
1659 auto render_thread = CreateNewThread(
"custom_render_thread");
1662 std::scoped_lock engine_lock(engine_mutex);
1671 &render_task_runner.GetFlutterTaskRunnerDescription());
1674 context.AddNativeCallback(
1677 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1680 std::scoped_lock lock(engine_mutex);
1684 ASSERT_TRUE(
engine.is_valid());
1692 metrics.
width = 800;
1703 ASSERT_TRUE(result->added);
1704 auto add_view_latch =
1706 add_view_latch->
Signal();
1709 add_view_latch.
Wait();
1711 std::atomic_bool view_available =
true;
1716 render_thread->PostTask([&] {
1717 std::this_thread::sleep_for(std::chrono::milliseconds(50));
1719 EXPECT_TRUE(view_available);
1720 raster_thread_latch.
Signal();
1726 remove_view_info.
view_id = 123;
1727 remove_view_info.
user_data = &remove_view_latch;
1730 ASSERT_TRUE(result->removed);
1731 auto remove_view_latch =
1733 remove_view_latch->
Signal();
1738 remove_view_latch.
Wait();
1742 view_available =
false;
1743 raster_thread_latch.
Wait();
1753 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1758 ASSERT_TRUE(
engine.is_valid());
1773 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1779 context.AddNativeCallback(
1782 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1785 context.AddNativeCallback(
"SignalNativeMessage",
1789 Dart_GetNativeArgument(
args, 0));
1794 ASSERT_TRUE(
engine.is_valid());
1800 std::atomic<int> count = 0;
1807 metrics.
width = 800;
1818 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
1820 int count = captures->count.fetch_add(1);
1823 ASSERT_TRUE(result->added);
1825 EXPECT_FALSE(result->added);
1826 captures->failure_latch.Signal();
1830 message_latch.
Wait();
1831 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1832 ASSERT_FALSE(captures.failure_latch.IsSignaledForTest());
1836 captures.failure_latch.Wait();
1837 ASSERT_EQ(captures.count, 2);
1845 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1851 context.AddNativeCallback(
1854 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1857 context.AddNativeCallback(
"SignalNativeMessage",
1861 Dart_GetNativeArgument(
args, 0));
1866 ASSERT_TRUE(
engine.is_valid());
1873 metrics.
width = 800;
1883 ASSERT_TRUE(result->added);
1886 message_latch.
Wait();
1887 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1894 ASSERT_TRUE(result->removed);
1897 message_latch.
Wait();
1898 ASSERT_EQ(
message,
"View IDs: [0]");
1902 message_latch.
Wait();
1903 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1910 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1915 ASSERT_TRUE(
engine.is_valid());
1923 EXPECT_FALSE(result->removed);
1936 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1942 context.AddNativeCallback(
1945 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1947 std::atomic<int> message_count = 0;
1948 context.AddNativeCallback(
"SignalNativeMessage",
1950 message_count.fetch_add(1);
1954 ASSERT_TRUE(
engine.is_valid());
1971 metrics123.
width = 800;
1978 metrics456.
width = 800;
1998 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2000 ASSERT_TRUE(result->added);
2001 ASSERT_FALSE(captures->add_first_view.IsSignaledForTest());
2002 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
2003 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2004 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2006 captures->add_first_view.Signal();
2012 add_duplicate_view_info.
view_id = 123;
2014 add_duplicate_view_info.
user_data = &captures;
2017 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2019 ASSERT_FALSE(result->added);
2020 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2021 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
2022 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2023 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2025 captures->add_duplicate_view.Signal();
2031 add_second_view_info.
view_id = 456;
2033 add_second_view_info.
user_data = &captures;
2036 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2038 ASSERT_TRUE(result->added);
2039 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2040 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
2041 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2042 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2044 captures->add_second_view.Signal();
2050 remove_second_view_info.
view_id = 456;
2051 remove_second_view_info.
user_data = &captures;
2054 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2056 ASSERT_TRUE(result->removed);
2057 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2058 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
2059 ASSERT_TRUE(captures->add_second_view.IsSignaledForTest());
2060 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2062 captures->remove_second_view.Signal();
2072 captures.remove_second_view.Wait();
2073 captures.add_second_view.Wait();
2074 captures.add_duplicate_view.Wait();
2075 captures.add_first_view.Wait();
2076 ASSERT_EQ(message_count, 3);
2083 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2090 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2093 context.GetCompositor().SetPresentCallback(
2110 ASSERT_TRUE(
engine.is_valid());
2115 metrics0.
width = 800;
2125 metrics123.
width = 800;
2135 ASSERT_TRUE(result->added);
2151 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2152 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
2154 static std::mutex engine_mutex;
2157 std::scoped_lock lock(engine_mutex);
2158 if (!
engine.is_valid()) {
2164 std::vector<FlutterViewFocusChangeRequest> received_requests;
2165 platform_task_runner->PostTask([&]() {
2169 const auto platform_task_runner_description =
2170 test_platform_task_runner.GetFlutterTaskRunnerDescription();
2174 EXPECT_TRUE(platform_task_runner->RunsTasksOnCurrentThread());
2175 received_requests.push_back(*request);
2179 ASSERT_TRUE(
engine.is_valid());
2183 std::vector<FlutterViewFocusChangeRequest> expected_requests{
2189 ASSERT_EQ(received_requests.size(), expected_requests.size());
2190 for (
size_t i = 0;
i < received_requests.size(); ++
i) {
2191 ASSERT_TRUE(received_requests[
i] == expected_requests[
i]);
2196 std::scoped_lock lock(engine_mutex);
2202 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
2208 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2214 std::string last_event;
2216 context.AddNativeCallback(
2219 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
2220 context.AddNativeCallback(
"NotifyStringValue",
2222 const auto message_from_dart =
2224 Dart_GetNativeArgument(
args, 0));
2225 last_event = message_from_dart;
2230 ASSERT_TRUE(
engine.is_valid());
2245 ASSERT_EQ(last_event,
2246 "1 ViewFocusState.focused ViewFocusDirection.undefined");
2258 ASSERT_EQ(last_event,
2259 "2 ViewFocusState.unfocused ViewFocusDirection.backward");
2280 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2288 context.GetCompositor().GetGrContext(),
2289 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2292 struct CompositorUserData {
2299 bool second_expected;
2300 bool third_expected;
2302 int backing_stores_created;
2304 CompositorUserData compositor_user_data{
2305 .producer = &producer,
2306 .backing_stores_created = 0,
2311 .
user_data =
reinterpret_cast<void*
>(&compositor_user_data),
2312 .create_backing_store_callback =
2316 EXPECT_TRUE(config->
view_id == 0 ||
2317 config->
view_id == kSecondViewId ||
2318 config->
view_id == kThirdViewId);
2319 auto compositor_user_data =
2320 reinterpret_cast<CompositorUserData*
>(
user_data);
2321 compositor_user_data->backing_stores_created += 1;
2322 bool result = compositor_user_data->producer->Create(
2323 config, backing_store_out);
2326 backing_store_out->user_data =
2327 reinterpret_cast<void*
>(config->
view_id);
2332 .present_layers_callback =
nullptr,
2333 .avoid_backing_store_cache =
false,
2334 .present_view_callback =
2336 EXPECT_EQ(info->layers_count, 1u);
2339 int64_t store_view_id =
reinterpret_cast<int64_t
>(
2340 info->layers[0]->backing_store->user_data);
2341 EXPECT_EQ(store_view_id, info->view_id);
2342 auto compositor_user_data =
2343 reinterpret_cast<CompositorUserData*
>(info->user_data);
2345 switch (info->view_id) {
2347 compositor_user_data->latch_implicit.Signal();
2350 EXPECT_TRUE(compositor_user_data->second_expected);
2351 compositor_user_data->latch_second.Signal();
2354 EXPECT_TRUE(compositor_user_data->third_expected);
2355 compositor_user_data->latch_third.Signal();
2364 compositor_user_data.second_expected =
true;
2365 compositor_user_data.third_expected =
false;
2370 ASSERT_TRUE(
engine.is_valid());
2395 add_view_info.
view_id = kSecondViewId;
2398 ASSERT_TRUE(result->added);
2403 compositor_user_data.latch_implicit.Wait();
2404 compositor_user_data.latch_second.Wait();
2408 compositor_user_data.second_expected =
false;
2409 compositor_user_data.third_expected =
true;
2410 EXPECT_EQ(compositor_user_data.backing_stores_created, 2);
2415 remove_view_info.
view_id = kSecondViewId;
2418 ASSERT_TRUE(result->removed);
2423 add_view_info.
view_id = kThirdViewId;
2424 metrics_add.
view_id = kThirdViewId;
2428 compositor_user_data.latch_implicit.Wait();
2429 compositor_user_data.latch_third.Wait();
2430 EXPECT_EQ(compositor_user_data.backing_stores_created, 3);
2434 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2439 context.AddNativeCallback(
2442 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
2445 context.AddNativeCallback(
2446 "SignalNativeCount",
2449 Dart_GetNativeArgument(
args, 0)),
2455 ASSERT_TRUE(
engine.is_valid());
2474 std::vector<const FlutterLocale*> locales;
2475 locales.push_back(&locale1);
2476 locales.push_back(&locale2);
2493 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2495 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2499 ASSERT_TRUE(
engine.is_valid());
2504 std::vector<std::string> supported_locales;
2505 supported_locales.push_back(
"es");
2506 supported_locales.push_back(
"MX");
2507 supported_locales.push_back(
"");
2508 auto result = shell.
GetPlatformView()->ComputePlatformResolvedLocales(
2511 ASSERT_EQ((*result).size(), supported_locales.size());
2512 ASSERT_EQ((*result)[0], supported_locales[0]);
2513 ASSERT_EQ((*result)[1], supported_locales[1]);
2514 ASSERT_EQ((*result)[2], supported_locales[2]);
2525 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2533 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2536 auto rendered_scene = context.GetNextSceneImage();
2539 context.GetCompositor().SetNextPresentCallback(
2556 .rects = paint_region_rects,
2560 .paint_region = &paint_region,
2571 ASSERT_EQ(*
layers[0], layer);
2587 ASSERT_EQ(*
layers[1], layer);
2593 context.GetCompositor().SetPlatformViewRendererCallback(
2595 GrDirectContext* context) -> sk_sp<SkImage> {
2598 auto canvas =
surface->getCanvas();
2605 paint.setColor(SK_ColorGREEN);
2606 paint.setAlpha(127);
2609 canvas->drawRect(rect, paint);
2614 <<
"Test was asked to composite an unknown platform view.";
2617 return surface->makeImageSnapshot();
2627 event.pixel_ratio = 1.0;
2628 event.physical_view_inset_top = 0.0;
2629 event.physical_view_inset_right = 0.0;
2630 event.physical_view_inset_bottom = 0.0;
2631 event.physical_view_inset_left = 0.0;
2634 ASSERT_TRUE(
engine.is_valid());
2641#if !defined(FML_OS_LINUX)
2642 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
2649 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2656 ASSERT_TRUE(
engine.is_valid());
2668 size_t worker_count = 0;
2675 auto platform_task_runner = CreateNewThread(
"platform_thread");
2677 platform_task_runner->PostTask([&]() {
2678 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2684 ASSERT_TRUE(
engine.is_valid());
2697 const auto engine_threads_count = worker_count + 4u;
2707 std::mutex captures_mutex;
2709 std::set<std::thread::id> thread_ids;
2711 size_t platform_threads_count = 0;
2712 size_t render_threads_count = 0;
2713 size_t ui_threads_count = 0;
2714 size_t worker_threads_count = 0;
2716 explicit Captures(
size_t count) : latch(count) {}
2719 Captures captures(engine_threads_count);
2721 platform_task_runner->PostTask([&]() {
2725 auto captures = reinterpret_cast<Captures*>(baton);
2727 std::scoped_lock lock(captures->captures_mutex);
2729 case kFlutterNativeThreadTypeRender:
2730 captures->render_threads_count++;
2732 case kFlutterNativeThreadTypeWorker:
2733 captures->worker_threads_count++;
2735 case kFlutterNativeThreadTypeUI:
2736 captures->ui_threads_count++;
2738 case kFlutterNativeThreadTypePlatform:
2739 captures->platform_threads_count++;
2742 captures->thread_ids.insert(std::this_thread::get_id());
2744 captures->latch.CountDown();
2750 captures.latch.Wait();
2751 ASSERT_EQ(captures.thread_ids.size(), engine_threads_count);
2752 ASSERT_EQ(captures.platform_threads_count, 1u);
2753 ASSERT_EQ(captures.render_threads_count, 1u);
2754 ASSERT_EQ(captures.ui_threads_count, 1u);
2755 ASSERT_EQ(captures.worker_threads_count, worker_count + 1u );
2756 EXPECT_GE(captures.worker_threads_count - 1, 2u);
2757 EXPECT_LE(captures.worker_threads_count - 1, 4u);
2759 platform_task_runner->PostTask([&]() {
2761 sync_latch.Signal();
2766 ASSERT_FALSE(
engine.is_valid());
2779 ASSERT_EQ(data_out,
nullptr);
2788 ASSERT_EQ(data_out,
nullptr);
2795 ASSERT_EQ(data_in.
elf_path,
nullptr);
2796 ASSERT_EQ(data_out,
nullptr);
2803 ASSERT_EQ(data_out,
nullptr);
2809 ASSERT_EQ(data_in.
elf_path,
"/bin/true");
2810 ASSERT_EQ(data_out,
nullptr);
2818 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2822 EmbedderConfigBuilder::InitializationPreference::kMultiAOTInitialize);
2827 ASSERT_FALSE(
engine.is_valid());
2841 const auto elf_path =
2845 data_in.
elf_path = elf_path.c_str();
2849 ASSERT_EQ(data_in.
elf_path, elf_path.c_str());
2850 ASSERT_NE(data_out,
nullptr);
2860 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2863 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2867 EmbedderConfigBuilder::InitializationPreference::kAOTDataInitialize);
2872 ASSERT_TRUE(
engine.is_valid());
2879#if defined(__clang_analyzer__)
2880#define TEST_VM_SNAPSHOT_DATA "vm_data"
2881#define TEST_VM_SNAPSHOT_INSTRUCTIONS "vm_instructions"
2882#define TEST_ISOLATE_SNAPSHOT_DATA "isolate_data"
2883#define TEST_ISOLATE_SNAPSHOT_INSTRUCTIONS "isolate_instructions"
2893#if defined(OS_FUCHSIA)
2894 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2903 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2909 const std::string vm_snapshot_data =
2911 const std::string vm_snapshot_instructions =
2913 const std::string isolate_snapshot_data =
2915 const std::string isolate_snapshot_instructions =
2920 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
2922 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
2924 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
2926 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
2949#if defined(OS_FUCHSIA)
2950 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2959 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2965 reinterpret_cast<const uint8_t*
>(
"invalid_vm_data");
2967 reinterpret_cast<const uint8_t*
>(
"invalid_vm_instructions");
2969 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2971 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
2996 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3002 const std::string vm_snapshot_data =
3004 const std::string vm_snapshot_instructions =
3006 const std::string isolate_snapshot_data =
3008 const std::string isolate_snapshot_instructions =
3013 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
3015 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
3017 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
3019 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
3022 ASSERT_TRUE(
engine.is_valid());
3036 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3042 const std::string vm_snapshot_data =
3044 const std::string vm_snapshot_instructions =
3049 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
3051 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
3054 ASSERT_TRUE(
engine.is_valid());
3069 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3075 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
3077 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
3080 ASSERT_TRUE(
engine.is_valid());
3095 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3105 ASSERT_TRUE(
engine.is_valid());
3109 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3114 ASSERT_TRUE(
engine.is_valid());
3120 event.pixel_ratio = 0.0;
3121 event.physical_view_inset_top = 0.0;
3122 event.physical_view_inset_right = 0.0;
3123 event.physical_view_inset_bottom = 0.0;
3124 event.physical_view_inset_left = 0.0;
3130 event.pixel_ratio = 1.0;
3131 event.physical_view_inset_top = -1.0;
3132 event.physical_view_inset_right = -1.0;
3133 event.physical_view_inset_bottom = -1.0;
3134 event.physical_view_inset_left = -1.0;
3140 event.physical_view_inset_top = 700;
3141 event.physical_view_inset_right = 900;
3142 event.physical_view_inset_bottom = 700;
3143 event.physical_view_inset_left = 900;
3152 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3157 ASSERT_TRUE(
engine.is_valid());
3164 event.pixel_ratio = 1.0;
3165 event.has_constraints =
true;
3166 event.min_width_constraint = 400;
3167 event.max_width_constraint = 1200;
3168 event.min_height_constraint = 300;
3169 event.max_height_constraint = 900;
3178 event_no_constraints.
struct_size =
sizeof(event_no_constraints);
3179 event_no_constraints.
width = 1024;
3180 event_no_constraints.
height = 768;
3197 event_invalid_min.
struct_size =
sizeof(event_invalid_min);
3198 event_invalid_min.
width = 300;
3199 event_invalid_min.
height = 600;
3214 event_invalid_max.
struct_size =
sizeof(event_invalid_max);
3215 event_invalid_max.
width = 1300;
3216 event_invalid_max.
height = 600;
3231 event_invalid_height.
struct_size =
sizeof(event_invalid_height);
3232 event_invalid_height.
width = 800;
3233 event_invalid_height.
height = 200;
3249 std::string entrypoint,
3251 const std::vector<uint8_t>& bytes) {
3256 bool matches =
false;
3258 builder.SetSurface(
DlISize(1, 1));
3259 builder.SetCompositor();
3260 builder.SetDartEntrypoint(std::move(entrypoint));
3261 builder.SetRenderTargetType(
3262 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2,
3265 auto engine = builder.LaunchEngine();
3266 ASSERT_TRUE(
engine.is_valid());
3268 context.GetCompositor().SetNextPresentCallback(
3276 context.GetCompositor().GetSurface(
layers[0]->backing_store);
3286 event.pixel_ratio = 1.0;
3291 ASSERT_TRUE(matches);
3296template <
typename T>
3299 std::string entrypoint,
3302 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(&pixelvalue);
3304 test, std::move(entrypoint), pixfmt,
3305 std::vector<uint8_t>(bytes, bytes +
sizeof(T)));
3308#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher) \
3309 TEST_F(EmbedderTest, SoftwareRenderingPixelFormats##test_name) { \
3310 expectSoftwareRenderingOutputMatches(*this, #dart_entrypoint, pixfmt, \
3328 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3332 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3349 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3353 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3370 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3374 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3385 std::shared_ptr<fml::AutoResetWaitableEvent>
latch;
3434 EXPECT_EQ(subject.
type, baseline.
type);
3442 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3443 uint64_t echoed_char;
3447 auto native_echo_event = [&](Dart_NativeArguments
args) {
3450 Dart_GetNativeArgument(
args, 0)));
3453 Dart_GetNativeArgument(
args, 1)));
3455 Dart_GetNativeArgument(
args, 2));
3457 Dart_GetNativeArgument(
args, 3));
3459 Dart_GetNativeArgument(
args, 4));
3464 Dart_GetNativeArgument(
args, 6)));
3466 message_latch->Signal();
3469 auto platform_task_runner = CreateNewThread(
"platform_thread");
3473 platform_task_runner->PostTask([&]() {
3474 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3483 context.AddNativeCallback(
3486 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3488 context.AddNativeCallback(
"EchoKeyEvent",
3492 ASSERT_TRUE(
engine.is_valid());
3502 .physical = 0x00070004,
3503 .logical = 0x00000000061,
3505 .synthesized =
false,
3508 platform_task_runner->PostTask([&]() {
3512 message_latch->Wait();
3515 EXPECT_EQ(echoed_char, 0x41llu);
3522 .physical = 0x00070005,
3523 .logical = 0x00000000062,
3525 .synthesized =
false,
3528 platform_task_runner->PostTask([&]() {
3532 message_latch->Wait();
3535 EXPECT_EQ(echoed_char, 0x2206llu);
3540 .timestamp = 1000000,
3542 .physical = 0x00070006,
3543 .logical = 0x00000000063,
3545 .synthesized =
true,
3548 platform_task_runner->PostTask([&]() {
3551 message_latch->Wait();
3554 EXPECT_EQ(echoed_char, 0llu);
3557 platform_task_runner->PostTask([&]() {
3561 shutdown_latch.
Wait();
3565 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3566 std::vector<FlutterKeyEvent> echoed_events;
3568 auto native_echo_event = [&](Dart_NativeArguments
args) {
3572 Dart_GetNativeArgument(
args, 1))),
3575 Dart_GetNativeArgument(
args, 0))),
3577 Dart_GetNativeArgument(
args, 2)),
3579 Dart_GetNativeArgument(
args, 3)),
3581 Dart_GetNativeArgument(
args, 5)),
3584 Dart_GetNativeArgument(
args, 6))),
3587 message_latch->Signal();
3590 auto platform_task_runner = CreateNewThread(
"platform_thread");
3594 platform_task_runner->PostTask([&]() {
3595 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3604 context.AddNativeCallback(
3607 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3609 context.AddNativeCallback(
"EchoKeyEvent",
3613 ASSERT_TRUE(
engine.is_valid());
3620 .physical = 0x00070004,
3621 .logical = 0x00000000061,
3623 .synthesized =
false,
3628 sample_event.timestamp = 1.0l;
3629 platform_task_runner->PostTask([&]() {
3631 message_latch->Signal();
3633 message_latch->Wait();
3636 EXPECT_EQ(echoed_events.size(), 0u);
3642 nullptr, &response_handle);
3646 .
channel =
"test/starts_echo",
3649 .response_handle = response_handle,
3652 platform_task_runner->PostTask([&]() {
3661 message_latch->Wait();
3663 EXPECT_EQ(echoed_events.size(), 1u);
3666 sample_event.timestamp = 10.0l;
3667 platform_task_runner->PostTask([&]() {
3670 message_latch->Wait();
3673 EXPECT_EQ(echoed_events.size(), 2u);
3676 platform_task_runner->PostTask([&]() {
3680 shutdown_latch.
Wait();
3692 auto platform_task_runner = CreateNewThread(
"platform_thread");
3694 platform_task_runner->PostTask([&]() {
3695 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3699 context.AddNativeCallback(
3702 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3703 context.AddNativeCallback(
3707 ASSERT_TRUE(
engine.is_valid());
3719 .physical = 0x00070005,
3720 .logical = 0x00000000062,
3726 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3729 event.synthesized =
true;
3730 platform_task_runner->PostTask([&]() {
3739 [](
bool handled,
void* untyped_user_data) {
3740 KeyEventUserData* user_data =
3741 reinterpret_cast<KeyEventUserData*>(untyped_user_data);
3742 EXPECT_EQ(handled, true);
3743 user_data->latch->Signal();
3747 user_data1.latch->Wait();
3749 platform_task_runner->PostTask([&]() {
3753 shutdown_latch.
Wait();
3765 auto platform_task_runner = CreateNewThread(
"platform_thread");
3767 platform_task_runner->PostTask([&]() {
3768 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3772 context.AddNativeCallback(
3775 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3777 context.AddNativeCallback(
3781 ASSERT_TRUE(
engine.is_valid());
3793 .physical = 0x00070005,
3794 .logical = 0x00000000062,
3796 .synthesized =
false,
3803 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3807 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3810 auto callback23 = [](
bool handled,
void* untyped_user_data) {
3813 EXPECT_EQ(handled,
false);
3817 platform_task_runner->PostTask([&]() {
3821 user_data2.latch->Wait();
3822 user_data3.latch->Wait();
3824 EXPECT_TRUE(user_data2.returned);
3825 EXPECT_TRUE(user_data3.returned);
3828 platform_task_runner->PostTask([&]() {
3832 shutdown_latch.
Wait();
3850 auto platform_task_runner = CreateNewThread(
"platform_thread");
3852 platform_task_runner->PostTask([&]() {
3853 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3854 context.SetVsyncCallback([&](intptr_t baton) {
3855 platform_task_runner->PostTask([baton = baton, &
engine, &vsync_latch]() {
3857 NanosFromEpoch(32));
3861 context.AddNativeCallback(
3871 ASSERT_TRUE(
engine.is_valid());
3878 event.pixel_ratio = 1.0;
3885 present_latch.
Wait();
3888 platform_task_runner->PostTask([&]() {
3892 shutdown_latch.
Wait();
3896 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3901 context.AddNativeCallback(
3904 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
3907 context.AddNativeCallback(
3908 "SignalNativeCount",
3910 [&check_latch](Dart_NativeArguments
args) { check_latch.
Signal(); }));
3913 ASSERT_TRUE(
engine.is_valid());
3924 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3930 ASSERT_TRUE(
engine.is_valid());
3938 callback_latch->
Signal();
3950 event.pixel_ratio = 1.0;
3951 event.physical_view_inset_top = 0.0;
3952 event.physical_view_inset_right = 0.0;
3953 event.physical_view_inset_bottom = 0.0;
3954 event.physical_view_inset_left = 0.0;
3958 callback_latch.
Wait();
3961#if defined(FML_OS_MACOSX)
3964 pthread_t tid = pthread_self();
3965 struct sched_param param;
3966 int policy = SCHED_OTHER;
3969 param.sched_priority = 10;
3972 param.sched_priority = 1;
3974 pthread_setschedparam(tid,
policy, ¶m);
3977TEST_F(EmbedderTest, EmbedderThreadHostUseCustomThreadConfig) {
3980 nullptr, MockThreadConfigSetter);
3984 struct sched_param ui_param;
3986 thread_host->GetTaskRunners().GetUITaskRunner()->PostTask([&] {
3987 pthread_t current_thread = pthread_self();
3988 pthread_getschedparam(current_thread, &ui_policy, &ui_param);
3989 ASSERT_EQ(ui_param.sched_priority, 10);
3995 struct sched_param io_param;
3996 thread_host->GetTaskRunners().GetIOTaskRunner()->PostTask([&] {
3997 pthread_t current_thread = pthread_self();
3998 pthread_getschedparam(current_thread, &io_policy, &io_param);
3999 ASSERT_EQ(io_param.sched_priority, 1);
4011 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4017 context.AddNativeCallback(
4020 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4021 context.AddNativeCallback(
4022 "SignalNativeCount",
4025 Dart_GetNativeArgument(
args, 0));
4026 ASSERT_EQ(count, 1);
4029 context.AddNativeCallback(
4030 "SignalNativeMessage",
4033 Dart_GetNativeArgument(
args, 0));
4034 ASSERT_EQ(
"PointerData(viewId: 0, x: 123.0, y: 456.0)",
message);
4039 ASSERT_TRUE(
engine.is_valid());
4046 pointer_event.
x = 123;
4047 pointer_event.
y = 456;
4048 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
4056 message_latch.
Wait();
4062 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4068 context.AddNativeCallback(
4071 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4072 context.AddNativeCallback(
4073 "SignalNativeMessage",
4076 Dart_GetNativeArgument(
args, 0));
4077 ASSERT_EQ(
"ViewID: 2",
message);
4082 ASSERT_TRUE(
engine.is_valid());
4088 metrics.
width = 800;
4098 EXPECT_TRUE(result->added);
4101 add_view_latch->
Signal();
4105 add_view_latch.
Wait();
4111 pointer_event.
x = 123;
4112 pointer_event.
y = 456;
4113 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
4120 message_latch.
Wait();
4124 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4130 context.AddNativeCallback(
4133 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4134 context.AddNativeCallback(
4135 "SignalNativeMessage",
4138 Dart_GetNativeArgument(
args, 0));
4139 ASSERT_EQ(
"Changed: [0]",
message);
4144 ASSERT_TRUE(
engine.is_valid());
4154 event.pixel_ratio = 1.5;
4161 message_latch.
Wait();
4165 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4171 context.AddNativeCallback(
4174 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4176 context.AddNativeCallback(
4177 "SignalNativeMessage",
4180 Dart_GetNativeArgument(
args, 0));
4184 ASSERT_EQ(
"Changed: [0]",
message);
4189 ASSERT_TRUE(
engine.is_valid());
4197 bad_event.
width = 200;
4211 event.pixel_ratio = 1.5;
4217 message_latch.
Wait();
4221 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4225 bool listening =
false;
4226 context.AddNativeCallback(
4230 EXPECT_STREQ(update->
channel,
"test/listen");
4241 ASSERT_TRUE(
engine.is_valid());
4248 ASSERT_TRUE(listening);
4252 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4255 static std::thread::id ffi_call_thread_id;
4256 static void (*ffi_signal_native_test)() = []() ->
void {
4257 ffi_call_thread_id = std::this_thread::get_id();
4261 Dart_FfiNativeResolver ffi_resolver = [](
const char*
name,
4262 uintptr_t args_n) ->
void* {
4263 if (std::string_view(
name) ==
"FFISignalNativeTest") {
4264 return reinterpret_cast<void*
>(ffi_signal_native_test);
4272 context.AddNativeCallback(
4274 Dart_SetFfiNativeResolver(Dart_RootLibrary(), ffi_resolver);
4277 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
4283 if (!
engine.is_valid()) {
4289 std::thread::id platform_thread_id;
4290 platform_task_runner->PostTask([&]() {
4291 platform_thread_id = std::this_thread::get_id();
4294 const auto task_runner_description =
4295 test_task_runner.GetFlutterTaskRunnerDescription();
4301 ASSERT_TRUE(
engine.is_valid());
4310 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
4315 ASSERT_EQ(platform_thread_id, ffi_call_thread_id);
static size_t GetVMLaunchCount()
The number of times the VM has been launched in the process. This call is inherently racy because the...
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
std::shared_ptr< fml::ConcurrentMessageLoop > GetConcurrentMessageLoop()
The concurrent message loop hosts threads that are used by the engine to perform tasks long running b...
const TaskRunners & GetTaskRunners() const
static std::unique_ptr< EmbedderThreadHost > CreateEmbedderOrEngineManagedThreadHost(const FlutterCustomTaskRunners *custom_task_runners, const flutter::ThreadConfigSetter &config_setter=fml::Thread::SetCurrentThreadName)
DartVM * GetDartVM()
Get a pointer to the Dart VM used by this running shell instance.
const Settings & GetSettings() const override
fml::WeakPtr< PlatformView > GetPlatformView()
Platform views may only be accessed on the platform task runner.
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
void SetPlatformTaskRunner(const FlutterTaskRunnerDescription *runner)
void SetSurface(DlISize surface_size)
void SetupVsyncCallback()
void SetLogTag(std::string tag)
void SetExecutableName(std::string executable_name)
void SetRenderTargetType(EmbedderTestBackingStoreProducer::RenderTargetType type, FlutterSoftwarePixelFormat software_pixfmt=kFlutterSoftwarePixelFormatNative32)
void SetDartEntrypoint(std::string entrypoint)
void AddCommandLineArgument(std::string arg)
void SetViewFocusChangeRequestCallback(const std::function< void(const FlutterViewFocusChangeRequest *)> &callback)
FlutterProjectArgs & GetProjectArgs()
void SetRenderTaskRunner(const FlutterTaskRunnerDescription *runner)
void AddDartEntrypointArgument(std::string arg)
void SetUITaskRunner(const FlutterTaskRunnerDescription *runner)
FlutterCompositor & GetCompositor()
UniqueEngine LaunchEngine() const
void SetCompositor(bool avoid_backing_store_cache=false, bool use_present_layers_callback=false)
UniqueEngine InitializeEngine() const
void SetPlatformMessageCallback(const std::function< void(const FlutterPlatformMessage *)> &callback)
A task runner that we expect the embedder to provide but whose implementation is a real FML task runn...
void SetDestructionCallback(VoidCallback callback)
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
void RunExpiredTasksNow()
virtual void PostTask(const fml::closure &task) override
virtual void PostDelayedTask(const fml::closure &task, fml::TimeDelta delay)
@ kDisplay
Suitable for threads which generate data for the display.
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
static constexpr TimeDelta FromNanoseconds(int64_t nanos)
static constexpr TimeDelta FromMilliseconds(int64_t millis)
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
FlutterEngineResult FlutterEngineRunTask(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterTask *task)
Inform the engine to run the specified task. This task has been given to the embedder via the Flutter...
FlutterEngineResult FlutterEngineOnVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, intptr_t baton, uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos)
Notify the engine that a vsync event occurred. A baton passed to the platform via the vsync callback ...
FlutterEngineResult FlutterEngineUpdateLocales(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterLocale **locales, size_t locales_count)
Notify a running engine instance that the locale has been updated. The preferred locale must be the f...
FlutterEngineResult FlutterEngineSendViewFocusEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterViewFocusEvent *event)
Notifies the engine that platform view focus state has changed.
FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Schedule a new frame to redraw the content.
FlutterEngineResult FlutterEngineSendWindowMetricsEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent *flutter_metrics)
uint64_t FlutterEngineGetCurrentTime()
Get the current time in nanoseconds from the clock used by the flutter engine. This is the system mon...
FlutterEngineResult FlutterEngineSetNextFrameCallback(FLUTTER_API_SYMBOL(FlutterEngine) engine, VoidCallback callback, void *user_data)
Schedule a callback to be called after the next frame is drawn. This must be called from the platform...
FLUTTER_EXPORT FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Stops running the Flutter engine instance. After this call, the embedder is also guaranteed that no m...
FlutterEngineResult FlutterEnginePostCallbackOnAllNativeThreads(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterNativeThreadCallback callback, void *user_data)
Schedule a callback to be run on all engine managed threads. The engine will attempt to service this ...
FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterAddViewInfo *info)
Adds a view.
FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterDataCallback data_callback, void *user_data, FlutterPlatformMessageResponseHandle **response_out)
Creates a platform message response handle that allows the embedder to set a native callback for a re...
FlutterEngineResult FlutterEngineCollectAOTData(FlutterEngineAOTData data)
Collects the AOT data.
FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
bool FlutterEngineRunsAOTCompiledDartCode(void)
Returns if the Flutter engine instance will run AOT compiled Dart code. This call has no threading re...
FlutterEngineResult FlutterEngineReloadSystemFonts(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Reloads the system fonts in engine.
FlutterEngineResult FlutterEngineSendPointerEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPointerEvent *pointers, size_t events_count)
FlutterEngineResult FlutterEngineRunInitialized(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Runs an initialized engine instance. An engine can be initialized via FlutterEngineInitialize....
FlutterEngineResult FlutterEngineNotifyLowMemoryWarning(FLUTTER_API_SYMBOL(FlutterEngine) raw_engine)
Posts a low memory notification to a running engine instance. The engine will do its best to release ...
FlutterEngineResult FlutterEngineSendKeyEvent(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Sends a key event to the engine. The framework will decide whether to handle this event in a synchron...
FlutterEngineResult FlutterEngineSendPlatformMessageResponse(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
Send a response from the native side to a platform message from the Dart Flutter application.
FLUTTER_EXPORT FlutterEngineResult FlutterEngineRemoveView(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterRemoveViewInfo *info)
Removes a view.
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
FlutterEngineResult FlutterEngineCreateAOTData(const FlutterEngineAOTDataSource *source, FlutterEngineAOTData *data_out)
Creates the necessary data structures to launch a Flutter Dart application in AOT mode....
FlutterKeyEventDeviceType
@ kFlutterKeyEventDeviceTypeKeyboard
@ kFlutterKeyEventDeviceTypeDirectionalPad
@ kFlutterKeyEventDeviceTypeHdmi
@ kFlutterKeyEventDeviceTypeJoystick
@ kFlutterKeyEventDeviceTypeGamepad
@ kFlutterLayerContentTypePlatformView
Indicates that the contents of this layer are determined by the embedder.
@ kFlutterLayerContentTypeBackingStore
FlutterEngineAOTDataSourceType
AOT data source type.
@ kFlutterEngineAOTDataSourceTypeElfPath
FlutterSoftwarePixelFormat
@ kFlutterSoftwarePixelFormatRGBA4444
@ kFlutterSoftwarePixelFormatRGBA8888
@ kFlutterSoftwarePixelFormatBGRA8888
@ kFlutterSoftwarePixelFormatGray8
@ kFlutterSoftwarePixelFormatRGB565
void(* VoidCallback)(void *)
@ kFlutterKeyEventTypeDown
@ kFlutterKeyEventTypeRepeat
@ kFlutterBackingStoreTypeSoftware2
@ kFlutterBackingStoreTypeSoftware
Specified an software allocation for Flutter to render into using the CPU.
FlutterSize FlutterSizeMake(double width, double height)
FlutterRect FlutterRectMakeLTRB(double l, double t, double r, double b)
FlutterPoint FlutterPointMake(double x, double y)
flutter::EmbedderEngine * ToEmbedderEngine(const FlutterEngine &engine)
#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_UNREACHABLE()
TEST_F(DisplayListTest, Defaults)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
sk_sp< SkSurface > CreateRenderSurface(const FlutterLayer &layer, GrDirectContext *context)
FlutterKeyEventType UnserializeKeyEventType(uint64_t kind)
bool SurfacePixelDataMatchesBytes(SkSurface *surface, const std::vector< uint8_t > &bytes)
const char * GetSourcePath()
testing::EmbedderTest EmbedderTest
void ExpectKeyEventEq(const FlutterKeyEvent &subject, const FlutterKeyEvent &baseline)
constexpr const char * kDefaultAOTAppELFFileName
bool ImageMatchesFixture(const std::string &fixture_file_name, const sk_sp< SkImage > &scene_image)
TEST(NativeAssetsManagerTest, NoAvailableAssets)
static void expectSoftwareRenderingOutputMatches(EmbedderTest &test, std::string entrypoint, FlutterSoftwarePixelFormat pixfmt, const std::vector< uint8_t > &bytes)
FlutterKeyEventDeviceType UnserializeKeyEventDeviceType(uint64_t source)
constexpr int64_t kFlutterImplicitViewId
impeller::ISize32 DlISize
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network policy
DEF_SWITCHES_START aot vmservice shared library name
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
bool operator==(const ViewportMetrics &a, const ViewportMetrics &b)
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
std::string JoinPaths(std::initializer_list< std::string > components)
internal::CopyableLambda< T > MakeCopyable(T lambda)
FlutterAddViewCallback add_view_callback
FlutterViewId view_id
The identifier for the view to add. This must be unique.
const FlutterWindowMetricsEvent * view_metrics
FlutterBackingStoreType type
Specifies the type of backing store.
FlutterSoftwareBackingStore software
The description of the software backing store.
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStorePresentInfo).
An update to whether a message channel has a listener set or not.
bool listening
True if a listener has been set, false if one has been cleared.
const char * channel
The name of the channel.
FlutterEngineAOTDataSourceType type
const char * elf_path
Absolute path to an ELF library file.
size_t struct_size
The size of this struct. Must be sizeof(FlutterKeyEvent).
FlutterKeyEventDeviceType device_type
The source device for the key event.
FlutterKeyEventType type
The event kind.
FlutterLayerContentType type
const FlutterBackingStore * backing_store
FlutterBackingStorePresentInfo * backing_store_present_info
const FlutterPlatformView * platform_view
size_t struct_size
This size of this struct. Must be sizeof(FlutterLayer).
FlutterSize size
The size of the layer (in physical pixels).
const char * language_code
size_t struct_size
This size of this struct. Must be sizeof(FlutterLocale).
const char * country_code
const char * variant_code
size_t struct_size
The size of this struct. Must be sizeof(FlutterPointerEvent).
FlutterViewId view_id
The identifier of the view that received the pointer event.
double y
The y coordinate of the pointer event in physical pixels.
double x
The x coordinate of the pointer event in physical pixels.
FlutterPointerPhase phase
const uint8_t * isolate_snapshot_data
const uint8_t * vm_snapshot_data
size_t isolate_snapshot_instructions_size
const uint8_t * vm_snapshot_instructions
size_t isolate_snapshot_data_size
size_t vm_snapshot_instructions_size
size_t vm_snapshot_data_size
const uint8_t * isolate_snapshot_instructions
A structure to represent a rectangle.
A region represented by a collection of non-overlapping rectangles.
size_t struct_size
The size of this struct. Must be sizeof(FlutterRegion).
FlutterRemoveViewCallback remove_view_callback
size_t height
The number of rows in the allocation.
FlutterViewFocusState state
The focus state of the view.
FlutterViewId view_id
The identifier of the view that received the focus event.
FlutterViewFocusDirection direction
The direction in which the focus transitioned across [FlutterView]s.
size_t struct_size
The size of this struct. Must be sizeof(FlutterWindowMetricsEvent).
size_t height
Physical height of the window.
size_t min_height_constraint
size_t min_width_constraint
int64_t view_id
The view that this event is describing.
double pixel_ratio
Scale factor for the physical screen.
size_t max_width_constraint
size_t max_height_constraint
size_t width
Physical width of the window.
MappingCallback isolate_snapshot_instr
MappingCallback isolate_snapshot_data
MappingCallback vm_snapshot_data
MappingCallback vm_snapshot_instr
MappingCallback dart_library_sources_kernel
std::shared_ptr< fml::AutoResetWaitableEvent > latch
The ThreadConfig is the thread info include thread name, thread priority.
#define CREATE_NATIVE_ENTRY(native_entry)