5#define FML_USED_ON_EMBEDDER
24#include "flutter/flow/layers/backdrop_filter_layer.h"
25#include "flutter/flow/layers/clip_rect_layer.h"
26#include "flutter/flow/layers/display_list_layer.h"
27#include "flutter/flow/layers/layer_raster_cache_item.h"
28#include "flutter/flow/layers/platform_view_layer.h"
29#include "flutter/flow/layers/transform_layer.h"
30#include "flutter/fml/backtrace.h"
31#include "flutter/fml/command_line.h"
32#include "flutter/fml/make_copyable.h"
33#include "flutter/fml/message_loop.h"
34#include "flutter/fml/synchronization/count_down_latch.h"
35#include "flutter/fml/synchronization/waitable_event.h"
36#include "flutter/runtime/dart_vm.h"
37#include "flutter/shell/common/platform_view.h"
38#include "flutter/shell/common/rasterizer.h"
39#include "flutter/shell/common/shell_test.h"
40#include "flutter/shell/common/shell_test_external_view_embedder.h"
41#include "flutter/shell/common/shell_test_platform_view.h"
42#include "flutter/shell/common/switches.h"
43#include "flutter/shell/common/thread_host.h"
44#include "flutter/shell/common/vsync_waiter_fallback.h"
45#include "flutter/shell/common/vsync_waiters_test.h"
46#include "flutter/shell/version/version.h"
47#include "flutter/testing/mock_canvas.h"
48#include "flutter/testing/testing.h"
49#include "gmock/gmock.h"
51#include "third_party/rapidjson/include/rapidjson/writer.h"
55#ifdef SHELL_ENABLE_VULKAN
56#include "flutter/vulkan/vulkan_application.h"
68using ::testing::Return;
71class MockPlatformViewDelegate :
public PlatformView::Delegate {
73 OnPlatformViewCreated,
74 (std::unique_ptr<Surface>
surface),
77 MOCK_METHOD(
void, OnPlatformViewDestroyed, (), (
override));
79 MOCK_METHOD(
void, OnPlatformViewScheduleFrame, (), (
override));
82 OnPlatformViewAddView,
84 const ViewportMetrics& viewport_metrics,
89 OnPlatformViewRemoveView,
90 (int64_t view_id, RemoveViewCallback
callback),
94 OnPlatformViewSetNextFrameCallback,
99 OnPlatformViewSetViewportMetrics,
100 (int64_t view_id,
const ViewportMetrics& metrics),
104 OnPlatformViewDispatchPlatformMessage,
105 (std::unique_ptr<PlatformMessage>
message),
109 OnPlatformViewDispatchPointerDataPacket,
110 (std::unique_ptr<PointerDataPacket> packet),
114 OnPlatformViewDispatchSemanticsAction,
119 OnPlatformViewSetSemanticsEnabled,
124 OnPlatformViewSetAccessibilityFeatures,
129 OnPlatformViewRegisterTexture,
130 (std::shared_ptr<Texture>
texture),
134 OnPlatformViewUnregisterTexture,
139 OnPlatformViewMarkTextureFrameAvailable,
143 MOCK_METHOD(
const Settings&,
144 OnPlatformViewGetSettings,
150 (intptr_t loading_unit_id,
151 std::unique_ptr<const fml::Mapping> snapshot_data,
152 std::unique_ptr<const fml::Mapping> snapshot_instructions),
156 LoadDartDeferredLibraryError,
157 (intptr_t loading_unit_id,
158 const std::string error_message,
163 UpdateAssetResolverByType,
164 (std::unique_ptr<AssetResolver> updated_asset_resolver,
171 MOCK_METHOD(
bool, IsValid, (), (
override));
173 MOCK_METHOD(std::unique_ptr<SurfaceFrame>,
178 MOCK_METHOD(
SkMatrix, GetRootTransformation, (), (
const,
override));
182 MOCK_METHOD(std::unique_ptr<GLContextResult>,
183 MakeRenderContextCurrent,
187 MOCK_METHOD(
bool, ClearRenderContext, (), (
override));
193 const TaskRunners& task_runners)
194 : PlatformView(delegate, task_runners) {}
195 MOCK_METHOD(std::unique_ptr<Surface>, CreateRenderingSurface, (), (
override));
196 MOCK_METHOD(std::shared_ptr<PlatformMessageHandler>,
197 GetPlatformMessageHandler,
202class TestPlatformView :
public PlatformView {
204 TestPlatformView(Shell&
shell,
const TaskRunners& task_runners)
205 : PlatformView(
shell, task_runners) {}
206 MOCK_METHOD(std::unique_ptr<Surface>, CreateRenderingSurface, (), (
override));
212 HandlePlatformMessage,
213 (std::unique_ptr<PlatformMessage>
message),
216 DoesHandlePlatformMessageOnPlatformThread,
221 (
int response_id, std::unique_ptr<fml::Mapping> mapping),
234 MOCK_METHOD(
void, Complete, (std::unique_ptr<fml::Mapping>
data), (
override));
235 MOCK_METHOD(
void, CompleteEmpty, (), (
override));
242 : valid_(valid), type_(
type) {}
244 bool IsValid()
const override {
return true; }
252 const std::string& asset_name)
const override {
257 const std::string& asset_pattern,
258 const std::optional<std::string>& subdir)
const override {
263 return this == &other;
274 std::shared_ptr<fml::ConcurrentMessageLoop> concurrent_loop)
275 : concurrent_loop_(
std::move(concurrent_loop)) {}
278 bool IsValid()
const override {
return true; }
285 return AssetResolverType::kApkAssetProvider;
290 const std::string& asset_name)
const override {
291 if (asset_name ==
"FontManifest.json") {
296 EXPECT_TRUE(concurrent_loop_->RunsTasksOnCurrentThread())
304 return this == &other;
308 std::shared_ptr<fml::ConcurrentMessageLoop> concurrent_loop_;
316 if (!
shell->IsSetup()) {
325 shell->GetTaskRunners().GetPlatformTaskRunner(), [
shell, &latch]() {
326 shell->GetPlatformView()->NotifyDestroyed();
337 bool is_torn_down =
false;
339 shell->GetTaskRunners().GetRasterTaskRunner(),
340 [
shell, &latch, &is_torn_down]() {
341 is_torn_down = shell->GetRasterizer()->IsTornDown();
349 ASSERT_TRUE(
shell !=
nullptr);
350 ASSERT_TRUE(
shell->IsSetup());
361 std::string flags_string =
flags[0];
362 for (
size_t i = 1;
i <
flags.size(); ++
i) {
371 const std::vector<fml::CommandLine::Option>
options = {
376 for (
size_t i = 0;
i <
flags.size(); ++
i) {
401 TaskRunners task_runners(
"test",
nullptr,
nullptr,
nullptr,
nullptr);
413 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
423 DestroyShell(std::move(
shell), task_runners);
431 ThreadHost::Type::kPlatform);
433 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
438 DestroyShell(std::move(
shell), task_runners);
447 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
452 DestroyShell(std::move(
shell), task_runners);
457 InitializeWithMultipleThreadButCallingThreadAsPlatformThread) {
462 ThreadHost::Type::kUi);
474 const auto vsync_clock = std::make_shared<ShellTestVsyncClock>();
477 [task_runners =
shell.GetTaskRunners()]() {
478 return static_cast<std::unique_ptr<VsyncWaiter>>(
479 std::make_unique<VsyncWaiterFallback>(task_runners));
482 shell.GetIsGpuDisabledSyncSwitch());
487 DestroyShell(std::move(
shell), task_runners);
495 ThreadHost::Type::kPlatform);
497 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
499 auto shell = CreateShell({
501 .task_runners = task_runners,
502 .is_gpu_disabled =
true,
507 bool is_disabled =
false;
508 shell->GetIsGpuDisabledSyncSwitch()->Execute(
510 ASSERT_TRUE(is_disabled);
512 DestroyShell(std::move(
shell), task_runners);
520 ThreadHost::Type::kPlatform | ThreadHost::Type::kIo |
521 ThreadHost::Type::kUi);
532 DestroyShell(std::move(
shell), task_runners);
538 auto settings = CreateSettingsForFixture();
543 ASSERT_TRUE(configuration.IsValid());
544 configuration.SetEntrypoint(
"fixturesAreFunctionalMain");
548 "SayHiFromFixturesAreFunctionalMain",
551 RunEngine(
shell.get(), std::move(configuration));
554 DestroyShell(std::move(
shell));
560 auto settings = CreateSettingsForFixture();
565 ASSERT_TRUE(configuration.IsValid());
566 configuration.SetEntrypoint(
"testCanLaunchSecondaryIsolate");
573 RunEngine(
shell.get(), std::move(configuration));
578 DestroyShell(std::move(
shell));
584 auto settings = CreateSettingsForFixture();
589 ASSERT_TRUE(configuration.IsValid());
590 std::string entry_point =
"fixturesAreFunctionalMain";
591 configuration.SetEntrypoint(entry_point);
594 std::string last_entry_point;
597 last_entry_point =
shell->GetEngine()->GetLastEntrypoint();
601 RunEngine(
shell.get(), std::move(configuration));
603 EXPECT_EQ(entry_point, last_entry_point);
605 DestroyShell(std::move(
shell));
611 auto settings = CreateSettingsForFixture();
616 ASSERT_TRUE(configuration.IsValid());
617 std::string entry_point =
"fixturesAreFunctionalMain";
618 std::vector<std::string> entry_point_args = {
"arg1"};
619 configuration.SetEntrypoint(entry_point);
620 configuration.SetEntrypointArgs(entry_point_args);
623 std::vector<std::string> last_entry_point_args;
626 last_entry_point_args =
shell->GetEngine()->GetLastEntrypointArgs();
630 RunEngine(
shell.get(), std::move(configuration));
632#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
633 EXPECT_EQ(last_entry_point_args, entry_point_args);
635 ASSERT_TRUE(last_entry_point_args.empty());
638 DestroyShell(std::move(
shell));
643#if defined(OS_FUCHSIA)
644 GTEST_SKIP() <<
"This test flakes on Fuchsia. https://fxbug.dev/110006 ";
648 ::testing::FLAGS_gtest_death_test_style =
"threadsafe";
650 const std::vector<fml::CommandLine::Option>
options = {
655 const char* expected =
656 "Encountered disallowed Dart VM flag: --verify_after_gc";
662 std::vector<const char*>
flags = {
663 "--enable-isolate-groups",
664 "--no-enable-isolate-groups",
667 flags.push_back(
"--max_profile_depth 1");
668 flags.push_back(
"--random_seed 42");
669 flags.push_back(
"--max_subtype_cache_entries=22");
671 flags.push_back(
"--enable_mirrors");
679 auto settings = CreateSettingsForFixture();
683 PlatformViewNotifyCreated(
shell.get());
686 configuration.SetEntrypoint(
"emptyMain");
688 RunEngine(
shell.get(), std::move(configuration));
689 PumpOneFrame(
shell.get());
690 ASSERT_FALSE(GetNeedsReportTimings(
shell.get()));
702 ASSERT_EQ(UnreportedTimingsCount(
shell.get()), 0);
703 DestroyShell(std::move(
shell));
707 auto settings = CreateSettingsForFixture();
711 PlatformViewNotifyCreated(
shell.get());
714 configuration.SetEntrypoint(
"dummyReportTimingsMain");
716 RunEngine(
shell.get(), std::move(configuration));
717 PumpOneFrame(
shell.get());
718 ASSERT_TRUE(GetNeedsReportTimings(
shell.get()));
719 DestroyShell(std::move(
shell));
726 for (
size_t i = 0;
i < timings.size();
i += 1) {
739 ASSERT_TRUE(timings[
i].
Get(phase) >=
start);
740 ASSERT_TRUE(timings[
i].
Get(phase) <= finish);
743 ASSERT_TRUE(last_phase_time <= timings[
i].
Get(phase));
744 last_phase_time = timings[
i].Get(phase);
750 auto settings = CreateSettingsForFixture();
759 PlatformViewNotifyCreated(
shell.get());
762 ASSERT_TRUE(configuration.IsValid());
763 configuration.SetEntrypoint(
"reportTimingsMain");
765 std::vector<int64_t> timestamps;
766 auto nativeTimingCallback = [&reportLatch,
769 ASSERT_EQ(timestamps.size(), 0ul);
774 AddNativeCallback(
"NativeReportTimingsCallback",
776 RunEngine(
shell.get(), std::move(configuration));
780 for (
int i = 0;
i < 200;
i += 1) {
781 PumpOneFrame(
shell.get());
785 DestroyShell(std::move(
shell));
788 ASSERT_TRUE(!timestamps.empty());
804 auto settings = CreateSettingsForFixture();
808 settings.frame_rasterized_callback = [&timing,
817 using namespace std::chrono_literals;
818 std::this_thread::sleep_for(1ms);
829 ASSERT_TRUE(timing.
Get(phase) <
start);
833 PlatformViewNotifyCreated(
shell.get());
836 configuration.SetEntrypoint(
"onBeginFrameMain");
838 int64_t frame_target_time;
844 AddNativeCallback(
"NativeOnBeginFrame",
847 RunEngine(
shell.get(), std::move(configuration));
848 PumpOneFrame(
shell.get());
854 std::vector<FrameTiming> timings = {timing};
859 int64_t build_start =
861 ASSERT_GT(frame_target_time, build_start);
862 DestroyShell(std::move(
shell));
866 auto settings = CreateSettingsForFixture();
868 bool end_frame_called =
false;
869 auto end_frame_callback =
870 [&](
bool should_resubmit_frame,
872 ASSERT_TRUE(raster_thread_merger.get() ==
nullptr);
873 ASSERT_FALSE(should_resubmit_frame);
874 end_frame_called =
true;
877 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
879 auto shell = CreateShell({
882 .shell_test_external_view_embedder = external_view_embedder,
887 PlatformViewNotifyCreated(
shell.get());
890 configuration.SetEntrypoint(
"emptyMain");
892 RunEngine(
shell.get(), std::move(configuration));
895 auto display_list_layer = std::make_shared<DisplayListLayer>(
897 root->Add(display_list_layer);
901 end_frame_latch.
Wait();
902 ASSERT_TRUE(end_frame_called);
904 DestroyShell(std::move(
shell));
908#if defined(OS_FUCHSIA)
909 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
910 "https://github.com/flutter/flutter/issues/59816 ";
913 auto settings = CreateSettingsForFixture();
915 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
918 bool end_frame_called =
false;
919 std::vector<int64_t> visited_platform_views;
922 auto end_frame_callback =
923 [&](
bool should_resubmit_frame,
925 if (end_frame_called) {
928 ASSERT_TRUE(raster_thread_merger.get() ==
nullptr);
929 ASSERT_FALSE(should_resubmit_frame);
930 end_frame_called =
true;
931 visited_platform_views =
932 external_view_embedder->GetVisitedPlatformViews();
933 stack_50 = external_view_embedder->GetStack(50);
934 stack_75 = external_view_embedder->GetStack(75);
938 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
940 auto shell = CreateShell({
943 .shell_test_external_view_embedder = external_view_embedder,
948 PlatformViewNotifyCreated(
shell.get());
951 configuration.SetEntrypoint(
"emptyMain");
953 RunEngine(
shell.get(), std::move(configuration));
956 auto platform_view_layer = std::make_shared<PlatformViewLayer>(
958 root->Add(platform_view_layer);
959 auto transform_layer =
961 root->Add(transform_layer);
962 auto clip_rect_layer = std::make_shared<ClipRectLayer>(
964 transform_layer->Add(clip_rect_layer);
966 auto backdrop_filter_layer =
968 clip_rect_layer->Add(backdrop_filter_layer);
969 auto platform_view_layer2 = std::make_shared<PlatformViewLayer>(
971 backdrop_filter_layer->Add(platform_view_layer2);
975 end_frame_latch.
Wait();
976 ASSERT_EQ(visited_platform_views, (std::vector<int64_t>{50, 75}));
981 auto mutator = *stack_50.
Begin();
983 ASSERT_EQ(mutator->GetFilterMutation().GetFilter(), filter);
986 ASSERT_EQ(mutator->GetFilterMutation().GetFilterRect(),
989 DestroyShell(std::move(
shell));
995 ExternalEmbedderEndFrameIsCalledWhenPostPrerollResultIsResubmit) {
996#if defined(OS_FUCHSIA)
997 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
998 "https://github.com/flutter/flutter/issues/59816 ";
1001 auto settings = CreateSettingsForFixture();
1003 bool end_frame_called =
false;
1004 auto end_frame_callback =
1005 [&](
bool should_resubmit_frame,
1007 ASSERT_TRUE(raster_thread_merger.get() !=
nullptr);
1008 ASSERT_TRUE(should_resubmit_frame);
1009 end_frame_called =
true;
1010 end_frame_latch.
Signal();
1012 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1014 auto shell = CreateShell({
1017 .shell_test_external_view_embedder = external_view_embedder,
1022 PlatformViewNotifyCreated(
shell.get());
1025 configuration.SetEntrypoint(
"emptyMain");
1027 RunEngine(
shell.get(), std::move(configuration));
1030 auto display_list_layer = std::make_shared<DisplayListLayer>(
1032 root->Add(display_list_layer);
1036 end_frame_latch.
Wait();
1038 ASSERT_TRUE(end_frame_called);
1040 DestroyShell(std::move(
shell));
1045#if defined(OS_FUCHSIA)
1046 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1047 "https://github.com/flutter/flutter/issues/59816 ";
1050 auto settings = CreateSettingsForFixture();
1052 auto end_frame_callback =
1053 [&](
bool should_resubmit_frame,
1055 raster_thread_merger = std::move(thread_merger);
1057 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1060 auto shell = CreateShell({
1063 .shell_test_external_view_embedder = external_view_embedder,
1068 PlatformViewNotifyCreated(
shell.get());
1071 configuration.SetEntrypoint(
"emptyMain");
1073 RunEngine(
shell.get(), std::move(configuration));
1076 auto display_list_layer = std::make_shared<DisplayListLayer>(
1078 root->Add(display_list_layer);
1086 PostSync(
shell->GetTaskRunners().GetRasterTaskRunner(), [] {});
1087 ASSERT_TRUE(
result.ok()) <<
"Result: " <<
static_cast<int>(
result.code())
1088 <<
": " <<
result.message();
1090 ASSERT_TRUE(raster_thread_merger->
IsEnabled());
1093 ASSERT_TRUE(raster_thread_merger->
IsEnabled());
1097 ASSERT_TRUE(raster_thread_merger->
IsEnabled());
1098 DestroyShell(std::move(
shell));
1103#if defined(OS_FUCHSIA)
1104 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1105 "https://github.com/flutter/flutter/issues/59816 ";
1108 const int ThreadMergingLease = 10;
1109 auto settings = CreateSettingsForFixture();
1111 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1113 auto end_frame_callback =
1114 [&](
bool should_resubmit_frame,
1116 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1117 raster_thread_merger->MergeWithLease(ThreadMergingLease);
1119 ASSERT_TRUE(raster_thread_merger->IsMerged());
1120 external_view_embedder->UpdatePostPrerollResult(
1123 end_frame_latch.
Signal();
1125 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1128 external_view_embedder->UpdatePostPrerollResult(
1130 auto shell = CreateShell({
1133 .shell_test_external_view_embedder = external_view_embedder,
1138 PlatformViewNotifyCreated(
shell.get());
1141 configuration.SetEntrypoint(
"emptyMain");
1143 RunEngine(
shell.get(), std::move(configuration));
1146 auto display_list_layer = std::make_shared<DisplayListLayer>(
1148 root->Add(display_list_layer);
1153 end_frame_latch.
Wait();
1160 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1161 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1166 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1167 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1172 DestroyShell(std::move(
shell));
1177#if defined(OS_FUCHSIA)
1178 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1179 "https://github.com/flutter/flutter/issues/59816 ";
1182 const int kThreadMergingLease = 10;
1183 auto settings = CreateSettingsForFixture();
1185 auto end_frame_callback =
1186 [&](
bool should_resubmit_frame,
1188 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1189 raster_thread_merger->MergeWithLease(kThreadMergingLease);
1191 end_frame_latch.
Signal();
1196 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1199 auto shell = CreateShell({
1202 .shell_test_external_view_embedder = external_view_embedder,
1207 PlatformViewNotifyCreated(
shell.get());
1210 configuration.SetEntrypoint(
"emptyMain");
1212 RunEngine(
shell.get(), std::move(configuration));
1215 auto display_list_layer = std::make_shared<DisplayListLayer>(
1217 root->Add(display_list_layer);
1222 end_frame_latch.
Wait();
1224 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1225 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1229 external_view_embedder->UpdatePostPrerollResult(
1241 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1242 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1247 DestroyShell(std::move(
shell));
1252 OnPlatformViewDestroyWithThreadMergerWhileThreadsAreUnmerged) {
1253#if defined(OS_FUCHSIA)
1254 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1255 "https://github.com/flutter/flutter/issues/59816 ";
1258 auto settings = CreateSettingsForFixture();
1260 auto end_frame_callback =
1261 [&](
bool should_resubmit_frame,
1263 end_frame_latch.
Signal();
1265 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1267 auto shell = CreateShell({
1270 .shell_test_external_view_embedder = external_view_embedder,
1275 PlatformViewNotifyCreated(
shell.get());
1278 configuration.SetEntrypoint(
"emptyMain");
1280 RunEngine(
shell.get(), std::move(configuration));
1283 auto display_list_layer = std::make_shared<DisplayListLayer>(
1285 root->Add(display_list_layer);
1288 end_frame_latch.
Wait();
1292 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1293 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1298 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1299 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1304 DestroyShell(std::move(
shell));
1309 auto settings = CreateSettingsForFixture();
1314 PlatformViewNotifyCreated(
shell.get());
1317 configuration.SetEntrypoint(
"emptyMain");
1319 RunEngine(
shell.get(), std::move(configuration));
1322 auto display_list_layer = std::make_shared<DisplayListLayer>(
1324 root->Add(display_list_layer);
1330 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1331 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1336 shell->GetTaskRunners().GetRasterTaskRunner()->GetTaskQueueId(),
1337 shell->GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId()));
1342 DestroyShell(std::move(
shell));
1347#if defined(OS_FUCHSIA)
1348 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1349 "https://github.com/flutter/flutter/issues/59816 ";
1352 auto settings = CreateSettingsForFixture();
1354 auto end_frame_callback =
1355 [&](
bool should_resubmit_frame,
1357 end_frame_latch.
Signal();
1359 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1362 ThreadHost::Type::kPlatform | ThreadHost::Type::kIo |
1363 ThreadHost::Type::kUi);
1371 auto shell = CreateShell({
1373 .task_runners = task_runners,
1375 .shell_test_external_view_embedder = external_view_embedder,
1380 PlatformViewNotifyCreated(
shell.get());
1383 configuration.SetEntrypoint(
"emptyMain");
1385 RunEngine(
shell.get(), std::move(configuration));
1388 auto display_list_layer = std::make_shared<DisplayListLayer>(
1390 root->Add(display_list_layer);
1393 end_frame_latch.
Wait();
1400 DestroyShell(std::move(
shell), task_runners);
1405 auto settings = CreateSettingsForFixture();
1407 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1408 bool used_this_frame =
true;
1409 auto end_frame_callback =
1410 [&](
bool should_resubmit_frame,
1413 used_this_frame = external_view_embedder->GetUsedThisFrame();
1414 end_frame_latch.
Signal();
1416 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1418 auto shell = CreateShell({
1421 .shell_test_external_view_embedder = external_view_embedder,
1426 PlatformViewNotifyCreated(
shell.get());
1429 configuration.SetEntrypoint(
"emptyMain");
1431 RunEngine(
shell.get(), std::move(configuration));
1434 auto display_list_layer = std::make_shared<DisplayListLayer>(
1436 root->Add(display_list_layer);
1439 end_frame_latch.
Wait();
1440 ASSERT_FALSE(used_this_frame);
1445 DestroyShell(std::move(
shell));
1451#if defined(OS_FUCHSIA)
1452 GTEST_SKIP() <<
"RasterThreadMerger flakes on Fuchsia. "
1453 "https://github.com/flutter/flutter/issues/59816 ";
1456 auto settings = CreateSettingsForFixture();
1458 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
1460 auto end_frame_callback =
1461 [&](
bool should_resubmit_frame,
1463 if (should_resubmit_frame && !raster_thread_merger->IsMerged()) {
1464 raster_thread_merger->MergeWithLease(10);
1465 external_view_embedder->UpdatePostPrerollResult(
1468 end_frame_latch.
Signal();
1470 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
1473 auto shell = CreateShell({
1476 .shell_test_external_view_embedder = external_view_embedder,
1480 PlatformViewNotifyCreated(
shell.get());
1483 configuration.SetEntrypoint(
"emptyMain");
1484 RunEngine(
shell.get(), std::move(configuration));
1486 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
1488 PumpOneFrame(
shell.get());
1491 end_frame_latch.
Wait();
1495 end_frame_latch.
Wait();
1498 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
1500 PlatformViewNotifyDestroyed(
shell.get());
1501 DestroyShell(std::move(
shell));
1505TEST(SettingsTest, FrameTimingSetsAndGetsProperly) {
1510 int lastPhaseIndex = -1;
1513 ASSERT_TRUE(phase > lastPhaseIndex);
1514 lastPhaseIndex = phase;
1517 timing.
Set(phase, fake_time);
1518 ASSERT_TRUE(timing.
Get(phase) == fake_time);
1523 auto settings = CreateSettingsForFixture();
1527 PlatformViewNotifyCreated(
shell.get());
1530 ASSERT_TRUE(configuration.IsValid());
1531 configuration.SetEntrypoint(
"reportTimingsMain");
1533 std::vector<int64_t> timestamps;
1534 auto nativeTimingCallback = [&reportLatch,
1537 ASSERT_EQ(timestamps.size(), 0ul);
1539 args, 0, exception);
1542 AddNativeCallback(
"NativeReportTimingsCallback",
1544 ASSERT_TRUE(configuration.IsValid());
1545 RunEngine(
shell.get(), std::move(configuration));
1547 for (
int i = 0;
i < 10;
i += 1) {
1548 PumpOneFrame(
shell.get());
1552 DestroyShell(std::move(
shell));
1560 auto settings = CreateSettingsForFixture();
1564 PlatformViewNotifyCreated(
shell.get());
1567 configuration.SetEntrypoint(
"emptyMain");
1569 RunEngine(
shell.get(), std::move(configuration));
1570 PumpOneFrame(
shell.get());
1572 ASSERT_TRUE(
result.ok());
1574 DestroyShell(std::move(
shell));
1578 auto settings = CreateSettingsForFixture();
1582 PlatformViewNotifyCreated(
shell.get());
1585 configuration.SetEntrypoint(
"emptyMain");
1587 RunEngine(
shell.get(), std::move(configuration));
1590 EXPECT_FALSE(
result.ok());
1591 EXPECT_EQ(
result.message(),
"timeout");
1594 DestroyShell(std::move(
shell));
1598 auto settings = CreateSettingsForFixture();
1602 PlatformViewNotifyCreated(
shell.get());
1605 configuration.SetEntrypoint(
"emptyMain");
1607 RunEngine(
shell.get(), std::move(configuration));
1609 ASSERT_FALSE(
result.ok());
1612 DestroyShell(std::move(
shell));
1616 auto settings = CreateSettingsForFixture();
1620 PlatformViewNotifyCreated(
shell.get());
1623 configuration.SetEntrypoint(
"emptyMain");
1625 RunEngine(
shell.get(), std::move(configuration));
1626 PumpOneFrame(
shell.get());
1628 ASSERT_TRUE(
result.ok());
1629 for (
int i = 0;
i < 100; ++
i) {
1631 ASSERT_TRUE(
result.ok());
1634 DestroyShell(std::move(
shell));
1642 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1644 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
1647 PlatformViewNotifyCreated(
shell.get());
1650 configuration.SetEntrypoint(
"emptyMain");
1652 RunEngine(
shell.get(), std::move(configuration));
1653 PumpOneFrame(
shell.get());
1657 ASSERT_FALSE(
result.ok());
1663 DestroyShell(std::move(
shell), task_runners);
1670 shell.GetTaskRunners().GetRasterTaskRunner(), [&]() {
1671 if (auto rasterizer = shell.GetRasterizer()) {
1672 bytes = rasterizer->GetResourceCacheMaxBytes().value_or(0U);
1682 auto settings = CreateSettingsForFixture();
1683 settings.resource_cache_max_bytes_threshold = 4000000U;
1689 auto result = std::make_unique<TestPlatformView>(
shell, task_runners);
1690 ON_CALL(*
result, CreateRenderingSurface())
1692 auto surface = std::make_unique<MockSurface>();
1694 .WillByDefault(Return(main_context.
get()));
1695 ON_CALL(*
surface, IsValid()).WillByDefault(Return(
true));
1696 ON_CALL(*
surface, MakeRenderContextCurrent())
1698 return std::make_unique<GLContextDefaultResult>(
true);
1705 auto shell = CreateShell({
1707 .task_runners = task_runners,
1708 .platform_view_create_callback = platform_view_create_callback,
1712 PlatformViewNotifyCreated(
shell.get());
1715 configuration.SetEntrypoint(
"emptyMain");
1717 RunEngine(
shell.get(), std::move(configuration));
1719 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1720 {1.0, 100, 100, 22, 0});
1725 static_cast<size_t>(480000U));
1727 auto shell_spawn_callback = [&]() {
1728 std::unique_ptr<Shell>
spawn;
1730 shell->GetTaskRunners().GetPlatformTaskRunner(),
1731 [
this, &
spawn, &spawner =
shell, platform_view_create_callback]() {
1732 auto configuration =
1733 RunConfiguration::InferFromSettings(CreateSettingsForFixture());
1734 configuration.SetEntrypoint(
"emptyMain");
1735 spawn = spawner->Spawn(
1736 std::move(configuration),
"", platform_view_create_callback,
1737 [](Shell& shell) { return std::make_unique<Rasterizer>(shell); });
1738 ASSERT_NE(
nullptr,
spawn.get());
1744 std::unique_ptr<Shell> second_shell = shell_spawn_callback();
1745 PlatformViewNotifyCreated(second_shell.get());
1746 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1748 second_shell->GetPlatformView()->SetViewportMetrics(
1749 kImplicitViewId, {1.0, 100, 100, 22, 0});
1753 static_cast<size_t>(960000U));
1755 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1757 second_shell->GetPlatformView()->SetViewportMetrics(
1758 kImplicitViewId, {1.0, 100, 300, 22, 0});
1762 static_cast<size_t>(1920000U));
1764 std::unique_ptr<Shell> third_shell = shell_spawn_callback();
1765 PlatformViewNotifyCreated(third_shell.get());
1766 PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
1768 third_shell->GetPlatformView()->SetViewportMetrics(
1769 kImplicitViewId, {1.0, 400, 100, 22, 0});
1773 static_cast<size_t>(3840000U));
1775 PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(),
1777 third_shell->GetPlatformView()->SetViewportMetrics(
1778 kImplicitViewId, {1.0, 800, 100, 22, 0});
1782 static_cast<size_t>(4000000U));
1783 DestroyShell(std::move(third_shell), task_runners);
1786 static_cast<size_t>(4000000U));
1788 PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(),
1790 second_shell->GetPlatformView()->SetViewportMetrics(
1791 kImplicitViewId, {1.0, 100, 100, 22, 0});
1795 static_cast<size_t>(960000U));
1797 DestroyShell(std::move(second_shell), task_runners);
1798 DestroyShell(std::move(
shell), task_runners);
1804 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1806 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
1809 PlatformViewNotifyCreated(
shell.get());
1811 auto configuration = RunConfiguration::InferFromSettings(
settings);
1812 configuration.SetEntrypoint(
"emptyMain");
1814 RunEngine(
shell.get(), std::move(configuration));
1815 PumpOneFrame(
shell.get());
1822#if defined(SHELL_ENABLE_VULKAN) && !defined(SHELL_ENABLE_GL)
1825#elif defined(SHELL_ENABLE_METAL)
1827 static_cast<size_t>(256 * (1 << 20)));
1830 static_cast<size_t>(24 * (1 << 20)));
1834 shell->GetTaskRunners().GetPlatformTaskRunner(), [&
shell]() {
1835 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1836 {1.0, 400, 200, 22, 0});
1838 PumpOneFrame(
shell.get());
1842 std::string request_json = R
"json({
1843 "method": "Skia.setResourceCacheMaxBytes",
1848 auto platform_message = std::make_unique<PlatformMessage>(
1849 "flutter/skia", std::move(
data),
nullptr);
1850 SendEnginePlatformMessage(
shell.get(), std::move(platform_message));
1851 PumpOneFrame(
shell.get());
1855 shell->GetTaskRunners().GetPlatformTaskRunner(), [&
shell]() {
1856 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1857 {1.0, 800, 400, 22, 0});
1859 PumpOneFrame(
shell.get());
1862 DestroyShell(std::move(
shell), task_runners);
1868 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1870 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
1873 shell->GetTaskRunners().GetPlatformTaskRunner(), [&
shell]() {
1874 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1875 {1.0, 400, 200, 22, 0});
1877 PumpOneFrame(
shell.get());
1880 PlatformViewNotifyCreated(
shell.get());
1882 auto configuration = RunConfiguration::InferFromSettings(
settings);
1883 configuration.SetEntrypoint(
"emptyMain");
1885 RunEngine(
shell.get(), std::move(configuration));
1886 PumpOneFrame(
shell.get());
1889 static_cast<size_t>(3840000U));
1890 DestroyShell(std::move(
shell), task_runners);
1896 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1898 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
1901 shell->GetTaskRunners().GetPlatformTaskRunner(), [&
shell]() {
1902 shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId,
1903 {1.0, 400, 200, 22, 0});
1905 PumpOneFrame(
shell.get());
1908 PlatformViewNotifyCreated(
shell.get());
1910 auto configuration = RunConfiguration::InferFromSettings(
settings);
1911 configuration.SetEntrypoint(
"testSkiaResourceCacheSendsResponse");
1914 static_cast<size_t>(3840000U));
1921 RunEngine(
shell.get(), std::move(configuration));
1922 PumpOneFrame(
shell.get());
1927 static_cast<size_t>(10000U));
1928 DestroyShell(std::move(
shell), task_runners);
1935 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
1938 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
1941 PlatformViewNotifyCreated(
shell.get());
1943 auto configuration = RunConfiguration::InferFromSettings(
settings);
1944 configuration.SetEntrypoint(
"canCreateImageFromDecompressedData");
1947 AddNativeCallback(
"NotifyWidthHeight",
1953 ASSERT_EQ(
width, 10);
1958 RunEngine(
shell.get(), std::move(configuration));
1961 DestroyShell(std::move(
shell), task_runners);
1964class MockTexture :
public Texture {
1967 std::shared_ptr<fml::AutoResetWaitableEvent> latch)
1968 :
Texture(textureId), latch_(
std::move(latch)) {}
1983 frames_available_++;
1988 unregistered_ =
true;
1996 bool unregistered_ =
false;
1997 int frames_available_ = 0;
1998 std::shared_ptr<fml::AutoResetWaitableEvent> latch_;
2003 auto configuration = RunConfiguration::InferFromSettings(
settings);
2005 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2007 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2010 PlatformViewNotifyCreated(
shell.get());
2012 RunEngine(
shell.get(), std::move(configuration));
2014 std::shared_ptr<fml::AutoResetWaitableEvent> latch =
2015 std::make_shared<fml::AutoResetWaitableEvent>();
2017 std::shared_ptr<MockTexture> mockTexture =
2018 std::make_shared<MockTexture>(0, latch);
2021 shell->GetTaskRunners().GetRasterTaskRunner(), [&]() {
2022 shell->GetPlatformView()->RegisterTexture(mockTexture);
2023 shell->GetPlatformView()->MarkTextureFrameAvailable(0);
2027 EXPECT_EQ(mockTexture->frames_available(), 1);
2030 shell->GetTaskRunners().GetRasterTaskRunner(),
2031 [&]() { shell->GetPlatformView()->UnregisterTexture(0); });
2034 EXPECT_EQ(mockTexture->unregistered(),
true);
2035 DestroyShell(std::move(
shell), task_runners);
2039 const std::string
message =
"dummy isolate launch data.";
2043 std::make_shared<fml::DataMapping>(
message);
2052 AddNativeCallback(
"NotifyMessage",
2054 const auto message_from_dart =
2057 ASSERT_EQ(
message, message_from_dart);
2061 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2063 ASSERT_TRUE(
shell->IsSetup());
2064 auto configuration = RunConfiguration::InferFromSettings(
settings);
2065 configuration.SetEntrypoint(
"canAccessIsolateLaunchData");
2068 shell->RunEngine(std::move(configuration), [&](
auto result) {
2069 ASSERT_EQ(
result, Engine::RunStatus::Success);
2072 message_latch.
Wait();
2073 DestroyShell(std::move(
shell), task_runners);
2084 AddNativeCallback(
"NativeOnBeginFrame",
2088 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2089 ASSERT_TRUE(
shell->IsSetup());
2091 auto configuration = RunConfiguration::InferFromSettings(
settings);
2092 configuration.SetEntrypoint(
"onBeginFrameWithNotifyNativeMain");
2093 RunEngine(
shell.get(), std::move(configuration));
2099 shell->GetTaskRunners().GetPlatformTaskRunner(),
2100 [&
shell]() { shell->GetPlatformView()->ScheduleFrame(); });
2102 DestroyShell(std::move(
shell), task_runners);
2106 bool is_on_begin_frame_called =
false;
2107 bool is_secondary_callback_called =
false;
2108 bool test_started =
false;
2116 AddNativeCallback(
"NativeOnBeginFrame",
2118 if (!test_started) {
2121 EXPECT_FALSE(is_on_begin_frame_called);
2122 EXPECT_FALSE(is_secondary_callback_called);
2123 is_on_begin_frame_called =
true;
2126 std::unique_ptr<Shell>
shell = CreateShell({
2128 .task_runners = task_runners,
2130 ASSERT_TRUE(
shell->IsSetup());
2132 auto configuration = RunConfiguration::InferFromSettings(
settings);
2133 configuration.SetEntrypoint(
"onBeginFrameWithNotifyNativeMain");
2134 RunEngine(
shell.get(), std::move(configuration));
2140 shell->GetTaskRunners().GetUITaskRunner(), [&]() {
2141 shell->GetEngine()->ScheduleSecondaryVsyncCallback(0, [&]() {
2142 if (!test_started) {
2145 EXPECT_TRUE(is_on_begin_frame_called);
2146 EXPECT_FALSE(is_secondary_callback_called);
2147 is_secondary_callback_called = true;
2148 count_down_latch.CountDown();
2150 shell->GetEngine()->ScheduleFrame();
2151 test_started =
true;
2153 count_down_latch.Wait();
2156 DestroyShell(std::move(
shell), task_runners);
2161 std::ostringstream ostr;
2162 for (
size_t i = 0;
i <
data->size();) {
2163 ostr << std::hex << std::setfill(
'0') << std::setw(2)
2164 <<
static_cast<int>(
data->bytes()[
i]) <<
" ";
2166 if (
i % 16 == 0 ||
i ==
data->size()) {
2175 auto settings = CreateSettingsForFixture();
2177 settings.frame_rasterized_callback =
2183 PlatformViewNotifyCreated(
shell.get());
2185 auto configuration = RunConfiguration::InferFromSettings(
settings);
2186 configuration.SetEntrypoint(
"emptyMain");
2188 RunEngine(
shell.get(), std::move(configuration));
2191 auto display_list_layer = std::make_shared<DisplayListLayer>(
2193 root->Add(display_list_layer);
2196 PumpOneFrame(
shell.get(), ViewContent::ImplicitView(100, 100,
builder));
2197 firstFrameLatch.
Wait();
2199 std::promise<Rasterizer::Screenshot> screenshot_promise;
2200 auto screenshot_future = screenshot_promise.get_future();
2203 shell->GetTaskRunners().GetRasterTaskRunner(),
2204 [&screenshot_promise, &
shell]() {
2205 auto rasterizer = shell->GetRasterizer();
2206 screenshot_promise.set_value(rasterizer->ScreenshotLastLayerTree(
2207 Rasterizer::ScreenshotType::CompressedImage, false));
2214 fixtures_dir,
"shelltest_screenshot.png");
2219 reference_png->GetMapping(), reference_png->GetSize());
2222 if (!reference_data->
equals(screenshot_data.
get())) {
2224 LogSkData(screenshot_data,
"screenshot");
2228 DestroyShell(std::move(
shell));
2239 std::string dart_isolate_time_str;
2244 dart_isolate_time_str =
2250 auto settings = CreateSettingsForFixture();
2251 auto configuration = RunConfiguration::InferFromSettings(
settings);
2252 configuration.SetEntrypoint(
"localtimesMatch");
2254 ASSERT_NE(
shell.get(),
nullptr);
2255 RunEngine(
shell.get(), std::move(configuration));
2259 const time_t timestamp =
time(
nullptr);
2260 const struct tm* local_time = localtime(×tamp);
2261 ASSERT_NE(local_time,
nullptr)
2262 <<
"Could not get local time: errno=" << errno <<
": " << strerror(errno);
2264 const size_t format_size =
2265 strftime(timestr,
sizeof(timestr),
"%Y-%m-%d %H", local_time);
2266 ASSERT_NE(format_size, 0
UL)
2267 <<
"strftime failed: host time: " << std::string(timestr)
2268 <<
" dart isolate time: " << dart_isolate_time_str;
2270 const std::string host_local_time_str = timestr;
2272 ASSERT_EQ(dart_isolate_time_str, host_local_time_str)
2273 <<
"Local times in the dart isolate and the local time seen by the test "
2274 <<
"differ by more than 1 hour, but are expected to be about equal";
2276 DestroyShell(std::move(
shell));
2302 unsigned int frame_index,
2303 std::optional<unsigned int> prior_frame) {
2304 assert(
info.width() == 1);
2305 assert(
info.height() == 1);
2306 assert(row_bytes == 4);
2308 reinterpret_cast<uint32_t*
>(pixels)[0] = 0x00ff00ff;
2323 ASSERT_EQ(
width, 1);
2328 auto settings = CreateSettingsForFixture();
2329 auto configuration = RunConfiguration::InferFromSettings(
settings);
2330 configuration.SetEntrypoint(
"canRegisterImageDecoders");
2332 ASSERT_NE(
shell.get(),
nullptr);
2335 shell->GetTaskRunners().GetPlatformTaskRunner(), [&
shell]() {
2336 shell->RegisterImageDecoder(
2337 [](const sk_sp<SkData>& buffer) {
2338 return std::make_unique<SinglePixelImageGenerator>();
2343 RunEngine(
shell.get(), std::move(configuration));
2345 DestroyShell(std::move(
shell));
2351 PersistentCache::SetCacheDirectoryPath(base_dir.
path());
2352 PersistentCache::ResetCacheForProcess();
2356 std::vector<std::string> components = {
2358 PersistentCache::kSkSLSubdirName};
2361 const std::string x_key_str =
"A";
2362 const std::string x_value_str =
"x";
2367 auto x_data = PersistentCache::BuildCacheObject(*x_key, *x_value);
2369 const std::string y_key_str =
"B";
2370 const std::string y_value_str =
"y";
2375 auto y_data = PersistentCache::BuildCacheObject(*y_key, *y_value);
2383 rapidjson::Document document;
2384 OnServiceProtocol(
shell.get(), ServiceProtocolEnum::kGetSkSLs,
2385 shell->GetTaskRunners().GetIOTaskRunner(), empty_params,
2387 rapidjson::StringBuffer
buffer;
2388 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2389 document.Accept(writer);
2390 DestroyShell(std::move(
shell));
2392 const std::string expected_json1 =
2393 "{\"type\":\"GetSkSLs\",\"SkSLs\":{\"II\":\"eQ==\",\"IE\":\"eA==\"}}";
2394 const std::string expected_json2 =
2395 "{\"type\":\"GetSkSLs\",\"SkSLs\":{\"IE\":\"eA==\",\"II\":\"eQ==\"}}";
2396 bool json_is_expected = (expected_json1 ==
buffer.GetString()) ||
2397 (expected_json2 ==
buffer.GetString());
2398 ASSERT_TRUE(json_is_expected) <<
buffer.GetString() <<
" is not equal to "
2399 << expected_json1 <<
" or " << expected_json2;
2404 auto configuration = RunConfiguration::InferFromSettings(
settings);
2406 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2408 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2411 PlatformViewNotifyCreated(
shell.get());
2413 RunEngine(
shell.get(), std::move(configuration));
2415 auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
2417 PumpOneFrame(
shell.get());
2420 shell->GetTaskRunners().GetRasterTaskRunner(), [&
shell, &latch]() {
2421 Rasterizer::Screenshot screenshot =
2422 shell->GetRasterizer()->ScreenshotLastLayerTree(
2423 Rasterizer::ScreenshotType::CompressedImage, true);
2424 EXPECT_NE(screenshot.data, nullptr);
2429 DestroyShell(std::move(
shell), task_runners);
2434 auto configuration = RunConfiguration::InferFromSettings(
settings);
2436 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2438 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2441 PlatformViewNotifyCreated(
shell.get());
2443 RunEngine(
shell.get(), std::move(configuration));
2445 auto latch = std::make_shared<fml::AutoResetWaitableEvent>();
2447 PumpOneFrame(
shell.get());
2450 shell->GetTaskRunners().GetRasterTaskRunner(), [&
shell, &latch]() {
2451 SnapshotDelegate* delegate =
2452 reinterpret_cast<Rasterizer*>(shell->GetRasterizer().get());
2453 sk_sp<DlImage> image = delegate->MakeRasterSnapshotSync(
2454 MakeSizedDisplayList(50, 50), SkISize::Make(50, 50));
2455 EXPECT_NE(image, nullptr);
2460 DestroyShell(std::move(
shell), task_runners);
2469 auto display_list_layer = std::make_shared<DisplayListLayer>(
2474 std::promise<bool> rasterized;
2476 shell->GetTaskRunners().GetRasterTaskRunner()->PostTask(
2477 [&
shell, &rasterized, &display_list, &display_list_layer] {
2478 std::vector<RasterCacheItem*> raster_cache_items;
2479 auto* compositor_context =
shell->GetRasterizer()->compositor_context();
2480 auto& raster_cache = compositor_context->raster_cache();
2489 .gr_context =
nullptr,
2490 .dst_color_space =
nullptr,
2491 .view_embedder =
nullptr,
2492 .raster_time = raster_time,
2494 .texture_registry =
nullptr,
2495 .raster_cache = &raster_cache,
2501 .raster_cache = &raster_cache,
2503 .view_embedder =
nullptr,
2504 .state_stack = state_stack,
2505 .dst_color_space =
nullptr,
2506 .surface_needs_readback =
false,
2507 .raster_time = raster_time,
2509 .texture_registry =
nullptr,
2510 .has_platform_view =
false,
2511 .has_texture_layer =
false,
2512 .raster_cached_entries = &raster_cache_items,
2520 bool picture_cache_generated;
2522 display_list,
SkPoint(),
true,
false);
2523 for (
int i = 0;
i < 4;
i += 1) {
2529 picture_cache_generated =
2533 display_list_raster_cache_item.
Draw(paint_context, &dummy_canvas,
2536 ASSERT_TRUE(picture_cache_generated);
2546 layer_raster_cache_item.
Draw(paint_context, &dummy_canvas, &
paint);
2547 rasterized.set_value(
true);
2549 rasterized.get_future().wait();
2553 rapidjson::Document document;
2555 shell.get(), ServiceProtocolEnum::kEstimateRasterCacheMemory,
2556 shell->GetTaskRunners().GetRasterTaskRunner(), empty_params, &document);
2557 rapidjson::StringBuffer
buffer;
2558 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2559 document.Accept(writer);
2560 std::string expected_json =
2561 "{\"type\":\"EstimateRasterCacheMemory\",\"layerBytes\":40024,\"picture"
2563 std::string actual_json =
buffer.GetString();
2564 ASSERT_EQ(actual_json, expected_json);
2566 DestroyShell(std::move(
shell));
2571 auto settings = CreateSettingsForFixture();
2575 PlatformViewNotifyCreated(
shell.get());
2577 auto configuration = RunConfiguration::InferFromSettings(
settings);
2578 configuration.SetEntrypoint(
"scene_with_red_box");
2580 RunEngine(
shell.get(), std::move(configuration));
2584 engine->SetViewportMetrics(kImplicitViewId,
2585 ViewportMetrics{1, 1, 1, 22, 0});
2587 PumpOneFrame(
shell.get(), ViewContent::NoViews());
2590 rapidjson::Document document;
2592 shell.get(), ServiceProtocolEnum::kRenderFrameWithRasterStats,
2593 shell->GetTaskRunners().GetRasterTaskRunner(), empty_params, &document);
2594 rapidjson::StringBuffer
buffer;
2595 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2596 document.Accept(writer);
2601#ifdef SHELL_ENABLE_METAL
2602 std::string expected_json =
2603 "\"snapshot\":[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,3,32,0,"
2604 "0,2,88,8,6,0,0,0,154,118,130,112,0,0,0,1,115,82,71,66,0,174,206,28,233,"
2605 "0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,7,103,73,68,65,84,120,"
2606 "156,237,206,65,13,192,48,0,3,177,211,248,115,78,73,172,234,199,70,224,"
2607 "86,91,45,0,0,128,203,190,215,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2608 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2609 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2610 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2611 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2612 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2613 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2614 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2615 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2616 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2617 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2618 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2619 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2620 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2621 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2622 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2623 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2624 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2625 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2626 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2627 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2628 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2629 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2630 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2631 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2632 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2633 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2634 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2635 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2636 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2637 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2638 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2639 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2640 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2641 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2642 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2643 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2644 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2645 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2646 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2647 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2648 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2649 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2650 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2651 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2652 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2653 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2654 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2655 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2656 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2657 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2658 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
2659 "0,224,47,7,195,182,3,255,101,111,186,90,0,0,0,0,73,69,78,68,174,66,96,"
2662 std::string expected_json =
2663 "\"snapshot\":[137,80,78,71,13,10,26,10,0,"
2664 "0,0,13,73,72,68,82,0,0,0,1,0,0,0,1,8,6,0,0,0,31,21,196,137,0,0,0,1,115,"
2665 "82,71,66,0,174,206,28,233,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,"
2666 "0,0,13,73,68,65,84,8,153,99,248,207,192,240,31,0,5,0,1,255,171,206,54,"
2667 "137,0,0,0,0,73,69,78,68,174,66,96,130]";
2669 std::string actual_json =
buffer.GetString();
2671 EXPECT_THAT(actual_json, ::testing::HasSubstr(expected_json));
2672 EXPECT_THAT(actual_json,
2673 ::testing::HasSubstr(
"{\"type\":\"RenderFrameWithRasterStats\""));
2674 EXPECT_THAT(actual_json, ::testing::HasSubstr(
"\"duration_micros\""));
2676 PlatformViewNotifyDestroyed(
shell.get());
2677 DestroyShell(std::move(
shell));
2680#if defined(FML_OS_MACOSX)
2681TEST_F(ShellTest, OnServiceProtocolRenderFrameWithRasterStatsDisableImpeller) {
2682 auto settings = CreateSettingsForFixture();
2684 std::unique_ptr<Shell>
shell = CreateShell({
2686 .platform_view_create_callback = ShellTestPlatformViewBuilder({
2687 .rendering_backend =
2688 ShellTestPlatformView::BackendType::kMetalBackend,
2693 PlatformViewNotifyCreated(
shell.get());
2695 auto configuration = RunConfiguration::InferFromSettings(
settings);
2696 configuration.SetEntrypoint(
"scene_with_red_box");
2698 RunEngine(
shell.get(), std::move(configuration));
2699 PumpOneFrame(
shell.get(), ViewContent::NoViews());
2701 ServiceProtocol::Handler::ServiceProtocolMap empty_params;
2702 rapidjson::Document document;
2704 shell.get(), ServiceProtocolEnum::kRenderFrameWithRasterStats,
2705 shell->GetTaskRunners().GetRasterTaskRunner(), empty_params, &document);
2706 rapidjson::StringBuffer
buffer;
2707 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
2708 document.Accept(writer);
2709 std::string actual_json =
buffer.GetString();
2710 std::string expected_json =
2711 "{\"code\":-32000,\"message\":\"Raster status not supported on Impeller "
2714 ASSERT_EQ(actual_json, expected_json);
2716 PlatformViewNotifyDestroyed(
shell.get());
2717 DestroyShell(std::move(
shell));
2726 auto settings = CreateSettingsForFixture();
2732 auto end_frame_callback =
2733 [&](
bool should_merge_thread,
2735 end_frame_latch.
Signal();
2737 auto external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2739 std::unique_ptr<Shell>
shell = CreateShell({
2742 .shell_test_external_view_embedder = external_view_embedder,
2747 PlatformViewNotifyCreated(
shell.get());
2750 shell->GetTaskRunners().GetPlatformTaskRunner(),
2751 [&
shell, &expected_size]() {
2752 shell->GetPlatformView()->SetViewportMetrics(
2754 {1.0, static_cast<double>(expected_size.width()),
2755 static_cast<double>(expected_size.height()), 22, 0});
2758 auto configuration = RunConfiguration::InferFromSettings(
settings);
2759 configuration.SetEntrypoint(
"emptyMain");
2761 RunEngine(
shell.get(), std::move(configuration));
2763 PumpOneFrame(
shell.get(), ViewContent::DummyView(
2764 static_cast<double>(wrong_size.width()),
2765 static_cast<double>(wrong_size.height())));
2766 end_frame_latch.Wait();
2768 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2770 PumpOneFrame(
shell.get(), ViewContent::DummyView(
2771 static_cast<double>(expected_size.width()),
2772 static_cast<double>(expected_size.height())));
2773 end_frame_latch.Wait();
2775 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2776 ASSERT_EQ(expected_size, external_view_embedder->GetLastSubmittedFrameSize());
2778 PlatformViewNotifyDestroyed(
shell.get());
2779 DestroyShell(std::move(
shell));
2787 auto settings = CreateSettingsForFixture();
2796 std::shared_ptr<ShellTestExternalViewEmbedder> external_view_embedder;
2798 auto end_frame_callback =
2799 [&](
bool should_merge_thread,
2801 if (!raster_thread_merger_ref) {
2802 raster_thread_merger_ref = raster_thread_merger;
2804 if (should_merge_thread) {
2806 external_view_embedder->UpdatePostPrerollResult(
2809 end_frame_latch.
Signal();
2811 if (should_merge_thread) {
2812 resize_latch.
Wait();
2816 external_view_embedder = std::make_shared<ShellTestExternalViewEmbedder>(
2817 std::move(end_frame_callback), PostPrerollResult::kResubmitFrame,
true);
2819 std::unique_ptr<Shell>
shell = CreateShell({
2822 .shell_test_external_view_embedder = external_view_embedder,
2827 PlatformViewNotifyCreated(
shell.get());
2830 shell->GetTaskRunners().GetPlatformTaskRunner(),
2831 [&
shell, &origin_size]() {
2832 shell->GetPlatformView()->SetViewportMetrics(
2834 {1.0, static_cast<double>(origin_size.width()),
2835 static_cast<double>(origin_size.height()), 22, 0});
2838 auto configuration = RunConfiguration::InferFromSettings(
settings);
2839 configuration.SetEntrypoint(
"emptyMain");
2841 RunEngine(
shell.get(), std::move(configuration));
2843 PumpOneFrame(
shell.get(), ViewContent::DummyView(
2844 static_cast<double>(origin_size.width()),
2845 static_cast<double>(origin_size.height())));
2847 end_frame_latch.Wait();
2848 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2851 shell->GetTaskRunners().GetPlatformTaskRunner(),
2852 [&
shell, &new_size, &resize_latch]() {
2853 shell->GetPlatformView()->SetViewportMetrics(
2854 kImplicitViewId, {1.0, static_cast<double>(new_size.width()),
2855 static_cast<double>(new_size.height()), 22, 0});
2856 resize_latch.Signal();
2859 end_frame_latch.Wait();
2863 ASSERT_EQ(0, external_view_embedder->GetSubmittedFrameCount());
2866 PumpOneFrame(
shell.get(),
2867 ViewContent::DummyView(
static_cast<double>(new_size.width()),
2868 static_cast<double>(new_size.height())));
2870 end_frame_latch.Wait();
2871 ASSERT_TRUE(raster_thread_merger_ref->IsMerged());
2872 ASSERT_EQ(1, external_view_embedder->GetSubmittedFrameCount());
2873 ASSERT_EQ(new_size, external_view_embedder->GetLastSubmittedFrameSize());
2875 PlatformViewNotifyDestroyed(
shell.get());
2876 DestroyShell(std::move(
shell));
2881 double last_device_pixel_ratio;
2888 ASSERT_FALSE(last_device_pixel_ratio == 0.0);
2893 ASSERT_FALSE(last_width == 0.0);
2898 ASSERT_FALSE(last_height == 0.0);
2905 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2908 AddNativeCallback(
"ReportMetrics",
2911 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2913 auto configuration = RunConfiguration::InferFromSettings(
settings);
2914 configuration.SetEntrypoint(
"reportMetrics");
2916 RunEngine(
shell.get(), std::move(configuration));
2918 task_runner->PostTask([&]() {
2921 {0.0, 400, 200, 22, 0});
2922 task_runner->PostTask([&]() {
2925 {0.8, 0.0, 200, 22, 0});
2926 task_runner->PostTask([&]() {
2929 {0.8, 400, 0.0, 22, 0});
2930 task_runner->PostTask([&]() {
2939 ASSERT_EQ(last_device_pixel_ratio, 0.8);
2940 ASSERT_EQ(last_width, 400.0);
2941 ASSERT_EQ(last_height, 200.0);
2944 task_runner->PostTask([&]() {
2946 {1.2, 600, 300, 22, 0});
2949 ASSERT_EQ(last_device_pixel_ratio, 1.2);
2950 ASSERT_EQ(last_width, 600.0);
2951 ASSERT_EQ(last_height, 300.0);
2953 DestroyShell(std::move(
shell), task_runners);
2958 double last_device_pixel_ratio;
2965 ASSERT_TRUE(last_device_pixel_ratio > 2.5);
2972 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
2975 AddNativeCallback(
"ReportMetrics",
2978 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
2980 auto configuration = RunConfiguration::InferFromSettings(
settings);
2981 configuration.SetEntrypoint(
"reportMetrics");
2983 RunEngine(
shell.get(), std::move(configuration));
2985 task_runner->PostTask([&]() {
2989 task_runner->PostTask([&]() {
2992 {3.0, 400, 200, 22, 0});
2996 ASSERT_EQ(last_device_pixel_ratio, 3.0);
2999 DestroyShell(std::move(
shell), task_runners);
3006 RunConfiguration::InferFromSettings(
settings);
3007 configuration.
SetEntrypoint(
"canAccessResourceFromAssetDir");
3014 bool can_access_resource =
false;
3015 auto native_can_access_resource = [&can_access_resource,
3018 can_access_resource =
3022 AddNativeCallback(
"NotifyCanAccessResource",
3027 auto native_notify_set_asset_bundle_path =
3031 params[
"assetDirectory"] =
"assetDirectory";
3032 rapidjson::Document document;
3033 OnServiceProtocol(
shell.get(), ServiceProtocolEnum::kSetAssetBundlePath,
3034 shell->GetTaskRunners().GetUITaskRunner(),
params,
3036 rapidjson::StringBuffer
buffer;
3037 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
3038 document.Accept(writer);
3040 AddNativeCallback(
"NotifySetAssetBundlePath",
3043 RunEngine(
shell.get(), std::move(configuration));
3046 ASSERT_TRUE(can_access_resource);
3048 DestroyShell(std::move(
shell));
3052 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3055 auto vm_settings = CreateSettingsForFixture();
3057 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3061 settings.root_isolate_create_callback = [&](
const auto& isolate) {
3062 isolate_create_latch.
Signal();
3066 auto configuration = RunConfiguration::InferFromSettings(
settings);
3067 ASSERT_TRUE(configuration.IsValid());
3068 RunEngine(
shell.get(), std::move(configuration));
3069 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3070 DestroyShell(std::move(
shell));
3071 isolate_create_latch.
Wait();
3079 std::string filename =
"test_name";
3080 std::string
content =
"test_content";
3084 ASSERT_TRUE(success);
3088 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3091 ASSERT_TRUE(mapping !=
nullptr);
3093 std::string
result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3094 mapping->GetSize());
3104 std::vector<std::string> filenames = {
3111 for (
const auto& filename : filenames) {
3114 ASSERT_TRUE(success);
3119 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3121 auto mappings = asset_manager.
GetAsMappings(
"(.*)", std::nullopt);
3122 EXPECT_EQ(mappings.size(), 4u);
3124 std::vector<std::string> expected_results = {
3129 mappings = asset_manager.
GetAsMappings(
"(.*)good(.*)", std::nullopt);
3130 ASSERT_EQ(mappings.size(), expected_results.size());
3132 for (
auto& mapping : mappings) {
3133 std::string
result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3134 mapping->GetSize());
3137 expected_results.end());
3141#if defined(OS_FUCHSIA)
3142TEST_F(ShellTest, AssetManagerMultiSubdir) {
3143 std::string subdir_path =
"subdir";
3152 std::vector<std::string> filenames = {
3158 std::vector<std::string> subdir_filenames = {
3164 for (
auto filename : filenames) {
3167 ASSERT_TRUE(success);
3170 for (
auto filename : subdir_filenames) {
3173 ASSERT_TRUE(success);
3176 AssetManager asset_manager;
3177 asset_manager.PushBack(
3178 std::make_unique<DirectoryAssetBundle>(std::move(asset_dir_fd),
false));
3180 auto mappings = asset_manager.GetAsMappings(
"(.*)", std::nullopt);
3181 EXPECT_EQ(mappings.size(), 5u);
3183 mappings = asset_manager.GetAsMappings(
"(.*)", subdir_path);
3184 EXPECT_EQ(mappings.size(), 3u);
3186 std::vector<std::string> expected_results = {
3191 mappings = asset_manager.GetAsMappings(
"(.*)good(.*)", subdir_path);
3192 ASSERT_EQ(mappings.size(), expected_results.size());
3194 for (
auto& mapping : mappings) {
3195 std::string
result(
reinterpret_cast<const char*
>(mapping->GetMapping()),
3196 mapping->GetSize());
3199 expected_results.end());
3205 auto settings = CreateSettingsForFixture();
3209 auto configuration = RunConfiguration::InferFromSettings(
settings);
3210 ASSERT_TRUE(configuration.IsValid());
3211 configuration.SetEntrypoint(
"fixturesAreFunctionalMain");
3213 auto second_configuration = RunConfiguration::InferFromSettings(
settings);
3214 ASSERT_TRUE(second_configuration.IsValid());
3215 second_configuration.SetEntrypoint(
"testCanLaunchSecondaryIsolate");
3217 const std::string initial_route(
"/foo");
3220 std::string last_entry_point;
3224 last_entry_point =
shell->GetEngine()->GetLastEntrypoint();
3236 RunEngine(
shell.get(), std::move(configuration));
3238 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3240 ASSERT_EQ(
"fixturesAreFunctionalMain", last_entry_point);
3243 shell->GetTaskRunners().GetPlatformTaskRunner(),
3244 [
this, &spawner =
shell, &second_configuration, &second_latch,
3246 MockPlatformViewDelegate platform_view_delegate;
3247 auto spawn = spawner->Spawn(
3248 std::move(second_configuration), initial_route,
3249 [&platform_view_delegate](Shell& shell) {
3250 auto result = std::make_unique<MockPlatformView>(
3251 platform_view_delegate, shell.GetTaskRunners());
3252 ON_CALL(*result, CreateRenderingSurface())
3253 .WillByDefault(::testing::Invoke(
3254 [] { return std::make_unique<MockSurface>(); }));
3257 [](
Shell&
shell) { return std::make_unique<Rasterizer>(shell); });
3258 ASSERT_NE(
nullptr,
spawn.get());
3261 PostSync(spawner->GetTaskRunners().GetUITaskRunner(), [&
spawn, &spawner,
3264 ASSERT_EQ(
"testCanLaunchSecondaryIsolate",
3265 spawn->GetEngine()->GetLastEntrypoint());
3266 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3268 ASSERT_NE(spawner->GetEngine()
3269 ->GetRuntimeController()
3270 ->GetRootIsolateGroup(),
3272 ASSERT_EQ(spawner->GetEngine()
3273 ->GetRuntimeController()
3274 ->GetRootIsolateGroup(),
3276 ->GetRuntimeController()
3277 ->GetRootIsolateGroup());
3278 auto spawner_snapshot_delegate = spawner->GetEngine()
3279 ->GetRuntimeController()
3280 ->GetSnapshotDelegate();
3281 auto spawn_snapshot_delegate =
3282 spawn->GetEngine()->GetRuntimeController()->GetSnapshotDelegate();
3283 PostSync(spawner->GetTaskRunners().GetRasterTaskRunner(),
3284 [spawner_snapshot_delegate, spawn_snapshot_delegate] {
3285 ASSERT_NE(spawner_snapshot_delegate.get(),
3286 spawn_snapshot_delegate.get());
3290 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &
spawn] {
3291 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3292 spawn->GetIOManager()->GetResourceContext().get());
3297 second_latch.Wait();
3299 DestroyShell(std::move(
spawn));
3302 DestroyShell(std::move(
shell));
3303 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3307 auto settings = CreateSettingsForFixture();
3311 auto configuration = RunConfiguration::InferFromSettings(
settings);
3312 ASSERT_TRUE(configuration.IsValid());
3313 configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineRun");
3314 const std::vector<std::string> entrypoint_args{
"foo",
"bar"};
3315 configuration.SetEntrypointArgs(entrypoint_args);
3317 auto second_configuration = RunConfiguration::InferFromSettings(
settings);
3318 ASSERT_TRUE(second_configuration.IsValid());
3319 second_configuration.SetEntrypoint(
"canReceiveArgumentsWhenEngineSpawn");
3320 const std::vector<std::string> second_entrypoint_args{
"arg1",
"arg2"};
3321 second_configuration.SetEntrypointArgs(second_entrypoint_args);
3323 const std::string initial_route(
"/foo");
3326 std::string last_entry_point;
3328 AddNativeCallback(
"NotifyNativeWhenEngineRun",
3333 shell->GetEngine()->GetLastEntrypoint();
3339 AddNativeCallback(
"NotifyNativeWhenEngineSpawn",
3344 shell->GetEngine()->GetLastEntrypoint();
3345 second_latch.Signal();
3348 RunEngine(
shell.get(), std::move(configuration));
3350 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3352 ASSERT_EQ(
"canReceiveArgumentsWhenEngineRun", last_entry_point);
3355 shell->GetTaskRunners().GetPlatformTaskRunner(),
3356 [
this, &spawner =
shell, &second_configuration, &second_latch,
3358 MockPlatformViewDelegate platform_view_delegate;
3359 auto spawn = spawner->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 ASSERT_NE(
nullptr,
spawn.get());
3373 PostSync(spawner->GetTaskRunners().GetUITaskRunner(),
3374 [&
spawn, &spawner, initial_route] {
3376 ASSERT_EQ(
"canReceiveArgumentsWhenEngineSpawn",
3377 spawn->GetEngine()->GetLastEntrypoint());
3378 ASSERT_EQ(initial_route, spawn->GetEngine()->InitialRoute());
3380 ASSERT_NE(spawner->GetEngine()
3381 ->GetRuntimeController()
3382 ->GetRootIsolateGroup(),
3384 ASSERT_EQ(spawner->GetEngine()
3385 ->GetRuntimeController()
3386 ->GetRootIsolateGroup(),
3388 ->GetRuntimeController()
3389 ->GetRootIsolateGroup());
3393 spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &
spawn] {
3394 ASSERT_EQ(spawner->GetIOManager()->GetResourceContext().get(),
3395 spawn->GetIOManager()->GetResourceContext().get());
3400 second_latch.Wait();
3402 DestroyShell(std::move(
spawn));
3405 DestroyShell(std::move(
shell));
3406 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3410 auto settings = CreateSettingsForFixture();
3414 PostSync(
shell->GetTaskRunners().GetPlatformTaskRunner(), [
this,
3417 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3418 ASSERT_TRUE(second_configuration.IsValid());
3419 second_configuration.SetEntrypoint(
"emptyMain");
3420 const std::string initial_route(
"/foo");
3421 MockPlatformViewDelegate platform_view_delegate;
3422 auto spawn = spawner->Spawn(
3423 std::move(second_configuration), initial_route,
3424 [&platform_view_delegate](Shell& shell) {
3425 auto result = std::make_unique<MockPlatformView>(
3426 platform_view_delegate, shell.GetTaskRunners());
3427 ON_CALL(*result, CreateRenderingSurface())
3428 .WillByDefault(::testing::Invoke(
3429 [] { return std::make_unique<MockSurface>(); }));
3432 [](
Shell&
shell) { return std::make_unique<Rasterizer>(shell); });
3435 PostSync(spawner->GetTaskRunners().GetIOTaskRunner(), [&spawner, &
spawn] {
3436 ASSERT_NE(spawner->GetIOManager().get(), nullptr);
3437 ASSERT_EQ(spawner->GetIOManager().get(), spawn->GetIOManager().get());
3441 DestroyShell(std::move(
spawn));
3444 DestroyShell(std::move(
shell));
3448 auto settings = CreateSettingsForFixture();
3454 auto runtime_controller = shell->GetEngine()->GetRuntimeController();
3455 PostSync(shell->GetTaskRunners().GetIOTaskRunner(),
3456 [&shell, &runtime_controller] {
3458 auto io_manager = runtime_controller->GetIOManager();
3460 ASSERT_NE(io_manager.get(), nullptr);
3461 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3463 ASSERT_NE(shell->GetIOManager().get(), nullptr);
3467 std::unique_ptr<Shell>
spawn;
3471 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3472 ASSERT_TRUE(second_configuration.IsValid());
3473 second_configuration.SetEntrypoint(
"emptyMain");
3474 const std::string initial_route(
"/foo");
3475 MockPlatformViewDelegate platform_view_delegate;
3476 auto child = shell->Spawn(
3477 std::move(second_configuration), initial_route,
3478 [&platform_view_delegate](Shell& shell) {
3479 auto result = std::make_unique<MockPlatformView>(
3480 platform_view_delegate, shell.GetTaskRunners());
3481 ON_CALL(*result, CreateRenderingSurface())
3482 .WillByDefault(::testing::Invoke(
3483 [] { return std::make_unique<MockSurface>(); }));
3486 [](
Shell&
shell) { return std::make_unique<Rasterizer>(shell); });
3487 spawn = std::move(child);
3490 DestroyShell(std::move(
shell));
3494 auto runtime_controller = spawn->GetEngine()->GetRuntimeController();
3495 PostSync(spawn->GetTaskRunners().GetIOTaskRunner(),
3496 [&spawn, &runtime_controller] {
3498 auto io_manager = runtime_controller->GetIOManager();
3500 ASSERT_NE(io_manager.get(), nullptr);
3501 ASSERT_NE(io_manager->GetSkiaUnrefQueue().get(), nullptr);
3503 ASSERT_NE(spawn->GetIOManager().get(), nullptr);
3507 DestroyShell(std::move(
spawn));
3511 auto settings = CreateSettingsForFixture();
3515 std::unique_ptr<Shell>
spawn;
3519 auto second_configuration = RunConfiguration::InferFromSettings(settings);
3520 ASSERT_TRUE(second_configuration.IsValid());
3521 second_configuration.SetEntrypoint(
"emptyMain");
3522 const std::string initial_route(
"/foo");
3523 MockPlatformViewDelegate platform_view_delegate;
3524 auto child = shell->Spawn(
3525 std::move(second_configuration), initial_route,
3526 [&platform_view_delegate](Shell& shell) {
3527 auto result = std::make_unique<MockPlatformView>(
3528 platform_view_delegate, shell.GetTaskRunners());
3529 ON_CALL(*result, CreateRenderingSurface())
3530 .WillByDefault(::testing::Invoke(
3531 [] { return std::make_unique<MockSurface>(); }));
3534 [](
Shell&
shell) { return std::make_unique<Rasterizer>(shell); });
3535 spawn = std::move(child);
3539 std::shared_ptr<const DartIsolate> isolate =
3540 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3541 ASSERT_TRUE(isolate);
3542 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3546 DestroyShell(std::move(
shell));
3549 std::shared_ptr<const DartIsolate> isolate =
3550 spawn->GetEngine()->GetRuntimeController()->GetRootIsolate().lock();
3551 ASSERT_TRUE(isolate);
3552 ASSERT_TRUE(isolate->GetImageGeneratorRegistry());
3555 DestroyShell(std::move(
spawn));
3559 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3564 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3567 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3570 auto configuration = RunConfiguration::InferFromSettings(
settings);
3571 configuration.SetEntrypoint(
"emptyMain");
3572 auto asset_manager = configuration.GetAssetManager();
3574 shell->RunEngine(std::move(configuration), [&](
auto result) {
3575 ASSERT_EQ(
result, Engine::RunStatus::Success);
3579 std::make_unique<PlatformView>(*
shell.get(), task_runners);
3581 auto old_resolver = std::make_unique<TestAssetResolver>(
3582 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3583 ASSERT_TRUE(old_resolver->IsValid());
3584 asset_manager->PushBack(std::move(old_resolver));
3586 auto updated_resolver = std::make_unique<TestAssetResolver>(
3587 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3588 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3590 std::move(updated_resolver),
3591 AssetResolver::AssetResolverType::kApkAssetProvider);
3593 auto resolvers = asset_manager->TakeResolvers();
3594 ASSERT_EQ(resolvers.size(), 2ull);
3595 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3597 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3599 DestroyShell(std::move(
shell), task_runners);
3600 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3604 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3609 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3612 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3615 auto configuration = RunConfiguration::InferFromSettings(
settings);
3616 configuration.SetEntrypoint(
"emptyMain");
3617 auto asset_manager = configuration.GetAssetManager();
3619 shell->RunEngine(std::move(configuration), [&](
auto result) {
3620 ASSERT_EQ(
result, Engine::RunStatus::Success);
3624 std::make_unique<PlatformView>(*
shell.get(), task_runners);
3626 auto updated_resolver = std::make_unique<TestAssetResolver>(
3627 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3628 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3630 std::move(updated_resolver),
3631 AssetResolver::AssetResolverType::kApkAssetProvider);
3633 auto resolvers = asset_manager->TakeResolvers();
3634 ASSERT_EQ(resolvers.size(), 2ull);
3635 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3637 ASSERT_FALSE(resolvers[1]->IsValidAfterAssetManagerChange());
3639 DestroyShell(std::move(
shell), task_runners);
3640 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3644 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3648 ThreadHost::Type::kPlatform));
3650 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3653 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3656 auto configuration = RunConfiguration::InferFromSettings(
settings);
3657 configuration.SetEntrypoint(
"emptyMain");
3658 auto asset_manager = configuration.GetAssetManager();
3659 RunEngine(
shell.get(), std::move(configuration));
3662 std::make_unique<PlatformView>(*
shell.get(), task_runners);
3664 auto old_resolver = std::make_unique<TestAssetResolver>(
3665 true, AssetResolver::AssetResolverType::kApkAssetProvider);
3666 ASSERT_TRUE(old_resolver->IsValid());
3667 asset_manager->PushBack(std::move(old_resolver));
3670 nullptr, AssetResolver::AssetResolverType::kApkAssetProvider);
3672 auto resolvers = asset_manager->TakeResolvers();
3673 ASSERT_EQ(resolvers.size(), 2ull);
3674 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3675 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3677 DestroyShell(std::move(
shell), task_runners);
3678 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3682 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3687 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
3690 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3693 auto configuration = RunConfiguration::InferFromSettings(
settings);
3694 configuration.SetEntrypoint(
"emptyMain");
3695 auto asset_manager = configuration.GetAssetManager();
3697 shell->RunEngine(std::move(configuration), [&](
auto result) {
3698 ASSERT_EQ(
result, Engine::RunStatus::Success);
3702 std::make_unique<PlatformView>(*
shell.get(), task_runners);
3704 auto old_resolver = std::make_unique<TestAssetResolver>(
3705 true, AssetResolver::AssetResolverType::kAssetManager);
3706 ASSERT_TRUE(old_resolver->IsValid());
3707 asset_manager->PushBack(std::move(old_resolver));
3709 auto updated_resolver = std::make_unique<TestAssetResolver>(
3710 false, AssetResolver::AssetResolverType::kApkAssetProvider);
3711 ASSERT_FALSE(updated_resolver->IsValidAfterAssetManagerChange());
3713 std::move(updated_resolver),
3714 AssetResolver::AssetResolverType::kApkAssetProvider);
3716 auto resolvers = asset_manager->TakeResolvers();
3717 ASSERT_EQ(resolvers.size(), 3ull);
3718 ASSERT_TRUE(resolvers[0]->IsValidAfterAssetManagerChange());
3720 ASSERT_TRUE(resolvers[1]->IsValidAfterAssetManagerChange());
3722 ASSERT_FALSE(resolvers[2]->IsValidAfterAssetManagerChange());
3724 DestroyShell(std::move(
shell), task_runners);
3725 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3733 auto settings = CreateSettingsForFixture();
3734 std::unique_ptr<Shell>
shell = CreateShell({
3737 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
3740 ASSERT_NE(
shell,
nullptr);
3741 ASSERT_TRUE(
shell->IsSetup());
3742 auto configuration = RunConfiguration::InferFromSettings(
settings);
3743 PlatformViewNotifyCreated(
shell.get());
3744 configuration.SetEntrypoint(
"emptyMain");
3745 RunEngine(
shell.get(), std::move(configuration));
3746 PumpOneFrame(
shell.get());
3747 PlatformViewNotifyDestroyed(
shell.get());
3748 DestroyShell(std::move(
shell));
3753#if !SHELL_ENABLE_VULKAN
3756 auto settings = CreateSettingsForFixture();
3757 std::unique_ptr<Shell>
shell = CreateShell({
3760 .rendering_backend =
3761 ShellTestPlatformView::BackendType::kVulkanBackend,
3764 ASSERT_NE(
shell,
nullptr);
3765 ASSERT_TRUE(
shell->IsSetup());
3766 auto configuration = RunConfiguration::InferFromSettings(
settings);
3767 PlatformViewNotifyCreated(
shell.get());
3768 configuration.SetEntrypoint(
"emptyMain");
3769 RunEngine(
shell.get(), std::move(configuration));
3770 PumpOneFrame(
shell.get());
3771 PlatformViewNotifyDestroyed(
shell.get());
3772 DestroyShell(std::move(
shell));
3777#if !SHELL_ENABLE_METAL
3780 auto settings = CreateSettingsForFixture();
3781 std::unique_ptr<Shell>
shell = CreateShell({
3784 .rendering_backend =
3785 ShellTestPlatformView::BackendType::kMetalBackend,
3788 ASSERT_NE(
shell,
nullptr);
3789 ASSERT_TRUE(
shell->IsSetup());
3790 auto configuration = RunConfiguration::InferFromSettings(
settings);
3791 PlatformViewNotifyCreated(
shell.get());
3792 configuration.SetEntrypoint(
"emptyMain");
3793 RunEngine(
shell.get(), std::move(configuration));
3794 PumpOneFrame(
shell.get());
3795 PlatformViewNotifyDestroyed(
shell.get());
3796 DestroyShell(std::move(
shell));
3801 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
3804 auto vm_settings = CreateSettingsForFixture();
3806 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3817 isolate_create_latch.
Signal();
3823 auto configuration = RunConfiguration::InferFromSettings(
settings);
3824 ASSERT_TRUE(configuration.IsValid());
3826 RunEngine(
shell.get(), std::move(configuration));
3827 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
3829 DestroyShell(std::move(
shell));
3830 isolate_create_latch.
Wait();
3834 auto settings = CreateSettingsForFixture();
3835 settings.prefetched_default_font_manager =
true;
3836 std::unique_ptr<Shell>
shell;
3838 auto get_font_manager_count = [&] {
3840 size_t font_manager_count;
3842 shell->GetTaskRunners().GetUITaskRunner(),
3843 [
this, &
shell, &latch, &font_manager_count]() {
3844 font_manager_count =
3845 GetFontCollection(shell.get())->GetFontManagersCount();
3849 return font_manager_count;
3851 size_t initial_font_manager_count = 0;
3852 settings.root_isolate_create_callback = [&](
const auto& isolate) {
3853 ASSERT_GT(initial_font_manager_count, 0ul);
3856 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count);
3861 initial_font_manager_count = get_font_manager_count();
3863 auto configuration = RunConfiguration::InferFromSettings(
settings);
3864 configuration.SetEntrypoint(
"emptyMain");
3865 RunEngine(
shell.get(), std::move(configuration));
3869 ASSERT_EQ(get_font_manager_count(), initial_font_manager_count + 1);
3871 DestroyShell(std::move(
shell));
3877 auto settings = CreateSettingsForFixture();
3882 [&latch]() { latch.Wait(); });
3884 ShellTest::PlatformViewNotifyCreated(
shell.get());
3887 DestroyShell(std::move(
shell));
3891 auto settings = CreateSettingsForFixture();
3893 auto configuration = RunConfiguration::InferFromSettings(
settings);
3894 configuration.SetEntrypoint(
"drawFrames");
3899 notify_native_latch.
Signal();
3903 RunEngine(
shell.get(), std::move(configuration));
3906 notify_native_latch.
Wait();
3908 ShellTest::PlatformViewNotifyCreated(
shell.get());
3912 shell->GetTaskRunners().GetPlatformTaskRunner(),
3913 [&
shell, &destroy_latch]() {
3914 shell->GetPlatformView()->NotifyDestroyed();
3915 destroy_latch.Signal();
3918 destroy_latch.
Wait();
3927 shell->GetTaskRunners().GetUITaskRunner(),
3928 [&ui_flush_latch]() { ui_flush_latch.Signal(); });
3929 ui_flush_latch.
Wait();
3930 DestroyShell(std::move(
shell));
3935 auto settings = CreateSettingsForFixture();
3936 MockPlatformViewDelegate platform_view_delegate;
3937 auto platform_message_handler =
3938 std::make_shared<MockPlatformMessageHandler>();
3940 EXPECT_CALL(*platform_message_handler, HandlePlatformMessage(_));
3941 EXPECT_CALL(*platform_message_handler,
3944 [&platform_view_delegate, task_runners,
3946 auto result = std::make_unique<MockPlatformView>(platform_view_delegate,
3948 EXPECT_CALL(*
result, GetPlatformMessageHandler())
3949 .WillOnce(Return(platform_message_handler));
3952 auto shell = CreateShell({
3954 .task_runners = task_runners,
3955 .platform_view_create_callback = platform_view_create_callback,
3958 EXPECT_EQ(platform_message_handler,
shell->GetPlatformMessageHandler());
3960 size_t data_size = 4;
3961 fml::MallocMapping bytes =
3962 fml::MallocMapping(static_cast<uint8_t*>(malloc(data_size)), data_size);
3963 fml::RefPtr<MockPlatformMessageResponse> response =
3964 MockPlatformMessageResponse::Create();
3965 auto message = std::make_unique<PlatformMessage>(
3966 "foo", std::move(bytes), response);
3967 (static_cast<Engine::Delegate*>(shell.get()))
3968 ->OnEngineHandlePlatformMessage(std::move(message));
3970 shell->GetPlatformMessageHandler()
3971 ->InvokePlatformMessageEmptyResponseCallback(message_id);
3972 DestroyShell(std::move(
shell));
3976 auto settings = CreateSettingsForFixture();
3980 auto configuration = RunConfiguration::InferFromSettings(
settings);
3981 ASSERT_TRUE(configuration.IsValid());
3982 configuration.SetEntrypoint(
"onErrorA");
3984 auto second_configuration = RunConfiguration::InferFromSettings(
settings);
3985 ASSERT_TRUE(second_configuration.IsValid());
3986 second_configuration.SetEntrypoint(
"onErrorB");
3995 EXPECT_STREQ(c_str,
"Exception: I should be coming from A");
4004 EXPECT_STREQ(c_str,
"Exception: I should be coming from B");
4008 RunEngine(
shell.get(), std::move(configuration));
4010 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4013 shell->GetTaskRunners().GetPlatformTaskRunner(),
4014 [
this, &spawner =
shell, &second_configuration, &latch]() {
4015 ::testing::NiceMock<MockPlatformViewDelegate> platform_view_delegate;
4016 auto spawn = spawner->Spawn(
4017 std::move(second_configuration),
"",
4018 [&platform_view_delegate](Shell& shell) {
4020 std::make_unique<::testing::NiceMock<MockPlatformView>>(
4021 platform_view_delegate, shell.GetTaskRunners());
4022 ON_CALL(*result, CreateRenderingSurface())
4023 .WillByDefault(::testing::Invoke([] {
4024 return std::make_unique<::testing::NiceMock<MockSurface>>();
4028 [](
Shell&
shell) { return std::make_unique<Rasterizer>(shell); });
4029 ASSERT_NE(
nullptr,
spawn.get());
4036 DestroyShell(std::move(
spawn));
4039 DestroyShell(std::move(
shell));
4040 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4046 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4048 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4051 AddNativeCallback(
"NotifyNative",
4055 PlatformViewNotifyCreated(
shell.get());
4057 auto configuration = RunConfiguration::InferFromSettings(
settings);
4058 configuration.SetEntrypoint(
"testThatAssetLoadingHappensOnWorkerThread");
4059 auto asset_manager = configuration.GetAssetManager();
4060 auto test_resolver = std::make_unique<ThreadCheckingAssetResolver>(
4061 shell->GetDartVM()->GetConcurrentMessageLoop());
4062 auto leaked_resolver = test_resolver.get();
4063 asset_manager->PushBack(std::move(test_resolver));
4065 RunEngine(
shell.get(), std::move(configuration));
4066 PumpOneFrame(
shell.get());
4070 EXPECT_EQ(leaked_resolver->mapping_requests[0],
"DoesNotExist");
4072 PlatformViewNotifyDestroyed(
shell.get());
4073 DestroyShell(std::move(
shell), task_runners);
4081 auto settings = CreateSettingsForFixture();
4082 std::unique_ptr<Shell>
shell = CreateShell({
4085 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
4089 AddNativeCallback(
"NativeOnBeforeToImageSync",
4097 PlatformViewNotifyDestroyed(
shell.get());
4098 PlatformViewNotifyCreated(
shell.get());
4102 ASSERT_NE(
shell,
nullptr);
4103 ASSERT_TRUE(
shell->IsSetup());
4104 auto configuration = RunConfiguration::InferFromSettings(
settings);
4105 PlatformViewNotifyCreated(
shell.get());
4106 configuration.SetEntrypoint(
"toImageSync");
4107 RunEngine(
shell.get(), std::move(configuration));
4108 PumpOneFrame(
shell.get());
4112 PlatformViewNotifyDestroyed(
shell.get());
4113 DestroyShell(std::move(
shell));
4118#if !SHELL_ENABLE_METAL
4122 auto settings = CreateSettingsForFixture();
4124 std::unique_ptr<Shell>
shell = CreateShell({
4127 .rendering_backend =
4128 ShellTestPlatformView::BackendType::kMetalBackend,
4132 AddNativeCallback(
"NativeOnBeforeToImageSync",
4140 PlatformViewNotifyDestroyed(
shell.get());
4141 PlatformViewNotifyCreated(
shell.get());
4145 ASSERT_NE(
shell,
nullptr);
4146 ASSERT_TRUE(
shell->IsSetup());
4147 auto configuration = RunConfiguration::InferFromSettings(
settings);
4153 configuration.SetEntrypoint(
"toImageSync");
4154 RunEngine(
shell.get(), std::move(configuration));
4155 PumpOneFrame(
shell.get());
4159 PlatformViewNotifyDestroyed(
shell.get());
4160 DestroyShell(std::move(
shell));
4166TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) {
4170 ThreadHost::Type::kPlatform);
4171 auto task_runner = thread_host.platform_thread->GetTaskRunner();
4172 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4175 auto settings = CreateSettingsForFixture();
4176 std::unique_ptr<Shell>
shell = CreateShell({
4178 .task_runners = task_runners,
4179 .platform_view_create_callback = ShellTestPlatformViewBuilder({
4180 .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend,
4189 ::eglMakeCurrent(::eglGetCurrentDisplay(), NULL, NULL, NULL);
4195 PlatformViewNotifyDestroyed(
shell.get());
4196 PlatformViewNotifyCreated(
shell.get());
4200 ASSERT_NE(
shell,
nullptr);
4201 ASSERT_TRUE(
shell->IsSetup());
4202 auto configuration = RunConfiguration::InferFromSettings(
settings);
4203 PlatformViewNotifyCreated(
shell.get());
4204 configuration.SetEntrypoint(
"toImageSync");
4205 RunEngine(
shell.get(), std::move(configuration));
4206 PumpOneFrame(
shell.get());
4210 PlatformViewNotifyDestroyed(
shell.get());
4211 DestroyShell(std::move(
shell), task_runners);
4216 auto settings = CreateSettingsForFixture();
4224 args, 0, exception);
4228 ASSERT_NE(
shell,
nullptr);
4229 ASSERT_TRUE(
shell->IsSetup());
4230 auto configuration = RunConfiguration::InferFromSettings(
settings);
4231 PlatformViewNotifyCreated(
shell.get());
4232 configuration.SetEntrypoint(
"testPluginUtilitiesCallbackHandle");
4233 RunEngine(
shell.get(), std::move(configuration));
4234 PumpOneFrame(
shell.get());
4238 ASSERT_TRUE(test_passed);
4240 PlatformViewNotifyDestroyed(
shell.get());
4241 DestroyShell(std::move(
shell));
4245 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4248 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4250 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4254 thread_host.
io_thread->GetTaskRunner());
4256 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4261 auto configuration = RunConfiguration::InferFromSettings(
settings);
4262 configuration.SetEntrypoint(
"emptyMain");
4263 RunEngine(
shell.get(), std::move(configuration));
4267 auto runtime_controller = const_cast<RuntimeController*>(
4268 shell->GetEngine()->GetRuntimeController());
4270 auto now = fml::TimeDelta::FromMicroseconds(Dart_TimelineGetMicros());
4272 EXPECT_FALSE(runtime_controller->NotifyIdle(
4273 now - fml::TimeDelta::FromMilliseconds(10)));
4274 EXPECT_FALSE(runtime_controller->NotifyIdle(now));
4275 EXPECT_FALSE(runtime_controller->NotifyIdle(
4276 now + fml::TimeDelta::FromNanoseconds(100)));
4278 EXPECT_TRUE(runtime_controller->NotifyIdle(
4279 now + fml::TimeDelta::FromMilliseconds(100)));
4285 DestroyShell(std::move(
shell), task_runners);
4286 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4290 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4293 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4295 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4299 thread_host.
io_thread->GetTaskRunner());
4301 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4311 bool is_in_latency_mode =
4314 shell->GetEngine()->GetRuntimeController());
4318 EXPECT_EQ(success, !is_in_latency_mode);
4322 auto configuration = RunConfiguration::InferFromSettings(
settings);
4323 configuration.SetEntrypoint(
"performanceModeImpactsNotifyIdle");
4324 RunEngine(
shell.get(), std::move(configuration));
4328 DestroyShell(std::move(
shell), task_runners);
4329 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4333 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4336 ThreadHost::Type::kPlatform | ThreadHost::kUi |
4338 auto platform_task_runner = thread_host.
platform_thread->GetTaskRunner();
4342 thread_host.
io_thread->GetTaskRunner());
4344 ASSERT_TRUE(DartVMRef::IsInstanceRunning());
4350 shell->GetEngine()->GetRuntimeController());
4356 auto configuration = RunConfiguration::InferFromSettings(
settings);
4357 configuration.SetEntrypoint(
"callNotifyDestroyed");
4358 RunEngine(
shell.get(), std::move(configuration));
4362 DestroyShell(std::move(
shell), task_runners);
4363 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4367#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG || OS_FUCHSIA
4368 GTEST_SKIP() <<
"Test is for debug mode only on non-fuchsia targets.";
4372 ThreadHost::Type::kPlatform);
4374 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4383 SendPlatformMessage(
shell.get(), std::make_unique<PlatformMessage>(
4384 "com.test.plugin",
nullptr));
4388 ::testing::EndsWith(
4389 "The 'com.test.plugin' channel sent a message from native to "
4390 "Flutter on a non-platform thread. Platform channel messages "
4391 "must be sent on the platform thread. Failure to do so may "
4392 "result in data loss or crashes, and must be fixed in the "
4393 "plugin or application code creating that channel.\nSee "
4394 "https://docs.flutter.dev/platform-integration/"
4395 "platform-channels#channels-and-platform-threading for more "
4404 SendPlatformMessage(
shell.get(), std::make_unique<PlatformMessage>(
4405 "com.test.plugin",
nullptr));
4407 EXPECT_EQ(log_capture.
str(),
"");
4410 DestroyShell(std::move(
shell), task_runners);
4411 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4416#if defined(OS_FUCHSIA)
4417 GTEST_SKIP() <<
"Fuchsia";
4419 ::testing::FLAGS_gtest_death_test_style =
"threadsafe";
4422 settings.enable_software_rendering =
true;
4424 ThreadHost::Type::kPlatform);
4426 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4428 EXPECT_DEATH_IF_SUPPORTED(
4429 CreateShell(
settings, task_runners),
4430 "Software rendering is incompatible with Impeller.");
4437 bool* hasImplicitView,
4438 std::vector<int64_t>* viewIds) {
4443 ASSERT_EQ(exception,
nullptr);
4445 args, 1, exception);
4446 ASSERT_EQ(exception,
nullptr);
4450 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4453 TaskRunners task_runners(
"test", task_runner, task_runner, task_runner,
4455 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4458 bool hasImplicitView;
4459 std::vector<int64_t> viewIds;
4461 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4466 AddNativeCallback(
"NativeReportViewIdsCallback",
4469 PlatformViewNotifyCreated(
shell.get());
4470 auto configuration = RunConfiguration::InferFromSettings(
settings);
4471 configuration.SetEntrypoint(
"testReportViewIds");
4472 RunEngine(
shell.get(), std::move(configuration));
4475 ASSERT_TRUE(hasImplicitView);
4476 ASSERT_EQ(viewIds.size(), 1u);
4477 ASSERT_EQ(viewIds[0], 0ll);
4479 PlatformViewNotifyDestroyed(
shell.get());
4480 DestroyShell(std::move(
shell), task_runners);
4485 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4490 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4494 thread_host.
io_thread->GetTaskRunner());
4495 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4498 bool hasImplicitView;
4499 std::vector<int64_t> viewIds;
4501 auto nativeViewIdsCallback = [&reportLatch, &hasImplicitView,
4506 AddNativeCallback(
"NativeReportViewIdsCallback",
4509 PlatformViewNotifyCreated(
shell.get());
4510 auto configuration = RunConfiguration::InferFromSettings(
settings);
4511 configuration.SetEntrypoint(
"testReportViewIds");
4512 RunEngine(
shell.get(), std::move(configuration));
4515 ASSERT_TRUE(hasImplicitView);
4516 ASSERT_EQ(viewIds.size(), 1u);
4517 ASSERT_EQ(viewIds[0], 0ll);
4520 shell->GetPlatformView()->AddView(2, ViewportMetrics{},
4521 [](
bool added) { EXPECT_TRUE(added); });
4524 ASSERT_TRUE(hasImplicitView);
4525 ASSERT_EQ(viewIds.size(), 2u);
4526 ASSERT_EQ(viewIds[1], 2ll);
4529 shell->GetPlatformView()->RemoveView(
4530 2, [](bool removed) { ASSERT_TRUE(removed); });
4533 ASSERT_TRUE(hasImplicitView);
4534 ASSERT_EQ(viewIds.size(), 1u);
4535 ASSERT_EQ(viewIds[0], 0ll);
4538 shell->GetPlatformView()->AddView(4, ViewportMetrics{},
4539 [](
bool added) { EXPECT_TRUE(added); });
4542 ASSERT_TRUE(hasImplicitView);
4543 ASSERT_EQ(viewIds.size(), 2u);
4544 ASSERT_EQ(viewIds[1], 4ll);
4546 PlatformViewNotifyDestroyed(
shell.get());
4547 DestroyShell(std::move(
shell), task_runners);
4552 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4557 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4561 thread_host.
io_thread->GetTaskRunner());
4562 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4565 bool has_implicit_view;
4566 std::vector<int64_t> view_ids;
4568 AddNativeCallback(
"NativeReportViewIdsCallback",
4574 PlatformViewNotifyCreated(
shell.get());
4575 auto configuration = RunConfiguration::InferFromSettings(
settings);
4576 configuration.SetEntrypoint(
"testReportViewIds");
4577 RunEngine(
shell.get(), std::move(configuration));
4579 report_latch.
Wait();
4580 ASSERT_TRUE(has_implicit_view);
4581 ASSERT_EQ(view_ids.size(), 1u);
4588 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4596 report_latch.Wait();
4597 ASSERT_EQ(view_ids.size(), 2u);
4599 ASSERT_EQ(view_ids[1], 123);
4604 shell->GetPlatformView()->AddView(123, ViewportMetrics{}, [&](
bool added) {
4605 EXPECT_FALSE(added);
4612 PlatformViewNotifyDestroyed(
shell.get());
4613 DestroyShell(std::move(
shell), task_runners);
4618 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4623 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4627 thread_host.
io_thread->GetTaskRunner());
4628 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4631 bool has_implicit_view;
4632 std::vector<int64_t> view_ids;
4634 AddNativeCallback(
"NativeReportViewIdsCallback",
4640 PlatformViewNotifyCreated(
shell.get());
4641 auto configuration = RunConfiguration::InferFromSettings(
settings);
4642 configuration.SetEntrypoint(
"testReportViewIds");
4643 RunEngine(
shell.get(), std::move(configuration));
4645 report_latch.
Wait();
4646 ASSERT_TRUE(has_implicit_view);
4647 ASSERT_EQ(view_ids.size(), 1u);
4653 [&
shell, &remove_latch] {
4654 shell->GetPlatformView()->RemoveView(123, [&](bool removed) {
4655 EXPECT_FALSE(removed);
4656 remove_latch.Signal();
4660 remove_latch.Wait();
4662 PlatformViewNotifyDestroyed(
shell.get());
4663 DestroyShell(std::move(
shell), task_runners);
4669 std::map<int64_t, int64_t>* viewWidths) {
4671 viewWidths->clear();
4672 std::vector<int64_t> viewWidthPacket =
4675 ASSERT_EQ(exception,
nullptr);
4676 ASSERT_EQ(viewWidthPacket.size() % 2, 0ul);
4677 for (
size_t packetIndex = 0; packetIndex < viewWidthPacket.size();
4679 (*viewWidths)[viewWidthPacket[packetIndex]] =
4680 viewWidthPacket[packetIndex + 1];
4688 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4693 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4697 thread_host.
io_thread->GetTaskRunner());
4698 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4702 auto platform_view = shell->GetPlatformView();
4705 platform_view->SetViewportMetrics(0, ViewportMetrics{1, 10, 1, 0, 0});
4707 [](
bool added) { ASSERT_TRUE(added); });
4711 bool first_report =
true;
4712 std::map<int64_t, int64_t> viewWidths;
4714 auto nativeViewWidthsCallback = [&reportLatch, &viewWidths,
4717 first_report =
false;
4721 AddNativeCallback(
"NativeReportViewWidthsCallback",
4724 PlatformViewNotifyCreated(
shell.get());
4725 auto configuration = RunConfiguration::InferFromSettings(
settings);
4726 configuration.SetEntrypoint(
"testReportViewWidths");
4727 RunEngine(
shell.get(), std::move(configuration));
4730 EXPECT_EQ(viewWidths.size(), 2u);
4731 EXPECT_EQ(viewWidths[0], 20ll);
4732 EXPECT_EQ(viewWidths[1], 30ll);
4734 PlatformViewNotifyDestroyed(
shell.get());
4735 DestroyShell(std::move(
shell), task_runners);
4740 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4745 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4749 thread_host.
io_thread->GetTaskRunner());
4750 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4754 auto platform_view = shell->GetPlatformView();
4759 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 30, 1, 0, 0},
4760 [](
bool added) { ASSERT_FALSE(added); });
4761 shell->GetPlatformView()->RemoveView(
4762 123, [](
bool removed) { ASSERT_FALSE(removed); });
4765 bool first_report =
true;
4766 std::map<int64_t, int64_t> view_widths;
4768 AddNativeCallback(
"NativeReportViewWidthsCallback",
4771 first_report =
false;
4776 PlatformViewNotifyCreated(
shell.get());
4777 auto configuration = RunConfiguration::InferFromSettings(
settings);
4778 configuration.SetEntrypoint(
"testReportViewWidths");
4779 RunEngine(
shell.get(), std::move(configuration));
4781 report_latch.
Wait();
4782 EXPECT_EQ(view_widths.size(), 1u);
4784 PlatformViewNotifyDestroyed(
shell.get());
4785 DestroyShell(std::move(
shell), task_runners);
4791 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4796 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4800 thread_host.
io_thread->GetTaskRunner());
4801 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4805 auto platform_view = shell->GetPlatformView();
4808 shell->GetPlatformView()->AddView(123, ViewportMetrics{1, 100, 1, 0, 0},
4809 [](
bool added) { ASSERT_TRUE(added); });
4812 [](
bool added) { ASSERT_FALSE(added); });
4816 [](
bool added) { ASSERT_TRUE(added); });
4819 bool first_report =
true;
4820 std::map<int64_t, int64_t> view_widths;
4822 AddNativeCallback(
"NativeReportViewWidthsCallback",
4825 first_report =
false;
4830 PlatformViewNotifyCreated(
shell.get());
4831 auto configuration = RunConfiguration::InferFromSettings(
settings);
4832 configuration.SetEntrypoint(
"testReportViewWidths");
4833 RunEngine(
shell.get(), std::move(configuration));
4835 report_latch.
Wait();
4836 EXPECT_EQ(view_widths.size(), 3u);
4837 EXPECT_EQ(view_widths[0], 0);
4838 EXPECT_EQ(view_widths[123], 100);
4839 EXPECT_EQ(view_widths[456], 300);
4841 PlatformViewNotifyDestroyed(
shell.get());
4842 DestroyShell(std::move(
shell), task_runners);
4846 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4852 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4856 thread_host.
io_thread->GetTaskRunner());
4857 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4863 UIDartState::Current()->GetRuntimeStageBackend();
4868 auto configuration = RunConfiguration::InferFromSettings(
settings);
4869 configuration.SetEntrypoint(
"mainNotifyNative");
4870 RunEngine(
shell.get(), std::move(configuration));
4874 DestroyShell(std::move(
shell), task_runners);
4877#if IMPELLER_SUPPORTS_RENDERING
4878TEST_F(ShellTest, RuntimeStageBackendWithImpeller) {
4879 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4885 ThreadHost::Type::kIo | ThreadHost::Type::kUi));
4886 TaskRunners task_runners(
"test", thread_host.platform_thread->GetTaskRunner(),
4887 thread_host.raster_thread->GetTaskRunner(),
4888 thread_host.ui_thread->GetTaskRunner(),
4889 thread_host.io_thread->GetTaskRunner());
4890 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4897 shell->GetTaskRunners().GetPlatformTaskRunner(),
4899 auto impeller_context = platform_view->GetImpellerContext();
4900 EXPECT_TRUE(impeller_context);
4901 impeller_backend = impeller_context->GetBackendType();
4908 auto backend = UIDartState::Current()->GetRuntimeStageBackend();
4909 switch (impeller_backend) {
4923 auto configuration = RunConfiguration::InferFromSettings(
settings);
4924 configuration.SetEntrypoint(
"mainNotifyNative");
4925 RunEngine(
shell.get(), std::move(configuration));
4929 DestroyShell(std::move(
shell), task_runners);
4934#if !IMPELLER_SUPPORTS_RENDERING
4935 GTEST_SKIP() <<
"This platform doesn't support Impeller.";
4937 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
4940 settings.warn_on_impeller_opt_out =
true;
4944 TaskRunners task_runners(
"test", runner, runner, runner, runner);
4945 std::ostringstream
stream;
4947 std::unique_ptr<Shell>
shell = CreateShell(
settings, task_runners);
4948 ASSERT_TRUE(
stream.str().find(
4949 "[Action Required] The application opted out of Impeller") !=
4952 DestroyShell(std::move(
shell), task_runners);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static sk_sp< Effect > Create()
@ kOpaque_SkAlphaType
pixel is opaque
int find(T *array, int N, T item)
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
bool equals(const SkData *other) const
const void * data() const
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
static const SkMatrix & I()
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 IsInstanceRunning()
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
bool TryToPrepareRasterCache(const PaintContext &context, bool parent_cached=false) const override
void PrerollSetup(PrerollContext *context, const SkMatrix &matrix) override
void PrerollFinalize(PrerollContext *context, const SkMatrix &matrix) override
bool Draw(const PaintContext &context, const DlPaint *paint) const override
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 SkMatrix &matrix) override
bool Draw(const PaintContext &context, const DlPaint *paint) const override
bool TryToPrepareRasterCache(const PaintContext &context, bool parent_cached=false) const override
void PrerollFinalize(PrerollContext *context, const SkMatrix &matrix) override
void set_preroll_delegate(const SkRect &cull_rect, const SkMatrix &matrix)
void set_delegate(DlCanvas *canvas)
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...
virtual bool NotifyDestroyed()
Notify the Dart VM that the attached flutter view has been destroyed. This gives the Dart VM to perfo...
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...
std::function< std::unique_ptr< T >(Shell &)> CreateCallback
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
void Paint(PaintContext &context, const SkRect &bounds, bool freeze, const DlImageSampling) override
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
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
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()
void MergeWithLease(size_t lease_term)
const std::string & path() const
static bool RunsOnTheSameThread(TaskQueueId queue_a, TaskQueueId queue_b)
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
static void DisableNextThreadCheckFailure()
constexpr int64_t ToMicroseconds() const
static constexpr TimeDelta Max()
static constexpr TimeDelta FromMicroseconds(int64_t micros)
static constexpr TimeDelta Zero()
TimeDelta ToEpochDelta() const
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
struct _Dart_Handle * Dart_Handle
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
struct _Dart_NativeArguments * Dart_NativeArguments
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle str, const char **cstr)
DART_EXPORT bool Dart_IdentityEquals(Dart_Handle obj1, Dart_Handle obj2)
DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, double *value)
DART_EXPORT bool Dart_IsDouble(Dart_Handle object)
@ kRaster
Suitable for thread which raster data.
const EmbeddedViewParams * params
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_LOG(severity)
static constexpr FlutterViewId kImplicitViewId
union flutter::testing::@2836::KeyboardChange::@76 content
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
fml::RefPtr< fml::TaskRunner > GetCurrentTaskRunner()
const GrXPFactory * Get(SkBlendMode mode)
SK_API GrDirectContext * GetContext(const SkImage *src)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
ObjectPtr Invoke(const Library &lib, const char *name)
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_F(ShellTest, WillLogWarningWhenImpellerIsOptedOut)
static void CheckFrameTimings(const std::vector< FrameTiming > &timings, fml::TimePoint start, fml::TimePoint finish)
static size_t GetRasterizerResourceCacheBytesSync(const Shell &shell)
TEST(DisplayListComplexity, EmptyDisplayList)
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)
Settings SettingsFromCommandLine(const fml::CommandLine &command_line)
static void PrefetchDefaultFontManager(JNIEnv *env, jclass jcaller)
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
static void SetViewportMetrics(JNIEnv *env, jobject jcaller, jlong shell_holder, jfloat devicePixelRatio, jint physicalWidth, jint physicalHeight, jint physicalPaddingTop, jint physicalPaddingRight, jint physicalPaddingBottom, jint physicalPaddingLeft, jint physicalViewInsetTop, jint physicalViewInsetRight, jint physicalViewInsetBottom, jint physicalViewInsetLeft, jint systemGestureInsetTop, jint systemGestureInsetRight, jint systemGestureInsetBottom, jint systemGestureInsetLeft, jint physicalTouchSlop, jintArray javaDisplayFeaturesBounds, jintArray javaDisplayFeaturesType, jintArray javaDisplayFeaturesState)
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 vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
EXPORTED void Spawn(const char *entrypoint, const char *route)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
@ kSrcOver
r = s + (1-sa)*d
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 double time(int loops, Benchmark *bench, Target *target)
static constexpr SkISize Make(int32_t w, int32_t h)
static constexpr SkPoint Make(float x, float y)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
static constexpr SkRect MakeWH(float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
static constexpr SkSize Make(SkScalar w, SkScalar h)
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
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 |SyncSwitch::Execute|.
#define CREATE_NATIVE_ENTRY(native_entry)
std::shared_ptr< const fml::Mapping > data
#define EXPECT_TRUE(handle)