Flutter Engine
The 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
5#include "flutter/fml/mapping.h"
6#include "flutter/fml/synchronization/count_down_latch.h"
7#include "flutter/fml/synchronization/waitable_event.h"
8#include "flutter/lib/ui/window/platform_message.h"
9#include "flutter/runtime/dart_isolate.h"
10#include "flutter/runtime/dart_vm.h"
11#include "flutter/runtime/dart_vm_lifecycle.h"
12#include "flutter/runtime/isolate_configuration.h"
13#include "flutter/runtime/platform_isolate_manager.h"
14#include "flutter/testing/dart_isolate_runner.h"
15#include "flutter/testing/fixture_test.h"
16#include "flutter/testing/testing.h"
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",
303 LatchCountDown();
304 })));
305 AddNativeCallback(
306 "PassMessage", CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
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",
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",
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) {
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 {}
716 std::unique_ptr<PlatformMessage> message) override {}
719 return *(FontCollection*)(this);
720 }
721 std::shared_ptr<AssetManager> GetAssetManager() override { return nullptr; }
722 void UpdateIsolateDescription(const std::string isolate_name,
723 int64_t isolate_port) override {}
724 void SetNeedsReportTimings(bool value) override {}
725 std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override {
726 return nullptr;
727 }
728 std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
729 const std::vector<std::string>& supported_locale_data) override {
730 return nullptr;
731 }
732 void RequestDartDeferredLibrary(intptr_t loading_unit_id) override {}
733 void SendChannelUpdate(std::string name, bool listening) override {}
734 double GetScaledFontSize(double unscaled_font_size,
735 int configuration_id) const override {
736 return 0;
737 }
738};
739
740TEST_F(DartIsolateTest, PlatformIsolateCreationAndShutdown) {
741 fml::AutoResetWaitableEvent message_latch;
742 AddNativeCallback(
743 "PassMessage",
747 ASSERT_EQ("Platform isolate is ready", message);
748 message_latch.Signal();
749 })));
750
752 auto platform_configuration =
753 std::make_unique<PlatformConfiguration>(&client);
754 Dart_Isolate platform_isolate = nullptr;
755
756 {
757 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
758 auto settings = CreateSettingsForFixture();
759 auto vm_ref = DartVMRef::Create(settings);
760 ASSERT_TRUE(vm_ref);
761 auto vm_data = vm_ref.GetVMData();
762 ASSERT_TRUE(vm_data);
763
764 auto platform_thread = CreateNewThread();
765 auto ui_thread = CreateNewThread();
766 TaskRunners task_runners(GetCurrentTestName(), // label
767 platform_thread, // platform
768 ui_thread, // raster
769 ui_thread, // ui
770 ui_thread // io
771 );
772 auto isolate =
773 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
774 GetDefaultKernelFilePath(), {}, nullptr,
775 std::move(platform_configuration));
776 ASSERT_TRUE(isolate);
777 auto root_isolate = isolate->get();
778 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
779 EXPECT_FALSE(
780 client.mgr->IsRegisteredForTestingOnly(root_isolate->isolate()));
781
782 // Post a task to the platform_thread that just waits, to delay execution of
783 // the platform isolate until we're ready.
784 fml::AutoResetWaitableEvent platform_thread_latch;
786 platform_thread, fml::MakeCopyable([&platform_thread_latch]() mutable {
787 platform_thread_latch.Wait();
788 }));
789
790 fml::AutoResetWaitableEvent ui_thread_latch;
792 ui_thread, fml::MakeCopyable([&]() mutable {
793 ASSERT_TRUE(
794 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
795 Dart_Handle lib = Dart_RootLibrary();
796 Dart_Handle entry_point = Dart_GetField(
797 lib, tonic::ToDart("mainForPlatformIsolates"));
798 char* error = nullptr;
799 platform_isolate =
800 root_isolate->CreatePlatformIsolate(entry_point, &error);
801
802 EXPECT_FALSE(error);
803 EXPECT_TRUE(platform_isolate);
804 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
805 return true;
806 }));
807 ui_thread_latch.Signal();
808 }));
809
810 ui_thread_latch.Wait();
811 ASSERT_TRUE(platform_isolate);
812 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
813
814 // Allow the platform isolate to run.
815 platform_thread_latch.Signal();
816
817 // Wait for a message from the platform isolate.
818 message_latch.Wait();
819
820 // root isolate will be auto-shutdown
821 }
822 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
823}
824
825TEST_F(DartIsolateTest, PlatformIsolateEarlyShutdown) {
827 auto platform_configuration =
828 std::make_unique<PlatformConfiguration>(&client);
829
830 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
831 auto settings = CreateSettingsForFixture();
832 auto vm_ref = DartVMRef::Create(settings);
833 ASSERT_TRUE(vm_ref);
834 auto vm_data = vm_ref.GetVMData();
835 ASSERT_TRUE(vm_data);
836
837 auto platform_thread = CreateNewThread();
838 auto ui_thread = CreateNewThread();
839 TaskRunners task_runners(GetCurrentTestName(), // label
840 platform_thread, // platform
841 ui_thread, // raster
842 ui_thread, // ui
843 ui_thread // io
844 );
845 auto isolate =
846 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
847 GetDefaultKernelFilePath(), {}, nullptr,
848 std::move(platform_configuration));
849 ASSERT_TRUE(isolate);
850 auto root_isolate = isolate->get();
851 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
852 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(root_isolate->isolate()));
853
854 fml::AutoResetWaitableEvent ui_thread_latch;
855 Dart_Isolate platform_isolate = nullptr;
857 ui_thread, fml::MakeCopyable([&]() mutable {
858 ASSERT_TRUE(
859 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
860 Dart_Handle lib = Dart_RootLibrary();
861 Dart_Handle entry_point =
862 Dart_GetField(lib, tonic::ToDart("emptyMain"));
863 char* error = nullptr;
864 platform_isolate =
865 root_isolate->CreatePlatformIsolate(entry_point, &error);
866
867 EXPECT_FALSE(error);
868 EXPECT_TRUE(platform_isolate);
869 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
870
871 return true;
872 }));
873 ui_thread_latch.Signal();
874 }));
875
876 ui_thread_latch.Wait();
877 ASSERT_TRUE(platform_isolate);
878 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
879
880 // Post a task to the platform thread to shut down the platform isolate.
881 fml::AutoResetWaitableEvent platform_thread_latch;
883 platform_thread,
884 fml::MakeCopyable([&platform_thread_latch, platform_isolate]() mutable {
885 Dart_EnterIsolate(platform_isolate);
887 platform_thread_latch.Signal();
888 }));
889 platform_thread_latch.Wait();
890
891 // The platform isolate should be shut down.
892 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
893
894 // root isolate will be auto-shutdown
895}
896
897TEST_F(DartIsolateTest, PlatformIsolateSendAndReceive) {
898 fml::AutoResetWaitableEvent message_latch;
899 AddNativeCallback(
900 "PassMessage",
904 ASSERT_EQ("Platform isolate received: Hello from root isolate!",
905 message);
906 message_latch.Signal();
907 })));
908
910 auto platform_configuration =
911 std::make_unique<PlatformConfiguration>(&client);
912
913 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
914 auto settings = CreateSettingsForFixture();
915 auto vm_ref = DartVMRef::Create(settings);
916 ASSERT_TRUE(vm_ref);
917 auto vm_data = vm_ref.GetVMData();
918 ASSERT_TRUE(vm_data);
919
920 auto platform_thread = CreateNewThread();
921 auto ui_thread = CreateNewThread();
922 TaskRunners task_runners(GetCurrentTestName(), // label
923 platform_thread, // platform
924 ui_thread, // raster
925 ui_thread, // ui
926 ui_thread // io
927 );
928 auto isolate =
929 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
930 GetDefaultKernelFilePath(), {}, nullptr,
931 std::move(platform_configuration));
932 ASSERT_TRUE(isolate);
933 auto root_isolate = isolate->get();
934 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
935
936 fml::AutoResetWaitableEvent ui_thread_latch;
937 Dart_Isolate platform_isolate = nullptr;
939 ui_thread, fml::MakeCopyable([&]() mutable {
940 ASSERT_TRUE(isolate->RunInIsolateScope([root_isolate,
941 &platform_isolate]() {
942 Dart_Handle lib = Dart_RootLibrary();
943 Dart_Handle entry_point = Dart_Invoke(
944 lib, tonic::ToDart("createEntryPointForPlatIsoSendAndRecvTest"),
945 0, nullptr);
946 char* error = nullptr;
947 platform_isolate =
948 root_isolate->CreatePlatformIsolate(entry_point, &error);
949 EXPECT_FALSE(error);
950 return true;
951 }));
952 ui_thread_latch.Signal();
953 }));
954 ui_thread_latch.Wait();
955
956 // Wait for a message from the platform isolate.
957 message_latch.Wait();
958
959 // Post a task to the platform_thread that runs after the platform isolate's
960 // entry point and all messages, and wait for it to run.
961 fml::AutoResetWaitableEvent epilogue_latch;
963 platform_thread, fml::MakeCopyable([&epilogue_latch]() mutable {
964 epilogue_latch.Signal();
965 }));
966 epilogue_latch.Wait();
967
968 // root isolate will be auto-shutdown
969}
970
971TEST_F(DartIsolateTest, PlatformIsolateCreationAfterManagerShutdown) {
972 AddNativeCallback("PassMessage",
975
977 auto platform_configuration =
978 std::make_unique<PlatformConfiguration>(&client);
979
980 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
981 auto settings = CreateSettingsForFixture();
982 auto vm_ref = DartVMRef::Create(settings);
983 ASSERT_TRUE(vm_ref);
984 auto vm_data = vm_ref.GetVMData();
985 ASSERT_TRUE(vm_data);
986
987 auto platform_thread = CreateNewThread();
988 auto ui_thread = CreateNewThread();
989 TaskRunners task_runners(GetCurrentTestName(), // label
990 platform_thread, // platform
991 ui_thread, // raster
992 ui_thread, // ui
993 ui_thread // io
994 );
995 auto isolate =
996 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
997 GetDefaultKernelFilePath(), {}, nullptr,
998 std::move(platform_configuration));
999 ASSERT_TRUE(isolate);
1000 auto root_isolate = isolate->get();
1001 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
1002
1003 // Shut down the manager on the platform thread.
1004 fml::AutoResetWaitableEvent manager_shutdown_latch;
1006 platform_thread,
1007 fml::MakeCopyable([&manager_shutdown_latch, &client]() mutable {
1008 client.mgr->ShutdownPlatformIsolates();
1009 manager_shutdown_latch.Signal();
1010 }));
1011 manager_shutdown_latch.Wait();
1012
1013 fml::AutoResetWaitableEvent ui_thread_latch;
1015 ui_thread, fml::MakeCopyable([&]() mutable {
1016 ASSERT_TRUE(isolate->RunInIsolateScope([root_isolate]() {
1017 Dart_Handle lib = Dart_RootLibrary();
1018 Dart_Handle entry_point =
1019 Dart_GetField(lib, tonic::ToDart("mainForPlatformIsolates"));
1020 char* error = nullptr;
1021 Dart_Isolate platform_isolate =
1022 root_isolate->CreatePlatformIsolate(entry_point, &error);
1023
1024 // Failed to create a platform isolate, but we've still re-entered the
1025 // root isolate.
1026 EXPECT_FALSE(error);
1027 EXPECT_FALSE(platform_isolate);
1028 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
1029
1030 return true;
1031 }));
1032 ui_thread_latch.Signal();
1033 }));
1034 ui_thread_latch.Wait();
1035
1036 // root isolate will be auto-shutdown
1037}
1038
1039TEST_F(DartIsolateTest, PlatformIsolateManagerShutdownBeforeMainRuns) {
1040 AddNativeCallback("PassMessage",
1043
1045 auto platform_configuration =
1046 std::make_unique<PlatformConfiguration>(&client);
1047
1048 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
1049 auto settings = CreateSettingsForFixture();
1050 auto vm_ref = DartVMRef::Create(settings);
1051 ASSERT_TRUE(vm_ref);
1052 auto vm_data = vm_ref.GetVMData();
1053 ASSERT_TRUE(vm_data);
1054
1055 auto platform_thread = CreateNewThread();
1056 auto ui_thread = CreateNewThread();
1057 TaskRunners task_runners(GetCurrentTestName(), // label
1058 platform_thread, // platform
1059 ui_thread, // raster
1060 ui_thread, // ui
1061 ui_thread // io
1062 );
1063 auto isolate =
1064 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
1065 GetDefaultKernelFilePath(), {}, nullptr,
1066 std::move(platform_configuration));
1067 ASSERT_TRUE(isolate);
1068 auto root_isolate = isolate->get();
1069 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
1070
1071 Dart_Isolate platform_isolate = nullptr;
1072
1073 // Post a task to the platform_thread that just waits, to delay execution of
1074 // the platform isolate until we're ready, and shutdown the manager just
1075 // before it runs.
1076 fml::AutoResetWaitableEvent platform_thread_latch;
1078 platform_thread, fml::MakeCopyable([&platform_thread_latch, &client,
1079 &platform_isolate]() mutable {
1080 platform_thread_latch.Wait();
1081 client.mgr->ShutdownPlatformIsolates();
1082 EXPECT_TRUE(platform_isolate);
1083 EXPECT_FALSE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1084 }));
1085
1086 fml::AutoResetWaitableEvent ui_thread_latch;
1088 ui_thread, fml::MakeCopyable([&]() mutable {
1089 ASSERT_TRUE(
1090 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
1091 Dart_Handle lib = Dart_RootLibrary();
1092 Dart_Handle entry_point =
1093 Dart_GetField(lib, tonic::ToDart("mainForPlatformIsolates"));
1094 char* error = nullptr;
1095 platform_isolate =
1096 root_isolate->CreatePlatformIsolate(entry_point, &error);
1097
1098 EXPECT_FALSE(error);
1099 EXPECT_TRUE(platform_isolate);
1100 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
1101
1102 return true;
1103 }));
1104 ui_thread_latch.Signal();
1105 }));
1106 ui_thread_latch.Wait();
1107 ASSERT_TRUE(platform_isolate);
1108 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1109
1110 // Allow the platform isolate to run, but its main is never run.
1111 platform_thread_latch.Signal();
1112
1113 // Post a task to the platform_thread that runs after the platform isolate's
1114 // entry point, and wait for it to run.
1115 fml::AutoResetWaitableEvent epilogue_latch;
1117 platform_thread, fml::MakeCopyable([&epilogue_latch]() mutable {
1118 epilogue_latch.Signal();
1119 }));
1120 epilogue_latch.Wait();
1121
1122 // root isolate will be auto-shutdown
1123}
1124
1125TEST_F(DartIsolateTest, PlatformIsolateMainThrowsError) {
1126 AddNativeCallback("PassMessage",
1129
1131 auto platform_configuration =
1132 std::make_unique<PlatformConfiguration>(&client);
1133
1134 ASSERT_FALSE(DartVMRef::IsInstanceRunning());
1135 auto settings = CreateSettingsForFixture();
1136 auto vm_ref = DartVMRef::Create(settings);
1137 ASSERT_TRUE(vm_ref);
1138 auto vm_data = vm_ref.GetVMData();
1139 ASSERT_TRUE(vm_data);
1140
1141 auto platform_thread = CreateNewThread();
1142 auto ui_thread = CreateNewThread();
1143 TaskRunners task_runners(GetCurrentTestName(), // label
1144 platform_thread, // platform
1145 ui_thread, // raster
1146 ui_thread, // ui
1147 ui_thread // io
1148 );
1149 auto isolate =
1150 RunDartCodeInIsolate(vm_ref, settings, task_runners, "emptyMain", {},
1151 GetDefaultKernelFilePath(), {}, nullptr,
1152 std::move(platform_configuration));
1153 ASSERT_TRUE(isolate);
1154 auto root_isolate = isolate->get();
1155 ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
1156
1157 Dart_Isolate platform_isolate = nullptr;
1158 fml::AutoResetWaitableEvent ui_thread_latch;
1160 ui_thread, fml::MakeCopyable([&]() mutable {
1161 ASSERT_TRUE(
1162 isolate->RunInIsolateScope([root_isolate, &platform_isolate]() {
1163 Dart_Handle lib = Dart_RootLibrary();
1164 Dart_Handle entry_point = Dart_GetField(
1165 lib, tonic::ToDart("mainForPlatformIsolatesThrowError"));
1166 char* error = nullptr;
1167 platform_isolate =
1168 root_isolate->CreatePlatformIsolate(entry_point, &error);
1169
1170 EXPECT_FALSE(error);
1171 EXPECT_TRUE(platform_isolate);
1172 EXPECT_EQ(Dart_CurrentIsolate(), root_isolate->isolate());
1173
1174 return true;
1175 }));
1176 ui_thread_latch.Signal();
1177 }));
1178 ui_thread_latch.Wait();
1179 ASSERT_TRUE(platform_isolate);
1180 EXPECT_TRUE(client.mgr->IsRegisteredForTestingOnly(platform_isolate));
1181
1182 // Post a task to the platform_thread that runs after the platform isolate's
1183 // entry point, and wait for it to run.
1184 fml::AutoResetWaitableEvent epilogue_latch;
1186 platform_thread, fml::MakeCopyable([&epilogue_latch]() mutable {
1187 epilogue_latch.Signal();
1188 }));
1189 epilogue_latch.Wait();
1190
1191 // root isolate will be auto-shutdown
1192}
1193
1194} // namespace testing
1195} // namespace flutter
1196
1197// 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)
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.
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 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 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 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...
void UpdateSemantics(SemanticsUpdate *update) override
Receives an updated semantics tree from the Framework.
Tests error handling path of Isolate.spawn() in the engine.
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
DART_EXPORT void Dart_ShutdownIsolate(void)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition dart_api.h:3010
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj, bool *value)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
TEST_F(FlGnomeSettingsTest, ClockFormat)
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
#define FML_UNREACHABLE()
Definition logging.h:109
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
const char * name
Definition fuchsia.cc:50
Win32Message message
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:15
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:19
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::shared_ptr< VolatilePathTracker > volatile_path_tracker, std::unique_ptr< PlatformConfiguration > platform_configuration)
std::vector< std::unique_ptr< const fml::Mapping > > Mappings
Definition settings.h:94
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)
#define EXPECT_TRUE(handle)
Definition unit_test.h:685