Flutter Engine
 
Loading...
Searching...
No Matches
dart_isolate_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
17#include "third_party/dart/runtime/include/dart_api.h"
20
21// CREATE_NATIVE_ENTRY is leaky by design
22// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
23
24namespace flutter {
25namespace testing {
26
28 public:
30
31 void Wait() { latch_.Wait(); }
32
33 void Signal() { latch_.Signal(); }
34
35 private:
37
39};
40
41TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
42 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
43 auto settings = CreateSettingsForFixture();
44 auto vm_ref = DartVMRef::Create(settings);
45 ASSERT_TRUE(vm_ref);
46 auto vm_data = vm_ref.GetVMData();
47 ASSERT_TRUE(vm_data);
48 TaskRunners task_runners(GetCurrentTestName(), //
49 GetCurrentTaskRunner(), //
50 GetCurrentTaskRunner(), //
51 GetCurrentTaskRunner(), //
52 GetCurrentTaskRunner() //
53 );
54
55 auto isolate_configuration =
57
58 UIDartState::Context context(task_runners);
59 context.advisory_script_uri = "main.dart";
60 context.advisory_script_entrypoint = "main";
61 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
62 vm_data->GetSettings(), // settings
63 vm_data->GetIsolateSnapshot(), // isolate snapshot
64 nullptr, // platform configuration
65 DartIsolate::Flags{}, // flags
66 nullptr, // root_isolate_create_callback
67 settings.isolate_create_callback, // isolate create callback
68 settings.isolate_shutdown_callback, // isolate shutdown callback
69 "main", // dart entrypoint
70 std::nullopt, // dart entrypoint library
71 {}, // dart entrypoint arguments
72 std::move(isolate_configuration), // isolate configuration
73 context // engine context
74 );
75 auto root_isolate = weak_isolate.lock();
76 ASSERT_TRUE(root_isolate);
77 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
78 ASSERT_TRUE(root_isolate->Shutdown());
79}
80
81TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
82 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
83 auto settings = CreateSettingsForFixture();
84 auto vm_ref = DartVMRef::Create(settings);
85 ASSERT_TRUE(vm_ref);
86 auto vm_data = vm_ref.GetVMData();
87 ASSERT_TRUE(vm_data);
88 TaskRunners task_runners(GetCurrentTestName(), //
89 GetCurrentTaskRunner(), //
90 GetCurrentTaskRunner(), //
91 GetCurrentTaskRunner(), //
92 GetCurrentTaskRunner() //
93 );
94 auto isolate_configuration =
96
97 UIDartState::Context context(task_runners);
98 context.advisory_script_uri = "main.dart";
99 context.advisory_script_entrypoint = "main";
100 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
101 vm_data->GetSettings(), // settings
102 vm_data->GetIsolateSnapshot(), // isolate snapshot
103 nullptr, // platform configuration
104 DartIsolate::Flags{}, // flags
105 nullptr, // root_isolate_create_callback
106 settings.isolate_create_callback, // isolate create callback
107 settings.isolate_shutdown_callback, // isolate shutdown callback
108 "main", // dart entrypoint
109 std::nullopt, // dart entrypoint library
110 {}, // dart entrypoint arguments
111 std::move(isolate_configuration), // isolate configuration
112 context // engine context
113 );
114 auto root_isolate = weak_isolate.lock();
115 ASSERT_TRUE(root_isolate);
116 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
117 size_t destruction_callback_count = 0;
118 root_isolate->AddIsolateShutdownCallback([&destruction_callback_count]() {
119 ASSERT_NE(Dart_CurrentIsolate(), nullptr);
120 destruction_callback_count++;
121 });
122 ASSERT_TRUE(root_isolate->Shutdown());
123 ASSERT_EQ(destruction_callback_count, 1u);
124}
125
126TEST_F(DartIsolateTest, IsolateCanLoadAndRunDartCode) {
127 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
128 const auto settings = CreateSettingsForFixture();
129 auto vm_ref = DartVMRef::Create(settings);
130 TaskRunners task_runners(GetCurrentTestName(), //
131 GetCurrentTaskRunner(), //
132 GetCurrentTaskRunner(), //
133 GetCurrentTaskRunner(), //
134 GetCurrentTaskRunner() //
135 );
136 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main",
138 ASSERT_TRUE(isolate);
139 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
140}
141
142TEST_F(DartIsolateTest, IsolateCannotLoadAndRunUnknownDartEntrypoint) {
143 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
144 const auto settings = CreateSettingsForFixture();
145 auto vm_ref = DartVMRef::Create(settings);
146 TaskRunners task_runners(GetCurrentTestName(), //
147 GetCurrentTaskRunner(), //
148 GetCurrentTaskRunner(), //
149 GetCurrentTaskRunner(), //
150 GetCurrentTaskRunner() //
151 );
152 auto isolate =
153 RunDartCodeInIsolate(vm_ref, settings, task_runners, "thisShouldNotExist",
155 ASSERT_FALSE(isolate);
156}
157
158TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) {
159 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
160 const auto settings = CreateSettingsForFixture();
161 auto vm_ref = DartVMRef::Create(settings);
162 TaskRunners task_runners(GetCurrentTestName(), //
163 GetCurrentTaskRunner(), //
164 GetCurrentTaskRunner(), //
165 GetCurrentTaskRunner(), //
166 GetCurrentTaskRunner() //
167 );
168 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main",
170
171 ASSERT_TRUE(isolate);
172 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
173 ASSERT_TRUE(isolate->RunInIsolateScope([]() -> bool {
174 if (tonic::CheckAndHandleError(::Dart_Invoke(
175 Dart_RootLibrary(), tonic::ToDart("sayHi"), 0, nullptr))) {
176 return false;
177 }
178 return true;
179 }));
180}
181
182TEST_F(DartIsolateTest, ImpellerFlagIsCorrectWhenTrue) {
183 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
184 auto settings = CreateSettingsForFixture();
185 settings.enable_impeller = true;
186 auto vm_ref = DartVMRef::Create(settings);
187 TaskRunners task_runners(GetCurrentTestName(), //
188 GetCurrentTaskRunner(), //
189 GetCurrentTaskRunner(), //
190 GetCurrentTaskRunner(), //
191 GetCurrentTaskRunner() //
192 );
193 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main",
195
196 ASSERT_TRUE(isolate);
197 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
198 ASSERT_TRUE(isolate->RunInIsolateScope([settings]() -> bool {
199 Dart_Handle dart_ui = ::Dart_LookupLibrary(tonic::ToDart("dart:ui"));
200 if (tonic::CheckAndHandleError(dart_ui)) {
201 return false;
202 }
203 Dart_Handle impeller_enabled =
204 ::Dart_GetField(dart_ui, tonic::ToDart("_impellerEnabled"));
205 if (tonic::CheckAndHandleError(impeller_enabled)) {
206 return false;
207 }
208 bool result;
210 Dart_BooleanValue(impeller_enabled, &result))) {
211 return false;
212 }
213 return result == settings.enable_impeller;
214 }));
215}
216
217TEST_F(DartIsolateTest, ImpellerFlagIsCorrectWhenFalse) {
218 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
219 auto settings = CreateSettingsForFixture();
220 settings.enable_impeller = false;
221 auto vm_ref = DartVMRef::Create(settings);
222 TaskRunners task_runners(GetCurrentTestName(), //
223 GetCurrentTaskRunner(), //
224 GetCurrentTaskRunner(), //
225 GetCurrentTaskRunner(), //
226 GetCurrentTaskRunner() //
227 );
228 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main",
230
231 ASSERT_TRUE(isolate);
232 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
233 ASSERT_TRUE(isolate->RunInIsolateScope([settings]() -> bool {
234 Dart_Handle dart_ui = ::Dart_LookupLibrary(tonic::ToDart("dart:ui"));
235 if (tonic::CheckAndHandleError(dart_ui)) {
236 return false;
237 }
238 Dart_Handle impeller_enabled =
239 ::Dart_GetField(dart_ui, tonic::ToDart("_impellerEnabled"));
240 if (tonic::CheckAndHandleError(impeller_enabled)) {
241 return false;
242 }
243 bool result;
245 Dart_BooleanValue(impeller_enabled, &result))) {
246 return false;
247 }
248 return result == settings.enable_impeller;
249 }));
250}
251
252TEST_F(DartIsolateTest, CanRegisterNativeCallback) {
253 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
254 AddNativeCallback(
255 "NotifyNative",
256 CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { Signal(); })));
257 const auto settings = CreateSettingsForFixture();
258 auto vm_ref = DartVMRef::Create(settings);
259 auto thread = CreateNewThread();
260 TaskRunners task_runners(GetCurrentTestName(), //
261 thread, //
262 thread, //
263 thread, //
264 thread //
265 );
266 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
267 "canRegisterNativeCallback", {},
269 ASSERT_TRUE(isolate);
270 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
271 Wait();
272}
273
275 public:
277
278 void LatchCountDown() { latch_.CountDown(); }
279
280 void LatchWait() { latch_.Wait(); }
281
282 void ChildShutdownSignal() { child_shutdown_latch_.Signal(); }
283
284 void ChildShutdownWait() { child_shutdown_latch_.Wait(); }
285
286 void RootIsolateShutdownSignal() { root_isolate_shutdown_latch_.Signal(); }
287
289 return root_isolate_shutdown_latch_.IsSignaledForTest();
290 }
291
292 private:
293 fml::CountDownLatch latch_;
294 fml::AutoResetWaitableEvent child_shutdown_latch_;
295 fml::AutoResetWaitableEvent root_isolate_shutdown_latch_;
296
298};
299
300TEST_F(DartSecondaryIsolateTest, CanLaunchSecondaryIsolates) {
301 AddNativeCallback("NotifyNative",
302 CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
303 LatchCountDown();
304 })));
305 AddNativeCallback(
306 "PassMessage", CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
308 Dart_GetNativeArgument(args, 0));
309 ASSERT_EQ("Hello from code is secondary isolate.", message);
310 LatchCountDown();
311 })));
312 auto settings = CreateSettingsForFixture();
313 settings.root_isolate_shutdown_callback = [this]() {
314 RootIsolateShutdownSignal();
315 };
316 settings.isolate_shutdown_callback = [this]() { ChildShutdownSignal(); };
317 auto vm_ref = DartVMRef::Create(settings);
318 auto thread = CreateNewThread();
319 TaskRunners task_runners(GetCurrentTestName(), //
320 thread, //
321 thread, //
322 thread, //
323 thread //
324 );
325 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
326 "testCanLaunchSecondaryIsolate", {},
328 ASSERT_TRUE(isolate);
329 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
330 ChildShutdownWait(); // wait for child isolate to shutdown first
331 ASSERT_FALSE(RootIsolateIsSignaled());
332 LatchWait(); // wait for last NotifyNative called by main isolate
333 // root isolate will be auto-shutdown
334}
335
336/// Tests error handling path of `Isolate.spawn()` in the engine.
338 public:
340 void NotifyDone() { latch_.CountDown(); }
341 void WaitForDone() { latch_.Wait(); }
342
343 private:
344 fml::CountDownLatch latch_;
346};
347
349 HandlesIsolateInitializationFailureCorrectly) {
350 AddNativeCallback("MakeNextIsolateSpawnFail",
351 CREATE_NATIVE_ENTRY(([](Dart_NativeArguments args) {
352 Dart_SetRootLibrary(Dart_Null());
353 })));
354 AddNativeCallback("NotifyNative",
356 ([this](Dart_NativeArguments args) { NotifyDone(); })));
357 auto settings = CreateSettingsForFixture();
358 auto vm_ref = DartVMRef::Create(settings);
359 auto thread = CreateNewThread();
360 TaskRunners task_runners(GetCurrentTestName(), //
361 thread, //
362 thread, //
363 thread, //
364 thread //
365 );
366 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
367 "testIsolateStartupFailure", {},
369 ASSERT_TRUE(isolate);
370 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
371 WaitForDone();
372}
373
374TEST_F(DartIsolateTest, CanReceiveArguments) {
375 AddNativeCallback("NotifyNative",
376 CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
378 Dart_GetNativeArgument(args, 0)));
379 Signal();
380 })));
381
382 const auto settings = CreateSettingsForFixture();
383 auto vm_ref = DartVMRef::Create(settings);
384 auto thread = CreateNewThread();
385 TaskRunners task_runners(GetCurrentTestName(), //
386 thread, //
387 thread, //
388 thread, //
389 thread //
390 );
391 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
392 "testCanReceiveArguments", {"arg1"},
394 ASSERT_TRUE(isolate);
395 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
396
397 Wait();
398}
399
400TEST_F(DartIsolateTest, CanCreateServiceIsolate) {
401#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG) && \
402 (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_PROFILE)
403 GTEST_SKIP();
404#endif
405 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
406 fml::AutoResetWaitableEvent service_isolate_latch;
407 auto settings = CreateSettingsForFixture();
408 settings.enable_vm_service = true;
409 settings.vm_service_port = 0;
410 settings.vm_service_host = "127.0.0.1";
411 settings.enable_service_port_fallback = true;
412 settings.service_isolate_create_callback = [&service_isolate_latch]() {
413 service_isolate_latch.Signal();
414 };
415 auto vm_ref = DartVMRef::Create(settings);
416 ASSERT_TRUE(vm_ref);
417 auto vm_data = vm_ref.GetVMData();
418 ASSERT_TRUE(vm_data);
419 TaskRunners task_runners(GetCurrentTestName(), //
420 GetCurrentTaskRunner(), //
421 GetCurrentTaskRunner(), //
422 GetCurrentTaskRunner(), //
423 GetCurrentTaskRunner() //
424 );
425
426 auto isolate_configuration =
427 IsolateConfiguration::InferFromSettings(settings);
428
429 UIDartState::Context context(task_runners);
430 context.advisory_script_uri = "main.dart";
431 context.advisory_script_entrypoint = "main";
432 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
433 vm_data->GetSettings(), // settings
434 vm_data->GetIsolateSnapshot(), // isolate snapshot
435 nullptr, // platform configuration
436 DartIsolate::Flags{}, // flags
437 nullptr, // root_isolate_create_callback
438 settings.isolate_create_callback, // isolate create callback
439 settings.isolate_shutdown_callback, // isolate shutdown callback
440 "main", // dart entrypoint
441 std::nullopt, // dart entrypoint library
442 {}, // dart entrypoint arguments
443 std::move(isolate_configuration), // isolate configuration
444 context // engine context
445 );
446
447 auto root_isolate = weak_isolate.lock();
448 ASSERT_TRUE(root_isolate);
449 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
450 service_isolate_latch.Wait();
451 ASSERT_TRUE(root_isolate->Shutdown());
452}
453
455 RootIsolateCreateCallbackIsMadeOnceAndBeforeIsolateRunning) {
456 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
457 auto settings = CreateSettingsForFixture();
458 size_t create_callback_count = 0u;
459 settings.root_isolate_create_callback =
460 [&create_callback_count](const auto& isolate) {
461 ASSERT_EQ(isolate.GetPhase(), DartIsolate::Phase::Ready);
462 create_callback_count++;
463 ASSERT_NE(::Dart_CurrentIsolate(), nullptr);
464 };
465 auto vm_ref = DartVMRef::Create(settings);
466 TaskRunners task_runners(GetCurrentTestName(), //
467 GetCurrentTaskRunner(), //
468 GetCurrentTaskRunner(), //
469 GetCurrentTaskRunner(), //
470 GetCurrentTaskRunner() //
471 );
472 {
473 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, "main",
475 ASSERT_TRUE(isolate);
476 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
477 }
478 ASSERT_EQ(create_callback_count, 1u);
479}
480
482 IsolateCreateCallbacksTakeInstanceSettingsInsteadOfVMSettings) {
483 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
484 auto vm_settings = CreateSettingsForFixture();
485 auto vm_ref = DartVMRef::Create(vm_settings);
486 auto instance_settings = vm_settings;
487 size_t create_callback_count = 0u;
488 instance_settings.root_isolate_create_callback =
489 [&create_callback_count](const auto& isolate) {
490 ASSERT_EQ(isolate.GetPhase(), DartIsolate::Phase::Ready);
491 create_callback_count++;
492 ASSERT_NE(::Dart_CurrentIsolate(), nullptr);
493 };
494 TaskRunners task_runners(GetCurrentTestName(), //
495 GetCurrentTaskRunner(), //
496 GetCurrentTaskRunner(), //
497 GetCurrentTaskRunner(), //
498 GetCurrentTaskRunner() //
499 );
500 {
501 auto isolate = RunDartCodeInIsolate(vm_ref, instance_settings, task_runners,
502 "main", {}, GetDefaultKernelFilePath());
503 ASSERT_TRUE(isolate);
504 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
505 }
506 ASSERT_EQ(create_callback_count, 1u);
507}
508
509TEST_F(DartIsolateTest, InvalidLoadingUnitFails) {
510 if (!DartVM::IsRunningPrecompiledCode()) {
511 FML_LOG(INFO) << "Split AOT does not work in JIT mode";
512 return;
513 }
514 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
515 auto settings = CreateSettingsForFixture();
516 auto vm_ref = DartVMRef::Create(settings);
517 ASSERT_TRUE(vm_ref);
518 auto vm_data = vm_ref.GetVMData();
519 ASSERT_TRUE(vm_data);
520 TaskRunners task_runners(GetCurrentTestName(), //
521 GetCurrentTaskRunner(), //
522 GetCurrentTaskRunner(), //
523 GetCurrentTaskRunner(), //
524 GetCurrentTaskRunner() //
525 );
526 auto isolate_configuration =
527 IsolateConfiguration::InferFromSettings(settings);
528
529 UIDartState::Context context(task_runners);
530 context.advisory_script_uri = "main.dart";
531 context.advisory_script_entrypoint = "main";
532 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
533 vm_data->GetSettings(), // settings
534 vm_data->GetIsolateSnapshot(), // isolate snapshot
535 nullptr, // platform configuration
536 DartIsolate::Flags{}, // flags
537 nullptr, // root_isolate_create_callback
538 settings.isolate_create_callback, // isolate create callback
539 settings.isolate_shutdown_callback, // isolate shutdown callback
540 "main", // dart entrypoint
541 std::nullopt, // dart entrypoint library
542 {}, // dart entrypoint arguments
543 std::move(isolate_configuration), // isolate configuration
544 context // engine context
545 );
546
547 auto root_isolate = weak_isolate.lock();
548 ASSERT_TRUE(root_isolate);
549 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
550
551 auto isolate_data = std::make_unique<const fml::NonOwnedMapping>(
552 split_aot_symbols_.vm_isolate_data, 0);
553 auto isolate_instructions = std::make_unique<const fml::NonOwnedMapping>(
554 split_aot_symbols_.vm_isolate_instrs, 0);
555
556 // Invalid loading unit should fail gracefully with error message.
557 ASSERT_FALSE(root_isolate->LoadLoadingUnit(3, std::move(isolate_data),
558 std::move(isolate_instructions)));
559 ASSERT_TRUE(root_isolate->Shutdown());
560}
561
562TEST_F(DartIsolateTest, DartPluginRegistrantIsCalled) {
563 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
564
565 std::vector<std::string> messages;
567
568 AddNativeCallback(
569 "PassMessage",
570 CREATE_NATIVE_ENTRY(([&latch, &messages](Dart_NativeArguments args) {
572 Dart_GetNativeArgument(args, 0));
573 messages.push_back(message);
574 latch.Signal();
575 })));
576
577 const auto settings = CreateSettingsForFixture();
578 auto vm_ref = DartVMRef::Create(settings);
579 auto thread = CreateNewThread();
580 TaskRunners task_runners(GetCurrentTestName(), //
581 thread, //
582 thread, //
583 thread, //
584 thread //
585 );
586 auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
587 "mainForPluginRegistrantTest", {},
589 ASSERT_TRUE(isolate);
590 ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
591 latch.Wait();
592 ASSERT_EQ(messages.size(), 1u);
593 ASSERT_EQ(messages[0], "_PluginRegistrant.register() was called");
594}
595
596TEST_F(DartIsolateTest, SpawningAnIsolateDoesNotReloadKernel) {
597 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
598 auto settings = CreateSettingsForFixture();
599 auto vm_ref = DartVMRef::Create(settings);
600 ASSERT_TRUE(vm_ref);
601 auto vm_data = vm_ref.GetVMData();
602 ASSERT_TRUE(vm_data);
603 TaskRunners task_runners(GetCurrentTestName(), //
604 GetCurrentTaskRunner(), //
605 GetCurrentTaskRunner(), //
606 GetCurrentTaskRunner(), //
607 GetCurrentTaskRunner() //
608 );
609
610 size_t get_kernel_count = 0u;
611 if (!DartVM::IsRunningPrecompiledCode()) {
612 ASSERT_TRUE(settings.application_kernels);
613 auto mappings = settings.application_kernels();
614 ASSERT_EQ(mappings.size(), 1u);
615
616 // This feels a little brittle, but the alternative seems to be making
617 // DartIsolate have virtual methods so it can be mocked or exposing weird
618 // test-only API on IsolateConfiguration.
619 settings.application_kernels = fml::MakeCopyable(
620 [&get_kernel_count,
621 mapping = std::move(mappings.front())]() mutable -> Mappings {
622 get_kernel_count++;
623 EXPECT_EQ(get_kernel_count, 1u)
624 << "Unexpectedly got more than one call for the kernel mapping.";
625 EXPECT_TRUE(mapping);
626 std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
627 if (mapping) {
628 kernel_mappings.emplace_back(std::move(mapping));
629 }
630 return kernel_mappings;
631 });
632 }
633
634 std::shared_ptr<DartIsolate> root_isolate;
635 {
636 auto isolate_configuration =
637 IsolateConfiguration::InferFromSettings(settings);
638
639 UIDartState::Context context(task_runners);
640 context.advisory_script_uri = "main.dart";
641 context.advisory_script_entrypoint = "main";
642 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
643 /*settings=*/vm_data->GetSettings(),
644 /*isolate_snapshot=*/vm_data->GetIsolateSnapshot(),
645 /*platform_configuration=*/nullptr,
646 /*flags=*/DartIsolate::Flags{},
647 /*root_isolate_create_callback=*/nullptr,
648 /*isolate_create_callback=*/settings.isolate_create_callback,
649 /*isolate_shutdown_callback=*/settings.isolate_shutdown_callback,
650 /*dart_entrypoint=*/"main",
651 /*dart_entrypoint_library=*/std::nullopt,
652 /*dart_entrypoint_args=*/{},
653 /*isolate_configuration=*/std::move(isolate_configuration),
654 /*context=*/context);
655 root_isolate = weak_isolate.lock();
656 }
657 ASSERT_TRUE(root_isolate);
658 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
659 if (!DartVM::IsRunningPrecompiledCode()) {
660 ASSERT_EQ(get_kernel_count, 1u);
661 }
662
663 {
664 auto isolate_configuration = IsolateConfiguration::InferFromSettings(
665 /*settings=*/settings,
666 /*asset_manager=*/nullptr,
667 /*io_worker=*/nullptr,
668 /*launch_type=*/IsolateLaunchType::kExistingGroup);
669
670 UIDartState::Context context(task_runners);
671 context.advisory_script_uri = "main.dart";
672 context.advisory_script_entrypoint = "main";
673 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
674 /*settings=*/vm_data->GetSettings(),
675 /*isolate_snapshot=*/vm_data->GetIsolateSnapshot(),
676 /*platform_configuration=*/nullptr,
677 /*flags=*/DartIsolate::Flags{},
678 /*root_isolate_create_callback=*/nullptr,
679 /*isolate_create_callback=*/settings.isolate_create_callback,
680 /*isolate_shutdown_callback=*/settings.isolate_shutdown_callback,
681 /*dart_entrypoint=*/"main",
682 /*dart_entrypoint_library=*/std::nullopt,
683 /*dart_entrypoint_args=*/{},
684 /*isolate_configuration=*/std::move(isolate_configuration),
685 /*context=*/context,
686 /*spawning_isolate=*/root_isolate.get());
687 auto spawned_isolate = weak_isolate.lock();
688 ASSERT_TRUE(spawned_isolate);
689 ASSERT_EQ(spawned_isolate->GetPhase(), DartIsolate::Phase::Running);
690 if (!DartVM::IsRunningPrecompiledCode()) {
691 ASSERT_EQ(get_kernel_count, 1u);
692 }
693 ASSERT_TRUE(spawned_isolate->Shutdown());
694 }
695
696 ASSERT_TRUE(root_isolate->Shutdown());
697}
698
700 public:
701 std::shared_ptr<PlatformIsolateManager> mgr =
702 std::shared_ptr<PlatformIsolateManager>(new PlatformIsolateManager());
703 std::shared_ptr<PlatformIsolateManager> GetPlatformIsolateManager() override {
704 return mgr;
705 }
706
707 std::string DefaultRouteName() override { return ""; }
708 void ScheduleFrame() override {}
709 void EndWarmUpFrame() override {}
710 void Render(int64_t view_id,
711 Scene* scene,
712 double width,
713 double height) override {}
714 void UpdateSemantics(int64_t view_id, SemanticsUpdate* update) override {}
715 void SetApplicationLocale(std::string locale) override {}
716 void SetSemanticsTreeEnabled(bool enabled) override {}
718 std::unique_ptr<PlatformMessage> message) override {}
721 return *reinterpret_cast<FontCollection*>(this);
722 }
723 std::shared_ptr<AssetManager> GetAssetManager() override { return nullptr; }
724 void UpdateIsolateDescription(const std::string isolate_name,
725 int64_t isolate_port) override {}
726 void SetNeedsReportTimings(bool value) override {}
727 std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override {
728 return nullptr;
729 }
730 std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
731 const std::vector<std::string>& supported_locale_data) override {
732 return nullptr;
733 }
734 void RequestDartDeferredLibrary(intptr_t loading_unit_id) override {}
735 void SendChannelUpdate(std::string name, bool listening) override {}
736 double GetScaledFontSize(double unscaled_font_size,
737 int configuration_id) const override {
738 return 0;
739 }
740 void RequestViewFocusChange(const ViewFocusChangeRequest& request) override {}
741};
742
743TEST_F(DartIsolateTest, PlatformIsolateCreationAndShutdown) {
744 fml::AutoResetWaitableEvent message_latch;
745 AddNativeCallback(
746 "PassMessage",
747 CREATE_NATIVE_ENTRY(([&message_latch](Dart_NativeArguments args) {
749 Dart_GetNativeArgument(args, 0));
750 ASSERT_EQ("Platform isolate is ready", message);
751 message_latch.Signal();
752 })));
753
755 auto platform_configuration =
756 std::make_unique<PlatformConfiguration>(&client);
757 Dart_Isolate platform_isolate = nullptr;
758
759 {
760 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
761 auto settings = CreateSettingsForFixture();
762 auto vm_ref = DartVMRef::Create(settings);
763 ASSERT_TRUE(vm_ref);
764 auto vm_data = vm_ref.GetVMData();
765 ASSERT_TRUE(vm_data);
766
767 auto platform_thread = CreateNewThread();
768 auto ui_thread = CreateNewThread();
769 TaskRunners task_runners(GetCurrentTestName(), // label
770 platform_thread, // platform
771 ui_thread, // raster
772 ui_thread, // ui
773 ui_thread // io
774 );
775 auto isolate = RunDartCodeInIsolate(
776 vm_ref, settings, task_runners, "emptyMain", {},
777 GetDefaultKernelFilePath(), {}, std::move(platform_configuration));
778 ASSERT_TRUE(isolate);
779 auto root_isolate = isolate->get();
780 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
781 EXPECT_FALSE(
782 client.mgr->IsRegisteredForTestingOnly(root_isolate->isolate()));
783
784 // Post a task to the platform_thread that just waits, to delay execution of
785 // the platform isolate until we're ready.
786 fml::AutoResetWaitableEvent platform_thread_latch;
788 platform_thread, fml::MakeCopyable([&platform_thread_latch]() mutable {
789 platform_thread_latch.Wait();
790 }));
791
792 fml::AutoResetWaitableEvent ui_thread_latch;
794 ui_thread, fml::MakeCopyable([&]() mutable {
795 ASSERT_TRUE(
796 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
797 Dart_Handle lib = Dart_RootLibrary();
798 Dart_Handle entry_point = Dart_GetField(
799 lib, tonic::ToDart("mainForPlatformIsolates"));
800 char* error = nullptr;
801 platform_isolate =
802 root_isolate->CreatePlatformIsolate(entry_point, &error);
803
804 EXPECT_FALSE(error);
805 EXPECT_TRUE(platform_isolate);
806 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
807 return true;
808 }));
809 ui_thread_latch.Signal();
810 }));
811
812 ui_thread_latch.Wait();
813 ASSERT_TRUE(platform_isolate);
814 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
815
816 // Allow the platform isolate to run.
817 platform_thread_latch.Signal();
818
819 // Wait for a message from the platform isolate.
820 message_latch.Wait();
821
822 // root isolate will be auto-shutdown
823 }
824 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
825}
826
827TEST_F(DartIsolateTest, PlatformIsolateEarlyShutdown) {
829 auto platform_configuration =
830 std::make_unique<PlatformConfiguration>(&client);
831
832 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
833 auto settings = CreateSettingsForFixture();
834 auto vm_ref = DartVMRef::Create(settings);
835 ASSERT_TRUE(vm_ref);
836 auto vm_data = vm_ref.GetVMData();
837 ASSERT_TRUE(vm_data);
838
839 auto platform_thread = CreateNewThread();
840 auto ui_thread = CreateNewThread();
841 TaskRunners task_runners(GetCurrentTestName(), // label
842 platform_thread, // platform
843 ui_thread, // raster
844 ui_thread, // ui
845 ui_thread // io
846 );
847 auto isolate = RunDartCodeInIsolate(
848 vm_ref, settings, task_runners, "emptyMain", {},
849 GetDefaultKernelFilePath(), {}, std::move(platform_configuration));
850 ASSERT_TRUE(isolate);
851 auto root_isolate = isolate->get();
852 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
853 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(root_isolate->isolate()));
854
855 fml::AutoResetWaitableEvent ui_thread_latch;
856 Dart_Isolate platform_isolate = nullptr;
858 ui_thread, fml::MakeCopyable([&]() mutable {
859 ASSERT_TRUE(
860 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
861 Dart_Handle lib = Dart_RootLibrary();
862 Dart_Handle entry_point =
863 Dart_GetField(lib, tonic::ToDart("emptyMain"));
864 char* error = nullptr;
865 platform_isolate =
866 root_isolate->CreatePlatformIsolate(entry_point, &error);
867
868 EXPECT_FALSE(error);
869 EXPECT_TRUE(platform_isolate);
870 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
871
872 return true;
873 }));
874 ui_thread_latch.Signal();
875 }));
876
877 ui_thread_latch.Wait();
878 ASSERT_TRUE(platform_isolate);
879 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
880
881 // Post a task to the platform thread to shut down the platform isolate.
882 fml::AutoResetWaitableEvent platform_thread_latch;
884 platform_thread,
885 fml::MakeCopyable([&platform_thread_latch, platform_isolate]() mutable {
886 Dart_EnterIsolate(platform_isolate);
887 Dart_ShutdownIsolate();
888 platform_thread_latch.Signal();
889 }));
890 platform_thread_latch.Wait();
891
892 // The platform isolate should be shut down.
893 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
894
895 // root isolate will be auto-shutdown
896}
897
898TEST_F(DartIsolateTest, PlatformIsolateCreationAfterManagerShutdown) {
899 AddNativeCallback("PassMessage",
901 [](Dart_NativeArguments args) { FML_UNREACHABLE(); })));
902
904 auto platform_configuration =
905 std::make_unique<PlatformConfiguration>(&client);
906
907 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
908 auto settings = CreateSettingsForFixture();
909 auto vm_ref = DartVMRef::Create(settings);
910 ASSERT_TRUE(vm_ref);
911 auto vm_data = vm_ref.GetVMData();
912 ASSERT_TRUE(vm_data);
913
914 auto platform_thread = CreateNewThread();
915 auto ui_thread = CreateNewThread();
916 TaskRunners task_runners(GetCurrentTestName(), // label
917 platform_thread, // platform
918 ui_thread, // raster
919 ui_thread, // ui
920 ui_thread // io
921 );
922 auto isolate = RunDartCodeInIsolate(
923 vm_ref, settings, task_runners, "emptyMain", {},
924 GetDefaultKernelFilePath(), {}, std::move(platform_configuration));
925 ASSERT_TRUE(isolate);
926 auto root_isolate = isolate->get();
927 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
928
929 // Shut down the manager on the platform thread.
930 fml::AutoResetWaitableEvent manager_shutdown_latch;
932 platform_thread,
933 fml::MakeCopyable([&manager_shutdown_latch, &client]() mutable {
934 client.mgr->ShutdownPlatformIsolates();
935 manager_shutdown_latch.Signal();
936 }));
937 manager_shutdown_latch.Wait();
938
939 fml::AutoResetWaitableEvent ui_thread_latch;
941 ui_thread, fml::MakeCopyable([&]() mutable {
942 ASSERT_TRUE(isolate->RunInIsolateScope([root_isolate]() {
943 Dart_Handle lib = Dart_RootLibrary();
944 Dart_Handle entry_point =
945 Dart_GetField(lib, tonic::ToDart("mainForPlatformIsolates"));
946 char* error = nullptr;
947 Dart_Isolate platform_isolate =
948 root_isolate->CreatePlatformIsolate(entry_point, &error);
949
950 // Failed to create a platform isolate, but we've still re-entered the
951 // root isolate.
952 EXPECT_FALSE(error);
953 EXPECT_FALSE(platform_isolate);
954 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
955
956 return true;
957 }));
958 ui_thread_latch.Signal();
959 }));
960 ui_thread_latch.Wait();
961
962 // root isolate will be auto-shutdown
963}
964
965TEST_F(DartIsolateTest, PlatformIsolateManagerShutdownBeforeMainRuns) {
966 AddNativeCallback("PassMessage",
968 [](Dart_NativeArguments args) { FML_UNREACHABLE(); })));
969
971 auto platform_configuration =
972 std::make_unique<PlatformConfiguration>(&client);
973
974 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
975 auto settings = CreateSettingsForFixture();
976 auto vm_ref = DartVMRef::Create(settings);
977 ASSERT_TRUE(vm_ref);
978 auto vm_data = vm_ref.GetVMData();
979 ASSERT_TRUE(vm_data);
980
981 auto platform_thread = CreateNewThread();
982 auto ui_thread = CreateNewThread();
983 TaskRunners task_runners(GetCurrentTestName(), // label
984 platform_thread, // platform
985 ui_thread, // raster
986 ui_thread, // ui
987 ui_thread // io
988 );
989 auto isolate = RunDartCodeInIsolate(
990 vm_ref, settings, task_runners, "emptyMain", {},
991 GetDefaultKernelFilePath(), {}, std::move(platform_configuration));
992 ASSERT_TRUE(isolate);
993 auto root_isolate = isolate->get();
994 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
995
996 Dart_Isolate platform_isolate = nullptr;
997
998 // Post a task to the platform_thread that just waits, to delay execution of
999 // the platform isolate until we're ready, and shutdown the manager just
1000 // before it runs.
1001 fml::AutoResetWaitableEvent platform_thread_latch;
1003 platform_thread, fml::MakeCopyable([&platform_thread_latch, &client,
1004 &platform_isolate]() mutable {
1005 platform_thread_latch.Wait();
1006 client.mgr->ShutdownPlatformIsolates();
1007 EXPECT_TRUE(platform_isolate);
1008 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1009 }));
1010
1011 fml::AutoResetWaitableEvent ui_thread_latch;
1013 ui_thread, fml::MakeCopyable([&]() mutable {
1014 ASSERT_TRUE(
1015 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
1016 Dart_Handle lib = Dart_RootLibrary();
1017 Dart_Handle entry_point =
1018 Dart_GetField(lib, tonic::ToDart("mainForPlatformIsolates"));
1019 char* error = nullptr;
1020 platform_isolate =
1021 root_isolate->CreatePlatformIsolate(entry_point, &error);
1022
1023 EXPECT_FALSE(error);
1024 EXPECT_TRUE(platform_isolate);
1025 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
1026
1027 return true;
1028 }));
1029 ui_thread_latch.Signal();
1030 }));
1031 ui_thread_latch.Wait();
1032 ASSERT_TRUE(platform_isolate);
1033 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1034
1035 // Allow the platform isolate to run, but its main is never run.
1036 platform_thread_latch.Signal();
1037
1038 // Post a task to the platform_thread that runs after the platform isolate's
1039 // entry point, and wait for it to run.
1040 fml::AutoResetWaitableEvent epilogue_latch;
1042 platform_thread, fml::MakeCopyable([&epilogue_latch]() mutable {
1043 epilogue_latch.Signal();
1044 }));
1045 epilogue_latch.Wait();
1046
1047 // root isolate will be auto-shutdown
1048}
1049
1050TEST_F(DartIsolateTest, PlatformIsolateMainThrowsError) {
1051 AddNativeCallback("PassMessage",
1053 [](Dart_NativeArguments args) { FML_UNREACHABLE(); })));
1054
1056 auto platform_configuration =
1057 std::make_unique<PlatformConfiguration>(&client);
1058
1059 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
1060 auto settings = CreateSettingsForFixture();
1061 auto vm_ref = DartVMRef::Create(settings);
1062 ASSERT_TRUE(vm_ref);
1063 auto vm_data = vm_ref.GetVMData();
1064 ASSERT_TRUE(vm_data);
1065
1066 auto platform_thread = CreateNewThread();
1067 auto ui_thread = CreateNewThread();
1068 TaskRunners task_runners(GetCurrentTestName(), // label
1069 platform_thread, // platform
1070 ui_thread, // raster
1071 ui_thread, // ui
1072 ui_thread // io
1073 );
1074 auto isolate = RunDartCodeInIsolate(
1075 vm_ref, settings, task_runners, "emptyMain", {},
1076 GetDefaultKernelFilePath(), {}, std::move(platform_configuration));
1077 ASSERT_TRUE(isolate);
1078 auto root_isolate = isolate->get();
1079 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
1080
1081 Dart_Isolate platform_isolate = nullptr;
1082 fml::AutoResetWaitableEvent ui_thread_latch;
1084 ui_thread, fml::MakeCopyable([&]() mutable {
1085 ASSERT_TRUE(
1086 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
1087 Dart_Handle lib = Dart_RootLibrary();
1088 Dart_Handle entry_point = Dart_GetField(
1089 lib, tonic::ToDart("mainForPlatformIsolatesThrowError"));
1090 char* error = nullptr;
1091 platform_isolate =
1092 root_isolate->CreatePlatformIsolate(entry_point, &error);
1093
1094 EXPECT_FALSE(error);
1095 EXPECT_TRUE(platform_isolate);
1096 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
1097
1098 return true;
1099 }));
1100 ui_thread_latch.Signal();
1101 }));
1102 ui_thread_latch.Wait();
1103 ASSERT_TRUE(platform_isolate);
1104 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1105
1106 // Post a task to the platform_thread that runs after the platform isolate's
1107 // entry point, and wait for it to run.
1108 fml::AutoResetWaitableEvent epilogue_latch;
1110 platform_thread, fml::MakeCopyable([&epilogue_latch]() mutable {
1111 epilogue_latch.Signal();
1112 }));
1113 epilogue_latch.Wait();
1114
1115 // root isolate will be auto-shutdown
1116}
1117
1118TEST_F(DartIsolateTest, RootIsolateIsOwnedByMainThread) {
1119 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
1120 auto settings = CreateSettingsForFixture();
1121 auto vm_ref = DartVMRef::Create(settings);
1122 ASSERT_TRUE(vm_ref);
1123 auto vm_data = vm_ref.GetVMData();
1124 ASSERT_TRUE(vm_data);
1125 TaskRunners task_runners(GetCurrentTestName(), //
1126 GetCurrentTaskRunner(), //
1127 GetCurrentTaskRunner(), //
1128 GetCurrentTaskRunner(), //
1129 GetCurrentTaskRunner() //
1130 );
1131
1132 auto isolate_configuration =
1133 IsolateConfiguration::InferFromSettings(settings);
1134
1135 UIDartState::Context context(task_runners);
1136 context.advisory_script_uri = "main.dart";
1137 context.advisory_script_entrypoint = "main";
1138 auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
1139 vm_data->GetSettings(), // settings
1140 vm_data->GetIsolateSnapshot(), // isolate snapshot
1141 nullptr, // platform configuration
1142 DartIsolate::Flags{}, // flags
1143 nullptr, // root_isolate_create_callback
1144 settings.isolate_create_callback, // isolate create callback
1145 settings.isolate_shutdown_callback, // isolate shutdown callback
1146 "main", // dart entrypoint
1147 std::nullopt, // dart entrypoint library
1148 {}, // dart entrypoint arguments
1149 std::move(isolate_configuration), // isolate configuration
1150 context // engine context
1151 );
1152 auto root_isolate = weak_isolate.lock();
1153
1154 Dart_Port main_port;
1155 {
1156 tonic::DartState::Scope scope(root_isolate.get());
1157 main_port = Dart_GetMainPortId();
1158
1159 ASSERT_TRUE(Dart_GetCurrentThreadOwnsIsolate(main_port));
1160 }
1161
1162 ASSERT_TRUE(Dart_GetCurrentThreadOwnsIsolate(main_port));
1163
1164 std::thread([main_port]() {
1165 ASSERT_FALSE(Dart_GetCurrentThreadOwnsIsolate(main_port));
1166 }).join();
1167
1168 ASSERT_TRUE(root_isolate->Shutdown());
1169
1170 ASSERT_FALSE(Dart_GetCurrentThreadOwnsIsolate(main_port));
1171}
1172
1173} // namespace testing
1174} // namespace flutter
1175
1176// NOLINTEND(clang-analyzer-core.StackAddressEscape)
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, const fml::RefPtr< const DartSnapshot > &isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, const fml::closure &root_isolate_create_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration, const UIDartState::Context &context, const DartIsolate *spawning_isolate=nullptr, std::shared_ptr< NativeAssetsManager > native_assets_manager=nullptr)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
static bool IsInstanceRunning()
static std::unique_ptr< IsolateConfiguration > InferFromSettings(const Settings &settings, const std::shared_ptr< AssetManager > &asset_manager=nullptr, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer the isolate configuration from the Settings object. If the VM is configured for AOT...
A client interface that the RuntimeController uses to define handlers for PlatformConfiguration reque...
std::shared_ptr< const fml::Mapping > GetPersistentIsolateData() override
The embedder can specify data that the isolate can request synchronously on launch....
std::string DefaultRouteName() override
The route or path that the embedder requested when the application was launched.
void UpdateSemantics(int64_t view_id, SemanticsUpdate *update) override
Receives an updated semantics tree from the Framework.
std::shared_ptr< PlatformIsolateManager > GetPlatformIsolateManager() override
void SetNeedsReportTimings(bool value) override
Notifies this client that the application has an opinion about whether its frame timings need to be r...
void SetApplicationLocale(std::string locale) override
Framework sets the application locale.
void ScheduleFrame() override
Requests that, at the next appropriate opportunity, a new frame be scheduled for rendering.
void Render(int64_t view_id, Scene *scene, double width, double height) override
Updates the client's rendering on the GPU with the newly provided Scene.
std::shared_ptr< AssetManager > GetAssetManager() override
Returns the current collection of assets available on the platform.
void SetSemanticsTreeEnabled(bool enabled) override
Notifies whether Framework starts generating semantics tree.
void SendChannelUpdate(std::string name, bool listening) override
Invoked when a listener is registered on a platform channel.
std::shared_ptr< PlatformIsolateManager > mgr
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port) override
Notifies this client of the name of the root isolate and its port when that isolate is launched,...
void EndWarmUpFrame() override
Called when a warm up frame has ended.
double GetScaledFontSize(double unscaled_font_size, int configuration_id) const override
Synchronously invokes platform-specific APIs to apply the system text scaling on the given unscaled f...
void RequestViewFocusChange(const ViewFocusChangeRequest &request) override
Notifies the client that the Flutter view focus state has changed and the platform view should be upd...
void HandlePlatformMessage(std::unique_ptr< PlatformMessage > message) override
When the Flutter application has a message to send to the underlying platform, the message needs to b...
FontCollection & GetFontCollection() override
Returns the current collection of fonts available on the platform.
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocale(const std::vector< std::string > &supported_locale_data) override
Directly invokes platform-specific APIs to compute the locale the platform would have natively resolv...
Tests error handling path of Isolate.spawn() in the engine.
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
#define FML_LOG(severity)
Definition logging.h:101
#define FML_UNREACHABLE()
Definition logging.h:128
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
const char * name
Definition fuchsia.cc:49
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition testing.cc:14
TEST_F(DisplayListTest, Defaults)
std::string GetDefaultKernelFilePath()
Returns the default path to kernel_blob.bin. This file is within the directory returned by GetFixture...
Definition testing.cc:18
std::unique_ptr< AutoIsolateShutdown > RunDartCodeInIsolate(DartVMRef &vm_ref, const Settings &settings, const TaskRunners &task_runners, std::string entrypoint, const std::vector< std::string > &args, const std::string &kernel_file_path, fml::WeakPtr< IOManager > io_manager, std::unique_ptr< PlatformConfiguration > platform_configuration)
std::vector< std::unique_ptr< const fml::Mapping > > Mappings
Definition settings.h:88
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
internal::CopyableLambda< T > MakeCopyable(T lambda)
Dart_Handle ToDart(const T &object)
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
int32_t height
int32_t width
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
#define CREATE_NATIVE_ENTRY(native_entry)