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;
3153 std::string entrypoint,
3155 const std::vector<uint8_t>& bytes) {
3160 bool matches =
false;
3162 builder.SetSurface(
DlISize(1, 1));
3163 builder.SetCompositor();
3164 builder.SetDartEntrypoint(std::move(entrypoint));
3165 builder.SetRenderTargetType(
3166 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2,
3169 auto engine = builder.LaunchEngine();
3170 ASSERT_TRUE(
engine.is_valid());
3172 context.GetCompositor().SetNextPresentCallback(
3180 context.GetCompositor().GetSurface(
layers[0]->backing_store);
3190 event.pixel_ratio = 1.0;
3195 ASSERT_TRUE(matches);
3200template <
typename T>
3203 std::string entrypoint,
3206 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(&pixelvalue);
3208 test, std::move(entrypoint), pixfmt,
3209 std::vector<uint8_t>(bytes, bytes +
sizeof(T)));
3212#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher) \
3213 TEST_F(EmbedderTest, SoftwareRenderingPixelFormats##test_name) { \
3214 expectSoftwareRenderingOutputMatches(*this, #dart_entrypoint, pixfmt, \
3232 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3236 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3253 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3257 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
3274 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
3278 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
3289 std::shared_ptr<fml::AutoResetWaitableEvent>
latch;
3338 EXPECT_EQ(subject.
type, baseline.
type);
3346 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3347 uint64_t echoed_char;
3351 auto native_echo_event = [&](Dart_NativeArguments
args) {
3354 Dart_GetNativeArgument(
args, 0)));
3357 Dart_GetNativeArgument(
args, 1)));
3359 Dart_GetNativeArgument(
args, 2));
3361 Dart_GetNativeArgument(
args, 3));
3363 Dart_GetNativeArgument(
args, 4));
3368 Dart_GetNativeArgument(
args, 6)));
3370 message_latch->Signal();
3373 auto platform_task_runner = CreateNewThread(
"platform_thread");
3377 platform_task_runner->PostTask([&]() {
3378 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3387 context.AddNativeCallback(
3390 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3392 context.AddNativeCallback(
"EchoKeyEvent",
3396 ASSERT_TRUE(
engine.is_valid());
3406 .physical = 0x00070004,
3407 .logical = 0x00000000061,
3409 .synthesized =
false,
3412 platform_task_runner->PostTask([&]() {
3416 message_latch->Wait();
3419 EXPECT_EQ(echoed_char, 0x41llu);
3426 .physical = 0x00070005,
3427 .logical = 0x00000000062,
3429 .synthesized =
false,
3432 platform_task_runner->PostTask([&]() {
3436 message_latch->Wait();
3439 EXPECT_EQ(echoed_char, 0x2206llu);
3444 .timestamp = 1000000,
3446 .physical = 0x00070006,
3447 .logical = 0x00000000063,
3449 .synthesized =
true,
3452 platform_task_runner->PostTask([&]() {
3455 message_latch->Wait();
3458 EXPECT_EQ(echoed_char, 0llu);
3461 platform_task_runner->PostTask([&]() {
3465 shutdown_latch.
Wait();
3469 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3470 std::vector<FlutterKeyEvent> echoed_events;
3472 auto native_echo_event = [&](Dart_NativeArguments
args) {
3476 Dart_GetNativeArgument(
args, 1))),
3479 Dart_GetNativeArgument(
args, 0))),
3481 Dart_GetNativeArgument(
args, 2)),
3483 Dart_GetNativeArgument(
args, 3)),
3485 Dart_GetNativeArgument(
args, 5)),
3488 Dart_GetNativeArgument(
args, 6))),
3491 message_latch->Signal();
3494 auto platform_task_runner = CreateNewThread(
"platform_thread");
3498 platform_task_runner->PostTask([&]() {
3499 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3508 context.AddNativeCallback(
3511 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3513 context.AddNativeCallback(
"EchoKeyEvent",
3517 ASSERT_TRUE(
engine.is_valid());
3524 .physical = 0x00070004,
3525 .logical = 0x00000000061,
3527 .synthesized =
false,
3532 sample_event.timestamp = 1.0l;
3533 platform_task_runner->PostTask([&]() {
3535 message_latch->Signal();
3537 message_latch->Wait();
3540 EXPECT_EQ(echoed_events.size(), 0u);
3546 nullptr, &response_handle);
3550 .
channel =
"test/starts_echo",
3553 .response_handle = response_handle,
3556 platform_task_runner->PostTask([&]() {
3565 message_latch->Wait();
3567 EXPECT_EQ(echoed_events.size(), 1u);
3570 sample_event.timestamp = 10.0l;
3571 platform_task_runner->PostTask([&]() {
3574 message_latch->Wait();
3577 EXPECT_EQ(echoed_events.size(), 2u);
3580 platform_task_runner->PostTask([&]() {
3584 shutdown_latch.
Wait();
3596 auto platform_task_runner = CreateNewThread(
"platform_thread");
3598 platform_task_runner->PostTask([&]() {
3599 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3603 context.AddNativeCallback(
3606 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3607 context.AddNativeCallback(
3611 ASSERT_TRUE(
engine.is_valid());
3623 .physical = 0x00070005,
3624 .logical = 0x00000000062,
3630 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3633 event.synthesized =
true;
3634 platform_task_runner->PostTask([&]() {
3643 [](
bool handled,
void* untyped_user_data) {
3644 KeyEventUserData* user_data =
3645 reinterpret_cast<KeyEventUserData*>(untyped_user_data);
3646 EXPECT_EQ(handled, true);
3647 user_data->latch->Signal();
3651 user_data1.latch->Wait();
3653 platform_task_runner->PostTask([&]() {
3657 shutdown_latch.
Wait();
3669 auto platform_task_runner = CreateNewThread(
"platform_thread");
3671 platform_task_runner->PostTask([&]() {
3672 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3676 context.AddNativeCallback(
3679 [&ready](Dart_NativeArguments
args) { ready.
Signal(); }));
3681 context.AddNativeCallback(
3685 ASSERT_TRUE(
engine.is_valid());
3697 .physical = 0x00070005,
3698 .logical = 0x00000000062,
3700 .synthesized =
false,
3707 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3711 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3714 auto callback23 = [](
bool handled,
void* untyped_user_data) {
3717 EXPECT_EQ(handled,
false);
3721 platform_task_runner->PostTask([&]() {
3725 user_data2.latch->Wait();
3726 user_data3.latch->Wait();
3728 EXPECT_TRUE(user_data2.returned);
3729 EXPECT_TRUE(user_data3.returned);
3732 platform_task_runner->PostTask([&]() {
3736 shutdown_latch.
Wait();
3754 auto platform_task_runner = CreateNewThread(
"platform_thread");
3756 platform_task_runner->PostTask([&]() {
3757 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3758 context.SetVsyncCallback([&](intptr_t baton) {
3759 platform_task_runner->PostTask([baton = baton, &
engine, &vsync_latch]() {
3761 NanosFromEpoch(32));
3765 context.AddNativeCallback(
3775 ASSERT_TRUE(
engine.is_valid());
3782 event.pixel_ratio = 1.0;
3789 present_latch.
Wait();
3792 platform_task_runner->PostTask([&]() {
3796 shutdown_latch.
Wait();
3800 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3805 context.AddNativeCallback(
3808 [&latch](Dart_NativeArguments
args) { latch.
Signal(); }));
3811 context.AddNativeCallback(
3812 "SignalNativeCount",
3814 [&check_latch](Dart_NativeArguments
args) { check_latch.
Signal(); }));
3817 ASSERT_TRUE(
engine.is_valid());
3828 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3834 ASSERT_TRUE(
engine.is_valid());
3842 callback_latch->
Signal();
3854 event.pixel_ratio = 1.0;
3855 event.physical_view_inset_top = 0.0;
3856 event.physical_view_inset_right = 0.0;
3857 event.physical_view_inset_bottom = 0.0;
3858 event.physical_view_inset_left = 0.0;
3862 callback_latch.
Wait();
3865#if defined(FML_OS_MACOSX)
3868 pthread_t tid = pthread_self();
3869 struct sched_param param;
3870 int policy = SCHED_OTHER;
3873 param.sched_priority = 10;
3876 param.sched_priority = 1;
3878 pthread_setschedparam(tid,
policy, ¶m);
3881TEST_F(EmbedderTest, EmbedderThreadHostUseCustomThreadConfig) {
3884 nullptr, MockThreadConfigSetter);
3888 struct sched_param ui_param;
3890 thread_host->GetTaskRunners().GetUITaskRunner()->PostTask([&] {
3891 pthread_t current_thread = pthread_self();
3892 pthread_getschedparam(current_thread, &ui_policy, &ui_param);
3893 ASSERT_EQ(ui_param.sched_priority, 10);
3899 struct sched_param io_param;
3900 thread_host->GetTaskRunners().GetIOTaskRunner()->PostTask([&] {
3901 pthread_t current_thread = pthread_self();
3902 pthread_getschedparam(current_thread, &io_policy, &io_param);
3903 ASSERT_EQ(io_param.sched_priority, 1);
3915 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3921 context.AddNativeCallback(
3924 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
3925 context.AddNativeCallback(
3926 "SignalNativeCount",
3929 Dart_GetNativeArgument(
args, 0));
3930 ASSERT_EQ(count, 1);
3933 context.AddNativeCallback(
3934 "SignalNativeMessage",
3937 Dart_GetNativeArgument(
args, 0));
3938 ASSERT_EQ(
"PointerData(viewId: 0, x: 123.0, y: 456.0)",
message);
3943 ASSERT_TRUE(
engine.is_valid());
3950 pointer_event.
x = 123;
3951 pointer_event.
y = 456;
3952 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
3960 message_latch.
Wait();
3966 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
3972 context.AddNativeCallback(
3975 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
3976 context.AddNativeCallback(
3977 "SignalNativeMessage",
3980 Dart_GetNativeArgument(
args, 0));
3981 ASSERT_EQ(
"ViewID: 2",
message);
3986 ASSERT_TRUE(
engine.is_valid());
3992 metrics.
width = 800;
4002 EXPECT_TRUE(result->added);
4005 add_view_latch->
Signal();
4009 add_view_latch.
Wait();
4015 pointer_event.
x = 123;
4016 pointer_event.
y = 456;
4017 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
4024 message_latch.
Wait();
4028 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4034 context.AddNativeCallback(
4037 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4038 context.AddNativeCallback(
4039 "SignalNativeMessage",
4042 Dart_GetNativeArgument(
args, 0));
4043 ASSERT_EQ(
"Changed: [0]",
message);
4048 ASSERT_TRUE(
engine.is_valid());
4058 event.pixel_ratio = 1.5;
4065 message_latch.
Wait();
4069 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4075 context.AddNativeCallback(
4078 [&ready_latch](Dart_NativeArguments
args) { ready_latch.
Signal(); }));
4080 context.AddNativeCallback(
4081 "SignalNativeMessage",
4084 Dart_GetNativeArgument(
args, 0));
4088 ASSERT_EQ(
"Changed: [0]",
message);
4093 ASSERT_TRUE(
engine.is_valid());
4101 bad_event.
width = 200;
4115 event.pixel_ratio = 1.5;
4121 message_latch.
Wait();
4125 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4129 bool listening =
false;
4130 context.AddNativeCallback(
4134 EXPECT_STREQ(update->
channel,
"test/listen");
4145 ASSERT_TRUE(
engine.is_valid());
4152 ASSERT_TRUE(listening);
4156 auto& context = GetEmbedderContext<EmbedderTestContextSoftware>();
4159 static std::thread::id ffi_call_thread_id;
4160 static void (*ffi_signal_native_test)() = []() ->
void {
4161 ffi_call_thread_id = std::this_thread::get_id();
4165 Dart_FfiNativeResolver ffi_resolver = [](
const char*
name,
4166 uintptr_t args_n) ->
void* {
4167 if (std::string_view(
name) ==
"FFISignalNativeTest") {
4168 return reinterpret_cast<void*
>(ffi_signal_native_test);
4176 context.AddNativeCallback(
4178 Dart_SetFfiNativeResolver(Dart_RootLibrary(), ffi_resolver);
4181 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
4187 if (!
engine.is_valid()) {
4193 std::thread::id platform_thread_id;
4194 platform_task_runner->PostTask([&]() {
4195 platform_thread_id = std::this_thread::get_id();
4198 const auto task_runner_description =
4199 test_task_runner.GetFlutterTaskRunnerDescription();
4205 ASSERT_TRUE(
engine.is_valid());
4214 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
4219 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 GBytes * message
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.
int64_t view_id
The view that this event is describing.
double pixel_ratio
Scale factor for the physical screen.
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)