5#define FML_USED_ON_EMBEDDER
13#include "flutter/common/constants.h"
14#include "flutter/flow/raster_cache.h"
15#include "flutter/fml/file.h"
16#include "flutter/fml/make_copyable.h"
17#include "flutter/fml/mapping.h"
18#include "flutter/fml/message_loop.h"
19#include "flutter/fml/paths.h"
20#include "flutter/fml/synchronization/count_down_latch.h"
21#include "flutter/fml/synchronization/waitable_event.h"
22#include "flutter/fml/task_runner.h"
23#include "flutter/fml/thread.h"
24#include "flutter/fml/time/time_delta.h"
25#include "flutter/fml/time/time_point.h"
26#include "flutter/runtime/dart_vm.h"
27#include "flutter/shell/platform/embedder/tests/embedder_assertions.h"
28#include "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
29#include "flutter/shell/platform/embedder/tests/embedder_test.h"
30#include "flutter/shell/platform/embedder/tests/embedder_unittests_util.h"
31#include "flutter/testing/assertions_skia.h"
32#include "flutter/testing/testing.h"
36#if defined(FML_OS_MACOSX)
45static uint64_t NanosFromEpoch(
int millis_from_now) {
48 return (now +
delta).ToEpochDelta().ToNanoseconds();
58TEST(EmbedderTestNoFixture, MustNotRunWithInvalidArgs) {
63 ASSERT_FALSE(
engine.is_valid());
69 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
71 builder.SetSoftwareRendererConfig();
73 ASSERT_TRUE(
engine.is_valid());
83 builder.SetSoftwareRendererConfig();
84 for (
size_t i = 0;
i < 3; ++
i) {
86 ASSERT_TRUE(
engine.is_valid());
87 FML_LOG(INFO) <<
"Engine launch count: " <<
i + 1;
97 context.AddNativeCallback(
"SayHiFromCustomEntrypoint", entrypoint);
99 builder.SetSoftwareRendererConfig();
100 builder.SetDartEntrypoint(
"customEntrypoint");
103 ASSERT_TRUE(
engine.is_valid());
115 FML_LOG(INFO) <<
"In Callback 1";
119 context.AddNativeCallback(
"SayHiFromCustomEntrypoint1", native_entry1);
123 FML_LOG(INFO) <<
"In Callback 2";
126 context.AddNativeCallback(
"SayHiFromCustomEntrypoint2",
130 context.AddNativeCallback(
131 "SayHiFromCustomEntrypoint3",
133 FML_LOG(INFO) <<
"In Callback 3";
138 builder.SetSoftwareRendererConfig();
139 builder.SetDartEntrypoint(
"customEntrypoint1");
144 ASSERT_TRUE(
engine.is_valid());
150 builder.SetSoftwareRendererConfig();
151 builder.SetDartEntrypoint(
"terminateExitCodeHandler");
153 ASSERT_TRUE(
engine.is_valid());
162 context.AddNativeCallback(
166 EXPECT_EQ(
"/path/to/binary", dart_string);
171 builder.SetSoftwareRendererConfig();
172 builder.SetDartEntrypoint(
"executableNameNotNull");
173 builder.SetExecutableName(
"/path/to/binary");
184 bool implicitViewNotNull =
false;
186 context.AddNativeCallback(
194 builder.SetSoftwareRendererConfig();
195 builder.SetDartEntrypoint(
"implicitViewNotNull");
202std::atomic_size_t EmbedderTestTaskRunner::sEmbedderTaskRunnerIdentifiers = {};
211 static std::mutex engine_mutex;
212 static bool signaled_once =
false;
217 std::scoped_lock lock(engine_mutex);
228 signaled_once =
true;
229 ASSERT_TRUE(
engine.is_valid());
234 platform_task_runner->PostTask([&]() {
236 const auto task_runner_description =
237 test_task_runner.GetFlutterTaskRunnerDescription();
238 builder.SetSoftwareRendererConfig();
239 builder.SetPlatformTaskRunner(&task_runner_description);
240 builder.SetDartEntrypoint(
"invokePlatformTaskRunner");
241 std::scoped_lock lock(engine_mutex);
243 ASSERT_TRUE(
engine.is_valid());
248 ASSERT_TRUE(
engine.is_valid());
254 std::scoped_lock lock(engine_mutex);
260 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
264 ASSERT_TRUE(signaled_once);
265 signaled_once =
false;
268TEST(EmbedderTestNoFixture, CanGetCurrentTimeInNanoseconds) {
279 builder.SetSoftwareRendererConfig();
281 ASSERT_TRUE(
engine.is_valid());
293 std::string isolate_message;
297 builder.SetSoftwareRendererConfig();
298 builder.SetDartEntrypoint(
"main");
299 builder.SetPlatformMessageCallback(
301 if (strcmp(
message->channel,
"flutter/isolate") == 0) {
302 isolate_message = {reinterpret_cast<const char*>(message->message),
303 message->message_size};
308 ASSERT_TRUE(
engine.is_valid());
313 ASSERT_EQ(isolate_message.find(
"isolates/"), 0ul);
318 thread.GetTaskRunner()->PostTask(
331 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
333 builder.SetSoftwareRendererConfig();
334 builder.SetDartEntrypoint(
"platform_messages_response");
335 context.AddNativeCallback(
340 ASSERT_TRUE(
engine.is_valid());
348 ASSERT_NE(response_handle,
nullptr);
368 captures.thread_id = std::this_thread::get_id();
370 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
372 builder.SetSoftwareRendererConfig();
373 builder.SetDartEntrypoint(
"platform_messages_response");
376 context.AddNativeCallback(
382 ASSERT_TRUE(
engine.is_valid());
384 static std::string kMessageData =
"Hello from embedder.";
389 ASSERT_EQ(
size, kMessageData.size());
390 ASSERT_EQ(strncmp(
reinterpret_cast<const char*
>(kMessageData.data()),
391 reinterpret_cast<const char*
>(
data),
size),
393 auto captures =
reinterpret_cast<Captures*
>(
user_data);
394 ASSERT_EQ(captures->thread_id, std::this_thread::get_id());
395 captures->latch.Signal();
403 message.channel =
"test_channel";
404 message.message =
reinterpret_cast<const uint8_t*
>(kMessageData.data());
405 message.message_size = kMessageData.size();
406 message.response_handle = response_handle;
417 captures.latch.Wait();
426 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
428 builder.SetSoftwareRendererConfig();
429 builder.SetDartEntrypoint(
"platform_messages_no_response");
431 const std::string message_data =
"Hello but don't call me back.";
434 context.AddNativeCallback(
438 context.AddNativeCallback(
439 "SignalNativeMessage",
444 ASSERT_EQ(received_message, message_data);
450 ASSERT_TRUE(
engine.is_valid());
455 platform_message.
channel =
"test_channel";
457 reinterpret_cast<const uint8_t*
>(message_data.data());
471 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
473 builder.SetSoftwareRendererConfig();
474 builder.SetDartEntrypoint(
"null_platform_messages");
477 context.AddNativeCallback(
481 context.AddNativeCallback(
482 "SignalNativeMessage",
486 ASSERT_EQ(
"true", received_message);
492 ASSERT_TRUE(
engine.is_valid());
497 platform_message.
channel =
"test_channel";
498 platform_message.
message =
nullptr;
513 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
515 builder.SetSoftwareRendererConfig();
518 ASSERT_TRUE(
engine.is_valid());
522 platform_message.
channel =
"test_channel";
523 platform_message.
message =
nullptr;
537 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
539 builder.SetDartEntrypoint(
"custom_logger");
540 builder.SetSoftwareRendererConfig();
541 context.SetLogMessageCallback(
542 [&callback_latch](
const char* tag,
const char*
message) {
543 EXPECT_EQ(std::string(tag),
"flutter");
544 EXPECT_EQ(std::string(
message),
"hello world");
548 ASSERT_TRUE(
engine.is_valid());
549 callback_latch.
Wait();
556 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
558 builder.SetDartEntrypoint(
"custom_logger");
559 builder.SetSoftwareRendererConfig();
560 builder.SetLogTag(
"butterfly");
561 context.SetLogMessageCallback(
562 [&callback_latch](
const char* tag,
const char*
message) {
563 EXPECT_EQ(std::string(tag),
"butterfly");
564 EXPECT_EQ(std::string(
message),
"hello world");
568 ASSERT_TRUE(
engine.is_valid());
569 callback_latch.
Wait();
577 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
579 builder.SetSoftwareRendererConfig();
596 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
598 builder.SetSoftwareRendererConfig();
599 builder.AddDartEntrypointArgument(
"foo");
600 builder.AddDartEntrypointArgument(
"bar");
601 builder.SetDartEntrypoint(
"dart_entrypoint_args");
603 std::vector<std::string> callback_args;
604 auto nativeArgumentsCallback = [&callback_args,
612 context.AddNativeCallback(
"NativeArgumentsCallback",
615 callback_latch.
Wait();
616 ASSERT_EQ(callback_args[0],
"foo");
617 ASSERT_EQ(callback_args[1],
"bar");
630 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
632 builder.SetSoftwareRendererConfig();
635 builder.GetProjectArgs().vm_snapshot_data_size = 0;
636 builder.GetProjectArgs().vm_snapshot_instructions_size = 0;
637 builder.GetProjectArgs().isolate_snapshot_data_size = 0;
638 builder.GetProjectArgs().isolate_snapshot_instructions_size = 0;
641 ASSERT_TRUE(
engine.is_valid());
645 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
650 builder.SetDartEntrypoint(
"render_implicit_view");
652 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
656 context.GetCompositor().SetNextPresentCallback(
658 size_t layers_count) {
669 event.pixel_ratio = 1.0;
672 ASSERT_TRUE(
engine.is_valid());
677 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
683 builder.SetDartEntrypoint(
"render_implicit_view");
685 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
689 context.GetCompositor().SetNextPresentCallback(
691 size_t layers_count) {
702 event.pixel_ratio = 1.0;
705 ASSERT_TRUE(
engine.is_valid());
714#if FML_OS_MACOSX && FML_ARCH_CPU_ARM64
716 DISABLED_CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
719 CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) {
722 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
727 builder.SetDartEntrypoint(
"can_composite_platform_views_with_known_scene");
730 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
734 auto scene_image = context.GetNextSceneImage();
736 context.GetCompositor().SetNextPresentCallback(
738 size_t layers_count) {
739 ASSERT_EQ(layers_count, 5u);
754 .rects = paint_region_rects,
758 .paint_region = &paint_region,
769 ASSERT_EQ(*layers[0], layer);
785 ASSERT_EQ(*layers[1], layer);
801 .rects = paint_region_rects,
805 .paint_region = &paint_region,
816 ASSERT_EQ(*layers[2], layer);
832 ASSERT_EQ(*layers[3], layer);
848 .rects = paint_region_rects,
852 .paint_region = &paint_region,
863 ASSERT_EQ(*layers[4], layer);
869 context.GetCompositor().SetPlatformViewRendererCallback(
874 auto canvas =
surface->getCanvas();
901 <<
"Test was asked to composite an unknown platform view.";
904 return surface->makeImageSnapshot();
907 context.AddNativeCallback(
919 event.pixel_ratio = 1.0;
920 event.physical_view_inset_top = 0.0;
921 event.physical_view_inset_right = 0.0;
922 event.physical_view_inset_bottom = 0.0;
923 event.physical_view_inset_left = 0.0;
926 ASSERT_TRUE(
engine.is_valid());
933 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
941 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
946 builder.SetDartEntrypoint(
"can_composite_platform_views_transparent_overlay");
949 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
953 auto scene_image = context.GetNextSceneImage();
955 context.GetCompositor().SetNextPresentCallback(
957 size_t layers_count) {
958 ASSERT_EQ(layers_count, 2u);
973 .rects = paint_region_rects,
977 .paint_region = &paint_region,
988 ASSERT_EQ(*layers[0], layer);
1004 ASSERT_EQ(*layers[1], layer);
1010 context.GetCompositor().SetPlatformViewRendererCallback(
1015 auto canvas =
surface->getCanvas();
1023 paint.setAlpha(127);
1032 <<
"Test was asked to composite an unknown platform view.";
1035 return surface->makeImageSnapshot();
1038 context.AddNativeCallback(
1050 event.pixel_ratio = 1.0;
1051 event.physical_view_inset_top = 0.0;
1052 event.physical_view_inset_right = 0.0;
1053 event.physical_view_inset_bottom = 0.0;
1054 event.physical_view_inset_left = 0.0;
1057 ASSERT_TRUE(
engine.is_valid());
1063#if !defined(FML_OS_LINUX)
1064 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1067 "compositor_platform_layer_with_no_overlay.png", scene_image));
1070 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1078 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1083 builder.SetDartEntrypoint(
"can_composite_platform_views_no_overlay");
1086 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1090 auto scene_image = context.GetNextSceneImage();
1092 context.GetCompositor().SetNextPresentCallback(
1094 size_t layers_count) {
1095 ASSERT_EQ(layers_count, 2u);
1110 .rects = paint_region_rects,
1114 .paint_region = &paint_region,
1125 ASSERT_EQ(*layers[0], layer);
1141 ASSERT_EQ(*layers[1], layer);
1147 context.GetCompositor().SetPlatformViewRendererCallback(
1152 auto canvas =
surface->getCanvas();
1160 paint.setAlpha(127);
1169 <<
"Test was asked to composite an unknown platform view.";
1172 return surface->makeImageSnapshot();
1175 context.AddNativeCallback(
1187 event.pixel_ratio = 1.0;
1188 event.physical_view_inset_top = 0.0;
1189 event.physical_view_inset_right = 0.0;
1190 event.physical_view_inset_bottom = 0.0;
1191 event.physical_view_inset_left = 0.0;
1194 ASSERT_TRUE(
engine.is_valid());
1200#if !defined(FML_OS_LINUX)
1201 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
1204 "compositor_platform_layer_with_no_overlay.png", scene_image));
1207 ASSERT_EQ(context.GetSurfacePresentCount(), 0u);
1215 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
1216 builder.SetSoftwareRendererConfig();
1218 ASSERT_TRUE(
engine.is_valid());
1227 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
1228 builder.SetSoftwareRendererConfig();
1230 ASSERT_TRUE(
engine.is_valid());
1242 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
1243 builder.SetSoftwareRendererConfig();
1245 ASSERT_TRUE(
engine.is_valid());
1258 event.pixel_ratio = 1.0;
1259 event.physical_view_inset_top = 0.0;
1260 event.physical_view_inset_right = 0.0;
1261 event.physical_view_inset_bottom = 0.0;
1262 event.physical_view_inset_left = 0.0;
1272 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1274 builder.SetSoftwareRendererConfig();
1275 builder.SetDartEntrypoint(
"window_metrics_event_all_view_ids");
1278 context.AddNativeCallback(
1284 context.AddNativeCallback(
"SignalNativeMessage",
1293 ASSERT_TRUE(
engine.is_valid());
1299 metrics.
width = 800;
1307 info.view_metrics = &metrics;
1312 message_latch.
Wait();
1313 ASSERT_EQ(
"View IDs: [0, 123]",
message);
1320 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1322 builder.SetSoftwareRendererConfig();
1323 builder.SetDartEntrypoint(
"add_view_schedules_frame");
1325 context.AddNativeCallback(
1331 context.AddNativeCallback(
1332 "SignalNativeCount",
1337 ASSERT_TRUE(
engine.is_valid());
1344 metrics.
width = 800;
1352 info.view_metrics = &metrics;
1365 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1367 builder.SetSoftwareRendererConfig();
1368 builder.SetDartEntrypoint(
"window_metrics_event_all_view_ids");
1371 context.AddNativeCallback(
1377 context.AddNativeCallback(
"SignalNativeMessage",
1386 ASSERT_TRUE(
engine.is_valid());
1393 metrics.
width = 800;
1403 ASSERT_TRUE(
result->added);
1406 message_latch.
Wait();
1407 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1417 message_latch.
Wait();
1418 ASSERT_EQ(
message,
"View IDs: [0]");
1426 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1428 builder.SetSoftwareRendererConfig();
1431 ASSERT_TRUE(
engine.is_valid());
1446 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1448 builder.SetSoftwareRendererConfig();
1449 builder.SetDartEntrypoint(
"window_metrics_event_all_view_ids");
1452 context.AddNativeCallback(
1458 context.AddNativeCallback(
"SignalNativeMessage",
1467 ASSERT_TRUE(
engine.is_valid());
1473 std::atomic<int>
count = 0;
1480 metrics.
width = 800;
1491 auto captures =
reinterpret_cast<Captures*
>(
result->user_data);
1493 int count = captures->count.fetch_add(1);
1496 ASSERT_TRUE(
result->added);
1498 EXPECT_FALSE(
result->added);
1499 captures->failure_latch.Signal();
1503 message_latch.
Wait();
1504 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1505 ASSERT_FALSE(captures.failure_latch.IsSignaledForTest());
1509 captures.failure_latch.Wait();
1510 ASSERT_EQ(captures.count, 2);
1518 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1520 builder.SetSoftwareRendererConfig();
1521 builder.SetDartEntrypoint(
"window_metrics_event_all_view_ids");
1524 context.AddNativeCallback(
1530 context.AddNativeCallback(
"SignalNativeMessage",
1539 ASSERT_TRUE(
engine.is_valid());
1546 metrics.
width = 800;
1556 ASSERT_TRUE(
result->added);
1559 message_latch.
Wait();
1560 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1567 ASSERT_TRUE(
result->removed);
1570 message_latch.
Wait();
1571 ASSERT_EQ(
message,
"View IDs: [0]");
1575 message_latch.
Wait();
1576 ASSERT_EQ(
message,
"View IDs: [0, 123]");
1583 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1585 builder.SetSoftwareRendererConfig();
1588 ASSERT_TRUE(
engine.is_valid());
1594 info.user_data = &latch;
1596 EXPECT_FALSE(
result->removed);
1609 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1611 builder.SetSoftwareRendererConfig();
1612 builder.SetDartEntrypoint(
"window_metrics_event_all_view_ids");
1615 context.AddNativeCallback(
1620 std::atomic<int> message_count = 0;
1621 context.AddNativeCallback(
"SignalNativeMessage",
1623 message_count.fetch_add(1);
1627 ASSERT_TRUE(
engine.is_valid());
1644 metrics123.
width = 800;
1651 metrics456.
width = 800;
1671 auto captures =
reinterpret_cast<Captures*
>(
result->user_data);
1673 ASSERT_TRUE(
result->added);
1674 ASSERT_FALSE(captures->add_first_view.IsSignaledForTest());
1675 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
1676 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
1677 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
1679 captures->add_first_view.Signal();
1685 add_duplicate_view_info.
view_id = 123;
1687 add_duplicate_view_info.
user_data = &captures;
1690 auto captures =
reinterpret_cast<Captures*
>(
result->user_data);
1692 ASSERT_FALSE(
result->added);
1693 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
1694 ASSERT_FALSE(captures->add_duplicate_view.IsSignaledForTest());
1695 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
1696 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
1698 captures->add_duplicate_view.Signal();
1704 add_second_view_info.
view_id = 456;
1706 add_second_view_info.
user_data = &captures;
1709 auto captures =
reinterpret_cast<Captures*
>(
result->user_data);
1711 ASSERT_TRUE(
result->added);
1712 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
1713 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
1714 ASSERT_FALSE(captures->add_second_view.IsSignaledForTest());
1715 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
1717 captures->add_second_view.Signal();
1723 remove_second_view_info.
view_id = 456;
1724 remove_second_view_info.
user_data = &captures;
1727 auto captures =
reinterpret_cast<Captures*
>(
result->user_data);
1729 ASSERT_TRUE(
result->removed);
1730 ASSERT_TRUE(captures->add_first_view.IsSignaledForTest());
1731 ASSERT_TRUE(captures->add_duplicate_view.IsSignaledForTest());
1732 ASSERT_TRUE(captures->add_second_view.IsSignaledForTest());
1733 ASSERT_FALSE(captures->remove_second_view.IsSignaledForTest());
1735 captures->remove_second_view.Signal();
1745 captures.remove_second_view.Wait();
1746 captures.add_second_view.Wait();
1747 captures.add_duplicate_view.Wait();
1748 captures.add_first_view.Wait();
1749 ASSERT_EQ(message_count, 3);
1756 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1758 builder.SetSoftwareRendererConfig();
1760 builder.SetDartEntrypoint(
"render_all_views");
1763 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1766 context.GetCompositor().SetPresentCallback(
1768 size_t layers_count) {
1783 ASSERT_TRUE(
engine.is_valid());
1788 metrics0.
width = 800;
1798 metrics123.
width = 800;
1808 ASSERT_TRUE(
result->added);
1835 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1838 builder.SetDartEntrypoint(
"render_all_views");
1843 context.GetCompositor().GetGrContext(),
1844 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1847 struct CompositorUserData {
1854 bool second_expected;
1855 bool third_expected;
1857 int backing_stores_created;
1859 CompositorUserData compositor_user_data{
1860 .producer = &producer,
1861 .backing_stores_created = 0,
1866 .
user_data =
reinterpret_cast<void*
>(&compositor_user_data),
1867 .create_backing_store_callback =
1872 config->
view_id == kSecondViewId ||
1873 config->
view_id == kThirdViewId);
1874 auto compositor_user_data =
1875 reinterpret_cast<CompositorUserData*
>(
user_data);
1876 compositor_user_data->backing_stores_created += 1;
1877 bool result = compositor_user_data->producer->Create(
1878 config, backing_store_out);
1881 backing_store_out->user_data =
1882 reinterpret_cast<void*
>(config->
view_id);
1887 .present_layers_callback =
nullptr,
1888 .avoid_backing_store_cache =
false,
1889 .present_view_callback =
1891 EXPECT_EQ(
info->layers_count, 1u);
1894 int64_t store_view_id =
reinterpret_cast<int64_t
>(
1895 info->layers[0]->backing_store->user_data);
1896 EXPECT_EQ(store_view_id,
info->view_id);
1897 auto compositor_user_data =
1898 reinterpret_cast<CompositorUserData*
>(
info->user_data);
1900 switch (
info->view_id) {
1902 compositor_user_data->latch_implicit.Signal();
1905 EXPECT_TRUE(compositor_user_data->second_expected);
1906 compositor_user_data->latch_second.Signal();
1909 EXPECT_TRUE(compositor_user_data->third_expected);
1910 compositor_user_data->latch_third.Signal();
1919 compositor_user_data.second_expected =
true;
1920 compositor_user_data.third_expected =
false;
1925 ASSERT_TRUE(
engine.is_valid());
1945 .view_id = kSecondViewId,
1950 add_view_info.
view_id = kSecondViewId;
1953 ASSERT_TRUE(
result->added);
1958 compositor_user_data.latch_implicit.Wait();
1959 compositor_user_data.latch_second.Wait();
1963 compositor_user_data.second_expected =
false;
1964 compositor_user_data.third_expected =
true;
1965 EXPECT_EQ(compositor_user_data.backing_stores_created, 2);
1970 remove_view_info.
view_id = kSecondViewId;
1973 ASSERT_TRUE(
result->removed);
1978 add_view_info.
view_id = kThirdViewId;
1979 metrics_add.
view_id = kThirdViewId;
1983 compositor_user_data.latch_implicit.Wait();
1984 compositor_user_data.latch_third.Wait();
1985 EXPECT_EQ(compositor_user_data.backing_stores_created, 3);
1989 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
1991 builder.SetSoftwareRendererConfig();
1992 builder.SetDartEntrypoint(
"can_receive_locale_updates");
1994 context.AddNativeCallback(
2000 context.AddNativeCallback(
2001 "SignalNativeCount",
2010 ASSERT_TRUE(
engine.is_valid());
2029 std::vector<const FlutterLocale*> locales;
2030 locales.push_back(&locale1);
2031 locales.push_back(&locale2);
2048 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2050 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2052 builder.SetSoftwareRendererConfig();
2054 ASSERT_TRUE(
engine.is_valid());
2059 std::vector<std::string> supported_locales;
2060 supported_locales.push_back(
"es");
2061 supported_locales.push_back(
"MX");
2062 supported_locales.push_back(
"");
2063 auto result =
shell.GetPlatformView()->ComputePlatformResolvedLocales(
2066 ASSERT_EQ((*result).size(), supported_locales.size());
2067 ASSERT_EQ((*
result)[0], supported_locales[0]);
2068 ASSERT_EQ((*
result)[1], supported_locales[1]);
2069 ASSERT_EQ((*
result)[2], supported_locales[2]);
2080 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2085 builder.SetDartEntrypoint(
"verify_b143464703");
2088 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
2091 auto rendered_scene = context.GetNextSceneImage();
2094 context.GetCompositor().SetNextPresentCallback(
2096 size_t layers_count) {
2097 ASSERT_EQ(layers_count, 2u);
2111 .rects = paint_region_rects,
2115 .paint_region = &paint_region,
2126 ASSERT_EQ(*layers[0], layer);
2142 ASSERT_EQ(*layers[1], layer);
2148 context.GetCompositor().SetPlatformViewRendererCallback(
2153 auto canvas =
surface->getCanvas();
2161 paint.setAlpha(127);
2169 <<
"Test was asked to composite an unknown platform view.";
2172 return surface->makeImageSnapshot();
2182 event.pixel_ratio = 1.0;
2183 event.physical_view_inset_top = 0.0;
2184 event.physical_view_inset_right = 0.0;
2185 event.physical_view_inset_bottom = 0.0;
2186 event.physical_view_inset_left = 0.0;
2189 ASSERT_TRUE(
engine.is_valid());
2196#if !defined(FML_OS_LINUX)
2197 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
2204 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2207 builder.SetSoftwareRendererConfig();
2211 ASSERT_TRUE(
engine.is_valid());
2223 size_t worker_count = 0;
2232 platform_task_runner->PostTask([&]() {
2234 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2237 builder.SetSoftwareRendererConfig();
2241 ASSERT_TRUE(
engine.is_valid());
2254 const auto engine_threads_count = worker_count + 4u;
2264 std::mutex captures_mutex;
2266 std::set<std::thread::id> thread_ids;
2268 size_t platform_threads_count = 0;
2269 size_t render_threads_count = 0;
2270 size_t ui_threads_count = 0;
2271 size_t worker_threads_count = 0;
2273 explicit Captures(
size_t count) : latch(
count) {}
2276 Captures captures(engine_threads_count);
2278 platform_task_runner->PostTask([&]() {
2282 auto captures = reinterpret_cast<Captures*>(baton);
2284 std::scoped_lock lock(captures->captures_mutex);
2286 case kFlutterNativeThreadTypeRender:
2287 captures->render_threads_count++;
2289 case kFlutterNativeThreadTypeWorker:
2290 captures->worker_threads_count++;
2292 case kFlutterNativeThreadTypeUI:
2293 captures->ui_threads_count++;
2295 case kFlutterNativeThreadTypePlatform:
2296 captures->platform_threads_count++;
2299 captures->thread_ids.insert(std::this_thread::get_id());
2301 captures->latch.CountDown();
2307 captures.latch.Wait();
2308 ASSERT_EQ(captures.thread_ids.size(), engine_threads_count);
2309 ASSERT_EQ(captures.platform_threads_count, 1u);
2310 ASSERT_EQ(captures.render_threads_count, 1u);
2311 ASSERT_EQ(captures.ui_threads_count, 1u);
2312 ASSERT_EQ(captures.worker_threads_count, worker_count + 1u );
2313 EXPECT_GE(captures.worker_threads_count - 1, 2u);
2314 EXPECT_LE(captures.worker_threads_count - 1, 4u);
2316 platform_task_runner->PostTask([&]() {
2318 sync_latch.Signal();
2323 ASSERT_FALSE(
engine.is_valid());
2336 ASSERT_EQ(data_out,
nullptr);
2345 ASSERT_EQ(data_out,
nullptr);
2352 ASSERT_EQ(data_in.
elf_path,
nullptr);
2353 ASSERT_EQ(data_out,
nullptr);
2360 ASSERT_EQ(data_out,
nullptr);
2366 ASSERT_EQ(data_in.
elf_path,
"/bin/true");
2367 ASSERT_EQ(data_out,
nullptr);
2375 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2379 EmbedderConfigBuilder::InitializationPreference::kMultiAOTInitialize);
2381 builder.SetSoftwareRendererConfig();
2384 ASSERT_FALSE(
engine.is_valid());
2398 const auto elf_path =
2402 data_in.
elf_path = elf_path.c_str();
2406 ASSERT_EQ(data_in.
elf_path, elf_path.c_str());
2407 ASSERT_NE(data_out,
nullptr);
2417 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2420 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2424 EmbedderConfigBuilder::InitializationPreference::kAOTDataInitialize);
2426 builder.SetSoftwareRendererConfig();
2429 ASSERT_TRUE(
engine.is_valid());
2436#if defined(__clang_analyzer__)
2437#define TEST_VM_SNAPSHOT_DATA nullptr
2438#define TEST_VM_SNAPSHOT_INSTRUCTIONS nullptr
2439#define TEST_ISOLATE_SNAPSHOT_DATA nullptr
2440#define TEST_ISOLATE_SNAPSHOT_INSTRUCTIONS nullptr
2450#if defined(OS_FUCHSIA)
2451 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2460 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2462 builder.SetSoftwareRendererConfig();
2476 builder.GetProjectArgs().vm_snapshot_data =
2478 builder.GetProjectArgs().vm_snapshot_instructions =
2480 builder.GetProjectArgs().isolate_snapshot_data =
2482 builder.GetProjectArgs().isolate_snapshot_instructions =
2490 ASSERT_NE(
settings.vm_snapshot_data(),
nullptr);
2491 ASSERT_NE(
settings.vm_snapshot_instr(),
nullptr);
2492 ASSERT_NE(
settings.isolate_snapshot_data(),
nullptr);
2493 ASSERT_NE(
settings.isolate_snapshot_instr(),
nullptr);
2494 ASSERT_NE(
settings.dart_library_sources_kernel(),
nullptr);
2506#if defined(OS_FUCHSIA)
2507 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2516 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2518 builder.SetSoftwareRendererConfig();
2521 builder.GetProjectArgs().vm_snapshot_data =
2522 reinterpret_cast<const uint8_t*
>(
"invalid_vm_data");
2523 builder.GetProjectArgs().vm_snapshot_instructions =
2524 reinterpret_cast<const uint8_t*
>(
"invalid_vm_instructions");
2525 builder.GetProjectArgs().isolate_snapshot_data =
2526 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2527 builder.GetProjectArgs().isolate_snapshot_instructions =
2528 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
2535 ASSERT_EQ(
settings.vm_snapshot_data(),
nullptr);
2536 ASSERT_EQ(
settings.vm_snapshot_instr(),
nullptr);
2537 ASSERT_EQ(
settings.isolate_snapshot_data(),
nullptr);
2538 ASSERT_EQ(
settings.isolate_snapshot_instr(),
nullptr);
2553 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2555 builder.SetSoftwareRendererConfig();
2569 builder.GetProjectArgs().vm_snapshot_data =
2571 builder.GetProjectArgs().vm_snapshot_instructions =
2573 builder.GetProjectArgs().isolate_snapshot_data =
2575 builder.GetProjectArgs().isolate_snapshot_instructions =
2579 ASSERT_TRUE(
engine.is_valid());
2593 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2595 builder.SetSoftwareRendererConfig();
2605 builder.GetProjectArgs().vm_snapshot_data =
2607 builder.GetProjectArgs().vm_snapshot_instructions =
2611 ASSERT_TRUE(
engine.is_valid());
2626 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2628 builder.SetSoftwareRendererConfig();
2631 builder.GetProjectArgs().isolate_snapshot_data =
2632 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2633 builder.GetProjectArgs().isolate_snapshot_instructions =
2634 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
2637 ASSERT_TRUE(
engine.is_valid());
2652 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2654 builder.SetSoftwareRendererConfig();
2656 ASSERT_EQ(
builder.GetProjectArgs().vm_snapshot_data,
nullptr);
2657 ASSERT_EQ(
builder.GetProjectArgs().vm_snapshot_instructions,
nullptr);
2658 ASSERT_EQ(
builder.GetProjectArgs().isolate_snapshot_data,
nullptr);
2659 ASSERT_EQ(
builder.GetProjectArgs().isolate_snapshot_instructions,
nullptr);
2662 ASSERT_TRUE(
engine.is_valid());
2666 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2668 builder.SetSoftwareRendererConfig();
2671 ASSERT_TRUE(
engine.is_valid());
2677 event.pixel_ratio = 0.0;
2678 event.physical_view_inset_top = 0.0;
2679 event.physical_view_inset_right = 0.0;
2680 event.physical_view_inset_bottom = 0.0;
2681 event.physical_view_inset_left = 0.0;
2687 event.pixel_ratio = 1.0;
2688 event.physical_view_inset_top = -1.0;
2689 event.physical_view_inset_right = -1.0;
2690 event.physical_view_inset_bottom = -1.0;
2691 event.physical_view_inset_left = -1.0;
2697 event.physical_view_inset_top = 700;
2698 event.physical_view_inset_right = 900;
2699 event.physical_view_inset_bottom = 700;
2700 event.physical_view_inset_left = 900;
2710 std::string entrypoint,
2712 const std::vector<uint8_t>& bytes) {
2714 test.GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2720 builder.SetSoftwareRendererConfig();
2722 builder.SetDartEntrypoint(std::move(entrypoint));
2724 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2,
2728 ASSERT_TRUE(
engine.is_valid());
2730 context.GetCompositor().SetNextPresentCallback(
2733 size_t layers_count) {
2735 ASSERT_EQ(layers[0]->backing_store->
type,
2739 layers[0]->backing_store->software2.user_data),
2749 event.pixel_ratio = 1.0;
2759template <
typename T>
2762 std::string entrypoint,
2765 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(&pixelvalue);
2767 test, std::move(entrypoint), pixfmt,
2768 std::vector<uint8_t>(bytes, bytes +
sizeof(
T)));
2771#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher) \
2772 TEST_F(EmbedderTest, SoftwareRenderingPixelFormats##test_name) { \
2773 expectSoftwareRenderingOutputMatches(*this, #dart_entrypoint, pixfmt, \
2791 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
2795 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
2812 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
2816 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
2833 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
2837 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
2848 std::shared_ptr<fml::AutoResetWaitableEvent>
latch;
2897 EXPECT_EQ(subject.
type, baseline.
type);
2905 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
2906 uint64_t echoed_char;
2929 message_latch->Signal();
2936 platform_task_runner->PostTask([&]() {
2938 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2940 builder.SetSoftwareRendererConfig();
2941 builder.SetDartEntrypoint(
"key_data_echo");
2942 builder.SetPlatformMessageCallback(
2947 context.AddNativeCallback(
2952 context.AddNativeCallback(
"EchoKeyEvent",
2956 ASSERT_TRUE(
engine.is_valid());
2966 .physical = 0x00070004,
2967 .logical = 0x00000000061,
2969 .synthesized =
false,
2972 platform_task_runner->PostTask([&]() {
2976 message_latch->Wait();
2979 EXPECT_EQ(echoed_char, 0x41llu);
2986 .physical = 0x00070005,
2987 .logical = 0x00000000062,
2989 .synthesized =
false,
2992 platform_task_runner->PostTask([&]() {
2996 message_latch->Wait();
2999 EXPECT_EQ(echoed_char, 0x2206llu);
3004 .timestamp = 1000000,
3006 .physical = 0x00070006,
3007 .logical = 0x00000000063,
3009 .synthesized =
true,
3012 platform_task_runner->PostTask([&]() {
3015 message_latch->Wait();
3018 EXPECT_EQ(echoed_char, 0llu);
3021 platform_task_runner->PostTask([&]() {
3025 shutdown_latch.
Wait();
3029 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3030 std::vector<FlutterKeyEvent> echoed_events;
3051 message_latch->Signal();
3058 platform_task_runner->PostTask([&]() {
3060 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3062 builder.SetSoftwareRendererConfig();
3063 builder.SetDartEntrypoint(
"key_data_late_echo");
3064 builder.SetPlatformMessageCallback(
3069 context.AddNativeCallback(
3074 context.AddNativeCallback(
"EchoKeyEvent",
3078 ASSERT_TRUE(
engine.is_valid());
3085 .physical = 0x00070004,
3086 .logical = 0x00000000061,
3088 .synthesized =
false,
3093 sample_event.timestamp = 1.0l;
3094 platform_task_runner->PostTask([&]() {
3096 message_latch->Signal();
3098 message_latch->Wait();
3101 EXPECT_EQ(echoed_events.size(), 0u);
3107 nullptr, &response_handle);
3111 .channel =
"test/starts_echo",
3114 .response_handle = response_handle,
3117 platform_task_runner->PostTask([&]() {
3126 message_latch->Wait();
3128 EXPECT_EQ(echoed_events.size(), 1u);
3131 sample_event.timestamp = 10.0l;
3132 platform_task_runner->PostTask([&]() {
3135 message_latch->Wait();
3138 EXPECT_EQ(echoed_events.size(), 2u);
3141 platform_task_runner->PostTask([&]() {
3145 shutdown_latch.
Wait();
3159 platform_task_runner->PostTask([&]() {
3161 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3163 builder.SetSoftwareRendererConfig();
3164 builder.SetDartEntrypoint(
"key_data_echo");
3165 context.AddNativeCallback(
3169 context.AddNativeCallback(
3173 ASSERT_TRUE(
engine.is_valid());
3185 .physical = 0x00070005,
3186 .logical = 0x00000000062,
3192 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3195 event.synthesized =
true;
3196 platform_task_runner->PostTask([&]() {
3205 [](
bool handled,
void* untyped_user_data) {
3206 KeyEventUserData* user_data =
3207 reinterpret_cast<KeyEventUserData*>(untyped_user_data);
3208 EXPECT_EQ(handled, true);
3209 user_data->latch->Signal();
3213 user_data1.latch->Wait();
3215 platform_task_runner->PostTask([&]() {
3219 shutdown_latch.
Wait();
3233 platform_task_runner->PostTask([&]() {
3235 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3238 builder.SetSoftwareRendererConfig();
3239 builder.SetDartEntrypoint(
"key_data_echo");
3240 context.AddNativeCallback(
3245 context.AddNativeCallback(
3249 ASSERT_TRUE(
engine.is_valid());
3261 .physical = 0x00070005,
3262 .logical = 0x00000000062,
3264 .synthesized =
false,
3271 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3275 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3278 auto callback23 = [](
bool handled,
void* untyped_user_data) {
3281 EXPECT_EQ(handled,
false);
3285 platform_task_runner->PostTask([&]() {
3289 user_data2.latch->Wait();
3290 user_data3.latch->Wait();
3296 platform_task_runner->PostTask([&]() {
3300 shutdown_latch.
Wait();
3320 platform_task_runner->PostTask([&]() {
3322 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3324 context.SetVsyncCallback([&](intptr_t baton) {
3325 platform_task_runner->PostTask([baton = baton, &
engine, &vsync_latch]() {
3327 NanosFromEpoch(32));
3331 context.AddNativeCallback(
3337 builder.SetSoftwareRendererConfig();
3339 builder.SetDartEntrypoint(
"empty_scene");
3341 ASSERT_TRUE(
engine.is_valid());
3348 event.pixel_ratio = 1.0;
3355 present_latch.
Wait();
3358 platform_task_runner->PostTask([&]() {
3362 shutdown_latch.
Wait();
3366 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3368 builder.SetSoftwareRendererConfig();
3369 builder.SetDartEntrypoint(
"can_schedule_frame");
3371 context.AddNativeCallback(
3377 context.AddNativeCallback(
3378 "SignalNativeCount",
3383 ASSERT_TRUE(
engine.is_valid());
3394 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3396 builder.SetSoftwareRendererConfig();
3397 builder.SetDartEntrypoint(
"draw_solid_red");
3400 ASSERT_TRUE(
engine.is_valid());
3408 callback_latch->
Signal();
3420 event.pixel_ratio = 1.0;
3421 event.physical_view_inset_top = 0.0;
3422 event.physical_view_inset_right = 0.0;
3423 event.physical_view_inset_bottom = 0.0;
3424 event.physical_view_inset_left = 0.0;
3428 callback_latch.
Wait();
3431#if defined(FML_OS_MACOSX)
3434 pthread_t tid = pthread_self();
3435 struct sched_param param;
3436 int policy = SCHED_OTHER;
3439 param.sched_priority = 10;
3442 param.sched_priority = 1;
3444 pthread_setschedparam(tid,
policy, ¶m);
3450 nullptr, MockThreadConfigSetter);
3454 struct sched_param ui_param;
3456 thread_host->GetTaskRunners().GetUITaskRunner()->PostTask([&] {
3457 pthread_t current_thread = pthread_self();
3458 pthread_getschedparam(current_thread, &ui_policy, &ui_param);
3459 ASSERT_EQ(ui_param.sched_priority, 10);
3465 struct sched_param io_param;
3466 thread_host->GetTaskRunners().GetIOTaskRunner()->PostTask([&] {
3467 pthread_t current_thread = pthread_self();
3468 pthread_getschedparam(current_thread, &io_policy, &io_param);
3469 ASSERT_EQ(io_param.sched_priority, 1);
3481 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3483 builder.SetSoftwareRendererConfig();
3484 builder.SetDartEntrypoint(
"pointer_data_packet");
3487 context.AddNativeCallback(
3491 context.AddNativeCallback(
3492 "SignalNativeCount",
3496 ASSERT_EQ(
count, 1);
3499 context.AddNativeCallback(
3500 "SignalNativeMessage",
3504 ASSERT_EQ(
"PointerData(viewId: 0, x: 123.0, y: 456.0)",
message);
3509 ASSERT_TRUE(
engine.is_valid());
3516 pointer_event.
x = 123;
3517 pointer_event.
y = 456;
3518 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
3526 message_latch.
Wait();
3532 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3534 builder.SetSoftwareRendererConfig();
3535 builder.SetDartEntrypoint(
"pointer_data_packet_view_id");
3538 context.AddNativeCallback(
3542 context.AddNativeCallback(
3543 "SignalNativeMessage",
3547 ASSERT_EQ(
"ViewID: 2",
message);
3552 ASSERT_TRUE(
engine.is_valid());
3558 metrics.
width = 800;
3566 info.view_metrics = &metrics;
3571 add_view_latch->
Signal();
3573 info.user_data = &add_view_latch;
3575 add_view_latch.
Wait();
3581 pointer_event.
x = 123;
3582 pointer_event.
y = 456;
3583 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
3590 message_latch.
Wait();
3594 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3596 builder.SetSoftwareRendererConfig();
3597 builder.SetDartEntrypoint(
"window_metrics_event_view_id");
3600 context.AddNativeCallback(
3604 context.AddNativeCallback(
3605 "SignalNativeMessage",
3609 ASSERT_EQ(
"Changed: [0]",
message);
3614 ASSERT_TRUE(
engine.is_valid());
3624 event.pixel_ratio = 1.5;
3631 message_latch.
Wait();
3635 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3637 builder.SetSoftwareRendererConfig();
3638 builder.SetDartEntrypoint(
"window_metrics_event_view_id");
3641 context.AddNativeCallback(
3646 context.AddNativeCallback(
3647 "SignalNativeMessage",
3654 ASSERT_EQ(
"Changed: [0]",
message);
3659 ASSERT_TRUE(
engine.is_valid());
3667 bad_event.
width = 200;
3681 event.pixel_ratio = 1.5;
3687 message_latch.
Wait();
3691 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3695 bool listening =
false;
3696 context.AddNativeCallback(
3700 EXPECT_STREQ(
update->channel,
"test/listen");
3707 builder.SetSoftwareRendererConfig();
3708 builder.SetDartEntrypoint(
"channel_listener_response");
3711 ASSERT_TRUE(
engine.is_valid());
3718 ASSERT_TRUE(listening);
3722 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3726 static void (*ffi_signal_native_test)() = []() ->
void {
3727 ffi_call_thread_id = std::this_thread::get_id();
3732 uintptr_t args_n) ->
void* {
3733 if (std::string_view(
name) ==
"FFISignalNativeTest") {
3734 return reinterpret_cast<void*
>(ffi_signal_native_test);
3742 context.AddNativeCallback(
3753 if (!
engine.is_valid()) {
3760 platform_task_runner->PostTask([&]() {
3761 platform_thread_id = std::this_thread::get_id();
3764 const auto task_runner_description =
3765 test_task_runner.GetFlutterTaskRunnerDescription();
3766 builder.SetSoftwareRendererConfig();
3767 builder.SetPlatformTaskRunner(&task_runner_description);
3768 builder.SetDartEntrypoint(
"invokePlatformThreadIsolate");
3769 builder.AddCommandLineArgument(
"--enable-platform-isolates");
3771 ASSERT_TRUE(
engine.is_valid());
3780 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
3785 ASSERT_EQ(platform_thread_id, ffi_call_thread_id);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
constexpr SkColor SK_ColorMAGENTA
constexpr SkColor SK_ColorGREEN
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...
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.
A task runner that we expect the embedder to provide but whose implementation is a real FML task runn...
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
void RunExpiredTasksNow()
virtual void PostTask(const fml::closure &task) override
@ 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)
DART_EXPORT Dart_Handle Dart_SetFfiNativeResolver(Dart_Handle library, Dart_FfiNativeResolver resolver)
struct _Dart_Handle * Dart_Handle
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
void *(* Dart_FfiNativeResolver)(const char *name, uintptr_t args_n)
struct _Dart_NativeArguments * Dart_NativeArguments
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
DART_EXPORT Dart_Handle Dart_RootLibrary(void)
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 engine via the FlutterTa...
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 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
@ 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)
#define FAIL(name, result)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_UNREACHABLE()
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
sk_sp< SkBlender > blender SkRect rect
const uint8_t * isolate_snapshot_data
const uint8_t * vm_snapshot_data
const uint8_t * vm_snapshot_instructions
const uint8_t * isolate_snapshot_instructions
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
static void expectSoftwareRenderingOutputMatches(EmbedderTest &test, std::string entrypoint, FlutterSoftwarePixelFormat pixfmt, T pixelvalue)
bool ImageMatchesFixture(const std::string &fixture_file_name, const sk_sp< SkImage > &scene_image)
TEST(DisplayListComplexity, EmptyDisplayList)
FlutterKeyEventDeviceType UnserializeKeyEventDeviceType(uint64_t source)
constexpr int64_t kFlutterImplicitViewId
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
it will be possible to load the file into Perfetto s trace viewer 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
it will be possible to load the file into Perfetto s trace viewer 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
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.
An update to whether a message channel has a listener set or not.
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
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.
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.
static constexpr SkISize Make(int32_t w, int32_t h)
static constexpr SkRect MakeWH(float w, float h)
std::shared_ptr< fml::AutoResetWaitableEvent > latch
The ThreadConfig is the thread info include thread name, thread priority.
#define CREATE_NATIVE_ENTRY(native_entry)
#define EXPECT_TRUE(handle)