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) {
62 auto engine = builder.LaunchEngine();
63 ASSERT_FALSE(
engine.is_valid());
69 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
71 builder.SetSoftwareRendererConfig();
72 auto engine = builder.LaunchEngine();
73 ASSERT_TRUE(
engine.is_valid());
83 builder.SetSoftwareRendererConfig();
84 for (
size_t i = 0; i < 3; ++i) {
85 auto engine = builder.LaunchEngine();
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");
101 auto engine = builder.LaunchEngine();
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");
140 auto engine = builder.LaunchEngine();
144 ASSERT_TRUE(
engine.is_valid());
150 builder.SetSoftwareRendererConfig();
151 builder.SetDartEntrypoint(
"terminateExitCodeHandler");
152 auto engine = builder.LaunchEngine();
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");
174 auto engine = builder.LaunchEngine();
184 bool implicitViewNotNull =
false;
186 context.AddNativeCallback(
194 builder.SetSoftwareRendererConfig();
195 builder.SetDartEntrypoint(
"implicitViewNotNull");
196 auto engine = builder.LaunchEngine();
202std::atomic_size_t EmbedderTestTaskRunner::sEmbedderTaskRunnerIdentifiers = {};
210 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
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);
242 engine = builder.LaunchEngine();
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();
280 auto engine = builder.LaunchEngine();
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};
307 engine = builder.LaunchEngine();
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(
339 auto engine = builder.LaunchEngine();
340 ASSERT_TRUE(
engine.is_valid());
348 ASSERT_NE(response_handle,
nullptr);
363 std::thread::id thread_id;
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(
381 auto engine = builder.LaunchEngine();
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);
448 auto engine = builder.LaunchEngine();
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);
490 auto engine = builder.LaunchEngine();
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();
516 auto engine = builder.LaunchEngine();
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");
547 auto engine = builder.LaunchEngine();
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");
567 auto engine = builder.LaunchEngine();
568 ASSERT_TRUE(
engine.is_valid());
569 callback_latch.
Wait();
577 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
579 builder.SetSoftwareRendererConfig();
583 auto engine = builder.LaunchEngine();
588 auto engine = builder.LaunchEngine();
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",
614 auto engine = builder.LaunchEngine();
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;
640 auto engine = builder.LaunchEngine();
641 ASSERT_TRUE(
engine.is_valid());
645 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
649 builder.SetCompositor();
650 builder.SetDartEntrypoint(
"render_implicit_view");
651 builder.SetRenderTargetType(
652 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
656 context.GetCompositor().SetNextPresentCallback(
658 size_t layers_count) {
663 auto engine = builder.LaunchEngine();
669 event.pixel_ratio = 1.0;
672 ASSERT_TRUE(
engine.is_valid());
677 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
681 builder.SetCompositor(
false,
683 builder.SetDartEntrypoint(
"render_implicit_view");
684 builder.SetRenderTargetType(
685 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
689 context.GetCompositor().SetNextPresentCallback(
691 size_t layers_count) {
696 auto engine = builder.LaunchEngine();
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);
726 builder.SetCompositor();
727 builder.SetDartEntrypoint(
"can_composite_platform_views_with_known_scene");
729 builder.SetRenderTargetType(
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();
885 canvas->drawRect(rect,
paint);
895 canvas->drawRect(rect,
paint);
901 <<
"Test was asked to composite an unknown platform view.";
904 return surface->makeImageSnapshot();
907 context.AddNativeCallback(
912 auto engine = builder.LaunchEngine();
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);
945 builder.SetCompositor();
946 builder.SetDartEntrypoint(
"can_composite_platform_views_transparent_overlay");
948 builder.SetRenderTargetType(
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);
1026 canvas->drawRect(rect,
paint);
1032 <<
"Test was asked to composite an unknown platform view.";
1035 return surface->makeImageSnapshot();
1038 context.AddNativeCallback(
1043 auto engine = builder.LaunchEngine();
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);
1082 builder.SetCompositor();
1083 builder.SetDartEntrypoint(
"can_composite_platform_views_no_overlay");
1085 builder.SetRenderTargetType(
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);
1163 canvas->drawRect(rect,
paint);
1169 <<
"Test was asked to composite an unknown platform view.";
1172 return surface->makeImageSnapshot();
1175 context.AddNativeCallback(
1180 auto engine = builder.LaunchEngine();
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();
1217 auto engine = builder.InitializeEngine();
1218 ASSERT_TRUE(
engine.is_valid());
1227 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
1228 builder.SetSoftwareRendererConfig();
1229 auto engine = builder.InitializeEngine();
1230 ASSERT_TRUE(
engine.is_valid());
1242 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext));
1243 builder.SetSoftwareRendererConfig();
1244 auto engine = builder.InitializeEngine();
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",
1292 auto engine = builder.LaunchEngine();
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",
1336 auto engine = builder.LaunchEngine();
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",
1385 auto engine = builder.LaunchEngine();
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();
1430 auto engine = builder.LaunchEngine();
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",
1466 auto engine = builder.LaunchEngine();
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",
1538 auto engine = builder.LaunchEngine();
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();
1587 auto engine = builder.LaunchEngine();
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);
1626 auto engine = builder.LaunchEngine();
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();
1759 builder.SetCompositor();
1760 builder.SetDartEntrypoint(
"render_all_views");
1762 builder.SetRenderTargetType(
1763 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer);
1766 context.GetCompositor().SetPresentCallback(
1768 size_t layers_count) {
1782 auto engine = builder.LaunchEngine();
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");
1840 builder.SetCompositor();
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;
1924 auto engine = builder.LaunchEngine();
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",
2009 auto engine = builder.LaunchEngine();
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();
2053 auto engine = builder.LaunchEngine();
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);
2083 builder.SetSoftwareRendererConfig(
SkISize::Make(1024, 600));
2084 builder.SetCompositor();
2085 builder.SetDartEntrypoint(
"verify_b143464703");
2087 builder.SetRenderTargetType(
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);
2164 canvas->drawRect(rect,
paint);
2169 <<
"Test was asked to composite an unknown platform view.";
2172 return surface->makeImageSnapshot();
2175 auto engine = builder.LaunchEngine();
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();
2209 auto engine = builder.LaunchEngine();
2211 ASSERT_TRUE(
engine.is_valid());
2223 size_t worker_count = 0;
2230 auto platform_task_runner = CreateNewThread(
"platform_thread");
2232 platform_task_runner->PostTask([&]() {
2234 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2237 builder.SetSoftwareRendererConfig();
2239 engine = builder.LaunchEngine();
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 );
2314 platform_task_runner->PostTask([&]() {
2316 sync_latch.Signal();
2321 ASSERT_FALSE(
engine.is_valid());
2334 ASSERT_EQ(data_out,
nullptr);
2343 ASSERT_EQ(data_out,
nullptr);
2350 ASSERT_EQ(data_in.
elf_path,
nullptr);
2351 ASSERT_EQ(data_out,
nullptr);
2358 ASSERT_EQ(data_out,
nullptr);
2364 ASSERT_EQ(data_in.
elf_path,
"/bin/true");
2365 ASSERT_EQ(data_out,
nullptr);
2373 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2377 EmbedderConfigBuilder::InitializationPreference::kMultiAOTInitialize);
2379 builder.SetSoftwareRendererConfig();
2381 auto engine = builder.LaunchEngine();
2382 ASSERT_FALSE(
engine.is_valid());
2396 const auto elf_path =
2400 data_in.
elf_path = elf_path.c_str();
2404 ASSERT_EQ(data_in.
elf_path, elf_path.c_str());
2405 ASSERT_NE(data_out,
nullptr);
2415 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2418 context.AddIsolateCreateCallback([&latch]() { latch.
Signal(); });
2422 EmbedderConfigBuilder::InitializationPreference::kAOTDataInitialize);
2424 builder.SetSoftwareRendererConfig();
2426 auto engine = builder.LaunchEngine();
2427 ASSERT_TRUE(
engine.is_valid());
2434#if defined(__clang_analyzer__)
2435#define TEST_VM_SNAPSHOT_DATA nullptr
2436#define TEST_VM_SNAPSHOT_INSTRUCTIONS nullptr
2437#define TEST_ISOLATE_SNAPSHOT_DATA nullptr
2438#define TEST_ISOLATE_SNAPSHOT_INSTRUCTIONS nullptr
2448#if defined(OS_FUCHSIA)
2449 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2458 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2460 builder.SetSoftwareRendererConfig();
2464 const std::string vm_snapshot_data =
2466 const std::string vm_snapshot_instructions =
2468 const std::string isolate_snapshot_data =
2470 const std::string isolate_snapshot_instructions =
2474 builder.GetProjectArgs().vm_snapshot_data =
2475 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
2476 builder.GetProjectArgs().vm_snapshot_instructions =
2477 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
2478 builder.GetProjectArgs().isolate_snapshot_data =
2479 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
2480 builder.GetProjectArgs().isolate_snapshot_instructions =
2481 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
2483 auto engine = builder.LaunchEngine();
2486 const Settings settings = shell.GetSettings();
2488 ASSERT_NE(settings.vm_snapshot_data(),
nullptr);
2489 ASSERT_NE(settings.vm_snapshot_instr(),
nullptr);
2490 ASSERT_NE(settings.isolate_snapshot_data(),
nullptr);
2491 ASSERT_NE(settings.isolate_snapshot_instr(),
nullptr);
2492 ASSERT_NE(settings.dart_library_sources_kernel(),
nullptr);
2504#if defined(OS_FUCHSIA)
2505 GTEST_SKIP() <<
"Inconsistent paths in Fuchsia.";
2514 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2516 builder.SetSoftwareRendererConfig();
2519 builder.GetProjectArgs().vm_snapshot_data =
2520 reinterpret_cast<const uint8_t*
>(
"invalid_vm_data");
2521 builder.GetProjectArgs().vm_snapshot_instructions =
2522 reinterpret_cast<const uint8_t*
>(
"invalid_vm_instructions");
2523 builder.GetProjectArgs().isolate_snapshot_data =
2524 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2525 builder.GetProjectArgs().isolate_snapshot_instructions =
2526 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
2528 auto engine = builder.LaunchEngine();
2531 const Settings settings = shell.GetSettings();
2533 ASSERT_EQ(settings.vm_snapshot_data(),
nullptr);
2534 ASSERT_EQ(settings.vm_snapshot_instr(),
nullptr);
2535 ASSERT_EQ(settings.isolate_snapshot_data(),
nullptr);
2536 ASSERT_EQ(settings.isolate_snapshot_instr(),
nullptr);
2551 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2553 builder.SetSoftwareRendererConfig();
2557 const std::string vm_snapshot_data =
2559 const std::string vm_snapshot_instructions =
2561 const std::string isolate_snapshot_data =
2563 const std::string isolate_snapshot_instructions =
2567 builder.GetProjectArgs().vm_snapshot_data =
2568 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
2569 builder.GetProjectArgs().vm_snapshot_instructions =
2570 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
2571 builder.GetProjectArgs().isolate_snapshot_data =
2572 reinterpret_cast<const uint8_t*
>(isolate_snapshot_data.c_str());
2573 builder.GetProjectArgs().isolate_snapshot_instructions =
2574 reinterpret_cast<const uint8_t*
>(isolate_snapshot_instructions.c_str());
2576 auto engine = builder.LaunchEngine();
2577 ASSERT_TRUE(
engine.is_valid());
2591 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2593 builder.SetSoftwareRendererConfig();
2597 const std::string vm_snapshot_data =
2599 const std::string vm_snapshot_instructions =
2603 builder.GetProjectArgs().vm_snapshot_data =
2604 reinterpret_cast<const uint8_t*
>(vm_snapshot_data.c_str());
2605 builder.GetProjectArgs().vm_snapshot_instructions =
2606 reinterpret_cast<const uint8_t*
>(vm_snapshot_instructions.c_str());
2608 auto engine = builder.LaunchEngine();
2609 ASSERT_TRUE(
engine.is_valid());
2624 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2626 builder.SetSoftwareRendererConfig();
2629 builder.GetProjectArgs().isolate_snapshot_data =
2630 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_data");
2631 builder.GetProjectArgs().isolate_snapshot_instructions =
2632 reinterpret_cast<const uint8_t*
>(
"invalid_snapshot_instructions");
2634 auto engine = builder.LaunchEngine();
2635 ASSERT_TRUE(
engine.is_valid());
2650 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2652 builder.SetSoftwareRendererConfig();
2654 ASSERT_EQ(builder.GetProjectArgs().vm_snapshot_data,
nullptr);
2655 ASSERT_EQ(builder.GetProjectArgs().vm_snapshot_instructions,
nullptr);
2656 ASSERT_EQ(builder.GetProjectArgs().isolate_snapshot_data,
nullptr);
2657 ASSERT_EQ(builder.GetProjectArgs().isolate_snapshot_instructions,
nullptr);
2659 auto engine = builder.LaunchEngine();
2660 ASSERT_TRUE(
engine.is_valid());
2664 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2666 builder.SetSoftwareRendererConfig();
2667 auto engine = builder.LaunchEngine();
2669 ASSERT_TRUE(
engine.is_valid());
2675 event.pixel_ratio = 0.0;
2676 event.physical_view_inset_top = 0.0;
2677 event.physical_view_inset_right = 0.0;
2678 event.physical_view_inset_bottom = 0.0;
2679 event.physical_view_inset_left = 0.0;
2685 event.pixel_ratio = 1.0;
2686 event.physical_view_inset_top = -1.0;
2687 event.physical_view_inset_right = -1.0;
2688 event.physical_view_inset_bottom = -1.0;
2689 event.physical_view_inset_left = -1.0;
2695 event.physical_view_inset_top = 700;
2696 event.physical_view_inset_right = 900;
2697 event.physical_view_inset_bottom = 700;
2698 event.physical_view_inset_left = 900;
2708 std::string entrypoint,
2710 const std::vector<uint8_t>& bytes) {
2712 test.GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2716 bool matches =
false;
2718 builder.SetSoftwareRendererConfig();
2719 builder.SetCompositor();
2720 builder.SetDartEntrypoint(std::move(entrypoint));
2721 builder.SetRenderTargetType(
2722 EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2,
2725 auto engine = builder.LaunchEngine();
2726 ASSERT_TRUE(
engine.is_valid());
2728 context.GetCompositor().SetNextPresentCallback(
2731 size_t layers_count) {
2733 ASSERT_EQ(layers[0]->backing_store->
type,
2737 layers[0]->backing_store->software2.user_data),
2747 event.pixel_ratio = 1.0;
2752 ASSERT_TRUE(matches);
2757template <
typename T>
2760 std::string entrypoint,
2763 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(&pixelvalue);
2765 test, std::move(entrypoint), pixfmt,
2766 std::vector<uint8_t>(bytes, bytes +
sizeof(
T)));
2769#define SW_PIXFMT_TEST_F(test_name, dart_entrypoint, pixfmt, matcher) \
2770 TEST_F(EmbedderTest, SoftwareRenderingPixelFormats##test_name) { \
2771 expectSoftwareRenderingOutputMatches(*this, #dart_entrypoint, pixfmt, \
2789 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
2793 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
2810 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
2814 (std::vector<uint8_t>{0x00, 0xFF, 0x00, 0xFF}));
2831 (std::vector<uint8_t>{0x00, 0x00, 0xFF, 0xFF}));
2835 (std::vector<uint8_t>{0xFF, 0x00, 0x00, 0xFF}));
2846 std::shared_ptr<fml::AutoResetWaitableEvent>
latch;
2895 EXPECT_EQ(subject.
type, baseline.
type);
2903 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
2904 uint64_t echoed_char;
2927 message_latch->Signal();
2930 auto platform_task_runner = CreateNewThread(
"platform_thread");
2934 platform_task_runner->PostTask([&]() {
2936 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
2938 builder.SetSoftwareRendererConfig();
2939 builder.SetDartEntrypoint(
"key_data_echo");
2940 builder.SetPlatformMessageCallback(
2945 context.AddNativeCallback(
2950 context.AddNativeCallback(
"EchoKeyEvent",
2953 engine = builder.LaunchEngine();
2954 ASSERT_TRUE(
engine.is_valid());
2964 .physical = 0x00070004,
2965 .logical = 0x00000000061,
2967 .synthesized =
false,
2970 platform_task_runner->PostTask([&]() {
2974 message_latch->Wait();
2977 EXPECT_EQ(echoed_char, 0x41llu);
2984 .physical = 0x00070005,
2985 .logical = 0x00000000062,
2987 .synthesized =
false,
2990 platform_task_runner->PostTask([&]() {
2994 message_latch->Wait();
2997 EXPECT_EQ(echoed_char, 0x2206llu);
3002 .timestamp = 1000000,
3004 .physical = 0x00070006,
3005 .logical = 0x00000000063,
3007 .synthesized =
true,
3010 platform_task_runner->PostTask([&]() {
3013 message_latch->Wait();
3016 EXPECT_EQ(echoed_char, 0llu);
3019 platform_task_runner->PostTask([&]() {
3023 shutdown_latch.
Wait();
3027 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
3028 std::vector<FlutterKeyEvent> echoed_events;
3049 message_latch->Signal();
3052 auto platform_task_runner = CreateNewThread(
"platform_thread");
3056 platform_task_runner->PostTask([&]() {
3058 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3060 builder.SetSoftwareRendererConfig();
3061 builder.SetDartEntrypoint(
"key_data_late_echo");
3062 builder.SetPlatformMessageCallback(
3067 context.AddNativeCallback(
3072 context.AddNativeCallback(
"EchoKeyEvent",
3075 engine = builder.LaunchEngine();
3076 ASSERT_TRUE(
engine.is_valid());
3083 .physical = 0x00070004,
3084 .logical = 0x00000000061,
3086 .synthesized =
false,
3091 sample_event.timestamp = 1.0l;
3092 platform_task_runner->PostTask([&]() {
3094 message_latch->Signal();
3096 message_latch->Wait();
3099 EXPECT_EQ(echoed_events.size(), 0u);
3105 nullptr, &response_handle);
3109 .channel =
"test/starts_echo",
3112 .response_handle = response_handle,
3115 platform_task_runner->PostTask([&]() {
3124 message_latch->Wait();
3126 EXPECT_EQ(echoed_events.size(), 1u);
3129 sample_event.timestamp = 10.0l;
3130 platform_task_runner->PostTask([&]() {
3133 message_latch->Wait();
3136 EXPECT_EQ(echoed_events.size(), 2u);
3139 platform_task_runner->PostTask([&]() {
3143 shutdown_latch.
Wait();
3155 auto platform_task_runner = CreateNewThread(
"platform_thread");
3157 platform_task_runner->PostTask([&]() {
3159 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3161 builder.SetSoftwareRendererConfig();
3162 builder.SetDartEntrypoint(
"key_data_echo");
3163 context.AddNativeCallback(
3167 context.AddNativeCallback(
3170 engine = builder.LaunchEngine();
3171 ASSERT_TRUE(
engine.is_valid());
3183 .physical = 0x00070005,
3184 .logical = 0x00000000062,
3190 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3193 event.synthesized =
true;
3194 platform_task_runner->PostTask([&]() {
3203 [](
bool handled,
void* untyped_user_data) {
3204 KeyEventUserData* user_data =
3205 reinterpret_cast<KeyEventUserData*>(untyped_user_data);
3206 EXPECT_EQ(handled, true);
3207 user_data->latch->Signal();
3211 user_data1.latch->Wait();
3213 platform_task_runner->PostTask([&]() {
3217 shutdown_latch.
Wait();
3229 auto platform_task_runner = CreateNewThread(
"platform_thread");
3231 platform_task_runner->PostTask([&]() {
3233 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3236 builder.SetSoftwareRendererConfig();
3237 builder.SetDartEntrypoint(
"key_data_echo");
3238 context.AddNativeCallback(
3243 context.AddNativeCallback(
3246 engine = builder.LaunchEngine();
3247 ASSERT_TRUE(
engine.is_valid());
3259 .physical = 0x00070005,
3260 .logical = 0x00000000062,
3262 .synthesized =
false,
3269 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3273 .
latch = std::make_shared<fml::AutoResetWaitableEvent>(),
3276 auto callback23 = [](
bool handled,
void* untyped_user_data) {
3279 EXPECT_EQ(handled,
false);
3283 platform_task_runner->PostTask([&]() {
3287 user_data2.latch->Wait();
3288 user_data3.latch->Wait();
3294 platform_task_runner->PostTask([&]() {
3298 shutdown_latch.
Wait();
3316 auto platform_task_runner = CreateNewThread(
"platform_thread");
3318 platform_task_runner->PostTask([&]() {
3320 GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3322 context.SetVsyncCallback([&](intptr_t baton) {
3323 platform_task_runner->PostTask([baton = baton, &
engine, &vsync_latch]() {
3325 NanosFromEpoch(32));
3329 context.AddNativeCallback(
3335 builder.SetSoftwareRendererConfig();
3336 builder.SetupVsyncCallback();
3337 builder.SetDartEntrypoint(
"empty_scene");
3338 engine = builder.LaunchEngine();
3339 ASSERT_TRUE(
engine.is_valid());
3346 event.pixel_ratio = 1.0;
3353 present_latch.
Wait();
3356 platform_task_runner->PostTask([&]() {
3360 shutdown_latch.
Wait();
3364 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3366 builder.SetSoftwareRendererConfig();
3367 builder.SetDartEntrypoint(
"can_schedule_frame");
3369 context.AddNativeCallback(
3375 context.AddNativeCallback(
3376 "SignalNativeCount",
3380 auto engine = builder.LaunchEngine();
3381 ASSERT_TRUE(
engine.is_valid());
3392 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3394 builder.SetSoftwareRendererConfig();
3395 builder.SetDartEntrypoint(
"draw_solid_red");
3397 auto engine = builder.LaunchEngine();
3398 ASSERT_TRUE(
engine.is_valid());
3406 callback_latch->
Signal();
3418 event.pixel_ratio = 1.0;
3419 event.physical_view_inset_top = 0.0;
3420 event.physical_view_inset_right = 0.0;
3421 event.physical_view_inset_bottom = 0.0;
3422 event.physical_view_inset_left = 0.0;
3426 callback_latch.
Wait();
3429#if defined(FML_OS_MACOSX)
3432 pthread_t tid = pthread_self();
3433 struct sched_param param;
3434 int policy = SCHED_OTHER;
3437 param.sched_priority = 10;
3440 param.sched_priority = 1;
3442 pthread_setschedparam(tid,
policy, ¶m);
3445TEST_F(EmbedderTest, EmbedderThreadHostUseCustomThreadConfig) {
3448 nullptr, MockThreadConfigSetter);
3452 struct sched_param ui_param;
3454 thread_host->GetTaskRunners().GetUITaskRunner()->PostTask([&] {
3455 pthread_t current_thread = pthread_self();
3456 pthread_getschedparam(current_thread, &ui_policy, &ui_param);
3457 ASSERT_EQ(ui_param.sched_priority, 10);
3463 struct sched_param io_param;
3464 thread_host->GetTaskRunners().GetIOTaskRunner()->PostTask([&] {
3465 pthread_t current_thread = pthread_self();
3466 pthread_getschedparam(current_thread, &io_policy, &io_param);
3467 ASSERT_EQ(io_param.sched_priority, 1);
3479 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3481 builder.SetSoftwareRendererConfig();
3482 builder.SetDartEntrypoint(
"pointer_data_packet");
3485 context.AddNativeCallback(
3489 context.AddNativeCallback(
3490 "SignalNativeCount",
3494 ASSERT_EQ(
count, 1);
3497 context.AddNativeCallback(
3498 "SignalNativeMessage",
3502 ASSERT_EQ(
"PointerData(viewId: 0, x: 123.0, y: 456.0)",
message);
3506 auto engine = builder.LaunchEngine();
3507 ASSERT_TRUE(
engine.is_valid());
3514 pointer_event.
x = 123;
3515 pointer_event.
y = 456;
3516 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
3524 message_latch.
Wait();
3530 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3532 builder.SetSoftwareRendererConfig();
3533 builder.SetDartEntrypoint(
"pointer_data_packet_view_id");
3536 context.AddNativeCallback(
3540 context.AddNativeCallback(
3541 "SignalNativeMessage",
3545 ASSERT_EQ(
"ViewID: 2",
message);
3549 auto engine = builder.LaunchEngine();
3550 ASSERT_TRUE(
engine.is_valid());
3557 pointer_event.
x = 123;
3558 pointer_event.
y = 456;
3559 pointer_event.
timestamp =
static_cast<size_t>(1234567890);
3566 message_latch.
Wait();
3570 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3572 builder.SetSoftwareRendererConfig();
3573 builder.SetDartEntrypoint(
"window_metrics_event_view_id");
3576 context.AddNativeCallback(
3580 context.AddNativeCallback(
3581 "SignalNativeMessage",
3585 ASSERT_EQ(
"Changed: [0]",
message);
3589 auto engine = builder.LaunchEngine();
3590 ASSERT_TRUE(
engine.is_valid());
3600 event.pixel_ratio = 1.5;
3607 message_latch.
Wait();
3611 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3613 builder.SetSoftwareRendererConfig();
3614 builder.SetDartEntrypoint(
"window_metrics_event_view_id");
3617 context.AddNativeCallback(
3622 context.AddNativeCallback(
3623 "SignalNativeMessage",
3630 ASSERT_EQ(
"Changed: [0]",
message);
3634 auto engine = builder.LaunchEngine();
3635 ASSERT_TRUE(
engine.is_valid());
3643 bad_event.
width = 200;
3657 event.pixel_ratio = 1.5;
3663 message_latch.
Wait();
3667 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3671 bool listening =
false;
3672 context.AddNativeCallback(
3676 EXPECT_STREQ(
update->channel,
"test/listen");
3683 builder.SetSoftwareRendererConfig();
3684 builder.SetDartEntrypoint(
"channel_listener_response");
3686 auto engine = builder.LaunchEngine();
3687 ASSERT_TRUE(
engine.is_valid());
3694 ASSERT_TRUE(listening);
3698 auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext);
3701 static std::thread::id ffi_call_thread_id;
3702 static void (*ffi_signal_native_test)() = []() ->
void {
3703 ffi_call_thread_id = std::this_thread::get_id();
3708 uintptr_t args_n) ->
void* {
3709 if (std::string_view(
name) ==
"FFISignalNativeTest") {
3710 return reinterpret_cast<void*
>(ffi_signal_native_test);
3718 context.AddNativeCallback(
3723 auto platform_task_runner = CreateNewThread(
"test_platform_thread");
3729 if (!
engine.is_valid()) {
3735 std::thread::id platform_thread_id;
3736 platform_task_runner->PostTask([&]() {
3737 platform_thread_id = std::this_thread::get_id();
3740 const auto task_runner_description =
3741 test_task_runner.GetFlutterTaskRunnerDescription();
3742 builder.SetSoftwareRendererConfig();
3743 builder.SetPlatformTaskRunner(&task_runner_description);
3744 builder.SetDartEntrypoint(
"invokePlatformThreadIsolate");
3745 builder.AddCommandLineArgument(
"--enable-platform-isolates");
3746 engine = builder.LaunchEngine();
3747 ASSERT_TRUE(
engine.is_valid());
3756 platform_task_runner->PostTask([&kill_latch] { kill_latch.
Signal(); });
3761 ASSERT_EQ(platform_thread_id, ffi_call_thread_id);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
#define TEST(S, s, D, expected)
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()
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)
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
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)