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_thread = std::make_unique<fml::Thread>(
"test_ui_thread");
208 auto ui_task_runner = ui_thread->GetTaskRunner();
209 auto platform_thread = std::make_unique<fml::Thread>(
"test_platform_thread");
210 auto platform_task_runner = platform_thread->GetTaskRunner();
211 static std::mutex engine_mutex;
216 std::scoped_lock lock(engine_mutex);
224 std::scoped_lock lock(engine_mutex);
234 context.AddNativeCallback(
237 ASSERT_TRUE(ui_task_runner->RunsTasksOnCurrentThread());
238 signal_latch_ui.Signal();
241 platform_task_runner->PostTask([&]() {
243 const auto ui_task_runner_description =
244 test_ui_task_runner.GetFlutterTaskRunnerDescription();
245 const auto platform_task_runner_description =
246 test_platform_task_runner.GetFlutterTaskRunnerDescription();
253 ASSERT_TRUE(platform_task_runner->RunsTasksOnCurrentThread());
254 signal_latch_platform.
Signal();
257 std::scoped_lock lock(engine_mutex);
261 ASSERT_TRUE(
engine.is_valid());
263 signal_latch_ui.
Wait();
264 signal_latch_platform.
Wait();
267 platform_task_runner->PostTask([&] {
269 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
277 platform_thread.reset();
281 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
282 auto ui_task_runner = CreateNewThread(
"test_ui_thread");
283 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
284 static std::mutex engine_mutex;
299 std::scoped_lock lock(engine_mutex);
308 platform_task_runner->PostTask([&]() {
310 const auto ui_task_runner_description =
311 test_ui_task_runner.GetFlutterTaskRunnerDescription();
312 const auto platform_task_runner_description =
313 test_platform_task_runner.GetFlutterTaskRunnerDescription();
317 std::scoped_lock lock(engine_mutex);
324 engine_ptr =
engine.get();
334 platform_task_runner->PostTask([&] {
336 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
342 ui_task_runner->PostDelayedTask([&]() { kill_latch.
Signal(); },
348 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
349 auto task_runner = CreateNewThread(
"test_thread");
362 context.AddNativeCallback(
365 ASSERT_TRUE(task_runner->RunsTasksOnCurrentThread());
366 signal_latch_ui.Signal();
369 task_runner->PostTask([&]() {
371 const auto task_runner_description =
372 test_task_runner.GetFlutterTaskRunnerDescription();
379 ASSERT_TRUE(task_runner->RunsTasksOnCurrentThread());
380 signal_latch_platform.
Signal();
383 ASSERT_TRUE(
engine.is_valid());
385 signal_latch_ui.
Wait();
386 signal_latch_platform.
Wait();
389 task_runner->PostTask([&] {
391 task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
397 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
398 auto ui_task_runner = CreateNewThread(
"test_ui_thread");
412 context.AddNativeCallback(
414 ASSERT_TRUE(ui_task_runner->RunsTasksOnCurrentThread());
415 signal_latch.Signal();
418 ui_task_runner->PostTask([&]() {
420 const auto task_runner_description =
421 test_task_runner.GetFlutterTaskRunnerDescription();
426 ASSERT_TRUE(
engine.is_valid());
431 ui_task_runner->PostTask([&] {
433 ui_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
439 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
444 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
445 static std::mutex engine_mutex;
446 static bool signaled_once =
false;
447 static std::atomic<bool> destruction_callback_called =
false;
452 std::scoped_lock lock(engine_mutex);
463 signaled_once =
true;
464 ASSERT_TRUE(
engine.is_valid());
469 [](
void*
user_data) { destruction_callback_called =
true; });
471 platform_task_runner->PostTask([&]() {
473 const auto task_runner_description =
474 test_task_runner.GetFlutterTaskRunnerDescription();
478 std::scoped_lock lock(engine_mutex);
480 ASSERT_TRUE(
engine.is_valid());
485 ASSERT_TRUE(
engine.is_valid());
491 std::scoped_lock lock(engine_mutex);
497 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
501 ASSERT_TRUE(signaled_once);
502 signaled_once =
false;
504 ASSERT_TRUE(destruction_callback_called);
505 destruction_callback_called =
false;
508TEST(EmbedderTestNoFixture, CanGetCurrentTimeInNanoseconds) {
517 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
521 ASSERT_TRUE(
engine.is_valid());
528 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
533 std::string isolate_message;
541 if (strcmp(
message->channel,
"flutter/isolate") == 0) {
542 isolate_message = {reinterpret_cast<const char*>(message->message),
543 message->message_size};
547 engine = builder.LaunchEngine();
548 ASSERT_TRUE(
engine.is_valid());
553 ASSERT_EQ(isolate_message.find(
"isolates/"), 0ul);
558 thread.GetTaskRunner()->PostTask(
571 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
575 context.AddNativeCallback(
580 ASSERT_TRUE(
engine.is_valid());
588 ASSERT_NE(response_handle,
nullptr);
603 std::thread::id thread_id;
608 captures.thread_id = std::this_thread::get_id();
609 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
615 context.AddNativeCallback(
618 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
621 ASSERT_TRUE(
engine.is_valid());
623 static std::string kMessageData =
"Hello from embedder.";
628 ASSERT_EQ(
size, kMessageData.size());
629 ASSERT_EQ(strncmp(
reinterpret_cast<const char*
>(kMessageData.data()),
630 reinterpret_cast<const char*
>(
data),
size),
632 auto captures =
reinterpret_cast<Captures*
>(
user_data);
633 ASSERT_EQ(captures->thread_id, std::this_thread::get_id());
634 captures->latch.Signal();
642 message.channel =
"test_channel";
643 message.message =
reinterpret_cast<const uint8_t*
>(kMessageData.data());
644 message.message_size = kMessageData.size();
645 message.response_handle = response_handle;
656 captures.latch.Wait();
665 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
670 const std::string message_data =
"Hello but don't call me back.";
673 context.AddNativeCallback(
676 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
677 context.AddNativeCallback(
678 "SignalNativeMessage",
680 ([&
message, &message_data](Dart_NativeArguments
args) {
682 Dart_GetNativeArgument(
args, 0));
683 ASSERT_EQ(received_message, message_data);
689 ASSERT_TRUE(
engine.is_valid());
694 platform_message.
channel =
"test_channel";
696 reinterpret_cast<const uint8_t*
>(message_data.data());
710 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
716 context.AddNativeCallback(
719 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
720 context.AddNativeCallback(
721 "SignalNativeMessage",
724 Dart_GetNativeArgument(
args, 0));
725 ASSERT_EQ(
"true", received_message);
731 ASSERT_TRUE(
engine.is_valid());
736 platform_message.
channel =
"test_channel";
737 platform_message.
message =
nullptr;
752 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
757 ASSERT_TRUE(
engine.is_valid());
761 platform_message.
channel =
"test_channel";
762 platform_message.
message =
nullptr;
776 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
780 context.SetLogMessageCallback(
781 [&callback_latch](
const char* tag,
const char*
message) {
782 EXPECT_EQ(std::string(tag),
"flutter");
783 EXPECT_EQ(std::string(
message),
"hello world");
787 ASSERT_TRUE(
engine.is_valid());
788 callback_latch.
Wait();
795 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
800 context.SetLogMessageCallback(
801 [&callback_latch](
const char* tag,
const char*
message) {
802 EXPECT_EQ(std::string(tag),
"butterfly");
803 EXPECT_EQ(std::string(
message),
"hello world");
807 ASSERT_TRUE(
engine.is_valid());
808 callback_latch.
Wait();
816 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
835 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
842 std::vector<std::string> callback_args;
843 auto nativeArgumentsCallback = [&callback_args,
844 &callback_latch](Dart_NativeArguments
args) {
845 Dart_Handle exception =
nullptr;
851 context.AddNativeCallback(
"NativeArgumentsCallback",
854 callback_latch.
Wait();
855 ASSERT_EQ(callback_args[0],
"foo");
856 ASSERT_EQ(callback_args[1],
"bar");
869 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
880 ASSERT_TRUE(
engine.is_valid());
884 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
891 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
895 context.GetCompositor().SetNextPresentCallback(
908 event.pixel_ratio = 1.0;
911 ASSERT_TRUE(
engine.is_valid());
916 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
924 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
928 context.GetCompositor().SetNextPresentCallback(
941 event.pixel_ratio = 1.0;
944 ASSERT_TRUE(
engine.is_valid());
953#if FML_OS_MACOSX && FML_ARCH_CPU_ARM64
955 DISABLED_CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
958 CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
961 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
969 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
973 auto scene_image = context.GetNextSceneImage();
975 context.GetCompositor().SetNextPresentCallback(
993 .rects = paint_region_rects,
997 .paint_region = &paint_region,
1008 ASSERT_EQ(*
layers[0], layer);
1024 ASSERT_EQ(*
layers[1], layer);
1040 .rects = paint_region_rects,
1044 .paint_region = &paint_region,
1055 ASSERT_EQ(*
layers[2], layer);
1071 ASSERT_EQ(*
layers[3], layer);
1087 .rects = paint_region_rects,
1091 .paint_region = &paint_region,
1102 ASSERT_EQ(*
layers[4], layer);
1108 context.GetCompositor().SetPlatformViewRendererCallback(
1110 ) -> sk_sp<SkImage> {
1113 auto canvas =
surface->getCanvas();
1120 paint.setColor(SK_ColorGREEN);
1121 paint.setAlpha(127);
1124 canvas->drawRect(rect, paint);
1130 paint.setColor(SK_ColorMAGENTA);
1131 paint.setAlpha(127);
1134 canvas->drawRect(rect, paint);
1140 <<
"Test was asked to composite an unknown platform view.";
1143 return surface->makeImageSnapshot();
1146 context.AddNativeCallback(
1149 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1158 event.pixel_ratio = 1.0;
1159 event.physical_view_inset_top = 0.0;
1160 event.physical_view_inset_right = 0.0;
1161 event.physical_view_inset_bottom = 0.0;
1162 event.physical_view_inset_left = 0.0;
1165 ASSERT_TRUE(
engine.is_valid());
1172 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1180 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1188 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1192 auto scene_image = context.GetNextSceneImage();
1194 context.GetCompositor().SetNextPresentCallback(
1212 .rects = paint_region_rects,
1216 .paint_region = &paint_region,
1227 ASSERT_EQ(*
layers[0], layer);
1243 ASSERT_EQ(*
layers[1], layer);
1249 context.GetCompositor().SetPlatformViewRendererCallback(
1251 ) -> sk_sp<SkImage> {
1254 auto canvas =
surface->getCanvas();
1261 paint.setColor(SK_ColorGREEN);
1262 paint.setAlpha(127);
1265 canvas->drawRect(rect, paint);
1271 <<
"Test was asked to composite an unknown platform view.";
1274 return surface->makeImageSnapshot();
1277 context.AddNativeCallback(
1280 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1289 event.pixel_ratio = 1.0;
1290 event.physical_view_inset_top = 0.0;
1291 event.physical_view_inset_right = 0.0;
1292 event.physical_view_inset_bottom = 0.0;
1293 event.physical_view_inset_left = 0.0;
1296 ASSERT_TRUE(
engine.is_valid());
1302#if !defined(FML_OS_LINUX)
1303 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1306 "compositor_platform_layer_with_no_overlay.png", scene_image));
1309 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1317 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1325 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1329 auto scene_image = context.GetNextSceneImage();
1331 context.GetCompositor().SetNextPresentCallback(
1349 .rects = paint_region_rects,
1353 .paint_region = &paint_region,
1364 ASSERT_EQ(*
layers[0], layer);
1380 ASSERT_EQ(*
layers[1], layer);
1386 context.GetCompositor().SetPlatformViewRendererCallback(
1388 ) -> sk_sp<SkImage> {
1391 auto canvas =
surface->getCanvas();
1398 paint.setColor(SK_ColorGREEN);
1399 paint.setAlpha(127);
1402 canvas->drawRect(rect, paint);
1408 <<
"Test was asked to composite an unknown platform view.";
1411 return surface->makeImageSnapshot();
1414 context.AddNativeCallback(
1417 [&latch](Dart_NativeArguments
args) { latch.
CountDown(); }));
1426 event.pixel_ratio = 1.0;
1427 event.physical_view_inset_top = 0.0;
1428 event.physical_view_inset_right = 0.0;
1429 event.physical_view_inset_bottom = 0.0;
1430 event.physical_view_inset_left = 0.0;
1433 ASSERT_TRUE(
engine.is_valid());
1439#if !defined(FML_OS_LINUX)
1440 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1443 "compositor_platform_layer_with_no_overlay.png", scene_image));
1446 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1453 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1457 ASSERT_TRUE(
engine.is_valid());
1465 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1469 ASSERT_TRUE(
engine.is_valid());
1480 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1484 ASSERT_TRUE(
engine.is_valid());
1497 event.pixel_ratio = 1.0;
1498 event.physical_view_inset_top = 0.0;
1499 event.physical_view_inset_right = 0.0;
1500 event.physical_view_inset_bottom = 0.0;
1501 event.physical_view_inset_left = 0.0;
1511 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1517 context.AddNativeCallback(
1520 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1523 context.AddNativeCallback(
"SignalNativeMessage",
1527 Dart_GetNativeArgument(
args, 0));
1532 ASSERT_TRUE(
engine.is_valid());
1538 metrics.
width = 800;
1548 EXPECT_TRUE(result->added);
1551 message_latch.
Wait();
1552 ASSERT_EQ(
"View IDs: [0, 123]",
message);
1559 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1564 context.AddNativeCallback(
1567 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
1570 context.AddNativeCallback(
1571 "SignalNativeCount",
1573 [&check_latch](Dart_NativeArguments
args) { check_latch.
Signal(); }));
1576 ASSERT_TRUE(
engine.is_valid());
1583 metrics.
width = 800;
1593 EXPECT_TRUE(result->added);
1604 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1610 context.AddNativeCallback(
1613 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1616 context.AddNativeCallback(
"SignalNativeMessage",
1620 Dart_GetNativeArgument(
args, 0));
1625 ASSERT_TRUE(
engine.is_valid());
1632 metrics.
width = 800;
1642 ASSERT_TRUE(result->added);
1645 message_latch.
Wait();
1646 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1653 EXPECT_TRUE(result->removed);
1656 message_latch.
Wait();
1657 ASSERT_EQ(
message,
"View IDs: [0]");
1663 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1665 std::mutex engine_mutex;
1667 auto render_thread = CreateNewThread(
"custom_render_thread");
1670 std::scoped_lock engine_lock(engine_mutex);
1679 &render_task_runner.GetFlutterTaskRunnerDescription());
1682 context.AddNativeCallback(
1685 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1688 std::scoped_lock lock(engine_mutex);
1692 ASSERT_TRUE(
engine.is_valid());
1700 metrics.
width = 800;
1711 ASSERT_TRUE(result->added);
1712 auto add_view_latch =
1714 add_view_latch->
Signal();
1717 add_view_latch.
Wait();
1719 std::atomic_bool view_available =
true;
1724 render_thread->PostTask([&] {
1725 std::this_thread::sleep_for(std::chrono::milliseconds(50));
1727 EXPECT_TRUE(view_available);
1728 raster_thread_latch.
Signal();
1734 remove_view_info.
view_id = 123;
1735 remove_view_info.
user_data = &remove_view_latch;
1738 ASSERT_TRUE(result->removed);
1739 auto remove_view_latch =
1741 remove_view_latch->
Signal();
1746 remove_view_latch.
Wait();
1750 view_available =
false;
1751 raster_thread_latch.
Wait();
1761 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1766 ASSERT_TRUE(
engine.is_valid());
1781 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1787 context.AddNativeCallback(
1790 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1793 context.AddNativeCallback(
"SignalNativeMessage",
1797 Dart_GetNativeArgument(
args, 0));
1802 ASSERT_TRUE(
engine.is_valid());
1808 std::atomic<int> count = 0;
1815 metrics.
width = 800;
1826 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
1828 int count = captures->count.fetch_add(1);
1831 ASSERT_TRUE(result->added);
1833 EXPECT_FALSE(result->added);
1834 captures->failure_latch.Signal();
1838 message_latch.
Wait();
1839 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1840 ASSERT_FALSE(captures.failure_latch.IsSignaledForTest());
1844 captures.failure_latch.Wait();
1845 ASSERT_EQ(captures.count, 2);
1853 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1859 context.AddNativeCallback(
1862 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1865 context.AddNativeCallback(
"SignalNativeMessage",
1869 Dart_GetNativeArgument(
args, 0));
1874 ASSERT_TRUE(
engine.is_valid());
1881 metrics.
width = 800;
1891 ASSERT_TRUE(result->added);
1894 message_latch.
Wait();
1895 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1902 ASSERT_TRUE(result->removed);
1905 message_latch.
Wait();
1906 ASSERT_EQ(
message,
"View IDs: [0]");
1910 message_latch.
Wait();
1911 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1918 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1923 ASSERT_TRUE(
engine.is_valid());
1931 EXPECT_FALSE(result->removed);
1944 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
1950 context.AddNativeCallback(
1953 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
1955 std::atomic<int> message_count = 0;
1956 context.AddNativeCallback(
"SignalNativeMessage",
1958 message_count.fetch_add(1);
1962 ASSERT_TRUE(
engine.is_valid());
1979 metrics123.
width = 800;
1986 metrics456.
width = 800;
2006 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2008 ASSERT_TRUE(result->added);
2009 ASSERT_FALSE(captures->add_first_view.IsSignaledForTest());
2010 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
2011 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2012 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2014 captures->add_first_view.Signal();
2020 add_duplicate_view_info.
view_id = 123;
2022 add_duplicate_view_info.
user_data = &captures;
2025 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2027 ASSERT_FALSE(result->added);
2028 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2029 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
2030 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2031 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2033 captures->add_duplicate_view.Signal();
2039 add_second_view_info.
view_id = 456;
2041 add_second_view_info.
user_data = &captures;
2044 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2046 ASSERT_TRUE(result->added);
2047 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2048 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
2049 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
2050 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2052 captures->add_second_view.Signal();
2058 remove_second_view_info.
view_id = 456;
2059 remove_second_view_info.
user_data = &captures;
2062 auto captures =
reinterpret_cast<Captures*
>(result->user_data);
2064 ASSERT_TRUE(result->removed);
2065 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
2066 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
2067 ASSERT_TRUE(captures->add_second_view.IsSignaledForTest());
2068 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
2070 captures->remove_second_view.Signal();
2080 captures.remove_second_view.Wait();
2081 captures.add_second_view.Wait();
2082 captures.add_duplicate_view.Wait();
2083 captures.add_first_view.Wait();
2084 ASSERT_EQ(message_count, 3);
2091 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2098 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2101 context.GetCompositor().SetPresentCallback(
2118 ASSERT_TRUE(
engine.is_valid());
2123 metrics0.
width = 800;
2133 metrics123.
width = 800;
2143 ASSERT_TRUE(result->added);
2159 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2160 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
2162 static std::mutex engine_mutex;
2165 std::scoped_lock lock(engine_mutex);
2166 if (!
engine.is_valid()) {
2172 std::vector<FlutterViewFocusChangeRequest> received_requests;
2173 platform_task_runner->PostTask([&]() {
2177 const auto platform_task_runner_description =
2178 test_platform_task_runner.GetFlutterTaskRunnerDescription();
2182 EXPECT_TRUE(platform_task_runner->RunsTasksOnCurrentThread());
2183 received_requests.push_back(*request);
2187 ASSERT_TRUE(
engine.is_valid());
2191 std::vector<FlutterViewFocusChangeRequest> expected_requests{
2197 ASSERT_EQ(received_requests.size(), expected_requests.size());
2198 for (
size_t i = 0;
i < received_requests.size(); ++
i) {
2199 ASSERT_TRUE(received_requests[
i] == expected_requests[
i]);
2204 std::scoped_lock lock(engine_mutex);
2210 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
2216 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2222 std::string last_event;
2224 context.AddNativeCallback(
2227 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
2228 context.AddNativeCallback(
"NotifyStringValue",
2230 const auto message_from_dart =
2232 Dart_GetNativeArgument(
args, 0));
2233 last_event = message_from_dart;
2238 ASSERT_TRUE(
engine.is_valid());
2253 ASSERT_EQ(last_event,
2254 "1 ViewFocusState.focused ViewFocusDirection.undefined");
2266 ASSERT_EQ(last_event,
2267 "2 ViewFocusState.unfocused ViewFocusDirection.backward");
2288 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2296 context.GetCompositor().GetGrContext(),
2297 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2300 struct CompositorUserData {
2307 bool second_expected;
2308 bool third_expected;
2310 int backing_stores_created;
2312 CompositorUserData compositor_user_data{
2313 .producer = &producer,
2314 .backing_stores_created = 0,
2319 .
user_data =
reinterpret_cast<void*
>(&compositor_user_data),
2320 .create_backing_store_callback =
2324 EXPECT_TRUE(config->
view_id == 0 ||
2325 config->
view_id == kSecondViewId ||
2326 config->
view_id == kThirdViewId);
2327 auto compositor_user_data =
2328 reinterpret_cast<CompositorUserData*
>(
user_data);
2329 compositor_user_data->backing_stores_created += 1;
2330 bool result = compositor_user_data->producer->Create(
2331 config, backing_store_out);
2334 backing_store_out->user_data =
2335 reinterpret_cast<void*
>(config->
view_id);
2340 .present_layers_callback =
nullptr,
2341 .avoid_backing_store_cache =
false,
2342 .present_view_callback =
2344 EXPECT_EQ(info->layers_count, 1u);
2347 int64_t store_view_id =
reinterpret_cast<int64_t
>(
2348 info->layers[0]->backing_store->user_data);
2349 EXPECT_EQ(store_view_id, info->view_id);
2350 auto compositor_user_data =
2351 reinterpret_cast<CompositorUserData*
>(info->user_data);
2353 switch (info->view_id) {
2355 compositor_user_data->latch_implicit.Signal();
2358 EXPECT_TRUE(compositor_user_data->second_expected);
2359 compositor_user_data->latch_second.Signal();
2362 EXPECT_TRUE(compositor_user_data->third_expected);
2363 compositor_user_data->latch_third.Signal();
2372 compositor_user_data.second_expected =
true;
2373 compositor_user_data.third_expected =
false;
2378 ASSERT_TRUE(
engine.is_valid());
2403 add_view_info.
view_id = kSecondViewId;
2406 ASSERT_TRUE(result->added);
2411 compositor_user_data.latch_implicit.Wait();
2412 compositor_user_data.latch_second.Wait();
2416 compositor_user_data.second_expected =
false;
2417 compositor_user_data.third_expected =
true;
2418 EXPECT_EQ(compositor_user_data.backing_stores_created, 2);
2423 remove_view_info.
view_id = kSecondViewId;
2426 ASSERT_TRUE(result->removed);
2431 add_view_info.
view_id = kThirdViewId;
2432 metrics_add.
view_id = kThirdViewId;
2436 compositor_user_data.latch_implicit.Wait();
2437 compositor_user_data.latch_third.Wait();
2438 EXPECT_EQ(compositor_user_data.backing_stores_created, 3);
2442 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2447 context.AddNativeCallback(
2450 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
2453 context.AddNativeCallback(
2454 "SignalNativeCount",
2457 Dart_GetNativeArgument(
args, 0)),
2463 ASSERT_TRUE(
engine.is_valid());
2482 std::vector<const FlutterLocale*> locales;
2483 locales.push_back(&locale1);
2484 locales.push_back(&locale2);
2501 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2503 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2507 ASSERT_TRUE(
engine.is_valid());
2512 std::vector<std::string> supported_locales;
2513 supported_locales.push_back(
"es");
2514 supported_locales.push_back(
"MX");
2515 supported_locales.push_back(
"");
2516 auto result = shell.
GetPlatformView()->ComputePlatformResolvedLocales(
2519 ASSERT_EQ((*result).size(), supported_locales.size());
2520 ASSERT_EQ((*result)[0], supported_locales[0]);
2521 ASSERT_EQ((*result)[1], supported_locales[1]);
2522 ASSERT_EQ((*result)[2], supported_locales[2]);
2533 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2541 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2544 auto rendered_scene = context.GetNextSceneImage();
2547 context.GetCompositor().SetNextPresentCallback(
2564 .rects = paint_region_rects,
2568 .paint_region = &paint_region,
2579 ASSERT_EQ(*
layers[0], layer);
2595 ASSERT_EQ(*
layers[1], layer);
2601 context.GetCompositor().SetPlatformViewRendererCallback(
2603 GrDirectContext* context) -> sk_sp<SkImage> {
2606 auto canvas =
surface->getCanvas();
2613 paint.setColor(SK_ColorGREEN);
2614 paint.setAlpha(127);
2617 canvas->drawRect(rect, paint);
2622 <<
"Test was asked to composite an unknown platform view.";
2625 return surface->makeImageSnapshot();
2635 event.pixel_ratio = 1.0;
2636 event.physical_view_inset_top = 0.0;
2637 event.physical_view_inset_right = 0.0;
2638 event.physical_view_inset_bottom = 0.0;
2639 event.physical_view_inset_left = 0.0;
2642 ASSERT_TRUE(
engine.is_valid());
2649#if !defined(FML_OS_LINUX)
2650 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
2657 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2664 ASSERT_TRUE(
engine.is_valid());
2676 size_t worker_count = 0;
2683 auto platform_task_runner = CreateNewThread(
"platform_thread");
2685 platform_task_runner->PostTask([&]() {
2686 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2692 ASSERT_TRUE(
engine.is_valid());
2705 const auto engine_threads_count = worker_count + 4u;
2715 std::mutex captures_mutex;
2717 std::set<std::thread::id> thread_ids;
2719 size_t platform_threads_count = 0;
2720 size_t render_threads_count = 0;
2721 size_t ui_threads_count = 0;
2722 size_t worker_threads_count = 0;
2724 explicit Captures(
size_t count) : latch(count) {}
2727 Captures captures(engine_threads_count);
2729 platform_task_runner->PostTask([&]() {
2733 auto captures = reinterpret_cast<Captures*>(baton);
2735 std::scoped_lock lock(captures->captures_mutex);
2737 case kFlutterNativeThreadTypeRender:
2738 captures->render_threads_count++;
2740 case kFlutterNativeThreadTypeWorker:
2741 captures->worker_threads_count++;
2743 case kFlutterNativeThreadTypeUI:
2744 captures->ui_threads_count++;
2746 case kFlutterNativeThreadTypePlatform:
2747 captures->platform_threads_count++;
2750 captures->thread_ids.insert(std::this_thread::get_id());
2752 captures->latch.CountDown();
2758 captures.latch.Wait();
2759 ASSERT_EQ(captures.thread_ids.size(), engine_threads_count);
2760 ASSERT_EQ(captures.platform_threads_count, 1u);
2761 ASSERT_EQ(captures.render_threads_count, 1u);
2762 ASSERT_EQ(captures.ui_threads_count, 1u);
2763 ASSERT_EQ(captures.worker_threads_count, worker_count + 1u );
2764 EXPECT_GE(captures.worker_threads_count - 1, 2u);
2765 EXPECT_LE(captures.worker_threads_count - 1, 4u);
2767 platform_task_runner->PostTask([&]() {
2769 sync_latch.Signal();
2774 ASSERT_FALSE(
engine.is_valid());
2787 ASSERT_EQ(data_out,
nullptr);
2796 ASSERT_EQ(data_out,
nullptr);
2803 ASSERT_EQ(data_in.
elf_path,
nullptr);
2804 ASSERT_EQ(data_out,
nullptr);
2811 ASSERT_EQ(data_out,
nullptr);
2817 ASSERT_EQ(data_in.
elf_path,
"/bin/true");
2818 ASSERT_EQ(data_out,
nullptr);
2826 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2830 EmbedderConfigBuilder::InitializationPreference::kMultiAOTInitialize);
2835 ASSERT_FALSE(
engine.is_valid());
2849 const auto elf_path =
2853 data_in.
elf_path = elf_path.c_str();
2857 ASSERT_EQ(data_in.
elf_path, elf_path.c_str());
2858 ASSERT_NE(data_out,
nullptr);
2868 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2871 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2875 EmbedderConfigBuilder::InitializationPreference::kAOTDataInitialize);
2880 ASSERT_TRUE(
engine.is_valid());
2887#if defined(__clang_analyzer__)
2888#define TEST_VM_SNAPSHOT_DATA "vm_data"
2889#define TEST_VM_SNAPSHOT_INSTRUCTIONS "vm_instructions"
2890#define TEST_ISOLATE_SNAPSHOT_DATA "isolate_data"
2891#define TEST_ISOLATE_SNAPSHOT_INSTRUCTIONS "isolate_instructions"
2901#if defined(OS_FUCHSIA)
2902 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2911 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2917 const std::string vm_snapshot_data =
2919 const std::string vm_snapshot_instructions =
2921 const std::string isolate_snapshot_data =
2923 const std::string isolate_snapshot_instructions =
2928 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
2930 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
2932 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
2934 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
2957#if defined(OS_FUCHSIA)
2958 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2967 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
2973 reinterpret_cast<const uint8_t*
>(
"invalid_vm_data");
2975 reinterpret_cast<const uint8_t*
>(
"invalid_vm_instructions");
2977 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2979 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
3004 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3010 const std::string vm_snapshot_data =
3012 const std::string vm_snapshot_instructions =
3014 const std::string isolate_snapshot_data =
3016 const std::string isolate_snapshot_instructions =
3021 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
3023 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
3025 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
3027 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
3030 ASSERT_TRUE(
engine.is_valid());
3044 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3050 const std::string vm_snapshot_data =
3052 const std::string vm_snapshot_instructions =
3057 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
3059 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
3062 ASSERT_TRUE(
engine.is_valid());
3077 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3083 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
3085 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
3088 ASSERT_TRUE(
engine.is_valid());
3103 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3113 ASSERT_TRUE(
engine.is_valid());
3117 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3122 ASSERT_TRUE(
engine.is_valid());
3128 event.pixel_ratio = 0.0;
3129 event.physical_view_inset_top = 0.0;
3130 event.physical_view_inset_right = 0.0;
3131 event.physical_view_inset_bottom = 0.0;
3132 event.physical_view_inset_left = 0.0;
3138 event.pixel_ratio = 1.0;
3139 event.physical_view_inset_top = -1.0;
3140 event.physical_view_inset_right = -1.0;
3141 event.physical_view_inset_bottom = -1.0;
3142 event.physical_view_inset_left = -1.0;
3148 event.physical_view_inset_top = 700;
3149 event.physical_view_inset_right = 900;
3150 event.physical_view_inset_bottom = 700;
3151 event.physical_view_inset_left = 900;
3160 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3165 ASSERT_TRUE(
engine.is_valid());
3172 event.pixel_ratio = 1.0;
3173 event.has_constraints =
true;
3174 event.min_width_constraint = 400;
3175 event.max_width_constraint = 1200;
3176 event.min_height_constraint = 300;
3177 event.max_height_constraint = 900;
3186 event_no_constraints.
struct_size =
sizeof(event_no_constraints);
3187 event_no_constraints.
width = 1024;
3188 event_no_constraints.
height = 768;
3205 event_invalid_min.
struct_size =
sizeof(event_invalid_min);
3206 event_invalid_min.
width = 300;
3207 event_invalid_min.
height = 600;
3222 event_invalid_max.
struct_size =
sizeof(event_invalid_max);
3223 event_invalid_max.
width = 1300;
3224 event_invalid_max.
height = 600;
3239 event_invalid_height.
struct_size =
sizeof(event_invalid_height);
3240 event_invalid_height.
width = 800;
3241 event_invalid_height.
height = 200;
3257 std::string entrypoint,
3259 const std::vector<uint8_t>& bytes) {
3264 bool matches =
false;
3266 builder.SetSurface(
DlISize(1, 1));
3267 builder.SetCompositor();
3268 builder.SetDartEntrypoint(std::move(entrypoint));
3269 builder.SetRenderTargetType(
3270 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2,
3273 auto engine = builder.LaunchEngine();
3274 ASSERT_TRUE(
engine.is_valid());
3276 context.GetCompositor().SetNextPresentCallback(
3284 context.GetCompositor().GetSurface(
layers[0]->backing_store);
3294 event.pixel_ratio = 1.0;
3299 ASSERT_TRUE(matches);
3304template <
typename T>
3307 std::string entrypoint,
3310 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(&pixelvalue);
3312 test, std::move(entrypoint), pixfmt,
3313 std::vector<uint8_t>(bytes, bytes +
sizeof(T)));
3316#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher) \
3317 TEST_F(EmbedderTest, SoftwareRenderingPixelFormats##test_name) { \
3318 expectSoftwareRenderingOutputMatches(*this, #dart_entrypoint, pixfmt, \
3336 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3340 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3357 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3361 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3378 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3382 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3393 std::shared_ptr<fml::AutoResetWaitableEvent>
latch;
3442 EXPECT_EQ(subject.
type, baseline.
type);
3450 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3451 uint64_t echoed_char;
3455 auto native_echo_event = [&](Dart_NativeArguments
args) {
3458 Dart_GetNativeArgument(
args, 0)));
3461 Dart_GetNativeArgument(
args, 1)));
3463 Dart_GetNativeArgument(
args, 2));
3465 Dart_GetNativeArgument(
args, 3));
3467 Dart_GetNativeArgument(
args, 4));
3472 Dart_GetNativeArgument(
args, 6)));
3474 message_latch->Signal();
3477 auto platform_task_runner = CreateNewThread(
"platform_thread");
3481 platform_task_runner->PostTask([&]() {
3482 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3491 context.AddNativeCallback(
3494 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3496 context.AddNativeCallback(
"EchoKeyEvent",
3500 ASSERT_TRUE(
engine.is_valid());
3510 .physical = 0x00070004,
3511 .logical = 0x00000000061,
3513 .synthesized =
false,
3516 platform_task_runner->PostTask([&]() {
3520 message_latch->Wait();
3523 EXPECT_EQ(echoed_char, 0x41llu);
3530 .physical = 0x00070005,
3531 .logical = 0x00000000062,
3533 .synthesized =
false,
3536 platform_task_runner->PostTask([&]() {
3540 message_latch->Wait();
3543 EXPECT_EQ(echoed_char, 0x2206llu);
3548 .timestamp = 1000000,
3550 .physical = 0x00070006,
3551 .logical = 0x00000000063,
3553 .synthesized =
true,
3556 platform_task_runner->PostTask([&]() {
3559 message_latch->Wait();
3562 EXPECT_EQ(echoed_char, 0llu);
3565 platform_task_runner->PostTask([&]() {
3569 shutdown_latch.
Wait();
3573 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3574 std::vector<FlutterKeyEvent> echoed_events;
3576 auto native_echo_event = [&](Dart_NativeArguments
args) {
3580 Dart_GetNativeArgument(
args, 1))),
3583 Dart_GetNativeArgument(
args, 0))),
3585 Dart_GetNativeArgument(
args, 2)),
3587 Dart_GetNativeArgument(
args, 3)),
3589 Dart_GetNativeArgument(
args, 5)),
3592 Dart_GetNativeArgument(
args, 6))),
3595 message_latch->Signal();
3598 auto platform_task_runner = CreateNewThread(
"platform_thread");
3602 platform_task_runner->PostTask([&]() {
3603 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3612 context.AddNativeCallback(
3615 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3617 context.AddNativeCallback(
"EchoKeyEvent",
3621 ASSERT_TRUE(
engine.is_valid());
3628 .physical = 0x00070004,
3629 .logical = 0x00000000061,
3631 .synthesized =
false,
3636 sample_event.timestamp = 1.0l;
3637 platform_task_runner->PostTask([&]() {
3639 message_latch->Signal();
3641 message_latch->Wait();
3644 EXPECT_EQ(echoed_events.size(), 0u);
3650 nullptr, &response_handle);
3654 .
channel =
"test/starts_echo",
3657 .response_handle = response_handle,
3660 platform_task_runner->PostTask([&]() {
3669 message_latch->Wait();
3671 EXPECT_EQ(echoed_events.size(), 1u);
3674 sample_event.timestamp = 10.0l;
3675 platform_task_runner->PostTask([&]() {
3678 message_latch->Wait();
3681 EXPECT_EQ(echoed_events.size(), 2u);
3684 platform_task_runner->PostTask([&]() {
3688 shutdown_latch.
Wait();
3700 auto platform_task_runner = CreateNewThread(
"platform_thread");
3702 platform_task_runner->PostTask([&]() {
3703 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3707 context.AddNativeCallback(
3710 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3711 context.AddNativeCallback(
3715 ASSERT_TRUE(
engine.is_valid());
3727 .physical = 0x00070005,
3728 .logical = 0x00000000062,
3734 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3737 event.synthesized =
true;
3738 platform_task_runner->PostTask([&]() {
3747 [](
bool handled,
void* untyped_user_data) {
3748 KeyEventUserData* user_data =
3749 reinterpret_cast<KeyEventUserData*>(untyped_user_data);
3750 EXPECT_EQ(handled, true);
3751 user_data->latch->Signal();
3755 user_data1.latch->Wait();
3757 platform_task_runner->PostTask([&]() {
3761 shutdown_latch.
Wait();
3773 auto platform_task_runner = CreateNewThread(
"platform_thread");
3775 platform_task_runner->PostTask([&]() {
3776 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3780 context.AddNativeCallback(
3783 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3785 context.AddNativeCallback(
3789 ASSERT_TRUE(
engine.is_valid());
3801 .physical = 0x00070005,
3802 .logical = 0x00000000062,
3804 .synthesized =
false,
3811 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3815 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3818 auto callback23 = [](
bool handled,
void* untyped_user_data) {
3821 EXPECT_EQ(handled,
false);
3825 platform_task_runner->PostTask([&]() {
3829 user_data2.latch->Wait();
3830 user_data3.latch->Wait();
3832 EXPECT_TRUE(user_data2.returned);
3833 EXPECT_TRUE(user_data3.returned);
3836 platform_task_runner->PostTask([&]() {
3840 shutdown_latch.
Wait();
3858 auto platform_task_runner = CreateNewThread(
"platform_thread");
3860 platform_task_runner->PostTask([&]() {
3861 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3862 context.SetVsyncCallback([&](intptr_t baton) {
3863 platform_task_runner->PostTask([baton = baton, &
engine, &vsync_latch]() {
3865 NanosFromEpoch(32));
3869 context.AddNativeCallback(
3879 ASSERT_TRUE(
engine.is_valid());
3886 event.pixel_ratio = 1.0;
3893 present_latch.
Wait();
3896 platform_task_runner->PostTask([&]() {
3900 shutdown_latch.
Wait();
3904 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3909 context.AddNativeCallback(
3912 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
3915 context.AddNativeCallback(
3916 "SignalNativeCount",
3918 [&check_latch](Dart_NativeArguments
args) { check_latch.
Signal(); }));
3921 ASSERT_TRUE(
engine.is_valid());
3932 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3938 ASSERT_TRUE(
engine.is_valid());
3946 callback_latch->
Signal();
3958 event.pixel_ratio = 1.0;
3959 event.physical_view_inset_top = 0.0;
3960 event.physical_view_inset_right = 0.0;
3961 event.physical_view_inset_bottom = 0.0;
3962 event.physical_view_inset_left = 0.0;
3966 callback_latch.
Wait();
3969#if defined(FML_OS_MACOSX)
3972 pthread_t tid = pthread_self();
3973 struct sched_param param;
3974 int policy = SCHED_OTHER;
3977 param.sched_priority = 10;
3980 param.sched_priority = 1;
3982 pthread_setschedparam(tid,
policy, ¶m);
3985TEST_F(EmbedderTest, EmbedderThreadHostUseCustomThreadConfig) {
3988 nullptr, MockThreadConfigSetter);
3992 struct sched_param ui_param;
3994 thread_host->GetTaskRunners().GetUITaskRunner()->PostTask([&] {
3995 pthread_t current_thread = pthread_self();
3996 pthread_getschedparam(current_thread, &ui_policy, &ui_param);
3997 ASSERT_EQ(ui_param.sched_priority, 10);
4003 struct sched_param io_param;
4004 thread_host->GetTaskRunners().GetIOTaskRunner()->PostTask([&] {
4005 pthread_t current_thread = pthread_self();
4006 pthread_getschedparam(current_thread, &io_policy, &io_param);
4007 ASSERT_EQ(io_param.sched_priority, 1);
4019 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4025 context.AddNativeCallback(
4028 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4029 context.AddNativeCallback(
4030 "SignalNativeCount",
4033 Dart_GetNativeArgument(
args, 0));
4034 ASSERT_EQ(count, 1);
4037 context.AddNativeCallback(
4038 "SignalNativeMessage",
4041 Dart_GetNativeArgument(
args, 0));
4042 ASSERT_EQ(
"PointerData(viewId: 0, x: 123.0, y: 456.0)",
message);
4047 ASSERT_TRUE(
engine.is_valid());
4054 pointer_event.
x = 123;
4055 pointer_event.
y = 456;
4056 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
4064 message_latch.
Wait();
4070 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4076 context.AddNativeCallback(
4079 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4080 context.AddNativeCallback(
4081 "SignalNativeMessage",
4084 Dart_GetNativeArgument(
args, 0));
4085 ASSERT_EQ(
"ViewID: 2",
message);
4090 ASSERT_TRUE(
engine.is_valid());
4096 metrics.
width = 800;
4106 EXPECT_TRUE(result->added);
4109 add_view_latch->
Signal();
4113 add_view_latch.
Wait();
4119 pointer_event.
x = 123;
4120 pointer_event.
y = 456;
4121 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
4128 message_latch.
Wait();
4132 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4138 context.AddNativeCallback(
4141 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4142 context.AddNativeCallback(
4143 "SignalNativeMessage",
4146 Dart_GetNativeArgument(
args, 0));
4147 ASSERT_EQ(
"Changed: [0]",
message);
4152 ASSERT_TRUE(
engine.is_valid());
4162 event.pixel_ratio = 1.5;
4169 message_latch.
Wait();
4173 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4179 context.AddNativeCallback(
4182 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4184 context.AddNativeCallback(
4185 "SignalNativeMessage",
4188 Dart_GetNativeArgument(
args, 0));
4192 ASSERT_EQ(
"Changed: [0]",
message);
4197 ASSERT_TRUE(
engine.is_valid());
4205 bad_event.
width = 200;
4219 event.pixel_ratio = 1.5;
4225 message_latch.
Wait();
4229 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4233 bool listening =
false;
4234 context.AddNativeCallback(
4238 EXPECT_STREQ(update->
channel,
"test/listen");
4249 ASSERT_TRUE(
engine.is_valid());
4256 ASSERT_TRUE(listening);
4260 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4263 static std::thread::id ffi_call_thread_id;
4264 static void (*ffi_signal_native_test)() = []() ->
void {
4265 ffi_call_thread_id = std::this_thread::get_id();
4269 Dart_FfiNativeResolver ffi_resolver = [](
const char*
name,
4270 uintptr_t args_n) ->
void* {
4271 if (std::string_view(
name) ==
"FFISignalNativeTest") {
4272 return reinterpret_cast<void*
>(ffi_signal_native_test);
4280 context.AddNativeCallback(
4282 Dart_SetFfiNativeResolver(Dart_RootLibrary(), ffi_resolver);
4285 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
4291 if (!
engine.is_valid()) {
4297 std::thread::id platform_thread_id;
4298 platform_task_runner->PostTask([&]() {
4299 platform_thread_id = std::this_thread::get_id();
4302 const auto task_runner_description =
4303 test_task_runner.GetFlutterTaskRunnerDescription();
4309 ASSERT_TRUE(
engine.is_valid());
4318 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
4323 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)