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()),
85 document.AddMember(
key,
value, allocator);
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 EXPECT_NE(image, nullptr);
2497 DestroyShell(std::move(shell), task_runners);
2501 Settings settings = CreateSettingsForFixture();
2502 std::unique_ptr<Shell> shell = CreateShell(settings);
2506 auto display_list_layer = std::make_shared<DisplayListLayer>(
2508 display_list_layer->set_paint_bounds(DlRect::MakeWH(100, 100));
2511 std::promise<bool> rasterized;
2513 shell->GetTaskRunners().GetRasterTaskRunner()->PostTask(
2514 [&shell, &rasterized, &display_list, &display_list_layer] {
2515 std::vector<RasterCacheItem*> raster_cache_items;
2516 auto* compositor_context = shell->GetRasterizer()->compositor_context();
2517 auto& raster_cache = compositor_context->raster_cache();
2526 .gr_context =
nullptr,
2527 .dst_color_space =
nullptr,
2528 .view_embedder =
nullptr,
2529 .raster_time = raster_time,
2531 .texture_registry =
nullptr,
2532 .raster_cache = &raster_cache,
2538 .raster_cache = &raster_cache,
2540 .view_embedder =
nullptr,
2541 .state_stack = state_stack,
2542 .dst_color_space =
nullptr,
2543 .surface_needs_readback =
false,
2544 .raster_time = raster_time,
2546 .texture_registry =
nullptr,
2547 .has_platform_view =
false,
2548 .has_texture_layer =
false,
2549 .raster_cached_entries = &raster_cache_items,
2557 bool picture_cache_generated;
2559 display_list, SkPoint(),
true,
false);
2560 for (
int i = 0;
i < 4;
i += 1) {
2563 display_list_raster_cache_item.
PrerollSetup(&preroll_context, matrix);
2566 picture_cache_generated =
2570 display_list_raster_cache_item.
Draw(paint_context, &dummy_canvas,
2573 ASSERT_TRUE(picture_cache_generated);
2582 layer_raster_cache_item.
Draw(paint_context, &dummy_canvas, &paint);
2583 rasterized.set_value(
true);
2585 rasterized.get_future().wait();
2589 rapidjson::Document document;
2591 shell.get(), ServiceProtocolEnum::kEstimateRasterCacheMemory,
2592 shell->GetTaskRunners().GetRasterTaskRunner(), empty_params, &document);
2593 rapidjson::StringBuffer
buffer;
2594 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2595 document.Accept(writer);
2596 std::string expected_json =
2597 "{\"type\":\"EstimateRasterCacheMemory\",\"layerBytes\":40024,\"picture"
2599 std::string actual_json =
buffer.GetString();
2600 ASSERT_EQ(actual_json, expected_json);
2602 DestroyShell(std::move(shell));
2610 auto settings = CreateSettingsForFixture();
2616 auto end_frame_callback =
2617 [&](
bool should_merge_thread,
2619 end_frame_latch.
Signal();
2621 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2622 std::move(end_frame_callback), PostPrerollResult::kSuccess,
false);
2623 std::unique_ptr<Shell> shell = CreateShell({
2624 .settings = settings,
2626 .shell_test_external_view_embedder = external_view_embedder,
2631 PlatformViewNotifyCreated(shell.get());
2634 shell->GetTaskRunners().GetPlatformTaskRunner(),
2635 [&shell, &expected_size]() {
2636 shell->GetPlatformView()->SetViewportMetrics(
2638 {1.0, static_cast<double>(expected_size.width),
2639 static_cast<double>(expected_size.height), 22, 0});
2642 auto configuration = RunConfiguration::InferFromSettings(settings);
2643 configuration.SetEntrypoint(
"emptyMain");
2645 RunEngine(shell.get(), std::move(configuration));
2647 PumpOneFrame(shell.get(),
2648 ViewContent::DummyView(
static_cast<double>(wrong_size.width),
2649 static_cast<double>(wrong_size.height)));
2650 end_frame_latch.Wait();
2652 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2654 PumpOneFrame(shell.get(), ViewContent::DummyView(
2655 static_cast<double>(expected_size.width),
2656 static_cast<double>(expected_size.height)));
2657 end_frame_latch.Wait();
2659 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2660 ASSERT_EQ(expected_size, external_view_embedder->GetLastSubmittedFrameSize());
2662 PlatformViewNotifyDestroyed(shell.get());
2663 DestroyShell(std::move(shell));
2671 auto settings = CreateSettingsForFixture();
2680 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
2682 auto end_frame_callback =
2683 [&](
bool should_merge_thread,
2685 if (!raster_thread_merger_ref) {
2686 raster_thread_merger_ref = raster_thread_merger;
2688 if (should_merge_thread) {
2689 raster_thread_merger->MergeWithLease(10);
2690 external_view_embedder->UpdatePostPrerollResult(
2691 PostPrerollResult::kSuccess);
2693 end_frame_latch.
Signal();
2695 if (should_merge_thread) {
2696 resize_latch.
Wait();
2700 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2701 std::move(end_frame_callback), PostPrerollResult::kResubmitFrame,
true);
2703 std::unique_ptr<Shell> shell = CreateShell({
2704 .settings = settings,
2706 .shell_test_external_view_embedder = external_view_embedder,
2711 PlatformViewNotifyCreated(shell.get());
2714 shell->GetTaskRunners().GetPlatformTaskRunner(),
2715 [&shell, &origin_size]() {
2716 shell->GetPlatformView()->SetViewportMetrics(
2717 kImplicitViewId, {1.0, static_cast<double>(origin_size.width),
2718 static_cast<double>(origin_size.height), 22, 0});
2721 auto configuration = RunConfiguration::InferFromSettings(settings);
2722 configuration.SetEntrypoint(
"emptyMain");
2724 RunEngine(shell.get(), std::move(configuration));
2726 PumpOneFrame(shell.get(),
2727 ViewContent::DummyView(
static_cast<double>(origin_size.width),
2728 static_cast<double>(origin_size.height)));
2730 end_frame_latch.Wait();
2731 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2734 shell->GetTaskRunners().GetPlatformTaskRunner(),
2735 [&shell, &new_size, &resize_latch]() {
2736 shell->GetPlatformView()->SetViewportMetrics(
2737 kImplicitViewId, {1.0, static_cast<double>(new_size.width),
2738 static_cast<double>(new_size.height), 22, 0});
2739 resize_latch.Signal();
2742 end_frame_latch.Wait();
2746 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2749 PumpOneFrame(shell.get(),
2750 ViewContent::DummyView(
static_cast<double>(new_size.width),
2751 static_cast<double>(new_size.height)));
2753 end_frame_latch.Wait();
2754 ASSERT_TRUE(raster_thread_merger_ref->IsMerged());
2755 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2756 ASSERT_EQ(new_size, external_view_embedder->GetLastSubmittedFrameSize());
2758 PlatformViewNotifyDestroyed(shell.get());
2759 DestroyShell(std::move(shell));
2764 double last_device_pixel_ratio;
2767 auto native_report_device_pixel_ratio = [&](Dart_NativeArguments
args) {
2768 auto dpr_handle = Dart_GetNativeArgument(
args, 0);
2769 ASSERT_TRUE(Dart_IsDouble(dpr_handle));
2770 Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
2771 ASSERT_FALSE(last_device_pixel_ratio == 0.0);
2773 auto width_handle = Dart_GetNativeArgument(
args, 1);
2774 ASSERT_TRUE(Dart_IsDouble(width_handle));
2775 Dart_DoubleValue(width_handle, &last_width);
2776 ASSERT_FALSE(last_width == 0.0);
2778 auto height_handle = Dart_GetNativeArgument(
args, 2);
2779 ASSERT_TRUE(Dart_IsDouble(height_handle));
2780 Dart_DoubleValue(height_handle, &last_height);
2781 ASSERT_FALSE(last_height == 0.0);
2786 Settings settings = CreateSettingsForFixture();
2787 auto task_runner = CreateNewThread();
2788 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2791 AddNativeCallback(
"ReportMetrics",
2794 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2796 auto configuration = RunConfiguration::InferFromSettings(settings);
2797 configuration.SetEntrypoint(
"reportMetrics");
2799 RunEngine(shell.get(), std::move(configuration));
2801 task_runner->PostTask([&]() {
2804 {0.0, 400, 200, 22, 0});
2805 task_runner->PostTask([&]() {
2808 {0.8, 0.0, 200, 22, 0});
2809 task_runner->PostTask([&]() {
2812 {0.8, 400, 0.0, 22, 0});
2813 task_runner->PostTask([&]() {
2815 shell->GetPlatformView()->SetViewportMetrics(
2822 ASSERT_EQ(last_device_pixel_ratio, 0.8);
2823 ASSERT_EQ(last_width, 400.0);
2824 ASSERT_EQ(last_height, 200.0);
2827 task_runner->PostTask([&]() {
2829 {1.2, 600, 300, 22, 0});
2832 ASSERT_EQ(last_device_pixel_ratio, 1.2);
2833 ASSERT_EQ(last_width, 600.0);
2834 ASSERT_EQ(last_height, 300.0);
2836 DestroyShell(std::move(shell), task_runners);
2841 double last_device_pixel_ratio;
2843 auto native_report_device_pixel_ratio = [&](Dart_NativeArguments
args) {
2845 auto dpr_handle = Dart_GetNativeArgument(
args, 0);
2846 ASSERT_TRUE(Dart_IsDouble(dpr_handle));
2847 Dart_DoubleValue(dpr_handle, &last_device_pixel_ratio);
2848 ASSERT_TRUE(last_device_pixel_ratio > 2.5);
2853 Settings settings = CreateSettingsForFixture();
2854 auto task_runner = CreateNewThread();
2855 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2858 AddNativeCallback(
"ReportMetrics",
2861 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
2863 auto configuration = RunConfiguration::InferFromSettings(settings);
2864 configuration.SetEntrypoint(
"reportMetrics");
2866 RunEngine(shell.get(), std::move(configuration));
2868 task_runner->PostTask([&]() {
2871 shell->GetPlatformView()->SetViewportMetrics(2, {2.0, 400, 200, 22, 0});
2872 task_runner->PostTask([&]() {
2875 {3.0, 400, 200, 22, 0});
2879 ASSERT_EQ(last_device_pixel_ratio, 3.0);
2882 DestroyShell(std::move(shell), task_runners);
2886 Settings settings = CreateSettingsForFixture();
2887 std::unique_ptr<Shell> shell = CreateShell(settings);
2889 RunConfiguration::InferFromSettings(settings);
2890 configuration.
SetEntrypoint(
"canAccessResourceFromAssetDir");
2897 bool can_access_resource =
false;
2898 auto native_can_access_resource = [&can_access_resource,
2899 &latch](Dart_NativeArguments
args) {
2900 Dart_Handle exception =
nullptr;
2901 can_access_resource =
2905 AddNativeCallback(
"NotifyCanAccessResource",
2910 auto native_notify_set_asset_bundle_path =
2911 [&shell](Dart_NativeArguments
args) {
2914 params[
"assetDirectory"] =
"assetDirectory";
2915 rapidjson::Document document;
2916 OnServiceProtocol(shell.get(), ServiceProtocolEnum::kSetAssetBundlePath,
2917 shell->GetTaskRunners().GetUITaskRunner(),
params,
2919 rapidjson::StringBuffer
buffer;
2920 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2921 document.Accept(writer);
2923 AddNativeCallback(
"NotifySetAssetBundlePath",
2926 RunEngine(shell.get(), std::move(configuration));
2929 ASSERT_TRUE(can_access_resource);
2931 DestroyShell(std::move(shell));
2935 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
2938 auto vm_settings = CreateSettingsForFixture();
2939 auto vm_ref = DartVMRef::Create(vm_settings);
2940 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
2942 auto settings = vm_settings;
2944 settings.root_isolate_create_callback = [&](
const auto& isolate) {
2945 isolate_create_latch.
Signal();
2947 auto shell = CreateShell(settings);
2949 auto configuration = RunConfiguration::InferFromSettings(settings);
2950 ASSERT_TRUE(configuration.IsValid());
2951 RunEngine(shell.get(), std::move(configuration));
2952 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
2953 DestroyShell(std::move(shell));
2954 isolate_create_latch.
Wait();
2962 std::string filename =
"test_name";
2963 std::string
content =
"test_content";
2967 ASSERT_TRUE(success);
2971 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
2974 ASSERT_TRUE(mapping !=
nullptr);
2976 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
2977 mapping->GetSize());
2979 ASSERT_TRUE(result ==
content);
2987 std::vector<std::string> filenames = {
2994 for (
const auto& filename : filenames) {
2997 ASSERT_TRUE(success);
3002 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3004 auto mappings = asset_manager.
GetAsMappings(
"(.*)", std::nullopt);
3005 EXPECT_EQ(mappings.size(), 4u);
3007 std::vector<std::string> expected_results = {
3012 mappings = asset_manager.
GetAsMappings(
"(.*)good(.*)", std::nullopt);
3013 ASSERT_EQ(mappings.size(), expected_results.size());
3015 for (
auto& mapping : mappings) {
3016 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3017 mapping->GetSize());
3019 std::find(expected_results.begin(), expected_results.end(), result),
3020 expected_results.end());
3024#if defined(OS_FUCHSIA)
3025TEST_F(ShellTest, AssetManagerMultiSubdir) {
3026 std::string subdir_path =
"subdir";
3035 std::vector<std::string> filenames = {
3041 std::vector<std::string> subdir_filenames = {
3047 for (
auto filename : filenames) {
3050 ASSERT_TRUE(success);
3053 for (
auto filename : subdir_filenames) {
3056 ASSERT_TRUE(success);
3059 AssetManager asset_manager;
3060 asset_manager.PushBack(
3061 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3063 auto mappings = asset_manager.GetAsMappings(
"(.*)", std::nullopt);
3064 EXPECT_EQ(mappings.size(), 5u);
3066 mappings = asset_manager.GetAsMappings(
"(.*)", subdir_path);
3067 EXPECT_EQ(mappings.size(), 3u);
3069 std::vector<std::string> expected_results = {
3074 mappings = asset_manager.GetAsMappings(
"(.*)good(.*)", subdir_path);
3075 ASSERT_EQ(mappings.size(), expected_results.size());
3077 for (
auto& mapping : mappings) {
3078 std::string result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3079 mapping->GetSize());
3081 std::find(expected_results.begin(), expected_results.end(), result),
3082 expected_results.end());
3088 auto settings = CreateSettingsForFixture();
3089 auto shell = CreateShell(settings);
3092 auto configuration = RunConfiguration::InferFromSettings(settings);
3093 ASSERT_TRUE(configuration.IsValid());
3094 configuration.SetEntrypoint(
"fixturesAreFunctionalMain");
3096 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3097 ASSERT_TRUE(second_configuration.IsValid());
3098 second_configuration.SetEntrypoint(
"testCanLaunchSecondaryIsolate");
3100 const std::string initial_route(
"/foo");
3103 std::string last_entry_point;
3107 last_entry_point = shell->GetEngine()->GetLastEntrypoint();
3119 RunEngine(shell.get(), std::move(configuration));
3121 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3123 ASSERT_EQ(
"fixturesAreFunctionalMain", last_entry_point);
3126 shell->GetTaskRunners().GetPlatformTaskRunner(),
3127 [
this, &spawner = shell, &second_configuration, &second_latch,
3129 MockPlatformViewDelegate platform_view_delegate;
3130 auto spawn = spawner->Spawn(
3131 std::move(second_configuration), initial_route,
3132 [&platform_view_delegate](Shell& shell) {
3133 auto result = std::make_unique<MockPlatformView>(
3134 platform_view_delegate, shell.GetTaskRunners());
3135 ON_CALL(*result, CreateRenderingSurface())
3136 .WillByDefault(::testing::Invoke(
3137 [] { return std::make_unique<MockSurface>(); }));
3140 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3141 ASSERT_NE(
nullptr, spawn.get());
3144 PostSync(spawner->GetTaskRunners().GetUITaskRunner(), [&spawn, &spawner,
3147 ASSERT_EQ(
"testCanLaunchSecondaryIsolate",
3148 spawn->GetEngine()->GetLastEntrypoint());
3149 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3151 ASSERT_NE(spawner->GetEngine()
3152 ->GetRuntimeController()
3153 ->GetRootIsolateGroup(),
3155 ASSERT_EQ(spawner->GetEngine()
3156 ->GetRuntimeController()
3157 ->GetRootIsolateGroup(),
3159 ->GetRuntimeController()
3160 ->GetRootIsolateGroup());
3161 auto spawner_snapshot_delegate = spawner->GetEngine()
3162 ->GetRuntimeController()
3163 ->GetSnapshotDelegate();
3164 auto spawn_snapshot_delegate =
3165 spawn->GetEngine()->GetRuntimeController()->GetSnapshotDelegate();
3166 PostSync(spawner->GetTaskRunners().GetRasterTaskRunner(),
3167 [spawner_snapshot_delegate, spawn_snapshot_delegate] {
3168 ASSERT_NE(spawner_snapshot_delegate.get(),
3169 spawn_snapshot_delegate.get());
3173 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3174 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3175 spawn->GetIOManager()->GetResourceContext().get());
3180 second_latch.Wait();
3182 DestroyShell(std::move(spawn));
3185 DestroyShell(std::move(shell));
3186 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3190 auto settings = CreateSettingsForFixture();
3191 auto shell = CreateShell(settings);
3194 auto configuration = RunConfiguration::InferFromSettings(settings);
3195 ASSERT_TRUE(configuration.IsValid());
3196 configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineRun");
3197 const std::vector<std::string> entrypoint_args{
"foo",
"bar"};
3198 configuration.SetEntrypointArgs(entrypoint_args);
3200 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3201 ASSERT_TRUE(second_configuration.IsValid());
3202 second_configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineSpawn");
3203 const std::vector<std::string> second_entrypoint_args{
"arg1",
"arg2"};
3204 second_configuration.SetEntrypointArgs(second_entrypoint_args);
3206 const std::string initial_route(
"/foo");
3209 std::string last_entry_point;
3211 AddNativeCallback(
"NotifyNativeWhenEngineRun",
3214 Dart_GetNativeArgument(
args, 0)));
3216 shell->GetEngine()->GetLastEntrypoint();
3222 AddNativeCallback(
"NotifyNativeWhenEngineSpawn",
3225 Dart_GetNativeArgument(
args, 0)));
3227 shell->GetEngine()->GetLastEntrypoint();
3228 second_latch.Signal();
3231 RunEngine(shell.get(), std::move(configuration));
3233 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3235 ASSERT_EQ(
"canReceiveArgumentsWhenEngineRun", last_entry_point);
3238 shell->GetTaskRunners().GetPlatformTaskRunner(),
3239 [
this, &spawner = shell, &second_configuration, &second_latch,
3241 MockPlatformViewDelegate platform_view_delegate;
3242 auto spawn = spawner->Spawn(
3243 std::move(second_configuration), initial_route,
3244 [&platform_view_delegate](Shell& shell) {
3245 auto result = std::make_unique<MockPlatformView>(
3246 platform_view_delegate, shell.GetTaskRunners());
3247 ON_CALL(*result, CreateRenderingSurface())
3248 .WillByDefault(::testing::Invoke(
3249 [] { return std::make_unique<MockSurface>(); }));
3252 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3253 ASSERT_NE(
nullptr, spawn.get());
3256 PostSync(spawner->GetTaskRunners().GetUITaskRunner(),
3257 [&spawn, &spawner, initial_route] {
3259 ASSERT_EQ(
"canReceiveArgumentsWhenEngineSpawn",
3260 spawn->GetEngine()->GetLastEntrypoint());
3261 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3263 ASSERT_NE(spawner->GetEngine()
3264 ->GetRuntimeController()
3265 ->GetRootIsolateGroup(),
3267 ASSERT_EQ(spawner->GetEngine()
3268 ->GetRuntimeController()
3269 ->GetRootIsolateGroup(),
3271 ->GetRuntimeController()
3272 ->GetRootIsolateGroup());
3276 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3277 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3278 spawn->GetIOManager()->GetResourceContext().get());
3283 second_latch.Wait();
3285 DestroyShell(std::move(spawn));
3288 DestroyShell(std::move(shell));
3289 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3293 auto settings = CreateSettingsForFixture();
3294 auto shell = CreateShell(settings);
3297 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [
this,
3300 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3301 ASSERT_TRUE(second_configuration.IsValid());
3302 second_configuration.SetEntrypoint(
"emptyMain");
3303 const std::string initial_route(
"/foo");
3304 MockPlatformViewDelegate platform_view_delegate;
3305 auto spawn = spawner->Spawn(
3306 std::move(second_configuration), initial_route,
3307 [&platform_view_delegate](Shell& shell) {
3308 auto result = std::make_unique<MockPlatformView>(
3309 platform_view_delegate, shell.GetTaskRunners());
3310 ON_CALL(*result, CreateRenderingSurface())
3311 .WillByDefault(::testing::Invoke(
3312 [] { return std::make_unique<MockSurface>(); }));
3315 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3318 PostSync(spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &spawn] {
3319 ASSERT_NE(spawner->GetIOManager().get(), nullptr);
3320 ASSERT_EQ(spawner->GetIOManager().get(), spawn->GetIOManager().get());
3324 DestroyShell(std::move(spawn));
3327 DestroyShell(std::move(shell));
3331 auto settings = CreateSettingsForFixture();
3332 auto shell = CreateShell(settings);
3335 PostSync(shell->GetTaskRunners().GetUITaskRunner(), [&shell] {
3337 auto runtime_controller = shell->GetEngine()->GetRuntimeController();
3338 PostSync(shell->GetTaskRunners().GetIOTaskRunner(),
3339 [&shell, &runtime_controller] {
3341 auto io_manager = runtime_controller->GetIOManager();
3343 ASSERT_NE(io_manager.get(), nullptr);
3344 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3346 ASSERT_NE(shell->GetIOManager().get(), nullptr);
3350 std::unique_ptr<Shell> spawn;
3352 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &settings,
3354 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3355 ASSERT_TRUE(second_configuration.IsValid());
3356 second_configuration.SetEntrypoint(
"emptyMain");
3357 const std::string initial_route(
"/foo");
3358 MockPlatformViewDelegate platform_view_delegate;
3359 auto child = shell->Spawn(
3360 std::move(second_configuration), initial_route,
3361 [&platform_view_delegate](Shell& shell) {
3362 auto result = std::make_unique<MockPlatformView>(
3363 platform_view_delegate, shell.GetTaskRunners());
3364 ON_CALL(*result, CreateRenderingSurface())
3365 .WillByDefault(::testing::Invoke(
3366 [] { return std::make_unique<MockSurface>(); }));
3369 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3370 spawn = std::move(child);
3373 DestroyShell(std::move(shell));
3375 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3377 auto runtime_controller = spawn->GetEngine()->GetRuntimeController();
3378 PostSync(spawn->GetTaskRunners().GetIOTaskRunner(),
3379 [&spawn, &runtime_controller] {
3381 auto io_manager = runtime_controller->GetIOManager();
3383 ASSERT_NE(io_manager.get(), nullptr);
3384 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3386 ASSERT_NE(spawn->GetIOManager().get(), nullptr);
3390 DestroyShell(std::move(spawn));
3394 auto settings = CreateSettingsForFixture();
3395 auto shell = CreateShell(settings);
3398 std::unique_ptr<Shell> spawn;
3400 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &settings,
3402 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3403 ASSERT_TRUE(second_configuration.IsValid());
3404 second_configuration.SetEntrypoint(
"emptyMain");
3405 const std::string initial_route(
"/foo");
3406 MockPlatformViewDelegate platform_view_delegate;
3407 auto child = shell->Spawn(
3408 std::move(second_configuration), initial_route,
3409 [&platform_view_delegate](Shell& shell) {
3410 auto result = std::make_unique<MockPlatformView>(
3411 platform_view_delegate, shell.GetTaskRunners());
3412 ON_CALL(*result, CreateRenderingSurface())
3413 .WillByDefault(::testing::Invoke(
3414 [] { return std::make_unique<MockSurface>(); }));
3417 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3418 spawn = std::move(child);
3421 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3422 std::shared_ptr<const DartIsolate> isolate =
3423 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3424 ASSERT_TRUE(isolate);
3425 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3429 DestroyShell(std::move(shell));
3431 PostSync(spawn->GetTaskRunners().GetUITaskRunner(), [&spawn] {
3432 std::shared_ptr<const DartIsolate> isolate =
3433 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3434 ASSERT_TRUE(isolate);
3435 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3438 DestroyShell(std::move(spawn));
3442 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3443 Settings settings = CreateSettingsForFixture();
3447 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3449 auto shell = CreateShell(settings, task_runners);
3450 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3453 auto configuration = RunConfiguration::InferFromSettings(settings);
3454 configuration.SetEntrypoint(
"emptyMain");
3455 auto asset_manager = configuration.GetAssetManager();
3457 shell->RunEngine(std::move(configuration), [&](
auto result) {
3458 ASSERT_EQ(result, Engine::RunStatus::Success);
3462 std::make_unique<PlatformView>(*shell.get(), task_runners);
3464 auto old_resolver = std::make_unique<TestAssetResolver>(
3465 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3466 ASSERT_TRUE(old_resolver->IsValid());
3467 asset_manager->PushBack(std::move(old_resolver));
3469 auto updated_resolver = std::make_unique<TestAssetResolver>(
3470 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3471 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3473 std::move(updated_resolver),
3474 AssetResolver::AssetResolverType::kApkAssetProvider);
3476 auto resolvers = asset_manager->TakeResolvers();
3477 ASSERT_EQ(resolvers.size(), 2ull);
3478 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3480 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3482 DestroyShell(std::move(shell), task_runners);
3483 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3487 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3488 Settings settings = CreateSettingsForFixture();
3492 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3494 auto shell = CreateShell(settings, task_runners);
3495 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3498 auto configuration = RunConfiguration::InferFromSettings(settings);
3499 configuration.SetEntrypoint(
"emptyMain");
3500 auto asset_manager = configuration.GetAssetManager();
3502 shell->RunEngine(std::move(configuration), [&](
auto result) {
3503 ASSERT_EQ(result, Engine::RunStatus::Success);
3507 std::make_unique<PlatformView>(*shell.get(), task_runners);
3509 auto updated_resolver = std::make_unique<TestAssetResolver>(
3510 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3511 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3513 std::move(updated_resolver),
3514 AssetResolver::AssetResolverType::kApkAssetProvider);
3516 auto resolvers = asset_manager->TakeResolvers();
3517 ASSERT_EQ(resolvers.size(), 2ull);
3518 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3520 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3522 DestroyShell(std::move(shell), task_runners);
3523 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3527 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3528 Settings settings = CreateSettingsForFixture();
3531 ThreadHost::Type::kPlatform));
3533 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3535 auto shell = CreateShell(settings, task_runners);
3536 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3539 auto configuration = RunConfiguration::InferFromSettings(settings);
3540 configuration.SetEntrypoint(
"emptyMain");
3541 auto asset_manager = configuration.GetAssetManager();
3542 RunEngine(shell.get(), std::move(configuration));
3545 std::make_unique<PlatformView>(*shell.get(), task_runners);
3547 auto old_resolver = std::make_unique<TestAssetResolver>(
3548 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3549 ASSERT_TRUE(old_resolver->IsValid());
3550 asset_manager->PushBack(std::move(old_resolver));
3553 nullptr, AssetResolver::AssetResolverType::kApkAssetProvider);
3555 auto resolvers = asset_manager->TakeResolvers();
3556 ASSERT_EQ(resolvers.size(), 2ull);
3557 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3558 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3560 DestroyShell(std::move(shell), task_runners);
3561 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3565 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3566 Settings settings = CreateSettingsForFixture();
3570 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3572 auto shell = CreateShell(settings, task_runners);
3573 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3576 auto configuration = RunConfiguration::InferFromSettings(settings);
3577 configuration.SetEntrypoint(
"emptyMain");
3578 auto asset_manager = configuration.GetAssetManager();
3580 shell->RunEngine(std::move(configuration), [&](
auto result) {
3581 ASSERT_EQ(result, Engine::RunStatus::Success);
3585 std::make_unique<PlatformView>(*shell.get(), task_runners);
3587 auto old_resolver = std::make_unique<TestAssetResolver>(
3588 true, AssetResolver::AssetResolverType::kAssetManager);
3589 ASSERT_TRUE(old_resolver->IsValid());
3590 asset_manager->PushBack(std::move(old_resolver));
3592 auto updated_resolver = std::make_unique<TestAssetResolver>(
3593 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3594 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3596 std::move(updated_resolver),
3597 AssetResolver::AssetResolverType::kApkAssetProvider);
3599 auto resolvers = asset_manager->TakeResolvers();
3600 ASSERT_EQ(resolvers.size(), 3ull);
3601 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3603 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3605 ASSERT_FALSE(resolvers[2]->IsValidAfterAssetManagerChange());
3607 DestroyShell(std::move(shell), task_runners);
3608 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3616 auto settings = CreateSettingsForFixture();
3617 std::unique_ptr<Shell> shell = CreateShell({
3618 .settings = settings,
3620 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
3623 ASSERT_NE(shell,
nullptr);
3624 ASSERT_TRUE(shell->IsSetup());
3625 auto configuration = RunConfiguration::InferFromSettings(settings);
3626 PlatformViewNotifyCreated(shell.get());
3627 configuration.SetEntrypoint(
"emptyMain");
3628 RunEngine(shell.get(), std::move(configuration));
3629 PumpOneFrame(shell.get());
3630 PlatformViewNotifyDestroyed(shell.get());
3631 DestroyShell(std::move(shell));
3636#if !SHELL_ENABLE_VULKAN
3639 auto settings = CreateSettingsForFixture();
3640 std::unique_ptr<Shell> shell = CreateShell({
3641 .settings = settings,
3643 .rendering_backend =
3644 ShellTestPlatformView::BackendType::kVulkanBackend,
3647 ASSERT_NE(shell,
nullptr);
3648 ASSERT_TRUE(shell->IsSetup());
3649 auto configuration = RunConfiguration::InferFromSettings(settings);
3650 PlatformViewNotifyCreated(shell.get());
3651 configuration.SetEntrypoint(
"emptyMain");
3652 RunEngine(shell.get(), std::move(configuration));
3653 PumpOneFrame(shell.get());
3654 PlatformViewNotifyDestroyed(shell.get());
3655 DestroyShell(std::move(shell));
3660#if !SHELL_ENABLE_METAL
3663 auto settings = CreateSettingsForFixture();
3664 std::unique_ptr<Shell> shell = CreateShell({
3665 .settings = settings,
3667 .rendering_backend =
3668 ShellTestPlatformView::BackendType::kMetalBackend,
3671 ASSERT_NE(shell,
nullptr);
3672 ASSERT_TRUE(shell->IsSetup());
3673 auto configuration = RunConfiguration::InferFromSettings(settings);
3674 PlatformViewNotifyCreated(shell.get());
3675 configuration.SetEntrypoint(
"emptyMain");
3676 RunEngine(shell.get(), std::move(configuration));
3677 PumpOneFrame(shell.get());
3678 PlatformViewNotifyDestroyed(shell.get());
3679 DestroyShell(std::move(shell));
3684 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3687 auto vm_settings = CreateSettingsForFixture();
3688 auto vm_ref = DartVMRef::Create(vm_settings);
3689 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3691 auto settings = vm_settings;
3695 settings.root_isolate_create_callback = [&](
const DartIsolate& isolate) {
3696 Dart_Handle current_tag = Dart_GetCurrentUserTag();
3697 Dart_Handle startup_tag = Dart_NewUserTag(
"AppStartUp");
3698 EXPECT_TRUE(Dart_IdentityEquals(current_tag, startup_tag));
3700 isolate_create_latch.
Signal();
3703 auto shell = CreateShell(settings);
3706 auto configuration = RunConfiguration::InferFromSettings(settings);
3707 ASSERT_TRUE(configuration.IsValid());
3709 RunEngine(shell.get(), std::move(configuration));
3710 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3712 DestroyShell(std::move(shell));
3713 isolate_create_latch.
Wait();
3717 auto settings = CreateSettingsForFixture();
3718 settings.prefetched_default_font_manager =
true;
3719 std::unique_ptr<Shell> shell;
3721 auto get_font_manager_count = [&] {
3723 size_t font_manager_count;
3725 shell->GetTaskRunners().GetUITaskRunner(),
3726 [
this, &shell, &latch, &font_manager_count]() {
3727 font_manager_count =
3728 GetFontCollection(shell.get())->GetFontManagersCount();
3732 return font_manager_count;
3734 size_t initial_font_manager_count = 0;
3735 settings.root_isolate_create_callback = [&](
const auto& isolate) {
3736 ASSERT_GT(initial_font_manager_count, 0ul);
3739 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count);
3742 shell = CreateShell(settings);
3744 initial_font_manager_count = get_font_manager_count();
3746 auto configuration = RunConfiguration::InferFromSettings(settings);
3747 configuration.SetEntrypoint(
"emptyMain");
3748 RunEngine(shell.get(), std::move(configuration));
3752 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count + 1);
3754 DestroyShell(std::move(shell));
3760 auto settings = CreateSettingsForFixture();
3761 auto shell = CreateShell(settings);
3765 [&latch]() { latch.Wait(); });
3767 ShellTest::PlatformViewNotifyCreated(shell.get());
3770 DestroyShell(std::move(shell));
3774 auto settings = CreateSettingsForFixture();
3775 auto shell = CreateShell(settings);
3776 auto configuration = RunConfiguration::InferFromSettings(settings);
3777 configuration.SetEntrypoint(
"drawFrames");
3782 notify_native_latch.
Signal();
3786 RunEngine(shell.get(), std::move(configuration));
3789 notify_native_latch.
Wait();
3791 ShellTest::PlatformViewNotifyCreated(shell.get());
3795 shell->GetTaskRunners().GetPlatformTaskRunner(),
3796 [&shell, &destroy_latch]() {
3797 shell->GetPlatformView()->NotifyDestroyed();
3798 destroy_latch.Signal();
3801 destroy_latch.
Wait();
3810 shell->GetTaskRunners().GetUITaskRunner(),
3811 [&ui_flush_latch]() { ui_flush_latch.Signal(); });
3812 ui_flush_latch.
Wait();
3813 DestroyShell(std::move(shell));
3818 auto settings = CreateSettingsForFixture();
3819 MockPlatformViewDelegate platform_view_delegate;
3820 auto platform_message_handler =
3821 std::make_shared<MockPlatformMessageHandler>();
3823 EXPECT_CALL(*platform_message_handler, HandlePlatformMessage(_));
3824 EXPECT_CALL(*platform_message_handler,
3825 InvokePlatformMessageEmptyResponseCallback(message_id));
3827 [&platform_view_delegate, task_runners,
3829 auto result = std::make_unique<MockPlatformView>(platform_view_delegate,
3831 EXPECT_CALL(*result, GetPlatformMessageHandler())
3832 .WillOnce(Return(platform_message_handler));
3835 auto shell = CreateShell({
3836 .settings = settings,
3837 .task_runners = task_runners,
3838 .platform_view_create_callback = platform_view_create_callback,
3841 EXPECT_EQ(platform_message_handler, shell->GetPlatformMessageHandler());
3843 size_t data_size = 4;
3844 fml::MallocMapping bytes =
3845 fml::MallocMapping(static_cast<uint8_t*>(malloc(data_size)), data_size);
3846 fml::RefPtr<MockPlatformMessageResponse> response =
3847 MockPlatformMessageResponse::Create();
3848 auto message = std::make_unique<PlatformMessage>(
3849 "foo", std::move(bytes), response);
3850 (static_cast<Engine::Delegate*>(shell.get()))
3851 ->OnEngineHandlePlatformMessage(std::move(message));
3853 shell->GetPlatformMessageHandler()
3854 ->InvokePlatformMessageEmptyResponseCallback(message_id);
3855 DestroyShell(std::move(shell));
3859 auto settings = CreateSettingsForFixture();
3860 auto shell = CreateShell(settings);
3863 auto configuration = RunConfiguration::InferFromSettings(settings);
3864 ASSERT_TRUE(configuration.IsValid());
3865 configuration.SetEntrypoint(
"onErrorA");
3867 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3868 ASSERT_TRUE(second_configuration.IsValid());
3869 second_configuration.SetEntrypoint(
"onErrorB");
3875 auto string_handle = Dart_GetNativeArgument(
args, 0);
3877 Dart_StringToCString(string_handle, &c_str);
3878 EXPECT_STREQ(c_str,
"Exception: I should be coming from A");
3884 auto string_handle = Dart_GetNativeArgument(
args, 0);
3886 Dart_StringToCString(string_handle, &c_str);
3887 EXPECT_STREQ(c_str,
"Exception: I should be coming from B");
3891 RunEngine(shell.get(), std::move(configuration));
3893 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3896 shell->GetTaskRunners().GetPlatformTaskRunner(),
3897 [
this, &spawner = shell, &second_configuration, &latch]() {
3898 ::testing::NiceMock<MockPlatformViewDelegate> platform_view_delegate;
3899 auto spawn = spawner->Spawn(
3900 std::move(second_configuration),
"",
3901 [&platform_view_delegate](Shell& shell) {
3903 std::make_unique<::testing::NiceMock<MockPlatformView>>(
3904 platform_view_delegate, shell.GetTaskRunners());
3905 ON_CALL(*result, CreateRenderingSurface())
3906 .WillByDefault(::testing::Invoke([] {
3907 return std::make_unique<::testing::NiceMock<MockSurface>>();
3911 [](
Shell& shell) { return std::make_unique<Rasterizer>(shell); });
3912 ASSERT_NE(
nullptr, spawn.get());
3919 DestroyShell(std::move(spawn));
3922 DestroyShell(std::move(shell));
3923 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3927 Settings settings = CreateSettingsForFixture();
3928 auto task_runner = CreateNewThread();
3929 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3931 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
3934 AddNativeCallback(
"NotifyNative",
3938 PlatformViewNotifyCreated(shell.get());
3940 auto configuration = RunConfiguration::InferFromSettings(settings);
3941 configuration.SetEntrypoint(
"testThatAssetLoadingHappensOnWorkerThread");
3942 auto asset_manager = configuration.GetAssetManager();
3943 auto test_resolver = std::make_unique<ThreadCheckingAssetResolver>(
3944 shell->GetDartVM()->GetConcurrentMessageLoop());
3945 auto leaked_resolver = test_resolver.get();
3946 asset_manager->PushBack(std::move(test_resolver));
3948 RunEngine(shell.get(), std::move(configuration));
3949 PumpOneFrame(shell.get());
3953 EXPECT_EQ(leaked_resolver->mapping_requests[0],
"DoesNotExist");
3955 PlatformViewNotifyDestroyed(shell.get());
3956 DestroyShell(std::move(shell), task_runners);
3964 auto settings = CreateSettingsForFixture();
3965 std::unique_ptr<Shell> shell = CreateShell({
3966 .settings = settings,
3968 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
3972 AddNativeCallback(
"NativeOnBeforeToImageSync",
3980 PlatformViewNotifyDestroyed(shell.get());
3981 PlatformViewNotifyCreated(shell.get());
3985 ASSERT_NE(shell,
nullptr);
3986 ASSERT_TRUE(shell->IsSetup());
3987 auto configuration = RunConfiguration::InferFromSettings(settings);
3988 PlatformViewNotifyCreated(shell.get());
3989 configuration.SetEntrypoint(
"toImageSync");
3990 RunEngine(shell.get(), std::move(configuration));
3991 PumpOneFrame(shell.get());
3995 PlatformViewNotifyDestroyed(shell.get());
3996 DestroyShell(std::move(shell));
4001#if !SHELL_ENABLE_METAL
4005 auto settings = CreateSettingsForFixture();
4006 settings.enable_impeller =
true;
4007 std::unique_ptr<Shell> shell = CreateShell({
4008 .settings = settings,
4010 .rendering_backend =
4011 ShellTestPlatformView::BackendType::kMetalBackend,
4015 AddNativeCallback(
"NativeOnBeforeToImageSync",
4023 PlatformViewNotifyDestroyed(shell.get());
4024 PlatformViewNotifyCreated(shell.get());
4028 ASSERT_NE(shell,
nullptr);
4029 ASSERT_TRUE(shell->IsSetup());
4030 auto configuration = RunConfiguration::InferFromSettings(settings);
4036 configuration.SetEntrypoint(
"toImageSync");
4037 RunEngine(shell.get(), std::move(configuration));
4038 PumpOneFrame(shell.get());
4042 PlatformViewNotifyDestroyed(shell.get());
4043 DestroyShell(std::move(shell));
4049TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) {
4052 ThreadHost thread_host(
"io.flutter.test." + GetCurrentTestName() +
".",
4053 ThreadHost::Type::kPlatform);
4054 auto task_runner = thread_host.platform_thread->GetTaskRunner();
4055 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4058 auto settings = CreateSettingsForFixture();
4059 std::unique_ptr<Shell> shell = CreateShell({
4060 .settings = settings,
4061 .task_runners = task_runners,
4062 .platform_view_create_callback = ShellTestPlatformViewBuilder({
4063 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
4072 ::eglMakeCurrent(::eglGetCurrentDisplay(), NULL, NULL, NULL);
4078 PlatformViewNotifyDestroyed(shell.get());
4079 PlatformViewNotifyCreated(shell.get());
4083 ASSERT_NE(shell,
nullptr);
4084 ASSERT_TRUE(shell->IsSetup());
4085 auto configuration = RunConfiguration::InferFromSettings(settings);
4086 PlatformViewNotifyCreated(shell.get());
4087 configuration.SetEntrypoint(
"toImageSync");
4088 RunEngine(shell.get(), std::move(configuration));
4089 PumpOneFrame(shell.get());
4093 PlatformViewNotifyDestroyed(shell.get());
4094 DestroyShell(std::move(shell), task_runners);
4099 auto settings = CreateSettingsForFixture();
4100 std::unique_ptr<Shell> shell = CreateShell(settings);
4105 Dart_Handle exception =
nullptr;
4107 args, 0, exception);
4111 ASSERT_NE(shell,
nullptr);
4112 ASSERT_TRUE(shell->IsSetup());
4113 auto configuration = RunConfiguration::InferFromSettings(settings);
4114 PlatformViewNotifyCreated(shell.get());
4115 configuration.SetEntrypoint(
"testPluginUtilitiesCallbackHandle");
4116 RunEngine(shell.get(), std::move(configuration));
4117 PumpOneFrame(shell.get());
4121 ASSERT_TRUE(test_passed);
4123 PlatformViewNotifyDestroyed(shell.get());
4124 DestroyShell(std::move(shell));
4128 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4129 Settings settings = CreateSettingsForFixture();
4131 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4132 ThreadHost::kIo | ThreadHost::kRaster);
4133 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4137 thread_host.
io_thread->GetTaskRunner());
4138 auto shell = CreateShell(settings, task_runners);
4139 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4144 auto configuration = RunConfiguration::InferFromSettings(settings);
4145 configuration.SetEntrypoint(
"emptyMain");
4146 RunEngine(shell.get(), std::move(configuration));
4150 auto runtime_controller = const_cast<RuntimeController*>(
4151 shell->GetEngine()->GetRuntimeController());
4153 auto now = fml::TimeDelta::FromMicroseconds(Dart_TimelineGetMicros());
4155 EXPECT_FALSE(runtime_controller->NotifyIdle(
4156 now - fml::TimeDelta::FromMilliseconds(10)));
4157 EXPECT_FALSE(runtime_controller->NotifyIdle(now));
4158 EXPECT_FALSE(runtime_controller->NotifyIdle(
4159 now + fml::TimeDelta::FromNanoseconds(100)));
4161 EXPECT_TRUE(runtime_controller->NotifyIdle(
4162 now + fml::TimeDelta::FromMilliseconds(100)));
4168 DestroyShell(std::move(shell), task_runners);
4169 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4173 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4174 Settings settings = CreateSettingsForFixture();
4176 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4177 ThreadHost::kIo | ThreadHost::kRaster);
4178 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4182 thread_host.
io_thread->GetTaskRunner());
4183 auto shell = CreateShell(settings, task_runners);
4184 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4193 Dart_Handle exception =
nullptr;
4194 bool is_in_latency_mode =
4197 shell->GetEngine()->GetRuntimeController());
4200 Dart_TimelineGetMicros() + 100000));
4201 EXPECT_EQ(success, !is_in_latency_mode);
4205 auto configuration = RunConfiguration::InferFromSettings(settings);
4206 configuration.SetEntrypoint(
"performanceModeImpactsNotifyIdle");
4207 RunEngine(shell.get(), std::move(configuration));
4211 DestroyShell(std::move(shell), task_runners);
4212 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4216#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG || OS_FUCHSIA
4217 GTEST_SKIP() <<
"Test is for debug mode only on non-fuchsia targets.";
4219 Settings settings = CreateSettingsForFixture();
4221 ThreadHost::Type::kPlatform);
4223 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4225 auto shell = CreateShell(settings, task_runners);
4232 SendPlatformMessage(shell.get(), std::make_unique<PlatformMessage>(
4233 "com.test.plugin",
nullptr));
4237 ::testing::EndsWith(
4238 "The 'com.test.plugin' channel sent a message from native to "
4239 "Flutter on a non-platform thread. Platform channel messages "
4240 "must be sent on the platform thread. Failure to do so may "
4241 "result in data loss or crashes, and must be fixed in the "
4242 "plugin or application code creating that channel.\nSee "
4243 "https://docs.flutter.dev/platform-integration/"
4244 "platform-channels#channels-and-platform-threading for more "
4253 SendPlatformMessage(shell.get(), std::make_unique<PlatformMessage>(
4254 "com.test.plugin",
nullptr));
4256 EXPECT_EQ(log_capture.
str(),
"");
4259 DestroyShell(std::move(shell), task_runners);
4260 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4265 Settings settings = CreateSettingsForFixture();
4267 ThreadHost::Type::kPlatform);
4269 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4271 auto shell = CreateShell(settings, task_runners);
4273 auto latch = std::make_shared<fml::CountDownLatch>(1u);
4274 task_runner->PostTask([&]() {
4275 auto message = MakePlatformMessage(
4276 "flutter/navigation",
4277 {{
"method",
"setInitialRoute"}, {
"args",
"/testo"}},
nullptr);
4278 SendPlatformMessage(shell.get(), std::move(
message));
4279 EXPECT_EQ(shell->GetEngine()->InitialRoute(),
"/testo");
4285 DestroyShell(std::move(shell), task_runners);
4286 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4291 Settings settings = CreateSettingsForFixture();
4293 ThreadHost::Type::kPlatform);
4295 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4300 auto shell = CreateShell(settings, task_runners);
4301 auto configuration = RunConfiguration::InferFromSettings(settings);
4302 configuration.SetEntrypoint(
"testSemanticsActions");
4304 RunEngine(shell.get(), std::move(configuration));
4314 SendSemanticsAction(shell.get(), 456, 0, SemanticsAction::kTap,
4319 DestroyShell(std::move(shell), task_runners);
4320 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4325 Settings settings = CreateSettingsForFixture();
4327 ThreadHost::Type::kPlatform);
4329 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4334 auto shell = CreateShell(settings, task_runners);
4335 auto configuration = RunConfiguration::InferFromSettings(settings);
4336 configuration.SetEntrypoint(
"testPointerActions");
4338 RunEngine(shell.get(), std::move(configuration));
4347 DispatchFakePointerData(shell.get(), 23);
4350 DestroyShell(std::move(shell), task_runners);
4351 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4356 Settings settings = CreateSettingsForFixture();
4358 ThreadHost::Type::kPlatform);
4360 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4365 auto shell = CreateShell(settings, task_runners);
4366 auto configuration = RunConfiguration::InferFromSettings(settings);
4367 configuration.SetEntrypoint(
"testDispatchEvents");
4369 RunEngine(shell.get(), std::move(configuration));
4371 bool did_invoke_callback =
false;
4377 did_invoke_callback =
true;
4381 DispatchFakePointerData(shell.get(), 23);
4382 EXPECT_FALSE(did_invoke_callback);
4384 EXPECT_TRUE(did_invoke_callback);
4386 DestroyShell(std::move(shell), task_runners);
4387 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4391#if defined(OS_FUCHSIA)
4392 GTEST_SKIP() <<
"Fuchsia";
4394 ::testing::FLAGS_gtest_death_test_style =
"threadsafe";
4395 Settings settings = CreateSettingsForFixture();
4399 ThreadHost::Type::kPlatform);
4401 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4403 EXPECT_DEATH_IF_SUPPORTED(
4404 CreateShell(settings, task_runners),
4405 "Software rendering is incompatible with Impeller.");
4412 bool* hasImplicitView,
4413 std::vector<int64_t>* viewIds) {
4414 Dart_Handle exception =
nullptr;
4418 ASSERT_EQ(exception,
nullptr);
4420 args, 1, exception);
4421 ASSERT_EQ(exception,
nullptr);
4425 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4426 Settings settings = CreateSettingsForFixture();
4427 auto task_runner = CreateNewThread();
4428 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4430 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4433 bool hasImplicitView;
4434 std::vector<int64_t> viewIds;
4436 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4437 &viewIds](Dart_NativeArguments
args) {
4441 AddNativeCallback(
"NativeReportViewIdsCallback",
4444 PlatformViewNotifyCreated(shell.get());
4445 auto configuration = RunConfiguration::InferFromSettings(settings);
4446 configuration.SetEntrypoint(
"testReportViewIds");
4447 RunEngine(shell.get(), std::move(configuration));
4450 ASSERT_TRUE(hasImplicitView);
4451 ASSERT_EQ(viewIds.size(), 1u);
4452 ASSERT_EQ(viewIds[0], 0ll);
4454 PlatformViewNotifyDestroyed(shell.get());
4455 DestroyShell(std::move(shell), task_runners);
4460 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4461 Settings settings = CreateSettingsForFixture();
4464 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4465 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4469 thread_host.
io_thread->GetTaskRunner());
4470 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4473 bool hasImplicitView;
4474 std::vector<int64_t> viewIds;
4476 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4477 &viewIds](Dart_NativeArguments
args) {
4481 AddNativeCallback(
"NativeReportViewIdsCallback",
4484 PlatformViewNotifyCreated(shell.get());
4485 auto configuration = RunConfiguration::InferFromSettings(settings);
4486 configuration.SetEntrypoint(
"testReportViewIds");
4487 RunEngine(shell.get(), std::move(configuration));
4490 ASSERT_TRUE(hasImplicitView);
4491 ASSERT_EQ(viewIds.size(), 1u);
4492 ASSERT_EQ(viewIds[0], 0ll);
4494 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4495 shell->GetPlatformView()->AddView(2, ViewportMetrics{},
4496 [](
bool added) { EXPECT_TRUE(added); });
4499 ASSERT_TRUE(hasImplicitView);
4500 ASSERT_EQ(viewIds.size(), 2u);
4501 ASSERT_EQ(viewIds[1], 2ll);
4503 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4504 shell->GetPlatformView()->RemoveView(
4505 2, [](bool removed) { ASSERT_TRUE(removed); });
4508 ASSERT_TRUE(hasImplicitView);
4509 ASSERT_EQ(viewIds.size(), 1u);
4510 ASSERT_EQ(viewIds[0], 0ll);
4512 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4513 shell->GetPlatformView()->AddView(4, ViewportMetrics{},
4514 [](
bool added) { EXPECT_TRUE(added); });
4517 ASSERT_TRUE(hasImplicitView);
4518 ASSERT_EQ(viewIds.size(), 2u);
4519 ASSERT_EQ(viewIds[1], 4ll);
4521 PlatformViewNotifyDestroyed(shell.get());
4522 DestroyShell(std::move(shell), task_runners);
4527 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4528 Settings settings = CreateSettingsForFixture();
4531 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4532 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4536 thread_host.
io_thread->GetTaskRunner());
4537 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4540 bool has_implicit_view;
4541 std::vector<int64_t> view_ids;
4543 AddNativeCallback(
"NativeReportViewIdsCallback",
4549 PlatformViewNotifyCreated(shell.get());
4550 auto configuration = RunConfiguration::InferFromSettings(settings);
4551 configuration.SetEntrypoint(
"testReportViewIds");
4552 RunEngine(shell.get(), std::move(configuration));
4554 report_latch.
Wait();
4555 ASSERT_TRUE(has_implicit_view);
4556 ASSERT_EQ(view_ids.size(), 1u);
4561 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
4563 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4571 report_latch.Wait();
4572 ASSERT_EQ(view_ids.size(), 2u);
4574 ASSERT_EQ(view_ids[1], 123);
4577 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell,
4579 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4580 EXPECT_FALSE(added);
4587 PlatformViewNotifyDestroyed(shell.get());
4588 DestroyShell(std::move(shell), task_runners);
4594 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4595 Settings settings = CreateSettingsForFixture();
4598 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4599 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4603 thread_host.
io_thread->GetTaskRunner());
4604 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4607 bool has_implicit_view;
4608 std::vector<int64_t> view_ids;
4610 AddNativeCallback(
"NativeReportViewIdsCallback",
4616 PlatformViewNotifyCreated(shell.get());
4617 auto configuration = RunConfiguration::InferFromSettings(settings);
4618 configuration.SetEntrypoint(
"testReportViewIds");
4619 RunEngine(shell.get(), std::move(configuration));
4621 report_latch.
Wait();
4622 ASSERT_TRUE(has_implicit_view);
4623 ASSERT_EQ(view_ids.size(), 1u);
4628 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(),
4629 [&shell, &remove_latch] {
4630 shell->GetPlatformView()->RemoveView(123, [&](bool removed) {
4631 EXPECT_FALSE(removed);
4632 remove_latch.Signal();
4636 remove_latch.Wait();
4638 PlatformViewNotifyDestroyed(shell.get());
4639 DestroyShell(std::move(shell), task_runners);
4645 std::map<int64_t, int64_t>* viewWidths) {
4646 Dart_Handle exception =
nullptr;
4647 viewWidths->clear();
4648 std::vector<int64_t> viewWidthPacket =
4651 ASSERT_EQ(exception,
nullptr);
4652 ASSERT_EQ(viewWidthPacket.size() % 2, 0ul);
4653 for (
size_t packetIndex = 0; packetIndex < viewWidthPacket.size();
4655 (*viewWidths)[viewWidthPacket[packetIndex]] =
4656 viewWidthPacket[packetIndex + 1];
4664 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4665 Settings settings = CreateSettingsForFixture();
4668 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4669 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4673 thread_host.
io_thread->GetTaskRunner());
4674 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4677 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4678 auto platform_view = shell->GetPlatformView();
4681 platform_view->SetViewportMetrics(0, ViewportMetrics{1, 10, 1, 0, 0});
4683 [](
bool added) { ASSERT_TRUE(added); });
4687 bool first_report =
true;
4688 std::map<int64_t, int64_t> viewWidths;
4690 auto nativeViewWidthsCallback = [&reportLatch, &viewWidths,
4691 &first_report](Dart_NativeArguments
args) {
4692 EXPECT_TRUE(first_report);
4693 first_report =
false;
4694 ParseViewWidthsCallback(
args, &viewWidths);
4697 AddNativeCallback(
"NativeReportViewWidthsCallback",
4700 PlatformViewNotifyCreated(shell.get());
4701 auto configuration = RunConfiguration::InferFromSettings(settings);
4702 configuration.SetEntrypoint(
"testReportViewWidths");
4703 RunEngine(shell.get(), std::move(configuration));
4706 EXPECT_EQ(viewWidths.size(), 2u);
4707 EXPECT_EQ(viewWidths[0], 20ll);
4708 EXPECT_EQ(viewWidths[1], 30ll);
4710 PlatformViewNotifyDestroyed(shell.get());
4711 DestroyShell(std::move(shell), task_runners);
4716 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4717 Settings settings = CreateSettingsForFixture();
4720 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4721 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4725 thread_host.
io_thread->GetTaskRunner());
4726 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4729 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4730 auto platform_view = shell->GetPlatformView();
4735 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 30, 1, 0, 0},
4736 [](
bool added) { ASSERT_FALSE(added); });
4737 shell->GetPlatformView()->RemoveView(
4738 123, [](
bool removed) { ASSERT_FALSE(removed); });
4741 bool first_report =
true;
4742 std::map<int64_t, int64_t> view_widths;
4744 AddNativeCallback(
"NativeReportViewWidthsCallback",
4746 EXPECT_TRUE(first_report);
4747 first_report =
false;
4748 ParseViewWidthsCallback(
args, &view_widths);
4752 PlatformViewNotifyCreated(shell.get());
4753 auto configuration = RunConfiguration::InferFromSettings(settings);
4754 configuration.SetEntrypoint(
"testReportViewWidths");
4755 RunEngine(shell.get(), std::move(configuration));
4757 report_latch.
Wait();
4758 EXPECT_EQ(view_widths.size(), 1u);
4760 PlatformViewNotifyDestroyed(shell.get());
4761 DestroyShell(std::move(shell), task_runners);
4767 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4768 Settings settings = CreateSettingsForFixture();
4771 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4772 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4776 thread_host.
io_thread->GetTaskRunner());
4777 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4780 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell] {
4781 auto platform_view = shell->GetPlatformView();
4784 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 100, 1, 0, 0},
4785 [](
bool added) { ASSERT_TRUE(added); });
4787 shell->GetPlatformView()->AddView(123,
ViewportMetrics{1, 200, 1, 0, 0},
4788 [](
bool added) { ASSERT_FALSE(added); });
4791 shell->GetPlatformView()->AddView(456,
ViewportMetrics{1, 300, 1, 0, 0},
4792 [](
bool added) { ASSERT_TRUE(added); });
4795 bool first_report =
true;
4796 std::map<int64_t, int64_t> view_widths;
4798 AddNativeCallback(
"NativeReportViewWidthsCallback",
4800 EXPECT_TRUE(first_report);
4801 first_report =
false;
4802 ParseViewWidthsCallback(
args, &view_widths);
4806 PlatformViewNotifyCreated(shell.get());
4807 auto configuration = RunConfiguration::InferFromSettings(settings);
4808 configuration.SetEntrypoint(
"testReportViewWidths");
4809 RunEngine(shell.get(), std::move(configuration));
4811 report_latch.
Wait();
4812 EXPECT_EQ(view_widths.size(), 3u);
4813 EXPECT_EQ(view_widths[0], 0);
4814 EXPECT_EQ(view_widths[123], 100);
4815 EXPECT_EQ(view_widths[456], 300);
4817 PlatformViewNotifyDestroyed(shell.get());
4818 DestroyShell(std::move(shell), task_runners);
4822#if !IMPELLER_SUPPORTS_RENDERING
4823 GTEST_SKIP() <<
"This platform doesn't support Impeller.";
4825 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4826 Settings settings = CreateSettingsForFixture();
4832 TaskRunners task_runners(
"test", runner, runner, runner, runner);
4833 std::ostringstream stream;
4835 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4837 stream.str().find(
"[Action Required]: Impeller opt-out deprecated.") !=
4840 DestroyShell(std::move(shell), task_runners);
4844 Settings settings = CreateSettingsForFixture();
4847 std::string last_event;
4853 AddNativeCallback(
"NotifyMessage",
4855 const auto message_from_dart =
4857 Dart_GetNativeArgument(
args, 0));
4858 last_event = message_from_dart;
4863 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4864 ASSERT_TRUE(shell->IsSetup());
4866 auto configuration = RunConfiguration::InferFromSettings(settings);
4868 configuration.SetEntrypoint(
"testSendViewFocusEvent");
4869 RunEngine(shell.get(), std::move(configuration));
4873 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
4874 shell->GetPlatformView()->SendViewFocusEvent(ViewFocusEvent(
4875 1, ViewFocusState::kFocused, ViewFocusDirection::kUndefined));
4878 ASSERT_EQ(last_event,
4879 "1 ViewFocusState.focused ViewFocusDirection.undefined");
4882 PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
4883 shell->GetPlatformView()->SendViewFocusEvent(ViewFocusEvent(
4884 2, ViewFocusState::kUnfocused, ViewFocusDirection::kBackward));
4887 ASSERT_EQ(last_event,
4888 "2 ViewFocusState.unfocused ViewFocusDirection.backward");
4889 DestroyShell(std::move(shell), task_runners);
4893 Settings settings = CreateSettingsForFixture();
4897 std::optional<int> reported_handle = std::nullopt;
4901 Dart_Handle arg = Dart_GetNativeArgument(
args, 0);
4902 if (Dart_IsNull(arg)) {
4903 reported_handle = std::nullopt;
4911 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4912 ASSERT_TRUE(shell->IsSetup());
4914 auto configuration = RunConfiguration::InferFromSettings(settings);
4915 configuration.SetEngineId(99);
4916 configuration.SetEntrypoint(
"providesEngineId");
4917 RunEngine(shell.get(), std::move(configuration));
4920 ASSERT_EQ(reported_handle, 99);
4925 shell->GetTaskRunners().GetUITaskRunner(), [&]() {
4926 ASSERT_EQ(shell->GetEngine()->GetLastEngineId(), 99);
4930 DestroyShell(std::move(shell), task_runners);
4934 Settings settings = CreateSettingsForFixture();
4938 std::optional<int> reported_handle = std::nullopt;
4942 Dart_Handle arg = Dart_GetNativeArgument(
args, 0);
4943 if (Dart_IsNull(arg)) {
4944 reported_handle = std::nullopt;
4952 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4953 ASSERT_TRUE(shell->IsSetup());
4955 auto configuration = RunConfiguration::InferFromSettings(settings);
4956 configuration.SetEntrypoint(
"providesEngineId");
4957 RunEngine(shell.get(), std::move(configuration));
4960 ASSERT_EQ(reported_handle, std::nullopt);
4961 DestroyShell(std::move(shell), task_runners);
4965 Settings settings = CreateSettingsForFixture();
4967 Settings::MergedPlatformUIThread::kMergeAfterLaunch;
4970 ThreadHost::Type::kPlatform | ThreadHost::Type::kRaster |
4971 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4975 thread_host.
io_thread->GetTaskRunner());
4977 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
4992 auto configuration = RunConfiguration::InferFromSettings(settings);
4993 configuration.SetEntrypoint(
"mainNotifyNative");
4994 RunEngine(shell.get(), std::move(configuration));
5002 DestroyShell(std::move(shell), task_runners);
5007 auto settings = CreateSettingsForFixture();
5008 bool called_release_resource_context =
false;
5010 [task_runners, &called_release_resource_context](
flutter::Shell& shell) {
5011 auto result = std::make_unique<::testing::NiceMock<TestPlatformView>>(
5012 shell, task_runners);
5013 ON_CALL(*result, ReleaseResourceContext())
5015 ::testing::Assign(&called_release_resource_context,
true));
5019 auto parent_shell = CreateShell({
5020 .settings = settings,
5021 .task_runners = task_runners,
5022 .platform_view_create_callback = platform_view_create_callback,
5025 std::unique_ptr<Shell> child_shell;
5027 parent_shell->GetTaskRunners().GetPlatformTaskRunner(),
5028 [&parent_shell, &settings, &child_shell, platform_view_create_callback] {
5029 auto configuration = RunConfiguration::InferFromSettings(settings);
5030 configuration.SetEntrypoint(
"emptyMain");
5031 auto child = parent_shell->Spawn(
5032 std::move(configuration),
"", platform_view_create_callback,
5033 [](Shell& shell) { return std::make_unique<Rasterizer>(shell); });
5034 child_shell = std::move(child);
5037 DestroyShell(std::move(parent_shell), task_runners);
5038 ASSERT_FALSE(called_release_resource_context);
5040 DestroyShell(std::move(child_shell), task_runners);
5041 ASSERT_TRUE(called_release_resource_context);
5045 Settings settings = CreateSettingsForFixture();
5046 auto task_runner = CreateNewThread();
5047 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
5049 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
5052 shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() {
5053 shell->GetPlatformView()->SetViewportMetrics(
5082 PumpOneFrame(shell.get());
5085 std::make_unique<LayerTree>(
nullptr,
5087 ASSERT_FALSE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5090 std::make_unique<LayerTree>(
nullptr,
5092 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5095 std::make_unique<LayerTree>(
nullptr,
5097 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5099 auto min_width = std::make_unique<LayerTree>(
nullptr,
5101 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5103 auto min_height = std::make_unique<LayerTree>(
nullptr,
5105 ASSERT_TRUE(ShellTest::ShouldDiscardLayerTree(shell.get(),
kImplicitViewId,
5107 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 GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
static constexpr FlutterViewId kImplicitViewId
union flutter::testing::@2824::KeyboardChange::@78 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