5#define FML_USED_ON_EMBEDDER
48#include "gmock/gmock.h"
51#include "third_party/rapidjson/include/rapidjson/writer.h"
52#include "third_party/skia/include/codec/SkCodecAnimation.h"
55#ifdef SHELL_ENABLE_VULKAN
68using ::testing::Return;
72std::unique_ptr<PlatformMessage> MakePlatformMessage(
74 const std::map<std::string, std::string>& values,
76 rapidjson::Document document;
77 auto&
allocator = document.GetAllocator();
80 for (
const auto& pair : values) {
81 rapidjson::Value
key(pair.first.c_str(), strlen(pair.first.c_str()),
83 rapidjson::Value
value(pair.second.c_str(), strlen(pair.second.c_str()),
88 rapidjson::StringBuffer buffer;
89 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
90 document.Accept(writer);
91 const uint8_t*
data =
reinterpret_cast<const uint8_t*
>(buffer.GetString());
93 std::unique_ptr<PlatformMessage>
message = std::make_unique<PlatformMessage>(
98class MockPlatformViewDelegate :
public PlatformView::Delegate {
100 OnPlatformViewCreated,
101 (std::unique_ptr<Surface>
surface),
104 MOCK_METHOD(
void, OnPlatformViewDestroyed, (), (
override));
106 MOCK_METHOD(
void, OnPlatformViewScheduleFrame, (), (
override));
109 OnPlatformViewAddView,
111 const ViewportMetrics& viewport_metrics,
116 OnPlatformViewRemoveView,
121 OnPlatformViewSendViewFocusEvent,
122 (
const ViewFocusEvent& event),
126 OnPlatformViewSetNextFrameCallback,
131 OnPlatformViewSetViewportMetrics,
132 (int64_t
view_id,
const ViewportMetrics& metrics),
136 OnPlatformViewDispatchPlatformMessage,
137 (std::unique_ptr<PlatformMessage>
message),
141 OnPlatformViewDispatchPointerDataPacket,
142 (std::unique_ptr<PointerDataPacket> packet),
146 OnPlatformViewDispatchSemanticsAction,
154 OnPlatformViewSetSemanticsEnabled,
159 OnPlatformViewSetAccessibilityFeatures,
164 OnPlatformViewRegisterTexture,
165 (std::shared_ptr<Texture>
texture),
169 OnPlatformViewUnregisterTexture,
174 OnPlatformViewMarkTextureFrameAvailable,
178 MOCK_METHOD(
const Settings&,
179 OnPlatformViewGetSettings,
185 (intptr_t loading_unit_id,
186 std::unique_ptr<const fml::Mapping> snapshot_data,
187 std::unique_ptr<const fml::Mapping> snapshot_instructions),
191 LoadDartDeferredLibraryError,
192 (intptr_t loading_unit_id,
193 const std::string error_message,
198 UpdateAssetResolverByType,
199 (std::unique_ptr<AssetResolver> updated_asset_resolver,
206 MOCK_METHOD(
bool, IsValid, (), (
override));
208 MOCK_METHOD(std::unique_ptr<SurfaceFrame>,
213 MOCK_METHOD(
DlMatrix, GetRootTransformation, (), (
const,
override));
215 MOCK_METHOD(GrDirectContext*, GetContext, (), (
override));
217 MOCK_METHOD(std::unique_ptr<GLContextResult>,
218 MakeRenderContextCurrent,
222 MOCK_METHOD(
bool, ClearRenderContext, (), (
override));
228 const TaskRunners& task_runners)
229 : PlatformView(delegate, task_runners) {}
230 MOCK_METHOD(std::unique_ptr<Surface>, CreateRenderingSurface, (), (
override));
231 MOCK_METHOD(std::shared_ptr<PlatformMessageHandler>,
232 GetPlatformMessageHandler,
237class TestPlatformView :
public PlatformView {
239 TestPlatformView(Shell& shell,
const TaskRunners& task_runners)
240 : PlatformView(shell, task_runners) {}
241 MOCK_METHOD(std::unique_ptr<Surface>, CreateRenderingSurface, (), (
override));
242 MOCK_METHOD(
void, ReleaseResourceContext, (), (
const,
override));
248 HandlePlatformMessage,
249 (std::unique_ptr<PlatformMessage>
message),
252 DoesHandlePlatformMessageOnPlatformThread,
257 (
int response_id, std::unique_ptr<fml::Mapping> mapping),
270 MOCK_METHOD(
void, Complete, (std::unique_ptr<fml::Mapping>
data), (
override));
271 MOCK_METHOD(
void, CompleteEmpty, (), (
override));
278 : valid_(valid), type_(
type) {}
280 bool IsValid()
const override {
return true; }
288 const std::string& asset_name)
const override {
293 const std::string& asset_pattern,
294 const std::optional<std::string>& subdir)
const override {
299 return this == &other;
310 std::shared_ptr<fml::ConcurrentMessageLoop> concurrent_loop)
311 : concurrent_loop_(
std::move(concurrent_loop)) {}
314 bool IsValid()
const override {
return true; }
326 const std::string& asset_name)
const override {
327 if (asset_name ==
"FontManifest.json" ||
328 asset_name ==
"NativeAssetsManifest.json") {
333 EXPECT_TRUE(concurrent_loop_->RunsTasksOnCurrentThread())
341 return this == &other;
345 std::shared_ptr<fml::ConcurrentMessageLoop> concurrent_loop_;
363 shell->GetPlatformView()->NotifyDestroyed();
374 bool is_torn_down =
false;
377 [shell, &latch, &is_torn_down]() {
378 is_torn_down = shell->GetRasterizer()->IsTornDown();
386 ASSERT_TRUE(shell !=
nullptr);
398 std::string flags_string = flags[0];
399 for (
size_t i = 1;
i < flags.size(); ++
i) {
401 flags_string += flags[
i];
408 const std::vector<fml::CommandLine::Option> options = {
412 EXPECT_EQ(settings.
dart_flags.size(), flags.size());
413 for (
size_t i = 0;
i < flags.size(); ++
i) {
432 return builder.
Build();
437 Settings settings = CreateSettingsForFixture();
438 TaskRunners task_runners(
"test",
nullptr,
nullptr,
nullptr,
nullptr);
439 auto shell = CreateShell(settings, task_runners);
446 Settings settings = CreateSettingsForFixture();
457 auto shell = CreateShell(settings, task_runners);
460 DestroyShell(std::move(shell), task_runners);
466 Settings settings = CreateSettingsForFixture();
470 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
472 auto shell = CreateShell(settings, task_runners);
475 DestroyShell(std::move(shell), task_runners);
481 Settings settings = CreateSettingsForFixture();
484 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
486 auto shell = CreateShell(settings, task_runners);
489 DestroyShell(std::move(shell), task_runners);
494 InitializeWithMultipleThreadButCallingThreadAsPlatformThread) {
496 Settings settings = CreateSettingsForFixture();
511 const auto vsync_clock = std::make_shared<ShellTestVsyncClock>();
516 return static_cast<std::unique_ptr<VsyncWaiter>>(
517 std::make_unique<VsyncWaiterFallback>(task_runners));
521 [](
Shell& shell) {
return std::make_unique<Rasterizer>(shell); });
524 DestroyShell(std::move(shell), task_runners);
530 Settings settings = CreateSettingsForFixture();
534 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
536 auto shell = CreateShell({
537 .settings = settings,
538 .task_runners = task_runners,
539 .is_gpu_disabled =
true,
544 bool is_disabled =
false;
545 shell->GetIsGpuDisabledSyncSwitch()->Execute(
547 ASSERT_TRUE(is_disabled);
549 DestroyShell(std::move(shell), task_runners);
555 Settings settings = CreateSettingsForFixture();
566 auto shell = CreateShell(settings, task_runners);
569 DestroyShell(std::move(shell), task_runners);
575 auto settings = CreateSettingsForFixture();
576 auto shell = CreateShell(settings);
580 ASSERT_TRUE(configuration.IsValid());
581 configuration.SetEntrypoint(
"fixturesAreFunctionalMain");
585 "SayHiFromFixturesAreFunctionalMain",
588 RunEngine(shell.get(), std::move(configuration));
591 DestroyShell(std::move(shell));
597 auto settings = CreateSettingsForFixture();
598 auto shell = CreateShell(settings);
602 ASSERT_TRUE(configuration.IsValid());
603 configuration.SetEntrypoint(
"testCanLaunchSecondaryIsolate");
610 RunEngine(shell.get(), std::move(configuration));
615 DestroyShell(std::move(shell));
621 auto settings = CreateSettingsForFixture();
622 auto shell = CreateShell(settings);
626 ASSERT_TRUE(configuration.IsValid());
627 std::string entry_point =
"fixturesAreFunctionalMain";
628 configuration.SetEntrypoint(entry_point);
631 std::string last_entry_point;
634 last_entry_point = shell->GetEngine()->GetLastEntrypoint();
638 RunEngine(shell.get(), std::move(configuration));
640 EXPECT_EQ(entry_point, last_entry_point);
642 DestroyShell(std::move(shell));
648 auto settings = CreateSettingsForFixture();
649 auto shell = CreateShell(settings);
653 ASSERT_TRUE(configuration.IsValid());
654 std::string entry_point =
"fixturesAreFunctionalMain";
655 std::vector<std::string> entry_point_args = {
"arg1"};
656 configuration.SetEntrypoint(entry_point);
657 configuration.SetEntrypointArgs(entry_point_args);
660 std::vector<std::string> last_entry_point_args;
663 last_entry_point_args = shell->GetEngine()->GetLastEntrypointArgs();
667 RunEngine(shell.get(), std::move(configuration));
669#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
670 EXPECT_EQ(last_entry_point_args, entry_point_args);
672 ASSERT_TRUE(last_entry_point_args.empty());
675 DestroyShell(std::move(shell));
680#if defined(OS_FUCHSIA)
681 GTEST_SKIP() <<
"This test flakes on Fuchsia. https://fxbug.dev/110006 ";
685 ::testing::FLAGS_gtest_death_test_style =
"threadsafe";
687 const std::vector<fml::CommandLine::Option> options = {
692 const char* expected =
693 "Encountered disallowed Dart VM flag: --verify_after_gc";
699 std::vector<const char*> flags = {
700 "--enable-isolate-groups",
701 "--no-enable-isolate-groups",
704 flags.push_back(
"--max_profile_depth 1");
705 flags.push_back(
"--random_seed 42");
706 flags.push_back(
"--max_subtype_cache_entries=22");
708 flags.push_back(
"--enable_mirrors");
716 auto settings = CreateSettingsForFixture();
717 std::unique_ptr<Shell> shell = CreateShell(settings);
720 PlatformViewNotifyCreated(shell.get());
723 configuration.SetEntrypoint(
"emptyMain");
725 RunEngine(shell.get(), std::move(configuration));
726 PumpOneFrame(shell.get());
727 ASSERT_FALSE(GetNeedsReportTimings(shell.get()));
739 ASSERT_EQ(UnreportedTimingsCount(shell.get()), 0);
740 DestroyShell(std::move(shell));
744 auto settings = CreateSettingsForFixture();
745 std::unique_ptr<Shell> shell = CreateShell(settings);
748 PlatformViewNotifyCreated(shell.get());
751 configuration.SetEntrypoint(
"dummyReportTimingsMain");
753 RunEngine(shell.get(), std::move(configuration));
754 PumpOneFrame(shell.get());
755 ASSERT_TRUE(GetNeedsReportTimings(shell.get()));
756 DestroyShell(std::move(shell));
763 for (
size_t i = 0;
i < timings.size();
i += 1) {
776 ASSERT_TRUE(timings[
i].Get(phase) >=
start);
777 ASSERT_TRUE(timings[
i].Get(phase) <= finish);
780 ASSERT_TRUE(last_phase_time <= timings[
i].Get(phase));
781 last_phase_time = timings[
i].Get(phase);
787 auto settings = CreateSettingsForFixture();
788 std::unique_ptr<Shell> shell = CreateShell(settings);
796 PlatformViewNotifyCreated(shell.get());
799 ASSERT_TRUE(configuration.IsValid());
800 configuration.SetEntrypoint(
"reportTimingsMain");
802 std::vector<int64_t> timestamps;
803 auto nativeTimingCallback = [&reportLatch,
804 ×tamps](Dart_NativeArguments
args) {
805 Dart_Handle exception =
nullptr;
806 ASSERT_EQ(timestamps.size(), 0ul);
811 AddNativeCallback(
"NativeReportTimingsCallback",
813 RunEngine(shell.get(), std::move(configuration));
817 for (
int i = 0;
i < 200;
i += 1) {
818 PumpOneFrame(shell.get());
822 DestroyShell(std::move(shell));
825 ASSERT_TRUE(!timestamps.empty());
841 auto settings = CreateSettingsForFixture();
845 settings.frame_rasterized_callback = [&timing,
851 std::unique_ptr<Shell> shell = CreateShell(settings);
854 using namespace std::chrono_literals;
855 std::this_thread::sleep_for(1ms);
866 ASSERT_TRUE(timing.
Get(phase) <
start);
870 PlatformViewNotifyCreated(shell.get());
873 configuration.SetEntrypoint(
"onBeginFrameMain");
875 int64_t frame_target_time;
876 auto nativeOnBeginFrame = [&frame_target_time](Dart_NativeArguments
args) {
877 Dart_Handle exception =
nullptr;
881 AddNativeCallback(
"NativeOnBeginFrame",
884 RunEngine(shell.get(), std::move(configuration));
885 PumpOneFrame(shell.get());
891 std::vector<FrameTiming> timings = {timing};
896 int64_t build_start =
898 ASSERT_GT(frame_target_time, build_start);
899 DestroyShell(std::move(shell));
903 auto settings = CreateSettingsForFixture();
905 bool end_frame_called =
false;
906 auto end_frame_callback =
907 [&](
bool should_resubmit_frame,
909 ASSERT_TRUE(raster_thread_merger.get() ==
nullptr);
910 ASSERT_FALSE(should_resubmit_frame);
911 end_frame_called =
true;
914 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
916 auto shell = CreateShell({
917 .settings = settings,
919 .shell_test_external_view_embedder = external_view_embedder,
924 PlatformViewNotifyCreated(shell.get());
927 configuration.SetEntrypoint(
"emptyMain");
929 RunEngine(shell.get(), std::move(configuration));
931 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
932 auto display_list_layer = std::make_shared<DisplayListLayer>(
934 root->Add(display_list_layer);
938 end_frame_latch.
Wait();
939 ASSERT_TRUE(end_frame_called);
941 DestroyShell(std::move(shell));
945#if defined(OS_FUCHSIA)
946 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
947 "https://github.com/flutter/flutter/issues/59816 ";
950 auto settings = CreateSettingsForFixture();
952 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
955 bool end_frame_called =
false;
956 std::vector<int64_t> visited_platform_views;
959 auto end_frame_callback =
960 [&](
bool should_resubmit_frame,
962 if (end_frame_called) {
965 ASSERT_TRUE(raster_thread_merger.get() ==
nullptr);
966 ASSERT_FALSE(should_resubmit_frame);
967 end_frame_called =
true;
968 visited_platform_views =
969 external_view_embedder->GetVisitedPlatformViews();
970 stack_50 = external_view_embedder->GetStack(50);
971 stack_75 = external_view_embedder->GetStack(75);
975 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
977 auto shell = CreateShell({
978 .settings = settings,
980 .shell_test_external_view_embedder = external_view_embedder,
985 PlatformViewNotifyCreated(shell.get());
988 configuration.SetEntrypoint(
"emptyMain");
990 RunEngine(shell.get(), std::move(configuration));
992 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
993 auto platform_view_layer = std::make_shared<PlatformViewLayer>(
995 root->Add(platform_view_layer);
996 auto transform_layer = std::make_shared<TransformLayer>(
998 root->Add(transform_layer);
999 auto clip_rect_layer = std::make_shared<ClipRectLayer>(
1001 transform_layer->Add(clip_rect_layer);
1003 auto backdrop_filter_layer =
1004 std::make_shared<BackdropFilterLayer>(filter, DlBlendMode::kSrcOver);
1005 clip_rect_layer->Add(backdrop_filter_layer);
1006 auto platform_view_layer2 = std::make_shared<PlatformViewLayer>(
1008 backdrop_filter_layer->Add(platform_view_layer2);
1012 end_frame_latch.
Wait();
1013 ASSERT_EQ(visited_platform_views, (std::vector<int64_t>{50, 75}));
1018 auto mutator = *stack_50.
Begin();
1020 ASSERT_EQ(mutator->GetFilterMutation().GetFilter(), *filter);
1023 ASSERT_EQ(mutator->GetFilterMutation().GetFilterRect(),
1026 DestroyShell(std::move(shell));
1032 ExternalEmbedderEndFrameIsCalledWhenPostPrerollResultIsResubmit) {
1033#if defined(OS_FUCHSIA)
1034 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1035 "https://github.com/flutter/flutter/issues/59816 ";
1038 auto settings = CreateSettingsForFixture();
1040 bool end_frame_called =
false;
1041 auto end_frame_callback =
1042 [&](
bool should_resubmit_frame,
1044 ASSERT_TRUE(raster_thread_merger.get() !=
nullptr);
1045 ASSERT_TRUE(should_resubmit_frame);
1046 end_frame_called =
true;
1047 end_frame_latch.
Signal();
1049 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1051 auto shell = CreateShell({
1052 .settings = settings,
1054 .shell_test_external_view_embedder = external_view_embedder,
1059 PlatformViewNotifyCreated(shell.get());
1062 configuration.SetEntrypoint(
"emptyMain");
1064 RunEngine(shell.get(), std::move(configuration));
1066 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1067 auto display_list_layer = std::make_shared<DisplayListLayer>(
1069 root->Add(display_list_layer);
1073 end_frame_latch.
Wait();
1075 ASSERT_TRUE(end_frame_called);
1077 DestroyShell(std::move(shell));
1082#if defined(OS_FUCHSIA)
1083 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1084 "https://github.com/flutter/flutter/issues/59816 ";
1087 auto settings = CreateSettingsForFixture();
1089 auto end_frame_callback =
1090 [&](
bool should_resubmit_frame,
1092 raster_thread_merger = std::move(thread_merger);
1094 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1097 auto shell = CreateShell({
1098 .settings = settings,
1100 .shell_test_external_view_embedder = external_view_embedder,
1105 PlatformViewNotifyCreated(shell.get());
1108 configuration.SetEntrypoint(
"emptyMain");
1110 RunEngine(shell.get(), std::move(configuration));
1112 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1113 auto display_list_layer = std::make_shared<DisplayListLayer>(
1115 root->Add(display_list_layer);
1123 PostSync(shell->GetTaskRunners().GetRasterTaskRunner(), [] {});
1124 ASSERT_TRUE(result.ok()) <<
"Result: " <<
static_cast<int>(result.code())
1125 <<
": " << result.message();
1127 ASSERT_TRUE(raster_thread_merger->IsEnabled());
1130 ASSERT_TRUE(raster_thread_merger->IsEnabled());
1134 ASSERT_TRUE(raster_thread_merger->IsEnabled());
1135 DestroyShell(std::move(shell));
1140#if defined(OS_FUCHSIA)
1141 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1142 "https://github.com/flutter/flutter/issues/59816 ";
1145 const int ThreadMergingLease = 10;
1146 auto settings = CreateSettingsForFixture();
1148 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1150 auto end_frame_callback =
1151 [&](
bool should_resubmit_frame,
1153 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1154 raster_thread_merger->MergeWithLease(ThreadMergingLease);
1156 ASSERT_TRUE(raster_thread_merger->IsMerged());
1157 external_view_embedder->UpdatePostPrerollResult(
1160 end_frame_latch.
Signal();
1162 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1165 external_view_embedder->UpdatePostPrerollResult(
1167 auto shell = CreateShell({
1168 .settings = settings,
1170 .shell_test_external_view_embedder = external_view_embedder,
1175 PlatformViewNotifyCreated(shell.get());
1178 configuration.SetEntrypoint(
"emptyMain");
1180 RunEngine(shell.get(), std::move(configuration));
1182 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1183 auto display_list_layer = std::make_shared<DisplayListLayer>(
1185 root->Add(display_list_layer);
1190 end_frame_latch.
Wait();
1197 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1198 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1203 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1204 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1209 DestroyShell(std::move(shell));
1214#if defined(OS_FUCHSIA)
1215 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1216 "https://github.com/flutter/flutter/issues/59816 ";
1219 const int kThreadMergingLease = 10;
1220 auto settings = CreateSettingsForFixture();
1222 auto end_frame_callback =
1223 [&](
bool should_resubmit_frame,
1225 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1226 raster_thread_merger->MergeWithLease(kThreadMergingLease);
1228 end_frame_latch.
Signal();
1233 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1236 auto shell = CreateShell({
1237 .settings = settings,
1239 .shell_test_external_view_embedder = external_view_embedder,
1244 PlatformViewNotifyCreated(shell.get());
1247 configuration.SetEntrypoint(
"emptyMain");
1249 RunEngine(shell.get(), std::move(configuration));
1251 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1252 auto display_list_layer = std::make_shared<DisplayListLayer>(
1254 root->Add(display_list_layer);
1259 end_frame_latch.
Wait();
1261 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1262 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1266 external_view_embedder->UpdatePostPrerollResult(
1278 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1279 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1284 DestroyShell(std::move(shell));
1289 OnPlatformViewDestroyWithThreadMergerWhileThreadsAreUnmerged) {
1290#if defined(OS_FUCHSIA)
1291 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1292 "https://github.com/flutter/flutter/issues/59816 ";
1295 auto settings = CreateSettingsForFixture();
1297 auto end_frame_callback =
1298 [&](
bool should_resubmit_frame,
1300 end_frame_latch.
Signal();
1302 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1304 auto shell = CreateShell({
1305 .settings = settings,
1307 .shell_test_external_view_embedder = external_view_embedder,
1312 PlatformViewNotifyCreated(shell.get());
1315 configuration.SetEntrypoint(
"emptyMain");
1317 RunEngine(shell.get(), std::move(configuration));
1319 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1320 auto display_list_layer = std::make_shared<DisplayListLayer>(
1322 root->Add(display_list_layer);
1325 end_frame_latch.
Wait();
1329 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1330 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1335 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1336 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1341 DestroyShell(std::move(shell));
1346 auto settings = CreateSettingsForFixture();
1348 auto shell = CreateShell(settings);
1351 PlatformViewNotifyCreated(shell.get());
1354 configuration.SetEntrypoint(
"emptyMain");
1356 RunEngine(shell.get(), std::move(configuration));
1358 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1359 auto display_list_layer = std::make_shared<DisplayListLayer>(
1361 root->Add(display_list_layer);
1367 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1368 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1373 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1374 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1379 DestroyShell(std::move(shell));
1384#if defined(OS_FUCHSIA)
1385 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1386 "https://github.com/flutter/flutter/issues/59816 ";
1389 auto settings = CreateSettingsForFixture();
1391 auto end_frame_callback =
1392 [&](
bool should_resubmit_frame,
1394 end_frame_latch.
Signal();
1396 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1408 auto shell = CreateShell({
1409 .settings = settings,
1410 .task_runners = task_runners,
1412 .shell_test_external_view_embedder = external_view_embedder,
1417 PlatformViewNotifyCreated(shell.get());
1420 configuration.SetEntrypoint(
"emptyMain");
1422 RunEngine(shell.get(), std::move(configuration));
1424 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1425 auto display_list_layer = std::make_shared<DisplayListLayer>(
1427 root->Add(display_list_layer);
1430 end_frame_latch.
Wait();
1437 DestroyShell(std::move(shell), task_runners);
1442 auto settings = CreateSettingsForFixture();
1444 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1445 bool used_this_frame =
true;
1446 auto end_frame_callback =
1447 [&](
bool should_resubmit_frame,
1450 used_this_frame = external_view_embedder->GetUsedThisFrame();
1451 end_frame_latch.
Signal();
1453 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1455 auto shell = CreateShell({
1456 .settings = settings,
1458 .shell_test_external_view_embedder = external_view_embedder,
1463 PlatformViewNotifyCreated(shell.get());
1466 configuration.SetEntrypoint(
"emptyMain");
1468 RunEngine(shell.get(), std::move(configuration));
1470 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
1471 auto display_list_layer = std::make_shared<DisplayListLayer>(
1473 root->Add(display_list_layer);
1476 end_frame_latch.
Wait();
1477 ASSERT_FALSE(used_this_frame);
1482 DestroyShell(std::move(shell));
1488#if defined(OS_FUCHSIA)
1489 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1490 "https://github.com/flutter/flutter/issues/59816 ";
1493 auto settings = CreateSettingsForFixture();
1495 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1497 auto end_frame_callback =
1498 [&](
bool should_resubmit_frame,
1500 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1501 raster_thread_merger->MergeWithLease(10);
1502 external_view_embedder->UpdatePostPrerollResult(
1505 end_frame_latch.
Signal();
1507 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1510 auto shell = CreateShell({
1511 .settings = settings,
1513 .shell_test_external_view_embedder = external_view_embedder,
1517 PlatformViewNotifyCreated(shell.get());
1520 configuration.SetEntrypoint(
"emptyMain");
1521 RunEngine(shell.get(), std::move(configuration));
1523 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
1525 PumpOneFrame(shell.get());
1528 end_frame_latch.
Wait();
1532 end_frame_latch.
Wait();
1535 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
1537 PlatformViewNotifyDestroyed(shell.get());
1538 DestroyShell(std::move(shell));
1542TEST(SettingsTest, FrameTimingSetsAndGetsProperly) {
1547 int lastPhaseIndex = -1;
1550 ASSERT_TRUE(phase > lastPhaseIndex);
1551 lastPhaseIndex = phase;
1554 timing.
Set(phase, fake_time);
1555 ASSERT_TRUE(timing.
Get(phase) == fake_time);
1560 auto settings = CreateSettingsForFixture();
1561 std::unique_ptr<Shell> shell = CreateShell(settings);
1564 PlatformViewNotifyCreated(shell.get());
1567 ASSERT_TRUE(configuration.IsValid());
1568 configuration.SetEntrypoint(
"reportTimingsMain");
1570 std::vector<int64_t> timestamps;
1571 auto nativeTimingCallback = [&reportLatch,
1572 ×tamps](Dart_NativeArguments
args) {
1573 Dart_Handle exception =
nullptr;
1574 ASSERT_EQ(timestamps.size(), 0ul);
1576 args, 0, exception);
1579 AddNativeCallback(
"NativeReportTimingsCallback",
1581 ASSERT_TRUE(configuration.IsValid());
1582 RunEngine(shell.get(), std::move(configuration));
1584 for (
int i = 0;
i < 10;
i += 1) {
1585 PumpOneFrame(shell.get());
1589 DestroyShell(std::move(shell));
1597 auto settings = CreateSettingsForFixture();
1598 std::unique_ptr<Shell> shell = CreateShell(settings);
1601 PlatformViewNotifyCreated(shell.get());
1604 configuration.SetEntrypoint(
"emptyMain");
1606 RunEngine(shell.get(), std::move(configuration));
1607 PumpOneFrame(shell.get());
1609 ASSERT_TRUE(result.
ok());
1611 DestroyShell(std::move(shell));
1615 auto settings = CreateSettingsForFixture();
1616 std::unique_ptr<Shell> shell = CreateShell(settings);
1619 PlatformViewNotifyCreated(shell.get());
1622 configuration.SetEntrypoint(
"emptyMain");
1624 RunEngine(shell.get(), std::move(configuration));
1627 EXPECT_FALSE(result.
ok());
1628 EXPECT_EQ(result.
message(),
"timeout");
1631 DestroyShell(std::move(shell));
1635 auto settings = CreateSettingsForFixture();
1636 std::unique_ptr<Shell> shell = CreateShell(settings);
1639 PlatformViewNotifyCreated(shell.get());
1642 configuration.SetEntrypoint(
"emptyMain");
1644 RunEngine(shell.get(), std::move(configuration));
1646 ASSERT_FALSE(result.
ok());
1649 DestroyShell(std::move(shell));
1653 auto settings = CreateSettingsForFixture();
1654 std::unique_ptr<Shell> shell = CreateShell(settings);
1657 PlatformViewNotifyCreated(shell.get());
1660 configuration.SetEntrypoint(
"emptyMain");
1662 RunEngine(shell.get(), std::move(configuration));
1663 PumpOneFrame(shell.get());
1665 ASSERT_TRUE(result.
ok());
1666 for (
int i = 0;
i < 100; ++
i) {
1668 ASSERT_TRUE(result.
ok());
1671 DestroyShell(std::move(shell));
1677 Settings settings = CreateSettingsForFixture();
1678 auto task_runner = CreateNewThread();
1679 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1681 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
1684 PlatformViewNotifyCreated(shell.get());
1687 configuration.SetEntrypoint(
"emptyMain");
1689 RunEngine(shell.get(), std::move(configuration));
1690 PumpOneFrame(shell.get());
1692 task_runner->PostTask([&shell, &event] {
1694 ASSERT_FALSE(result.
ok());
1700 DestroyShell(std::move(shell), task_runners);
1708 if (auto rasterizer = shell.GetRasterizer()) {
1709 bytes = rasterizer->GetResourceCacheMaxBytes().value_or(0U);
1719 auto settings = CreateSettingsForFixture();
1720 settings.resource_cache_max_bytes_threshold = 4000000U;
1721 GrMockOptions main_context_options;
1722 sk_sp<GrDirectContext> main_context =
1723 GrDirectContext::MakeMock(&main_context_options);
1726 auto result = std::make_unique<TestPlatformView>(shell, task_runners);
1727 ON_CALL(*result, CreateRenderingSurface())
1728 .WillByDefault(::testing::Invoke([main_context] {
1729 auto surface = std::make_unique<MockSurface>();
1730 ON_CALL(*
surface, GetContext())
1731 .WillByDefault(Return(main_context.get()));
1732 ON_CALL(*
surface, IsValid()).WillByDefault(Return(
true));
1733 ON_CALL(*
surface, MakeRenderContextCurrent())
1734 .WillByDefault(::testing::Invoke([] {
1735 return std::make_unique<GLContextDefaultResult>(
true);
1742 auto shell = CreateShell({
1743 .settings = settings,
1744 .task_runners = task_runners,
1745 .platform_view_create_callback = platform_view_create_callback,
1749 PlatformViewNotifyCreated(shell.get());
1752 configuration.SetEntrypoint(
"emptyMain");
1754 RunEngine(shell.get(), std::move(configuration));
1755 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
1756 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1757 {1.0, 100, 100, 22, 0});
1761 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
1762 static_cast<size_t>(480000U));
1764 auto shell_spawn_callback = [&]() {
1765 std::unique_ptr<Shell> spawn;
1767 shell->GetTaskRunners().GetPlatformTaskRunner(),
1768 [
this, &spawn, &spawner = shell, platform_view_create_callback]() {
1769 auto configuration =
1770 RunConfiguration::InferFromSettings(CreateSettingsForFixture());
1771 configuration.SetEntrypoint(
"emptyMain");
1772 spawn = spawner->Spawn(
1773 std::move(configuration),
"", platform_view_create_callback,
1774 [](Shell& shell) { return std::make_unique<Rasterizer>(shell); });
1775 ASSERT_NE(
nullptr, spawn.get());
1776 ASSERT_TRUE(ValidateShell(spawn.get()));
1781 std::unique_ptr<Shell> second_shell = shell_spawn_callback();
1782 PlatformViewNotifyCreated(second_shell.get());
1783 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1785 second_shell->GetPlatformView()->SetViewportMetrics(
1786 kImplicitViewId, {1.0, 100, 100, 22, 0});
1790 static_cast<size_t>(960000U));
1792 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1794 second_shell->GetPlatformView()->SetViewportMetrics(
1795 kImplicitViewId, {1.0, 100, 300, 22, 0});
1799 static_cast<size_t>(1920000U));
1801 std::unique_ptr<Shell> third_shell = shell_spawn_callback();
1802 PlatformViewNotifyCreated(third_shell.get());
1803 PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
1805 third_shell->GetPlatformView()->SetViewportMetrics(
1806 kImplicitViewId, {1.0, 400, 100, 22, 0});
1810 static_cast<size_t>(3840000U));
1812 PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
1814 third_shell->GetPlatformView()->SetViewportMetrics(
1815 kImplicitViewId, {1.0, 800, 100, 22, 0});
1819 static_cast<size_t>(4000000U));
1820 DestroyShell(std::move(third_shell), task_runners);
1823 static_cast<size_t>(4000000U));
1825 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1827 second_shell->GetPlatformView()->SetViewportMetrics(
1828 kImplicitViewId, {1.0, 100, 100, 22, 0});
1832 static_cast<size_t>(960000U));
1834 DestroyShell(std::move(second_shell), task_runners);
1835 DestroyShell(std::move(shell), task_runners);
1839 Settings settings = CreateSettingsForFixture();
1840 auto task_runner = CreateNewThread();
1841 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1843 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
1846 PlatformViewNotifyCreated(shell.get());
1848 auto configuration = RunConfiguration::InferFromSettings(settings);
1849 configuration.SetEntrypoint(
"emptyMain");
1851 RunEngine(shell.get(), std::move(configuration));
1852 PumpOneFrame(shell.get());
1859#if defined(SHELL_ENABLE_VULKAN) && !defined(SHELL_ENABLE_GL)
1862#elif defined(SHELL_ENABLE_METAL)
1864 static_cast<size_t>(256 * (1 << 20)));
1867 static_cast<size_t>(24 * (1 << 20)));
1871 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
1872 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1873 {1.0, 400, 200, 22, 0});
1875 PumpOneFrame(shell.get());
1877 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), 3840000U);
1879 std::string request_json = R
"json({
1880 "method": "Skia.setResourceCacheMaxBytes",
1885 auto platform_message = std::make_unique<PlatformMessage>(
1886 "flutter/skia", std::move(
data),
nullptr);
1887 SendEnginePlatformMessage(shell.get(), std::move(platform_message));
1888 PumpOneFrame(shell.get());
1889 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), 10000U);
1892 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
1893 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1894 {1.0, 800, 400, 22, 0});
1896 PumpOneFrame(shell.get());
1898 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), 10000U);
1899 DestroyShell(std::move(shell), task_runners);
1903 Settings settings = CreateSettingsForFixture();
1904 auto task_runner = CreateNewThread();
1905 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1907 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
1910 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
1911 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1912 {1.0, 400, 200, 22, 0});
1914 PumpOneFrame(shell.get());
1917 PlatformViewNotifyCreated(shell.get());
1919 auto configuration = RunConfiguration::InferFromSettings(settings);
1920 configuration.SetEntrypoint(
"emptyMain");
1922 RunEngine(shell.get(), std::move(configuration));
1923 PumpOneFrame(shell.get());
1925 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
1926 static_cast<size_t>(3840000U));
1927 DestroyShell(std::move(shell), task_runners);
1931 Settings settings = CreateSettingsForFixture();
1932 auto task_runner = CreateNewThread();
1933 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1935 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
1938 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
1939 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1940 {1.0, 400, 200, 22, 0});
1942 PumpOneFrame(shell.get());
1945 PlatformViewNotifyCreated(shell.get());
1947 auto configuration = RunConfiguration::InferFromSettings(settings);
1948 configuration.SetEntrypoint(
"testSkiaResourceCacheSendsResponse");
1950 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
1951 static_cast<size_t>(3840000U));
1958 RunEngine(shell.get(), std::move(configuration));
1959 PumpOneFrame(shell.get());
1963 EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell),
1964 static_cast<size_t>(10000U));
1965 DestroyShell(std::move(shell), task_runners);
1969 Settings settings = CreateSettingsForFixture();
1970 auto task_runner = CreateNewThread();
1972 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1975 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
1978 PlatformViewNotifyCreated(shell.get());
1980 auto configuration = RunConfiguration::InferFromSettings(settings);
1981 configuration.SetEntrypoint(
"canCreateImageFromDecompressedData");
1984 AddNativeCallback(
"NotifyWidthHeight",
1987 Dart_GetNativeArgument(
args, 0));
1989 Dart_GetNativeArgument(
args, 1));
1990 ASSERT_EQ(
width, 10);
1995 RunEngine(shell.get(), std::move(configuration));
1998 DestroyShell(std::move(shell), task_runners);
2001class MockTexture :
public Texture {
2004 std::shared_ptr<fml::AutoResetWaitableEvent> latch)
2005 :
Texture(textureId), latch_(
std::move(latch)) {}
2020 frames_available_++;
2025 unregistered_ =
true;
2033 bool unregistered_ =
false;
2034 int frames_available_ = 0;
2035 std::shared_ptr<fml::AutoResetWaitableEvent> latch_;
2039 Settings settings = CreateSettingsForFixture();
2040 auto configuration = RunConfiguration::InferFromSettings(settings);
2041 auto task_runner = CreateNewThread();
2042 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2044 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2047 PlatformViewNotifyCreated(shell.get());
2049 RunEngine(shell.get(), std::move(configuration));
2051 std::shared_ptr<fml::AutoResetWaitableEvent> latch =
2052 std::make_shared<fml::AutoResetWaitableEvent>();
2054 std::shared_ptr<MockTexture> mockTexture =
2055 std::make_shared<MockTexture>(0, latch);
2058 shell->GetTaskRunners().GetRasterTaskRunner(), [&]() {
2059 shell->GetPlatformView()->RegisterTexture(mockTexture);
2060 shell->GetPlatformView()->MarkTextureFrameAvailable(0);
2064 EXPECT_EQ(mockTexture->frames_available(), 1);
2067 shell->GetTaskRunners().GetRasterTaskRunner(),
2068 [&]() { shell->GetPlatformView()->UnregisterTexture(0); });
2071 EXPECT_EQ(mockTexture->unregistered(),
true);
2072 DestroyShell(std::move(shell), task_runners);
2076 const std::string
message =
"dummy isolate launch data.";
2078 Settings settings = CreateSettingsForFixture();
2080 std::make_shared<fml::DataMapping>(
message);
2082 GetCurrentTaskRunner(),
2089 AddNativeCallback(
"NotifyMessage",
2091 const auto message_from_dart =
2093 Dart_GetNativeArgument(
args, 0));
2094 ASSERT_EQ(
message, message_from_dart);
2098 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2100 ASSERT_TRUE(shell->IsSetup());
2101 auto configuration = RunConfiguration::InferFromSettings(settings);
2102 configuration.SetEntrypoint(
"canAccessIsolateLaunchData");
2105 shell->RunEngine(std::move(configuration), [&](
auto result) {
2106 ASSERT_EQ(result, Engine::RunStatus::Success);
2109 message_latch.
Wait();
2110 DestroyShell(std::move(shell), task_runners);
2114 Settings settings = CreateSettingsForFixture();
2121 AddNativeCallback(
"NativeOnBeginFrame",
2125 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2126 ASSERT_TRUE(shell->IsSetup());
2128 auto configuration = RunConfiguration::InferFromSettings(settings);
2129 configuration.SetEntrypoint(
"onBeginFrameWithNotifyNativeMain");
2130 RunEngine(shell.get(), std::move(configuration));
2136 shell->GetTaskRunners().GetPlatformTaskRunner(),
2137 [&shell]() { shell->GetPlatformView()->ScheduleFrame(); });
2139 DestroyShell(std::move(shell), task_runners);
2143 bool is_on_begin_frame_called =
false;
2144 bool is_secondary_callback_called =
false;
2145 bool test_started =
false;
2146 Settings settings = CreateSettingsForFixture();
2153 AddNativeCallback(
"NativeOnBeginFrame",
2155 if (!test_started) {
2158 EXPECT_FALSE(is_on_begin_frame_called);
2159 EXPECT_FALSE(is_secondary_callback_called);
2160 is_on_begin_frame_called =
true;
2163 std::unique_ptr<Shell> shell = CreateShell({
2164 .settings = settings,
2165 .task_runners = task_runners,
2167 ASSERT_TRUE(shell->IsSetup());
2169 auto configuration = RunConfiguration::InferFromSettings(settings);
2170 configuration.SetEntrypoint(
"onBeginFrameWithNotifyNativeMain");
2171 RunEngine(shell.get(), std::move(configuration));
2177 shell->GetTaskRunners().GetUITaskRunner(), [&]() {
2178 shell->GetEngine()->ScheduleSecondaryVsyncCallback(0, [&]() {
2179 if (!test_started) {
2182 EXPECT_TRUE(is_on_begin_frame_called);
2183 EXPECT_FALSE(is_secondary_callback_called);
2184 is_secondary_callback_called = true;
2185 count_down_latch.CountDown();
2187 shell->GetEngine()->ScheduleFrame();
2188 test_started =
true;
2190 count_down_latch.Wait();
2191 EXPECT_TRUE(is_on_begin_frame_called);
2192 EXPECT_TRUE(is_secondary_callback_called);
2193 DestroyShell(std::move(shell), task_runners);
2197 FML_LOG(ERROR) <<
"---------- " << title;
2198 std::ostringstream ostr;
2199 for (
size_t i = 0;
i <
data->size();) {
2200 ostr << std::hex << std::setfill(
'0') << std::setw(2)
2201 <<
static_cast<int>(
data->bytes()[
i]) <<
" ";
2203 if (
i % 16 == 0 ||
i ==
data->size()) {
2212 auto settings = CreateSettingsForFixture();
2214 settings.frame_rasterized_callback =
2217 std::unique_ptr<Shell> shell = CreateShell(settings);
2220 PlatformViewNotifyCreated(shell.get());
2222 auto configuration = RunConfiguration::InferFromSettings(settings);
2223 configuration.SetEntrypoint(
"emptyMain");
2225 RunEngine(shell.get(), std::move(configuration));
2227 LayerTreeBuilder builder = [&](
const std::shared_ptr<ContainerLayer>& root) {
2228 auto display_list_layer = std::make_shared<DisplayListLayer>(
2230 root->Add(display_list_layer);
2233 PumpOneFrame(shell.get(), ViewContent::ImplicitView(100, 100, builder));
2234 firstFrameLatch.
Wait();
2236 std::promise<Rasterizer::Screenshot> screenshot_promise;
2237 auto screenshot_future = screenshot_promise.get_future();
2240 shell->GetTaskRunners().GetRasterTaskRunner(),
2241 [&screenshot_promise, &shell]() {
2242 auto rasterizer = shell->GetRasterizer();
2243 screenshot_promise.set_value(rasterizer->ScreenshotLastLayerTree(
2244 Rasterizer::ScreenshotType::CompressedImage, false));
2251 fixtures_dir,
"shelltest_screenshot.png");
2255 sk_sp<SkData> reference_data = SkData::MakeWithoutCopy(
2256 reference_png->GetMapping(), reference_png->GetSize());
2258 sk_sp<SkData> screenshot_data = screenshot_future.get().data;
2259 if (!reference_data->equals(screenshot_data.get())) {
2261 LogSkData(screenshot_data,
"screenshot");
2265 DestroyShell(std::move(shell));
2276 std::string dart_isolate_time_str;
2281 dart_isolate_time_str =
2283 Dart_GetNativeArgument(
args, 0));
2287 auto settings = CreateSettingsForFixture();
2288 auto configuration = RunConfiguration::InferFromSettings(settings);
2289 configuration.SetEntrypoint(
"localtimesMatch");
2290 std::unique_ptr<Shell> shell = CreateShell(settings);
2291 ASSERT_NE(shell.get(),
nullptr);
2292 RunEngine(shell.get(), std::move(configuration));
2296 const time_t timestamp = time(
nullptr);
2297 const struct tm* local_time = localtime(×tamp);
2298 ASSERT_NE(local_time,
nullptr)
2299 <<
"Could not get local time: errno=" << errno <<
": " << strerror(errno);
2301 const size_t format_size =
2302 strftime(timestr,
sizeof(timestr),
"%Y-%m-%d %H", local_time);
2303 ASSERT_NE(format_size, 0UL)
2304 <<
"strftime failed: host time: " << std::string(timestr)
2305 <<
" dart isolate time: " << dart_isolate_time_str;
2307 const std::string host_local_time_str = timestr;
2309 ASSERT_EQ(dart_isolate_time_str, host_local_time_str)
2310 <<
"Local times in the dart isolate and the local time seen by the test "
2311 <<
"differ by more than 1 hour, but are expected to be about equal";
2313 DestroyShell(std::move(shell));
2320 : info_(SkImageInfo::MakeN32(1, 1, SkAlphaType::kOpaque_SkAlphaType)) {};
2329 return {std::nullopt, 0, SkCodecAnimation::DisposalMethod::kKeep};
2333 return SkISize::Make(info_.width(), info_.height());
2339 unsigned int frame_index,
2340 std::optional<unsigned int> prior_frame) {
2341 assert(info.width() == 1);
2342 assert(info.height() == 1);
2343 assert(row_bytes == 4);
2345 reinterpret_cast<uint32_t*
>(pixels)[0] = 0x00ff00ff;
2357 Dart_GetNativeArgument(
args, 0));
2359 Dart_GetNativeArgument(
args, 1));
2360 ASSERT_EQ(
width, 1);
2365 auto settings = CreateSettingsForFixture();
2366 auto configuration = RunConfiguration::InferFromSettings(settings);
2367 configuration.SetEntrypoint(
"canRegisterImageDecoders");
2368 std::unique_ptr<Shell> shell = CreateShell(settings);
2369 ASSERT_NE(shell.get(),
nullptr);
2372 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
2373 shell->RegisterImageDecoder(
2374 [](const sk_sp<SkData>& buffer) {
2375 return std::make_unique<SinglePixelImageGenerator>();
2380 RunEngine(shell.get(), std::move(configuration));
2382 DestroyShell(std::move(shell));
2388 PersistentCache::SetCacheDirectoryPath(base_dir.
path());
2389 PersistentCache::ResetCacheForProcess();
2393 std::vector<std::string> components = {
2395 PersistentCache::kSkSLSubdirName};
2398 const std::string x_key_str =
"A";
2399 const std::string x_value_str =
"x";
2400 sk_sp<SkData> x_key =
2401 SkData::MakeWithCopy(x_key_str.data(), x_key_str.size());
2402 sk_sp<SkData> x_value =
2403 SkData::MakeWithCopy(x_value_str.data(), x_value_str.size());
2404 auto x_data = PersistentCache::BuildCacheObject(*x_key, *x_value);
2406 const std::string y_key_str =
"B";
2407 const std::string y_value_str =
"y";
2408 sk_sp<SkData> y_key =
2409 SkData::MakeWithCopy(y_key_str.data(), y_key_str.size());
2410 sk_sp<SkData> y_value =
2411 SkData::MakeWithCopy(y_value_str.data(), y_value_str.size());
2412 auto y_data = PersistentCache::BuildCacheObject(*y_key, *y_value);
2417 Settings settings = CreateSettingsForFixture();
2418 std::unique_ptr<Shell> shell = CreateShell(settings);
2420 rapidjson::Document document;
2421 OnServiceProtocol(shell.get(), ServiceProtocolEnum::kGetSkSLs,
2422 shell->GetTaskRunners().GetIOTaskRunner(), empty_params,
2424 rapidjson::StringBuffer
buffer;
2425 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2426 document.Accept(writer);
2427 DestroyShell(std::move(shell));
2429 const std::string expected_json1 =
2430 "{\"type\":\"GetSkSLs\",\"SkSLs\":{\"II\":\"eQ==\",\"IE\":\"eA==\"}}";
2431 const std::string expected_json2 =
2432 "{\"type\":\"GetSkSLs\",\"SkSLs\":{\"IE\":\"eA==\",\"II\":\"eQ==\"}}";
2433 bool json_is_expected = (expected_json1 ==
buffer.GetString()) ||
2434 (expected_json2 ==
buffer.GetString());
2435 ASSERT_TRUE(json_is_expected) <<
buffer.GetString() <<
" is not equal to "
2436 << expected_json1 <<
" or " << expected_json2;
2440 Settings settings = CreateSettingsForFixture();
2441 auto configuration = RunConfiguration::InferFromSettings(settings);
2442 auto task_runner = CreateNewThread();
2443 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2445 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2448 PlatformViewNotifyCreated(shell.get());
2450 RunEngine(shell.get(), std::move(configuration));
2452 auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
2454 PumpOneFrame(shell.get());
2457 shell->GetTaskRunners().GetRasterTaskRunner(), [&shell, &latch]() {
2458 Rasterizer::Screenshot screenshot =
2459 shell->GetRasterizer()->ScreenshotLastLayerTree(
2460 Rasterizer::ScreenshotType::CompressedImage, true);
2461 EXPECT_NE(screenshot.data, nullptr);
2466 DestroyShell(std::move(shell), task_runners);
2470 Settings settings = CreateSettingsForFixture();
2471 auto configuration = RunConfiguration::InferFromSettings(settings);
2472 auto task_runner = CreateNewThread();
2473 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2475 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2478 PlatformViewNotifyCreated(shell.get());
2480 RunEngine(shell.get(), std::move(configuration));
2482 auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
2484 PumpOneFrame(shell.get());
2487 shell->GetTaskRunners().GetRasterTaskRunner(), [&shell, &latch]() {
2488 SnapshotDelegate* delegate =
2489 reinterpret_cast<Rasterizer*>(shell->GetRasterizer().get());
2490 sk_sp<DlImage> image = delegate->MakeRasterSnapshotSync(
2491 MakeSizedDisplayList(50, 50), DlISize(50, 50),
2492 SnapshotPixelFormat::kDontCare);
2493 EXPECT_NE(image, nullptr);
2498 DestroyShell(std::move(shell), task_runners);
2502 Settings settings = CreateSettingsForFixture();
2503 std::unique_ptr<Shell> shell = CreateShell(settings);
2507 auto display_list_layer = std::make_shared<DisplayListLayer>(
2509 display_list_layer->set_paint_bounds(DlRect::MakeWH(100, 100));
2512 std::promise<bool> rasterized;
2514 shell->GetTaskRunners().GetRasterTaskRunner()->PostTask(
2515 [&shell, &rasterized, &display_list, &display_list_layer] {
2516 std::vector<RasterCacheItem*> raster_cache_items;
2517 auto* compositor_context = shell->GetRasterizer()->compositor_context();
2518 auto& raster_cache = compositor_context->raster_cache();
2527 .gr_context =
nullptr,
2528 .dst_color_space =
nullptr,
2529 .view_embedder =
nullptr,
2530 .raster_time = raster_time,
2532 .texture_registry =
nullptr,
2533 .raster_cache = &raster_cache,
2539 .raster_cache = &raster_cache,
2541 .view_embedder =
nullptr,
2542 .state_stack = state_stack,
2543 .dst_color_space =
nullptr,
2544 .surface_needs_readback =
false,
2545 .raster_time = raster_time,
2547 .texture_registry =
nullptr,
2548 .has_platform_view =
false,
2549 .has_texture_layer =
false,
2550 .raster_cached_entries = &raster_cache_items,
2558 bool picture_cache_generated;
2560 display_list, SkPoint(),
true,
false);
2561 for (
int i = 0;
i < 4;
i += 1) {
2564 display_list_raster_cache_item.
PrerollSetup(&preroll_context, matrix);
2567 picture_cache_generated =
2571 display_list_raster_cache_item.
Draw(paint_context, &dummy_canvas,
2574 ASSERT_TRUE(picture_cache_generated);
2583 layer_raster_cache_item.
Draw(paint_context, &dummy_canvas, &paint);
2584 rasterized.set_value(
true);
2586 rasterized.get_future().wait();
2590 rapidjson::Document document;
2592 shell.get(), ServiceProtocolEnum::kEstimateRasterCacheMemory,
2593 shell->GetTaskRunners().GetRasterTaskRunner(), empty_params, &document);
2594 rapidjson::StringBuffer
buffer;
2595 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2596 document.Accept(writer);
2597 std::string expected_json =
2598 "{\"type\":\"EstimateRasterCacheMemory\",\"layerBytes\":40024,\"picture"
2600 std::string actual_json =
buffer.GetString();
2601 ASSERT_EQ(actual_json, expected_json);
2603 DestroyShell(std::move(shell));
2611 auto settings = CreateSettingsForFixture();
2617 auto end_frame_callback =
2618 [&](
bool should_merge_thread,
2620 end_frame_latch.
Signal();
2622 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2623 std::move(end_frame_callback), PostPrerollResult::kSuccess,
false);
2624 std::unique_ptr<Shell> shell = CreateShell({
2625 .settings = settings,
2627 .shell_test_external_view_embedder = external_view_embedder,
2632 PlatformViewNotifyCreated(shell.get());
2635 shell->GetTaskRunners().GetPlatformTaskRunner(),
2636 [&shell, &expected_size]() {
2637 shell->GetPlatformView()->SetViewportMetrics(
2639 {1.0, static_cast<double>(expected_size.width),
2640 static_cast<double>(expected_size.height), 22, 0});
2643 auto configuration = RunConfiguration::InferFromSettings(settings);
2644 configuration.SetEntrypoint(
"emptyMain");
2646 RunEngine(shell.get(), std::move(configuration));
2648 PumpOneFrame(shell.get(),
2649 ViewContent::DummyView(
static_cast<double>(wrong_size.width),
2650 static_cast<double>(wrong_size.height)));
2651 end_frame_latch.Wait();
2653 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2655 PumpOneFrame(shell.get(), ViewContent::DummyView(
2656 static_cast<double>(expected_size.width),
2657 static_cast<double>(expected_size.height)));
2658 end_frame_latch.Wait();
2660 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2661 ASSERT_EQ(expected_size, external_view_embedder->GetLastSubmittedFrameSize());
2663 PlatformViewNotifyDestroyed(shell.get());
2664 DestroyShell(std::move(shell));
2672 auto settings = CreateSettingsForFixture();
2681 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
2683 auto end_frame_callback =
2684 [&](
bool should_merge_thread,
2686 if (!raster_thread_merger_ref) {
2687 raster_thread_merger_ref = raster_thread_merger;
2689 if (should_merge_thread) {
2690 raster_thread_merger->MergeWithLease(10);
2691 external_view_embedder->UpdatePostPrerollResult(
2692 PostPrerollResult::kSuccess);
2694 end_frame_latch.
Signal();
2696 if (should_merge_thread) {
2697 resize_latch.
Wait();
2701 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2702 std::move(end_frame_callback), PostPrerollResult::kResubmitFrame,
true);
2704 std::unique_ptr<Shell> shell = CreateShell({
2705 .settings = settings,
2707 .shell_test_external_view_embedder = external_view_embedder,
2712 PlatformViewNotifyCreated(shell.get());
2715 shell->GetTaskRunners().GetPlatformTaskRunner(),
2716 [&shell, &origin_size]() {
2717 shell->GetPlatformView()->SetViewportMetrics(
2718 kImplicitViewId, {1.0, static_cast<double>(origin_size.width),
2719 static_cast<double>(origin_size.height), 22, 0});
2722 auto configuration = RunConfiguration::InferFromSettings(settings);
2723 configuration.SetEntrypoint(
"emptyMain");
2725 RunEngine(shell.get(), std::move(configuration));
2727 PumpOneFrame(shell.get(),
2728 ViewContent::DummyView(
static_cast<double>(origin_size.width),
2729 static_cast<double>(origin_size.height)));
2731 end_frame_latch.Wait();
2732 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2735 shell->GetTaskRunners().GetPlatformTaskRunner(),
2736 [&shell, &new_size, &resize_latch]() {
2737 shell->GetPlatformView()->SetViewportMetrics(
2738 kImplicitViewId, {1.0, static_cast<double>(new_size.width),
2739 static_cast<double>(new_size.height), 22, 0});
2740 resize_latch.Signal();
2743 end_frame_latch.Wait();
2747 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2750 PumpOneFrame(shell.get(),
2751 ViewContent::DummyView(
static_cast<double>(new_size.width),
2752 static_cast<double>(new_size.height)));
2754 end_frame_latch.Wait();
2755 ASSERT_TRUE(raster_thread_merger_ref->IsMerged());
2756 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2757 ASSERT_EQ(new_size, external_view_embedder->GetLastSubmittedFrameSize());
2759 PlatformViewNotifyDestroyed(shell.get());
2760 DestroyShell(std::move(shell));
2765 double last_device_pixel_ratio;
2768 auto native_report_device_pixel_ratio = [&](Dart_NativeArguments
args) {
2769 auto dpr_handle = Dart_GetNativeArgument(
args, 0);
2770 ASSERT_TRUE(Dart_IsDouble(dpr_handle));
2771 Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
2772 ASSERT_FALSE(last_device_pixel_ratio == 0.0);
2774 auto width_handle = Dart_GetNativeArgument(
args, 1);
2775 ASSERT_TRUE(Dart_IsDouble(width_handle));
2776 Dart_DoubleValue(width_handle, &last_width);
2777 ASSERT_FALSE(last_width == 0.0);
2779 auto height_handle = Dart_GetNativeArgument(
args, 2);
2780 ASSERT_TRUE(Dart_IsDouble(height_handle));
2781 Dart_DoubleValue(height_handle, &last_height);
2782 ASSERT_FALSE(last_height == 0.0);
2787 Settings settings = CreateSettingsForFixture();
2788 auto task_runner = CreateNewThread();
2789 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2792 AddNativeCallback(
"ReportMetrics",
2795 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2797 auto configuration = RunConfiguration::InferFromSettings(settings);
2798 configuration.SetEntrypoint(
"reportMetrics");
2800 RunEngine(shell.get(), std::move(configuration));
2802 task_runner->PostTask([&]() {
2805 {0.0, 400, 200, 22, 0});
2806 task_runner->PostTask([&]() {
2809 {0.8, 0.0, 200, 22, 0});
2810 task_runner->PostTask([&]() {
2813 {0.8, 400, 0.0, 22, 0});
2814 task_runner->PostTask([&]() {
2816 shell->GetPlatformView()->SetViewportMetrics(
2823 ASSERT_EQ(last_device_pixel_ratio, 0.8);
2824 ASSERT_EQ(last_width, 400.0);
2825 ASSERT_EQ(last_height, 200.0);
2828 task_runner->PostTask([&]() {
2830 {1.2, 600, 300, 22, 0});
2833 ASSERT_EQ(last_device_pixel_ratio, 1.2);
2834 ASSERT_EQ(last_width, 600.0);
2835 ASSERT_EQ(last_height, 300.0);
2837 DestroyShell(std::move(shell), task_runners);
2842 double last_device_pixel_ratio;
2844 auto native_report_device_pixel_ratio = [&](Dart_NativeArguments
args) {
2846 auto dpr_handle = Dart_GetNativeArgument(
args, 0);
2847 ASSERT_TRUE(Dart_IsDouble(dpr_handle));
2848 Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
2849 ASSERT_TRUE(last_device_pixel_ratio > 2.5);
2854 Settings settings = CreateSettingsForFixture();
2855 auto task_runner = CreateNewThread();
2856 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2859 AddNativeCallback(
"ReportMetrics",
2862 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2864 auto configuration = RunConfiguration::InferFromSettings(settings);
2865 configuration.SetEntrypoint(
"reportMetrics");
2867 RunEngine(shell.get(), std::move(configuration));
2869 task_runner->PostTask([&]() {
2872 shell->GetPlatformView()->SetViewportMetrics(2, {2.0, 400, 200, 22, 0});
2873 task_runner->PostTask([&]() {
2876 {3.0, 400, 200, 22, 0});
2880 ASSERT_EQ(last_device_pixel_ratio, 3.0);
2883 DestroyShell(std::move(shell), task_runners);
2887 Settings settings = CreateSettingsForFixture();
2888 std::unique_ptr<Shell> shell = CreateShell(settings);
2890 RunConfiguration::InferFromSettings(settings);
2891 configuration.
SetEntrypoint(
"canAccessResourceFromAssetDir");
2898 bool can_access_resource =
false;
2899 auto native_can_access_resource = [&can_access_resource,
2900 &latch](Dart_NativeArguments
args) {
2901 Dart_Handle exception =
nullptr;
2902 can_access_resource =
2906 AddNativeCallback(
"NotifyCanAccessResource",
2911 auto native_notify_set_asset_bundle_path =
2912 [&shell](Dart_NativeArguments
args) {
2915 params[
"assetDirectory"] =
"assetDirectory";
2916 rapidjson::Document document;
2917 OnServiceProtocol(shell.get(), ServiceProtocolEnum::kSetAssetBundlePath,
2918 shell->GetTaskRunners().GetUITaskRunner(),
params,
2920 rapidjson::StringBuffer
buffer;
2921 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2922 document.Accept(writer);
2924 AddNativeCallback(
"NotifySetAssetBundlePath",
2927 RunEngine(shell.get(), std::move(configuration));
2930 ASSERT_TRUE(can_access_resource);
2932 DestroyShell(std::move(shell));
2936 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
2939 auto vm_settings = CreateSettingsForFixture();
2940 auto vm_ref = DartVMRef::Create(vm_settings);
2941 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
2943 auto settings = vm_settings;
2945 settings.root_isolate_create_callback = [&](
const auto& isolate) {
2946 isolate_create_latch.
Signal();
2948 auto shell = CreateShell(settings);
2950 auto configuration = RunConfiguration::InferFromSettings(settings);
2951 ASSERT_TRUE(configuration.IsValid());
2952 RunEngine(shell.get(), std::move(configuration));
2953 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
2954 DestroyShell(std::move(shell));
2955 isolate_create_latch.
Wait();
2963 std::string filename =
"test_name";
2964 std::string
content =
"test_content";
2968 ASSERT_TRUE(success);
2972 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
2975 ASSERT_TRUE(mapping !=
nullptr);
2977 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
2978 mapping->GetSize());
2980 ASSERT_TRUE(result ==
content);
2988 std::vector<std::string> filenames = {
2995 for (
const auto& filename : filenames) {
2998 ASSERT_TRUE(success);
3003 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3005 auto mappings = asset_manager.
GetAsMappings(
"(.*)", std::nullopt);
3006 EXPECT_EQ(mappings.size(), 4u);
3008 std::vector<std::string> expected_results = {
3013 mappings = asset_manager.
GetAsMappings(
"(.*)good(.*)", std::nullopt);
3014 ASSERT_EQ(mappings.size(), expected_results.size());
3016 for (
auto& mapping : mappings) {
3017 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3018 mapping->GetSize());
3020 std::find(expected_results.begin(), expected_results.end(), result),
3021 expected_results.end());
3025#if defined(OS_FUCHSIA)
3026TEST_F(ShellTest, AssetManagerMultiSubdir) {
3027 std::string subdir_path =
"subdir";
3036 std::vector<std::string> filenames = {
3042 std::vector<std::string> subdir_filenames = {
3048 for (
auto filename : filenames) {
3051 ASSERT_TRUE(success);
3054 for (
auto filename : subdir_filenames) {
3057 ASSERT_TRUE(success);
3060 AssetManager asset_manager;
3061 asset_manager.PushBack(
3062 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3064 auto mappings = asset_manager.GetAsMappings(
"(.*)", std::nullopt);
3065 EXPECT_EQ(mappings.size(), 5u);
3067 mappings = asset_manager.GetAsMappings(
"(.*)", subdir_path);
3068 EXPECT_EQ(mappings.size(), 3u);
3070 std::vector<std::string> expected_results = {
3075 mappings = asset_manager.GetAsMappings(
"(.*)good(.*)", subdir_path);
3076 ASSERT_EQ(mappings.size(), expected_results.size());
3078 for (
auto& mapping : mappings) {
3079 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3080 mapping->GetSize());
3082 std::find(expected_results.begin(), expected_results.end(), result),
3083 expected_results.end());
3089 auto settings = CreateSettingsForFixture();
3090 auto shell = CreateShell(settings);
3093 auto configuration = RunConfiguration::InferFromSettings(settings);
3094 ASSERT_TRUE(configuration.IsValid());
3095 configuration.SetEntrypoint(
"fixturesAreFunctionalMain");
3097 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3098 ASSERT_TRUE(second_configuration.IsValid());
3099 second_configuration.SetEntrypoint(
"testCanLaunchSecondaryIsolate");
3101 const std::string initial_route(
"/foo");
3104 std::string last_entry_point;
3108 last_entry_point = shell->GetEngine()->GetLastEntrypoint();
3120 RunEngine(shell.get(), std::move(configuration));
3122 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3124 ASSERT_EQ(
"fixturesAreFunctionalMain", last_entry_point);
3127 shell->GetTaskRunners().GetPlatformTaskRunner(),
3128 [
this, &spawner = shell, &second_configuration, &second_latch,
3130 MockPlatformViewDelegate platform_view_delegate;
3131 auto spawn = spawner->Spawn(
3132 std::move(second_configuration), initial_route,
3133 [&platform_view_delegate](Shell& shell) {
3134 auto result = std::make_unique<MockPlatformView>(
3135 platform_view_delegate, shell.GetTaskRunners());
3136 ON_CALL(*result, CreateRenderingSurface())
3137 .WillByDefault(::testing::Invoke(
3138 [] { return std::make_unique<MockSurface>(); }));
3141 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3142 ASSERT_NE(
nullptr, spawn.get());
3145 PostSync(spawner->GetTaskRunners().GetUITaskRunner(), [&spawn, &spawner,
3148 ASSERT_EQ(
"testCanLaunchSecondaryIsolate",
3149 spawn->GetEngine()->GetLastEntrypoint());
3150 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3152 ASSERT_NE(spawner->GetEngine()
3153 ->GetRuntimeController()
3154 ->GetRootIsolateGroup(),
3156 ASSERT_EQ(spawner->GetEngine()
3157 ->GetRuntimeController()
3158 ->GetRootIsolateGroup(),
3160 ->GetRuntimeController()
3161 ->GetRootIsolateGroup());
3162 auto spawner_snapshot_delegate = spawner->GetEngine()
3163 ->GetRuntimeController()
3164 ->GetSnapshotDelegate();
3165 auto spawn_snapshot_delegate =
3166 spawn->GetEngine()->GetRuntimeController()->GetSnapshotDelegate();
3167 PostSync(spawner->GetTaskRunners().GetRasterTaskRunner(),
3168 [spawner_snapshot_delegate, spawn_snapshot_delegate] {
3169 ASSERT_NE(spawner_snapshot_delegate.get(),
3170 spawn_snapshot_delegate.get());
3174 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3175 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3176 spawn->GetIOManager()->GetResourceContext().get());
3181 second_latch.Wait();
3183 DestroyShell(std::move(spawn));
3186 DestroyShell(std::move(shell));
3187 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3191 auto settings = CreateSettingsForFixture();
3192 auto shell = CreateShell(settings);
3195 auto configuration = RunConfiguration::InferFromSettings(settings);
3196 ASSERT_TRUE(configuration.IsValid());
3197 configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineRun");
3198 const std::vector<std::string> entrypoint_args{
"foo",
"bar"};
3199 configuration.SetEntrypointArgs(entrypoint_args);
3201 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3202 ASSERT_TRUE(second_configuration.IsValid());
3203 second_configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineSpawn");
3204 const std::vector<std::string> second_entrypoint_args{
"arg1",
"arg2"};
3205 second_configuration.SetEntrypointArgs(second_entrypoint_args);
3207 const std::string initial_route(
"/foo");
3210 std::string last_entry_point;
3212 AddNativeCallback(
"NotifyNativeWhenEngineRun",
3215 Dart_GetNativeArgument(
args, 0)));
3217 shell->GetEngine()->GetLastEntrypoint();
3223 AddNativeCallback(
"NotifyNativeWhenEngineSpawn",
3226 Dart_GetNativeArgument(
args, 0)));
3228 shell->GetEngine()->GetLastEntrypoint();
3229 second_latch.Signal();
3232 RunEngine(shell.get(), std::move(configuration));
3234 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3236 ASSERT_EQ(
"canReceiveArgumentsWhenEngineRun", last_entry_point);
3239 shell->GetTaskRunners().GetPlatformTaskRunner(),
3240 [
this, &spawner = shell, &second_configuration, &second_latch,
3242 MockPlatformViewDelegate platform_view_delegate;
3243 auto spawn = spawner->Spawn(
3244 std::move(second_configuration), initial_route,
3245 [&platform_view_delegate](Shell& shell) {
3246 auto result = std::make_unique<MockPlatformView>(
3247 platform_view_delegate, shell.GetTaskRunners());
3248 ON_CALL(*result, CreateRenderingSurface())
3249 .WillByDefault(::testing::Invoke(
3250 [] { return std::make_unique<MockSurface>(); }));
3253 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3254 ASSERT_NE(
nullptr, spawn.get());
3257 PostSync(spawner->GetTaskRunners().GetUITaskRunner(),
3258 [&spawn, &spawner, initial_route] {
3260 ASSERT_EQ(
"canReceiveArgumentsWhenEngineSpawn",
3261 spawn->GetEngine()->GetLastEntrypoint());
3262 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3264 ASSERT_NE(spawner->GetEngine()
3265 ->GetRuntimeController()
3266 ->GetRootIsolateGroup(),
3268 ASSERT_EQ(spawner->GetEngine()
3269 ->GetRuntimeController()
3270 ->GetRootIsolateGroup(),
3272 ->GetRuntimeController()
3273 ->GetRootIsolateGroup());
3277 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3278 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3279 spawn->GetIOManager()->GetResourceContext().get());
3284 second_latch.Wait();
3286 DestroyShell(std::move(spawn));
3289 DestroyShell(std::move(shell));
3290 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3294 auto settings = CreateSettingsForFixture();
3295 auto shell = CreateShell(settings);
3298 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [
this,
3301 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3302 ASSERT_TRUE(second_configuration.IsValid());
3303 second_configuration.SetEntrypoint(
"emptyMain");
3304 const std::string initial_route(
"/foo");
3305 MockPlatformViewDelegate platform_view_delegate;
3306 auto spawn = spawner->Spawn(
3307 std::move(second_configuration), initial_route,
3308 [&platform_view_delegate](Shell& shell) {
3309 auto result = std::make_unique<MockPlatformView>(
3310 platform_view_delegate, shell.GetTaskRunners());
3311 ON_CALL(*result, CreateRenderingSurface())
3312 .WillByDefault(::testing::Invoke(
3313 [] { return std::make_unique<MockSurface>(); }));
3316 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3319 PostSync(spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3320 ASSERT_NE(spawner->GetIOManager().get(), nullptr);
3321 ASSERT_EQ(spawner->GetIOManager().get(), spawn->GetIOManager().get());
3325 DestroyShell(std::move(spawn));
3328 DestroyShell(std::move(shell));
3332 auto settings = CreateSettingsForFixture();
3333 auto shell = CreateShell(settings);
3336 PostSync(shell->GetTaskRunners().GetUITaskRunner(), [&shell] {
3338 auto runtime_controller = shell->GetEngine()->GetRuntimeController();
3339 PostSync(shell->GetTaskRunners().GetIOTaskRunner(),
3340 [&shell, &runtime_controller] {
3342 auto io_manager = runtime_controller->GetIOManager();
3344 ASSERT_NE(io_manager.get(), nullptr);
3345 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3347 ASSERT_NE(shell->GetIOManager().get(), nullptr);
3351 std::unique_ptr<Shell> spawn;
3353 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &settings,
3355 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3356 ASSERT_TRUE(second_configuration.IsValid());
3357 second_configuration.SetEntrypoint(
"emptyMain");
3358 const std::string initial_route(
"/foo");
3359 MockPlatformViewDelegate platform_view_delegate;
3360 auto child = shell->Spawn(
3361 std::move(second_configuration), initial_route,
3362 [&platform_view_delegate](Shell& shell) {
3363 auto result = std::make_unique<MockPlatformView>(
3364 platform_view_delegate, shell.GetTaskRunners());
3365 ON_CALL(*result, CreateRenderingSurface())
3366 .WillByDefault(::testing::Invoke(
3367 [] { return std::make_unique<MockSurface>(); }));
3370 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3371 spawn = std::move(child);
3374 DestroyShell(std::move(shell));
3376 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3378 auto runtime_controller = spawn->GetEngine()->GetRuntimeController();
3379 PostSync(spawn->GetTaskRunners().GetIOTaskRunner(),
3380 [&spawn, &runtime_controller] {
3382 auto io_manager = runtime_controller->GetIOManager();
3384 ASSERT_NE(io_manager.get(), nullptr);
3385 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3387 ASSERT_NE(spawn->GetIOManager().get(), nullptr);
3391 DestroyShell(std::move(spawn));
3395 auto settings = CreateSettingsForFixture();
3396 auto shell = CreateShell(settings);
3399 std::unique_ptr<Shell> spawn;
3401 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &settings,
3403 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3404 ASSERT_TRUE(second_configuration.IsValid());
3405 second_configuration.SetEntrypoint(
"emptyMain");
3406 const std::string initial_route(
"/foo");
3407 MockPlatformViewDelegate platform_view_delegate;
3408 auto child = shell->Spawn(
3409 std::move(second_configuration), initial_route,
3410 [&platform_view_delegate](Shell& shell) {
3411 auto result = std::make_unique<MockPlatformView>(
3412 platform_view_delegate, shell.GetTaskRunners());
3413 ON_CALL(*result, CreateRenderingSurface())
3414 .WillByDefault(::testing::Invoke(
3415 [] { return std::make_unique<MockSurface>(); }));
3418 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3419 spawn = std::move(child);
3422 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3423 std::shared_ptr<const DartIsolate> isolate =
3424 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3425 ASSERT_TRUE(isolate);
3426 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3430 DestroyShell(std::move(shell));
3432 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3433 std::shared_ptr<const DartIsolate> isolate =
3434 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3435 ASSERT_TRUE(isolate);
3436 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3439 DestroyShell(std::move(spawn));
3443 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3444 Settings settings = CreateSettingsForFixture();
3448 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3450 auto shell = CreateShell(settings, task_runners);
3451 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3454 auto configuration = RunConfiguration::InferFromSettings(settings);
3455 configuration.SetEntrypoint(
"emptyMain");
3456 auto asset_manager = configuration.GetAssetManager();
3458 shell->RunEngine(std::move(configuration), [&](
auto result) {
3459 ASSERT_EQ(result, Engine::RunStatus::Success);
3463 std::make_unique<PlatformView>(*shell.get(), task_runners);
3465 auto old_resolver = std::make_unique<TestAssetResolver>(
3466 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3467 ASSERT_TRUE(old_resolver->IsValid());
3468 asset_manager->PushBack(std::move(old_resolver));
3470 auto updated_resolver = std::make_unique<TestAssetResolver>(
3471 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3472 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3474 std::move(updated_resolver),
3475 AssetResolver::AssetResolverType::kApkAssetProvider);
3477 auto resolvers = asset_manager->TakeResolvers();
3478 ASSERT_EQ(resolvers.size(), 2ull);
3479 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3481 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3483 DestroyShell(std::move(shell), task_runners);
3484 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3488 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3489 Settings settings = CreateSettingsForFixture();
3493 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3495 auto shell = CreateShell(settings, task_runners);
3496 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3499 auto configuration = RunConfiguration::InferFromSettings(settings);
3500 configuration.SetEntrypoint(
"emptyMain");
3501 auto asset_manager = configuration.GetAssetManager();
3503 shell->RunEngine(std::move(configuration), [&](
auto result) {
3504 ASSERT_EQ(result, Engine::RunStatus::Success);
3508 std::make_unique<PlatformView>(*shell.get(), task_runners);
3510 auto updated_resolver = std::make_unique<TestAssetResolver>(
3511 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3512 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3514 std::move(updated_resolver),
3515 AssetResolver::AssetResolverType::kApkAssetProvider);
3517 auto resolvers = asset_manager->TakeResolvers();
3518 ASSERT_EQ(resolvers.size(), 2ull);
3519 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3521 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3523 DestroyShell(std::move(shell), task_runners);
3524 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3528 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3529 Settings settings = CreateSettingsForFixture();
3532 ThreadHost::Type::kPlatform));
3534 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3536 auto shell = CreateShell(settings, task_runners);
3537 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3540 auto configuration = RunConfiguration::InferFromSettings(settings);
3541 configuration.SetEntrypoint(
"emptyMain");
3542 auto asset_manager = configuration.GetAssetManager();
3543 RunEngine(shell.get(), std::move(configuration));
3546 std::make_unique<PlatformView>(*shell.get(), task_runners);
3548 auto old_resolver = std::make_unique<TestAssetResolver>(
3549 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3550 ASSERT_TRUE(old_resolver->IsValid());
3551 asset_manager->PushBack(std::move(old_resolver));
3554 nullptr, AssetResolver::AssetResolverType::kApkAssetProvider);
3556 auto resolvers = asset_manager->TakeResolvers();
3557 ASSERT_EQ(resolvers.size(), 2ull);
3558 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3559 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3561 DestroyShell(std::move(shell), task_runners);
3562 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3566 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3567 Settings settings = CreateSettingsForFixture();
3571 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3573 auto shell = CreateShell(settings, task_runners);
3574 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3577 auto configuration = RunConfiguration::InferFromSettings(settings);
3578 configuration.SetEntrypoint(
"emptyMain");
3579 auto asset_manager = configuration.GetAssetManager();
3581 shell->RunEngine(std::move(configuration), [&](
auto result) {
3582 ASSERT_EQ(result, Engine::RunStatus::Success);
3586 std::make_unique<PlatformView>(*shell.get(), task_runners);
3588 auto old_resolver = std::make_unique<TestAssetResolver>(
3589 true, AssetResolver::AssetResolverType::kAssetManager);
3590 ASSERT_TRUE(old_resolver->IsValid());
3591 asset_manager->PushBack(std::move(old_resolver));
3593 auto updated_resolver = std::make_unique<TestAssetResolver>(
3594 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3595 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3597 std::move(updated_resolver),
3598 AssetResolver::AssetResolverType::kApkAssetProvider);
3600 auto resolvers = asset_manager->TakeResolvers();
3601 ASSERT_EQ(resolvers.size(), 3ull);
3602 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3604 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3606 ASSERT_FALSE(resolvers[2]->IsValidAfterAssetManagerChange());
3608 DestroyShell(std::move(shell), task_runners);
3609 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3617 auto settings = CreateSettingsForFixture();
3618 std::unique_ptr<Shell> shell = CreateShell({
3619 .settings = settings,
3621 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
3624 ASSERT_NE(shell,
nullptr);
3625 ASSERT_TRUE(shell->IsSetup());
3626 auto configuration = RunConfiguration::InferFromSettings(settings);
3627 PlatformViewNotifyCreated(shell.get());
3628 configuration.SetEntrypoint(
"emptyMain");
3629 RunEngine(shell.get(), std::move(configuration));
3630 PumpOneFrame(shell.get());
3631 PlatformViewNotifyDestroyed(shell.get());
3632 DestroyShell(std::move(shell));
3637#if !SHELL_ENABLE_VULKAN
3640 auto settings = CreateSettingsForFixture();
3641 std::unique_ptr<Shell> shell = CreateShell({
3642 .settings = settings,
3644 .rendering_backend =
3645 ShellTestPlatformView::BackendType::kVulkanBackend,
3648 ASSERT_NE(shell,
nullptr);
3649 ASSERT_TRUE(shell->IsSetup());
3650 auto configuration = RunConfiguration::InferFromSettings(settings);
3651 PlatformViewNotifyCreated(shell.get());
3652 configuration.SetEntrypoint(
"emptyMain");
3653 RunEngine(shell.get(), std::move(configuration));
3654 PumpOneFrame(shell.get());
3655 PlatformViewNotifyDestroyed(shell.get());
3656 DestroyShell(std::move(shell));
3661#if !SHELL_ENABLE_METAL
3664 auto settings = CreateSettingsForFixture();
3665 std::unique_ptr<Shell> shell = CreateShell({
3666 .settings = settings,
3668 .rendering_backend =
3669 ShellTestPlatformView::BackendType::kMetalBackend,
3672 ASSERT_NE(shell,
nullptr);
3673 ASSERT_TRUE(shell->IsSetup());
3674 auto configuration = RunConfiguration::InferFromSettings(settings);
3675 PlatformViewNotifyCreated(shell.get());
3676 configuration.SetEntrypoint(
"emptyMain");
3677 RunEngine(shell.get(), std::move(configuration));
3678 PumpOneFrame(shell.get());
3679 PlatformViewNotifyDestroyed(shell.get());
3680 DestroyShell(std::move(shell));
3685 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3688 auto vm_settings = CreateSettingsForFixture();
3689 auto vm_ref = DartVMRef::Create(vm_settings);
3690 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3692 auto settings = vm_settings;
3696 settings.root_isolate_create_callback = [&](
const DartIsolate& isolate) {
3697 Dart_Handle current_tag = Dart_GetCurrentUserTag();
3698 Dart_Handle startup_tag = Dart_NewUserTag(
"AppStartUp");
3699 EXPECT_TRUE(Dart_IdentityEquals(current_tag, startup_tag));
3701 isolate_create_latch.
Signal();
3704 auto shell = CreateShell(settings);
3707 auto configuration = RunConfiguration::InferFromSettings(settings);
3708 ASSERT_TRUE(configuration.IsValid());
3710 RunEngine(shell.get(), std::move(configuration));
3711 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3713 DestroyShell(std::move(shell));
3714 isolate_create_latch.
Wait();
3718 auto settings = CreateSettingsForFixture();
3719 settings.prefetched_default_font_manager =
true;
3720 std::unique_ptr<Shell> shell;
3722 auto get_font_manager_count = [&] {
3724 size_t font_manager_count;
3726 shell->GetTaskRunners().GetUITaskRunner(),
3727 [
this, &shell, &latch, &font_manager_count]() {
3728 font_manager_count =
3729 GetFontCollection(shell.get())->GetFontManagersCount();
3733 return font_manager_count;
3735 size_t initial_font_manager_count = 0;
3736 settings.root_isolate_create_callback = [&](
const auto& isolate) {
3737 ASSERT_GT(initial_font_manager_count, 0ul);
3740 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count);
3743 shell = CreateShell(settings);
3745 initial_font_manager_count = get_font_manager_count();
3747 auto configuration = RunConfiguration::InferFromSettings(settings);
3748 configuration.SetEntrypoint(
"emptyMain");
3749 RunEngine(shell.get(), std::move(configuration));
3753 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count + 1);
3755 DestroyShell(std::move(shell));
3761 auto settings = CreateSettingsForFixture();
3762 auto shell = CreateShell(settings);
3766 [&latch]() { latch.Wait(); });
3768 ShellTest::PlatformViewNotifyCreated(shell.get());
3771 DestroyShell(std::move(shell));
3775 auto settings = CreateSettingsForFixture();
3776 auto shell = CreateShell(settings);
3777 auto configuration = RunConfiguration::InferFromSettings(settings);
3778 configuration.SetEntrypoint(
"drawFrames");
3783 notify_native_latch.
Signal();
3787 RunEngine(shell.get(), std::move(configuration));
3790 notify_native_latch.
Wait();
3792 ShellTest::PlatformViewNotifyCreated(shell.get());
3796 shell->GetTaskRunners().GetPlatformTaskRunner(),
3797 [&shell, &destroy_latch]() {
3798 shell->GetPlatformView()->NotifyDestroyed();
3799 destroy_latch.Signal();
3802 destroy_latch.
Wait();
3811 shell->GetTaskRunners().GetUITaskRunner(),
3812 [&ui_flush_latch]() { ui_flush_latch.Signal(); });
3813 ui_flush_latch.
Wait();
3814 DestroyShell(std::move(shell));
3819 auto settings = CreateSettingsForFixture();
3820 MockPlatformViewDelegate platform_view_delegate;
3821 auto platform_message_handler =
3822 std::make_shared<MockPlatformMessageHandler>();
3824 EXPECT_CALL(*platform_message_handler, HandlePlatformMessage(_));
3825 EXPECT_CALL(*platform_message_handler,
3826 InvokePlatformMessageEmptyResponseCallback(message_id));
3828 [&platform_view_delegate, task_runners,
3830 auto result = std::make_unique<MockPlatformView>(platform_view_delegate,
3832 EXPECT_CALL(*result, GetPlatformMessageHandler())
3833 .WillOnce(Return(platform_message_handler));
3836 auto shell = CreateShell({
3837 .settings = settings,
3838 .task_runners = task_runners,
3839 .platform_view_create_callback = platform_view_create_callback,
3842 EXPECT_EQ(platform_message_handler, shell->GetPlatformMessageHandler());
3844 size_t data_size = 4;
3845 fml::MallocMapping bytes =
3846 fml::MallocMapping(static_cast<uint8_t*>(malloc(data_size)), data_size);
3847 fml::RefPtr<MockPlatformMessageResponse> response =
3848 MockPlatformMessageResponse::Create();
3849 auto message = std::make_unique<PlatformMessage>(
3850 "foo", std::move(bytes), response);
3851 (static_cast<Engine::Delegate*>(shell.get()))
3852 ->OnEngineHandlePlatformMessage(std::move(message));
3854 shell->GetPlatformMessageHandler()
3855 ->InvokePlatformMessageEmptyResponseCallback(message_id);
3856 DestroyShell(std::move(shell));
3860 auto settings = CreateSettingsForFixture();
3861 auto shell = CreateShell(settings);
3864 auto configuration = RunConfiguration::InferFromSettings(settings);
3865 ASSERT_TRUE(configuration.IsValid());
3866 configuration.SetEntrypoint(
"onErrorA");
3868 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3869 ASSERT_TRUE(second_configuration.IsValid());
3870 second_configuration.SetEntrypoint(
"onErrorB");
3876 auto string_handle = Dart_GetNativeArgument(
args, 0);
3878 Dart_StringToCString(string_handle, &c_str);
3879 EXPECT_STREQ(c_str,
"Exception: I should be coming from A");
3885 auto string_handle = Dart_GetNativeArgument(
args, 0);
3887 Dart_StringToCString(string_handle, &c_str);
3888 EXPECT_STREQ(c_str,
"Exception: I should be coming from B");
3892 RunEngine(shell.get(), std::move(configuration));
3894 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3897 shell->GetTaskRunners().GetPlatformTaskRunner(),
3898 [
this, &spawner = shell, &second_configuration, &latch]() {
3899 ::testing::NiceMock<MockPlatformViewDelegate> platform_view_delegate;
3900 auto spawn = spawner->Spawn(
3901 std::move(second_configuration),
"",
3902 [&platform_view_delegate](Shell& shell) {
3904 std::make_unique<::testing::NiceMock<MockPlatformView>>(
3905 platform_view_delegate, shell.GetTaskRunners());
3906 ON_CALL(*result, CreateRenderingSurface())
3907 .WillByDefault(::testing::Invoke([] {
3908 return std::make_unique<::testing::NiceMock<MockSurface>>();
3912 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3913 ASSERT_NE(
nullptr, spawn.get());
3920 DestroyShell(std::move(spawn));
3923 DestroyShell(std::move(shell));
3924 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3928 Settings settings = CreateSettingsForFixture();
3929 auto task_runner = CreateNewThread();
3930 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3932 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
3935 AddNativeCallback(
"NotifyNative",
3939 PlatformViewNotifyCreated(shell.get());
3941 auto configuration = RunConfiguration::InferFromSettings(settings);
3942 configuration.SetEntrypoint(
"testThatAssetLoadingHappensOnWorkerThread");
3943 auto asset_manager = configuration.GetAssetManager();
3944 auto test_resolver = std::make_unique<ThreadCheckingAssetResolver>(
3945 shell->GetDartVM()->GetConcurrentMessageLoop());
3946 auto leaked_resolver = test_resolver.get();
3947 asset_manager->PushBack(std::move(test_resolver));
3949 RunEngine(shell.get(), std::move(configuration));
3950 PumpOneFrame(shell.get());
3954 EXPECT_EQ(leaked_resolver->mapping_requests[0],
"DoesNotExist");
3956 PlatformViewNotifyDestroyed(shell.get());
3957 DestroyShell(std::move(shell), task_runners);
3965 auto settings = CreateSettingsForFixture();
3966 std::unique_ptr<Shell> shell = CreateShell({
3967 .settings = settings,
3969 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
3973 AddNativeCallback(
"NativeOnBeforeToImageSync",
3981 PlatformViewNotifyDestroyed(shell.get());
3982 PlatformViewNotifyCreated(shell.get());
3986 ASSERT_NE(shell,
nullptr);
3987 ASSERT_TRUE(shell->IsSetup());
3988 auto configuration = RunConfiguration::InferFromSettings(settings);
3989 PlatformViewNotifyCreated(shell.get());
3990 configuration.SetEntrypoint(
"toImageSync");
3991 RunEngine(shell.get(), std::move(configuration));
3992 PumpOneFrame(shell.get());
3996 PlatformViewNotifyDestroyed(shell.get());
3997 DestroyShell(std::move(shell));
4002#if !SHELL_ENABLE_METAL
4006 auto settings = CreateSettingsForFixture();
4007 settings.enable_impeller =
true;
4008 std::unique_ptr<Shell> shell = CreateShell({
4009 .settings = settings,
4011 .rendering_backend =
4012 ShellTestPlatformView::BackendType::kMetalBackend,
4016 AddNativeCallback(
"NativeOnBeforeToImageSync",
4024 PlatformViewNotifyDestroyed(shell.get());
4025 PlatformViewNotifyCreated(shell.get());
4029 ASSERT_NE(shell,
nullptr);
4030 ASSERT_TRUE(shell->IsSetup());
4031 auto configuration = RunConfiguration::InferFromSettings(settings);
4037 configuration.SetEntrypoint(
"toImageSync");
4038 RunEngine(shell.get(), std::move(configuration));
4039 PumpOneFrame(shell.get());
4043 PlatformViewNotifyDestroyed(shell.get());
4044 DestroyShell(std::move(shell));
4050TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) {
4053 ThreadHost thread_host(
"io.flutter.test." + GetCurrentTestName() +
".",
4054 ThreadHost::Type::kPlatform);
4055 auto task_runner = thread_host.platform_thread->GetTaskRunner();
4056 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4059 auto settings = CreateSettingsForFixture();
4060 std::unique_ptr<Shell> shell = CreateShell({
4061 .settings = settings,
4062 .task_runners = task_runners,
4063 .platform_view_create_callback = ShellTestPlatformViewBuilder({
4064 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
4073 ::eglMakeCurrent(::eglGetCurrentDisplay(), NULL, NULL, NULL);
4079 PlatformViewNotifyDestroyed(shell.get());
4080 PlatformViewNotifyCreated(shell.get());
4084 ASSERT_NE(shell,
nullptr);
4085 ASSERT_TRUE(shell->IsSetup());
4086 auto configuration = RunConfiguration::InferFromSettings(settings);
4087 PlatformViewNotifyCreated(shell.get());
4088 configuration.SetEntrypoint(
"toImageSync");
4089 RunEngine(shell.get(), std::move(configuration));
4090 PumpOneFrame(shell.get());
4094 PlatformViewNotifyDestroyed(shell.get());
4095 DestroyShell(std::move(shell), task_runners);
4100 auto settings = CreateSettingsForFixture();
4101 std::unique_ptr<Shell> shell = CreateShell(settings);
4106 Dart_Handle exception =
nullptr;
4108 args, 0, exception);
4112 ASSERT_NE(shell,
nullptr);
4113 ASSERT_TRUE(shell->IsSetup());
4114 auto configuration = RunConfiguration::InferFromSettings(settings);
4115 PlatformViewNotifyCreated(shell.get());
4116 configuration.SetEntrypoint(
"testPluginUtilitiesCallbackHandle");
4117 RunEngine(shell.get(), std::move(configuration));
4118 PumpOneFrame(shell.get());
4122 ASSERT_TRUE(test_passed);
4124 PlatformViewNotifyDestroyed(shell.get());
4125 DestroyShell(std::move(shell));
4129 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4130 Settings settings = CreateSettingsForFixture();
4132 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4133 ThreadHost::kIo | ThreadHost::kRaster);
4134 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4138 thread_host.
io_thread->GetTaskRunner());
4139 auto shell = CreateShell(settings, task_runners);
4140 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4145 auto configuration = RunConfiguration::InferFromSettings(settings);
4146 configuration.SetEntrypoint(
"emptyMain");
4147 RunEngine(shell.get(), std::move(configuration));
4151 auto runtime_controller = const_cast<RuntimeController*>(
4152 shell->GetEngine()->GetRuntimeController());
4154 auto now = fml::TimeDelta::FromMicroseconds(Dart_TimelineGetMicros());
4156 EXPECT_FALSE(runtime_controller->NotifyIdle(
4157 now - fml::TimeDelta::FromMilliseconds(10)));
4158 EXPECT_FALSE(runtime_controller->NotifyIdle(now));
4159 EXPECT_FALSE(runtime_controller->NotifyIdle(
4160 now + fml::TimeDelta::FromNanoseconds(100)));
4162 EXPECT_TRUE(runtime_controller->NotifyIdle(
4163 now + fml::TimeDelta::FromMilliseconds(100)));
4169 DestroyShell(std::move(shell), task_runners);
4170 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4174 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4175 Settings settings = CreateSettingsForFixture();
4177 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4178 ThreadHost::kIo | ThreadHost::kRaster);
4179 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4183 thread_host.
io_thread->GetTaskRunner());
4184 auto shell = CreateShell(settings, task_runners);
4185 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4194 Dart_Handle exception =
nullptr;
4195 bool is_in_latency_mode =
4198 shell->GetEngine()->GetRuntimeController());
4201 Dart_TimelineGetMicros() + 100000));
4202 EXPECT_EQ(success, !is_in_latency_mode);
4206 auto configuration = RunConfiguration::InferFromSettings(settings);
4207 configuration.SetEntrypoint(
"performanceModeImpactsNotifyIdle");
4208 RunEngine(shell.get(), std::move(configuration));
4212 DestroyShell(std::move(shell), task_runners);
4213 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4217#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG || OS_FUCHSIA
4218 GTEST_SKIP() <<
"Test is for debug mode only on non-fuchsia targets.";
4220 Settings settings = CreateSettingsForFixture();
4222 ThreadHost::Type::kPlatform);
4224 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4226 auto shell = CreateShell(settings, task_runners);
4233 SendPlatformMessage(shell.get(), std::make_unique<PlatformMessage>(
4234 "com.test.plugin",
nullptr));
4238 ::testing::EndsWith(
4239 "The 'com.test.plugin' channel sent a message from native to "
4240 "Flutter on a non-platform thread. Platform channel messages "
4241 "must be sent on the platform thread. Failure to do so may "
4242 "result in data loss or crashes, and must be fixed in the "
4243 "plugin or application code creating that channel.\nSee "
4244 "https://docs.flutter.dev/platform-integration/"
4245 "platform-channels#channels-and-platform-threading for more "
4254 SendPlatformMessage(shell.get(), std::make_unique<PlatformMessage>(
4255 "com.test.plugin",
nullptr));
4257 EXPECT_EQ(log_capture.
str(),
"");
4260 DestroyShell(std::move(shell), task_runners);
4261 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4266 Settings settings = CreateSettingsForFixture();
4268 ThreadHost::Type::kPlatform);
4270 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4272 auto shell = CreateShell(settings, task_runners);
4274 auto latch = std::make_shared<fml::CountDownLatch>(1u);
4275 task_runner->PostTask([&]() {
4276 auto message = MakePlatformMessage(
4277 "flutter/navigation",
4278 {{
"method",
"setInitialRoute"}, {
"args",
"/testo"}},
nullptr);
4279 SendPlatformMessage(shell.get(), std::move(
message));
4280 EXPECT_EQ(shell->GetEngine()->InitialRoute(),
"/testo");
4286 DestroyShell(std::move(shell), task_runners);
4287 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4292 Settings settings = CreateSettingsForFixture();
4294 ThreadHost::Type::kPlatform);
4296 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4301 auto shell = CreateShell(settings, task_runners);
4302 auto configuration = RunConfiguration::InferFromSettings(settings);
4303 configuration.SetEntrypoint(
"testSemanticsActions");
4305 RunEngine(shell.get(), std::move(configuration));
4315 SendSemanticsAction(shell.get(), 456, 0, SemanticsAction::kTap,
4320 DestroyShell(std::move(shell), task_runners);
4321 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4326 Settings settings = CreateSettingsForFixture();
4328 ThreadHost::Type::kPlatform);
4330 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4335 auto shell = CreateShell(settings, task_runners);
4336 auto configuration = RunConfiguration::InferFromSettings(settings);
4337 configuration.SetEntrypoint(
"testPointerActions");
4339 RunEngine(shell.get(), std::move(configuration));
4348 DispatchFakePointerData(shell.get(), 23);
4351 DestroyShell(std::move(shell), task_runners);
4352 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4357 Settings settings = CreateSettingsForFixture();
4359 ThreadHost::Type::kPlatform);
4361 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4366 auto shell = CreateShell(settings, task_runners);
4367 auto configuration = RunConfiguration::InferFromSettings(settings);
4368 configuration.SetEntrypoint(
"testDispatchEvents");
4370 RunEngine(shell.get(), std::move(configuration));
4372 bool did_invoke_callback =
false;
4378 did_invoke_callback =
true;
4382 DispatchFakePointerData(shell.get(), 23);
4383 EXPECT_FALSE(did_invoke_callback);
4385 EXPECT_TRUE(did_invoke_callback);
4387 DestroyShell(std::move(shell), task_runners);
4388 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4392#if defined(OS_FUCHSIA)
4393 GTEST_SKIP() <<
"Fuchsia";
4395 ::testing::FLAGS_gtest_death_test_style =
"threadsafe";
4396 Settings settings = CreateSettingsForFixture();
4400 ThreadHost::Type::kPlatform);
4402 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4404 EXPECT_DEATH_IF_SUPPORTED(
4405 CreateShell(settings, task_runners),
4406 "Software rendering is incompatible with Impeller.");
4413 bool* hasImplicitView,
4414 std::vector<int64_t>* viewIds) {
4415 Dart_Handle exception =
nullptr;
4419 ASSERT_EQ(exception,
nullptr);
4421 args, 1, exception);
4422 ASSERT_EQ(exception,
nullptr);
4426 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4427 Settings settings = CreateSettingsForFixture();
4428 auto task_runner = CreateNewThread();
4429 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4431 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4434 bool hasImplicitView;
4435 std::vector<int64_t> viewIds;
4437 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4438 &viewIds](Dart_NativeArguments
args) {
4442 AddNativeCallback(
"NativeReportViewIdsCallback",
4445 PlatformViewNotifyCreated(shell.get());
4446 auto configuration = RunConfiguration::InferFromSettings(settings);
4447 configuration.SetEntrypoint(
"testReportViewIds");
4448 RunEngine(shell.get(), std::move(configuration));
4451 ASSERT_TRUE(hasImplicitView);
4452 ASSERT_EQ(viewIds.size(), 1u);
4453 ASSERT_EQ(viewIds[0], 0ll);
4455 PlatformViewNotifyDestroyed(shell.get());
4456 DestroyShell(std::move(shell), task_runners);
4461 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4462 Settings settings = CreateSettingsForFixture();
4465 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4466 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4470 thread_host.
io_thread->GetTaskRunner());
4471 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4474 bool hasImplicitView;
4475 std::vector<int64_t> viewIds;
4477 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4478 &viewIds](Dart_NativeArguments
args) {
4482 AddNativeCallback(
"NativeReportViewIdsCallback",
4485 PlatformViewNotifyCreated(shell.get());
4486 auto configuration = RunConfiguration::InferFromSettings(settings);
4487 configuration.SetEntrypoint(
"testReportViewIds");
4488 RunEngine(shell.get(), std::move(configuration));
4491 ASSERT_TRUE(hasImplicitView);
4492 ASSERT_EQ(viewIds.size(), 1u);
4493 ASSERT_EQ(viewIds[0], 0ll);
4495 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4496 shell->GetPlatformView()->AddView(2, ViewportMetrics{},
4497 [](
bool added) { EXPECT_TRUE(added); });
4500 ASSERT_TRUE(hasImplicitView);
4501 ASSERT_EQ(viewIds.size(), 2u);
4502 ASSERT_EQ(viewIds[1], 2ll);
4504 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4505 shell->GetPlatformView()->RemoveView(
4506 2, [](bool removed) { ASSERT_TRUE(removed); });
4509 ASSERT_TRUE(hasImplicitView);
4510 ASSERT_EQ(viewIds.size(), 1u);
4511 ASSERT_EQ(viewIds[0], 0ll);
4513 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4514 shell->GetPlatformView()->AddView(4, ViewportMetrics{},
4515 [](
bool added) { EXPECT_TRUE(added); });
4518 ASSERT_TRUE(hasImplicitView);
4519 ASSERT_EQ(viewIds.size(), 2u);
4520 ASSERT_EQ(viewIds[1], 4ll);
4522 PlatformViewNotifyDestroyed(shell.get());
4523 DestroyShell(std::move(shell), task_runners);
4528 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4529 Settings settings = CreateSettingsForFixture();
4532 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4533 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4537 thread_host.
io_thread->GetTaskRunner());
4538 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4541 bool has_implicit_view;
4542 std::vector<int64_t> view_ids;
4544 AddNativeCallback(
"NativeReportViewIdsCallback",
4550 PlatformViewNotifyCreated(shell.get());
4551 auto configuration = RunConfiguration::InferFromSettings(settings);
4552 configuration.SetEntrypoint(
"testReportViewIds");
4553 RunEngine(shell.get(), std::move(configuration));
4555 report_latch.
Wait();
4556 ASSERT_TRUE(has_implicit_view);
4557 ASSERT_EQ(view_ids.size(), 1u);
4562 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
4564 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4572 report_latch.Wait();
4573 ASSERT_EQ(view_ids.size(), 2u);
4575 ASSERT_EQ(view_ids[1], 123);
4578 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
4580 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4581 EXPECT_FALSE(added);
4588 PlatformViewNotifyDestroyed(shell.get());
4589 DestroyShell(std::move(shell), task_runners);
4595 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4596 Settings settings = CreateSettingsForFixture();
4599 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4600 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4604 thread_host.
io_thread->GetTaskRunner());
4605 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4608 bool has_implicit_view;
4609 std::vector<int64_t> view_ids;
4611 AddNativeCallback(
"NativeReportViewIdsCallback",
4617 PlatformViewNotifyCreated(shell.get());
4618 auto configuration = RunConfiguration::InferFromSettings(settings);
4619 configuration.SetEntrypoint(
"testReportViewIds");
4620 RunEngine(shell.get(), std::move(configuration));
4622 report_latch.
Wait();
4623 ASSERT_TRUE(has_implicit_view);
4624 ASSERT_EQ(view_ids.size(), 1u);
4629 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(),
4630 [&shell, &remove_latch] {
4631 shell->GetPlatformView()->RemoveView(123, [&](bool removed) {
4632 EXPECT_FALSE(removed);
4633 remove_latch.Signal();
4637 remove_latch.Wait();
4639 PlatformViewNotifyDestroyed(shell.get());
4640 DestroyShell(std::move(shell), task_runners);
4646 std::map<int64_t, int64_t>* viewWidths) {
4647 Dart_Handle exception =
nullptr;
4648 viewWidths->clear();
4649 std::vector<int64_t> viewWidthPacket =
4652 ASSERT_EQ(exception,
nullptr);
4653 ASSERT_EQ(viewWidthPacket.size() % 2, 0ul);
4654 for (
size_t packetIndex = 0; packetIndex < viewWidthPacket.size();
4656 (*viewWidths)[viewWidthPacket[packetIndex]] =
4657 viewWidthPacket[packetIndex + 1];
4665 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4666 Settings settings = CreateSettingsForFixture();
4669 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4670 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4674 thread_host.
io_thread->GetTaskRunner());
4675 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4678 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4679 auto platform_view = shell->GetPlatformView();
4682 platform_view->SetViewportMetrics(0, ViewportMetrics{1, 10, 1, 0, 0});
4684 [](
bool added) { ASSERT_TRUE(added); });
4688 bool first_report =
true;
4689 std::map<int64_t, int64_t> viewWidths;
4691 auto nativeViewWidthsCallback = [&reportLatch, &viewWidths,
4692 &first_report](Dart_NativeArguments
args) {
4693 EXPECT_TRUE(first_report);
4694 first_report =
false;
4695 ParseViewWidthsCallback(
args, &viewWidths);
4698 AddNativeCallback(
"NativeReportViewWidthsCallback",
4701 PlatformViewNotifyCreated(shell.get());
4702 auto configuration = RunConfiguration::InferFromSettings(settings);
4703 configuration.SetEntrypoint(
"testReportViewWidths");
4704 RunEngine(shell.get(), std::move(configuration));
4707 EXPECT_EQ(viewWidths.size(), 2u);
4708 EXPECT_EQ(viewWidths[0], 20ll);
4709 EXPECT_EQ(viewWidths[1], 30ll);
4711 PlatformViewNotifyDestroyed(shell.get());
4712 DestroyShell(std::move(shell), task_runners);
4717 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4718 Settings settings = CreateSettingsForFixture();
4721 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4722 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4726 thread_host.
io_thread->GetTaskRunner());
4727 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4730 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4731 auto platform_view = shell->GetPlatformView();
4736 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 30, 1, 0, 0},
4737 [](
bool added) { ASSERT_FALSE(added); });
4738 shell->GetPlatformView()->RemoveView(
4739 123, [](
bool removed) { ASSERT_FALSE(removed); });
4742 bool first_report =
true;
4743 std::map<int64_t, int64_t> view_widths;
4745 AddNativeCallback(
"NativeReportViewWidthsCallback",
4747 EXPECT_TRUE(first_report);
4748 first_report =
false;
4749 ParseViewWidthsCallback(
args, &view_widths);
4753 PlatformViewNotifyCreated(shell.get());
4754 auto configuration = RunConfiguration::InferFromSettings(settings);
4755 configuration.SetEntrypoint(
"testReportViewWidths");
4756 RunEngine(shell.get(), std::move(configuration));
4758 report_latch.
Wait();
4759 EXPECT_EQ(view_widths.size(), 1u);
4761 PlatformViewNotifyDestroyed(shell.get());
4762 DestroyShell(std::move(shell), task_runners);
4768 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4769 Settings settings = CreateSettingsForFixture();
4772 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4773 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4777 thread_host.
io_thread->GetTaskRunner());
4778 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4781 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4782 auto platform_view = shell->GetPlatformView();
4785 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 100, 1, 0, 0},
4786 [](
bool added) { ASSERT_TRUE(added); });
4788 shell->GetPlatformView()->AddView(123,
ViewportMetrics{1, 200, 1, 0, 0},
4789 [](
bool added) { ASSERT_FALSE(added); });
4792 shell->GetPlatformView()->AddView(456,
ViewportMetrics{1, 300, 1, 0, 0},
4793 [](
bool added) { ASSERT_TRUE(added); });
4796 bool first_report =
true;
4797 std::map<int64_t, int64_t> view_widths;
4799 AddNativeCallback(
"NativeReportViewWidthsCallback",
4801 EXPECT_TRUE(first_report);
4802 first_report =
false;
4803 ParseViewWidthsCallback(
args, &view_widths);
4807 PlatformViewNotifyCreated(shell.get());
4808 auto configuration = RunConfiguration::InferFromSettings(settings);
4809 configuration.SetEntrypoint(
"testReportViewWidths");
4810 RunEngine(shell.get(), std::move(configuration));
4812 report_latch.
Wait();
4813 EXPECT_EQ(view_widths.size(), 3u);
4814 EXPECT_EQ(view_widths[0], 0);
4815 EXPECT_EQ(view_widths[123], 100);
4816 EXPECT_EQ(view_widths[456], 300);
4818 PlatformViewNotifyDestroyed(shell.get());
4819 DestroyShell(std::move(shell), task_runners);
4823#if !IMPELLER_SUPPORTS_RENDERING
4824 GTEST_SKIP() <<
"This platform doesn't support Impeller.";
4826 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4827 Settings settings = CreateSettingsForFixture();
4833 TaskRunners task_runners(
"test", runner, runner, runner, runner);
4834 std::ostringstream stream;
4836 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4838 stream.str().find(
"[Action Required]: Impeller opt-out deprecated.") !=
4841 DestroyShell(std::move(shell), task_runners);
4845 Settings settings = CreateSettingsForFixture();
4848 std::string last_event;
4854 AddNativeCallback(
"NotifyMessage",
4856 const auto message_from_dart =
4858 Dart_GetNativeArgument(
args, 0));
4859 last_event = message_from_dart;
4864 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4865 ASSERT_TRUE(shell->IsSetup());
4867 auto configuration = RunConfiguration::InferFromSettings(settings);
4869 configuration.SetEntrypoint(
"testSendViewFocusEvent");
4870 RunEngine(shell.get(), std::move(configuration));
4874 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
4875 shell->GetPlatformView()->SendViewFocusEvent(ViewFocusEvent(
4876 1, ViewFocusState::kFocused, ViewFocusDirection::kUndefined));
4879 ASSERT_EQ(last_event,
4880 "1 ViewFocusState.focused ViewFocusDirection.undefined");
4883 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
4884 shell->GetPlatformView()->SendViewFocusEvent(ViewFocusEvent(
4885 2, ViewFocusState::kUnfocused, ViewFocusDirection::kBackward));
4888 ASSERT_EQ(last_event,
4889 "2 ViewFocusState.unfocused ViewFocusDirection.backward");
4890 DestroyShell(std::move(shell), task_runners);
4894 Settings settings = CreateSettingsForFixture();
4898 std::optional<int> reported_handle = std::nullopt;
4902 Dart_Handle arg = Dart_GetNativeArgument(
args, 0);
4903 if (Dart_IsNull(arg)) {
4904 reported_handle = std::nullopt;
4912 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4913 ASSERT_TRUE(shell->IsSetup());
4915 auto configuration = RunConfiguration::InferFromSettings(settings);
4916 configuration.SetEngineId(99);
4917 configuration.SetEntrypoint(
"providesEngineId");
4918 RunEngine(shell.get(), std::move(configuration));
4921 ASSERT_EQ(reported_handle, 99);
4926 shell->GetTaskRunners().GetUITaskRunner(), [&]() {
4927 ASSERT_EQ(shell->GetEngine()->GetLastEngineId(), 99);
4931 DestroyShell(std::move(shell), task_runners);
4935 Settings settings = CreateSettingsForFixture();
4939 std::optional<int> reported_handle = std::nullopt;
4943 Dart_Handle arg = Dart_GetNativeArgument(
args, 0);
4944 if (Dart_IsNull(arg)) {
4945 reported_handle = std::nullopt;
4953 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4954 ASSERT_TRUE(shell->IsSetup());
4956 auto configuration = RunConfiguration::InferFromSettings(settings);
4957 configuration.SetEntrypoint(
"providesEngineId");
4958 RunEngine(shell.get(), std::move(configuration));
4961 ASSERT_EQ(reported_handle, std::nullopt);
4962 DestroyShell(std::move(shell), task_runners);
4966 Settings settings = CreateSettingsForFixture();
4968 Settings::MergedPlatformUIThread::kMergeAfterLaunch;
4971 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4972 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4976 thread_host.
io_thread->GetTaskRunner());
4978 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4993 auto configuration = RunConfiguration::InferFromSettings(settings);
4994 configuration.SetEntrypoint(
"mainNotifyNative");
4995 RunEngine(shell.get(), std::move(configuration));
5003 DestroyShell(std::move(shell), task_runners);
5008 auto settings = CreateSettingsForFixture();
5009 bool called_release_resource_context =
false;
5011 [task_runners, &called_release_resource_context](
flutter::Shell& shell) {
5012 auto result = std::make_unique<::testing::NiceMock<TestPlatformView>>(
5013 shell, task_runners);
5014 ON_CALL(*result, ReleaseResourceContext())
5016 ::testing::Assign(&called_release_resource_context,
true));
5020 auto parent_shell = CreateShell({
5021 .settings = settings,
5022 .task_runners = task_runners,
5023 .platform_view_create_callback = platform_view_create_callback,
5026 std::unique_ptr<Shell> child_shell;
5028 parent_shell->GetTaskRunners().GetPlatformTaskRunner(),
5029 [&parent_shell, &settings, &child_shell, platform_view_create_callback] {
5030 auto configuration = RunConfiguration::InferFromSettings(settings);
5031 configuration.SetEntrypoint(
"emptyMain");
5032 auto child = parent_shell->Spawn(
5033 std::move(configuration),
"", platform_view_create_callback,
5034 [](Shell& shell) { return std::make_unique<Rasterizer>(shell); });
5035 child_shell = std::move(child);
5038 DestroyShell(std::move(parent_shell), task_runners);
5039 ASSERT_FALSE(called_release_resource_context);
5041 DestroyShell(std::move(child_shell), task_runners);
5042 ASSERT_TRUE(called_release_resource_context);
5046 Settings settings = CreateSettingsForFixture();
5047 auto task_runner = CreateNewThread();
5048 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
5050 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
5053 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
5054 shell->GetPlatformView()->SetViewportMetrics(
5083 PumpOneFrame(shell.get());
5086 std::make_unique<LayerTree>(
nullptr,
5088 ASSERT_FALSE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5091 std::make_unique<LayerTree>(
nullptr,
5093 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5096 std::make_unique<LayerTree>(
nullptr,
5098 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5100 auto min_width = std::make_unique<LayerTree>(
nullptr,
5102 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5104 auto min_height = std::make_unique<LayerTree>(
nullptr,
5106 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5108 DestroyShell(std::move(shell), task_runners);
TEST_F(FlutterDisplayLinkTest, ViewAddedToWindowFirst)
std::vector< std::unique_ptr< fml::Mapping > > GetAsMappings(const std::string &asset_pattern, const std::optional< std::string > &subdir) const override
Same as GetAsMapping() but returns mappings for all files who's name matches a given pattern....
std::unique_ptr< fml::Mapping > GetAsMapping(const std::string &asset_name) const override
bool PushBack(std::unique_ptr< AssetResolver > resolver)
Adds an asset resolver to the end of the resolver queue. Assets would be loaded from this resolver af...
AssetResolverType
Identifies the type of AssetResolver an instance is.
Represents an instance of a live isolate. An isolate is a separate Dart execution context....
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
static bool IsInstanceRunning()
sk_sp< DisplayList > Build()
void DrawRect(const DlRect &rect, const DlPaint &paint) override
void PrerollSetup(PrerollContext *context, const DlMatrix &matrix) override
void PrerollFinalize(PrerollContext *context, const DlMatrix &matrix) override
bool TryToPrepareRasterCache(const PaintContext &context, bool parent_cached=false) const override
bool Draw(const PaintContext &context, const DlPaint *paint) const override
static std::shared_ptr< DlImageFilter > MakeBlur(DlScalar sigma_x, DlScalar sigma_y, DlTileMode tile_mode)
Used for fixed refresh rate cases.
static constexpr Phase kPhases[kCount]
fml::TimePoint Set(Phase phase, fml::TimePoint value)
fml::TimePoint Get(Phase phase) const
The minimal interface necessary for defining a decoder that can be used for both single and multi-fra...
void PrerollSetup(PrerollContext *context, const DlMatrix &matrix) override
void PrerollFinalize(PrerollContext *context, const DlMatrix &matrix) override
bool Draw(const PaintContext &context, const DlPaint *paint) const override
bool TryToPrepareRasterCache(const PaintContext &context, bool parent_cached=false) const override
void set_delegate(DlCanvas *canvas)
void set_preroll_delegate(const DlRect &cull_rect, const DlMatrix &matrix)
const std::vector< std::shared_ptr< Mutator > >::const_iterator Begin() const
bool need_caching() const
Specifies all the configuration required by the runtime library to launch the root isolate....
void SetEntrypoint(std::string entrypoint)
Updates the main application entrypoint. If this is not set, the "main" method is used as the entrypo...
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
virtual bool NotifyIdle(fml::TimeDelta deadline)
Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified dead...
std::map< std::string_view, std::string_view > ServiceProtocolMap
static std::unique_ptr< Shell > Create(const PlatformData &platform_data, const TaskRunners &task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer, bool is_gpu_disabled=false)
Creates a shell instance using the provided settings. The callbacks to create the various shell subco...
const TaskRunners & GetTaskRunners() const override
If callers wish to interact directly with any shell subcomponents, they must (on the platform thread)...
std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const override
Accessor for the disable GPU SyncSwitch.
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
bool IsSetup() const
Used by embedders to check if all shell subcomponents are initialized. It is the embedder's responsib...
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
void OnGrContextDestroyed() override
void OnGrContextCreated() override
~MockTexture() override=default
MockTexture(int64_t textureId, std::shared_ptr< fml::AutoResetWaitableEvent > latch)
void OnTextureUnregistered() override
void MarkNewFrameAvailable() override
void Paint(PaintContext &context, const DlRect &bounds, bool freeze, const DlImageSampling) override
static void PlatformViewNotifyDestroyed(Shell *shell)
static void PlatformViewNotifyCreated(Shell *shell)
An image generator that always creates a 1x1 single-frame green image.
unsigned int GetFrameCount() const
Get the number of frames that the encoded image stores. This method is always expected to be called b...
const SkImageInfo & GetInfo()
Returns basic information about the contents of the encoded image. This information can almost always...
const ImageGenerator::FrameInfo GetFrameInfo(unsigned int frame_index)
Get information about a single frame in the context of a multi-frame image, useful for animation and ...
bool GetPixels(const SkImageInfo &info, void *pixels, size_t row_bytes, unsigned int frame_index, std::optional< unsigned int > prior_frame)
Decode the image into a given buffer. This method is currently always used for sub-pixel image decodi...
SinglePixelImageGenerator()
~SinglePixelImageGenerator()=default
SkISize GetScaledDimensions(float scale)
Given a scale value, find the closest image size that can be used for efficiently decoding the image....
unsigned int GetPlayCount() const
The number of times an animated image should play through before playback stops.
TestAssetResolver(bool valid, AssetResolver::AssetResolverType type)
bool IsValidAfterAssetManagerChange() const override
Certain asset resolvers are still valid after the asset manager is replaced before a hot reload,...
bool IsValid() const override
std::unique_ptr< fml::Mapping > GetAsMapping(const std::string &asset_name) const override
bool operator==(const AssetResolver &other) const override
AssetResolver::AssetResolverType GetType() const override
Gets the type of AssetResolver this is. Types are defined in AssetResolverType.
std::vector< std::unique_ptr< fml::Mapping > > GetAsMappings(const std::string &asset_pattern, const std::optional< std::string > &subdir) const override
Same as GetAsMapping() but returns mappings for all files who's name matches a given pattern....
bool IsValid() const override
std::unique_ptr< fml::Mapping > GetAsMapping(const std::string &asset_name) const override
bool operator==(const AssetResolver &other) const override
bool IsValidAfterAssetManagerChange() const override
Certain asset resolvers are still valid after the asset manager is replaced before a hot reload,...
ThreadCheckingAssetResolver(std::shared_ptr< fml::ConcurrentMessageLoop > concurrent_loop)
AssetResolverType GetType() const
Gets the type of AssetResolver this is. Types are defined in AssetResolverType.
std::vector< std::string > mapping_requests
bool WaitWithTimeout(TimeDelta timeout)
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
static void CaptureNextLog(std::ostringstream *stream)
A Mapping like NonOwnedMapping, but uses Free as its release proc.
static MallocMapping Copy(const T *begin, const T *end)
static void EnsureInitializedForCurrentThread()
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
static FML_EMBEDDER_ONLY MessageLoop & GetCurrent()
const std::string & path() const
fml::StatusCode code() const
std::string_view message() const
static bool RunsOnTheSameThread(TaskQueueId queue_a, TaskQueueId queue_b)
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
virtual void PostTask(const fml::closure &task) override
virtual bool RunsTasksOnCurrentThread()
virtual TaskQueueId GetTaskQueueId()
static void DisableNextThreadCheckFailure()
constexpr int64_t ToMicroseconds() const
static constexpr TimeDelta Max()
static constexpr TimeDelta FromMicroseconds(int64_t micros)
static constexpr TimeDelta Zero()
constexpr TimeDelta ToEpochDelta() const
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
const EmbeddedViewParams * params
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
static constexpr FlutterViewId kImplicitViewId
std::shared_ptr< ImpellerAllocator > allocator
union flutter::testing::@2832::KeyboardChange::@77 content
static void LogSkData(const sk_sp< SkData > &data, const char *title)
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
TEST_F(DisplayListTest, Defaults)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
static void ParseViewIdsCallback(const Dart_NativeArguments &args, bool *hasImplicitView, std::vector< int64_t > *viewIds)
static void TestDartVmFlags(std::vector< const char * > &flags)
static sk_sp< DisplayList > MakeSizedDisplayList(int width, int height)
TaskRunners GetTaskRunnersForFixture()
std::function< void(std::shared_ptr< ContainerLayer > root)> LayerTreeBuilder
static void PostSync(const fml::RefPtr< fml::TaskRunner > &task_runner, const fml::closure &task)
static void ParseViewWidthsCallback(const Dart_NativeArguments &args, std::map< int64_t, int64_t > *viewWidths)
static bool ValidateShell(Shell *shell)
static std::string CreateFlagsString(std::vector< const char * > &flags)
TEST(NativeAssetsManagerTest, NoAvailableAssets)
static void CheckFrameTimings(const std::vector< FrameTiming > &timings, fml::TimePoint start, fml::TimePoint finish)
static size_t GetRasterizerResourceCacheBytesSync(const Shell &shell)
static void ValidateDestroyPlatformView(Shell *shell)
static bool RasterizerIsTornDown(Shell *shell)
constexpr int64_t kImplicitViewId
const char * GetSkiaVersion()
static void InvokePlatformMessageResponseCallback(JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId, jobject message, jint position)
static void InvokePlatformMessageEmptyResponseCallback(JNIEnv *env, jobject jcaller, jlong shell_holder, jint responseId)
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
const char * GetFlutterEngineVersion()
static void LoadDartDeferredLibrary(JNIEnv *env, jobject obj, jlong shell_holder, jint jLoadingUnitId, jobjectArray jSearchPaths)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Settings SettingsFromCommandLine(const fml::CommandLine &command_line, bool require_merged_platform_ui_thread)
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
std::string BacktraceHere(size_t offset)
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
RefPtr< T > AdoptRef(T *ptr)
static fml::UniqueFD CreateDirectory(const fml::UniqueFD &base_directory, const std::vector< std::string > &components, FilePermission permission, size_t index)
std::function< void()> closure
static const size_t kGrCacheMaxByteSize
static constexpr DlColor kRed()
Info about a single frame in the context of a multi-frame image, useful for animation and blending.
LayerStateStack & state_stack
GrDirectContext * gr_context
bool enable_software_rendering
MergedPlatformUIThread merged_platform_ui_thread
std::shared_ptr< const fml::Mapping > persistent_isolate_data
std::vector< std::string > dart_flags
bool warn_on_impeller_opt_out
The collection of all the threads used by the engine.
std::unique_ptr< fml::Thread > io_thread
std::unique_ptr< fml::Thread > platform_thread
std::unique_ptr< fml::Thread > raster_thread
std::unique_ptr< fml::Thread > ui_thread
static FrameContent ImplicitView(double width, double height, LayerTreeBuilder builder)
static FrameContent DummyView(double width=1, double height=1)
Represents the 2 code paths available when calling |SyncSwitchExecute|.
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
#define CREATE_NATIVE_ENTRY(native_entry)
std::shared_ptr< const fml::Mapping > data