Flutter Engine
dart_isolate.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/runtime/dart_isolate.h"
6 
7 #include <cstdlib>
8 #include <tuple>
9 
10 #include "flutter/fml/paths.h"
11 #include "flutter/fml/posix_wrappers.h"
12 #include "flutter/fml/trace_event.h"
13 #include "flutter/lib/io/dart_io.h"
14 #include "flutter/lib/ui/dart_runtime_hooks.h"
15 #include "flutter/lib/ui/dart_ui.h"
16 #include "flutter/runtime/dart_isolate_group_data.h"
17 #include "flutter/runtime/dart_service_isolate.h"
18 #include "flutter/runtime/dart_vm.h"
19 #include "flutter/runtime/dart_vm_lifecycle.h"
20 #include "flutter/runtime/isolate_configuration.h"
22 #include "fml/task_source.h"
23 #include "fml/time/time_point.h"
24 #include "third_party/dart/runtime/include/dart_api.h"
25 #include "third_party/dart/runtime/include/dart_tools_api.h"
35 
36 namespace flutter {
37 
38 namespace {
39 
40 constexpr std::string_view kFileUriPrefix = "file://";
41 
42 class DartErrorString {
43  public:
44  DartErrorString() : str_(nullptr) {}
45  ~DartErrorString() {
46  if (str_) {
47  ::free(str_);
48  }
49  }
50  char** error() { return &str_; }
51  const char* str() const { return str_; }
52  explicit operator bool() const { return str_ != nullptr; }
53 
54  private:
55  FML_DISALLOW_COPY_AND_ASSIGN(DartErrorString);
56  char* str_;
57 };
58 
59 } // anonymous namespace
60 
62 
63 DartIsolate::Flags::Flags(const Dart_IsolateFlags* flags) {
64  if (flags) {
65  flags_ = *flags;
66  } else {
67  ::Dart_IsolateFlagsInitialize(&flags_);
68  }
69 }
70 
71 DartIsolate::Flags::~Flags() = default;
72 
74  flags_.null_safety = enabled;
75 }
76 
77 Dart_IsolateFlags DartIsolate::Flags::Get() const {
78  return flags_;
79 }
80 
81 std::weak_ptr<DartIsolate> DartIsolate::SpawnIsolate(
82  const Settings& settings,
83  std::unique_ptr<PlatformConfiguration> platform_configuration,
84  fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
85  std::string advisory_script_uri,
86  std::string advisory_script_entrypoint,
87  Flags flags,
88  const fml::closure& isolate_create_callback,
89  const fml::closure& isolate_shutdown_callback,
90  std::optional<std::string> dart_entrypoint,
91  std::optional<std::string> dart_entrypoint_library,
92  std::unique_ptr<IsolateConfiguration> isolate_configration) const {
94  settings, //
95  GetIsolateGroupData().GetIsolateSnapshot(), //
96  std::move(platform_configuration), //
97  flags, //
98  isolate_create_callback, //
99  isolate_shutdown_callback, //
100  dart_entrypoint, //
101  dart_entrypoint_library, //
102  std::move(isolate_configration), //
104  snapshot_delegate, //
105  GetIOManager(), //
106  GetSkiaUnrefQueue(), //
107  GetImageDecoder(), //
109  advisory_script_uri, //
110  advisory_script_entrypoint, //
112  this //
113  );
114 }
115 
116 std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
117  const Settings& settings,
118  fml::RefPtr<const DartSnapshot> isolate_snapshot,
119  std::unique_ptr<PlatformConfiguration> platform_configuration,
120  Flags isolate_flags,
121  const fml::closure& isolate_create_callback,
122  const fml::closure& isolate_shutdown_callback,
123  std::optional<std::string> dart_entrypoint,
124  std::optional<std::string> dart_entrypoint_library,
125  std::unique_ptr<IsolateConfiguration> isolate_configration,
126  const UIDartState::Context& context,
127  const DartIsolate* spawning_isolate) {
128  if (!isolate_snapshot) {
129  FML_LOG(ERROR) << "Invalid isolate snapshot.";
130  return {};
131  }
132 
133  if (!isolate_configration) {
134  FML_LOG(ERROR) << "Invalid isolate configuration.";
135  return {};
136  }
137 
138  isolate_flags.SetNullSafetyEnabled(
139  isolate_configration->IsNullSafetyEnabled(*isolate_snapshot));
140 
141  auto isolate = CreateRootIsolate(settings, //
142  isolate_snapshot, //
143  std::move(platform_configuration), //
144  isolate_flags, //
145  isolate_create_callback, //
146  isolate_shutdown_callback, //
147  context, //
148  spawning_isolate //
149  )
150  .lock();
151 
152  if (!isolate) {
153  FML_LOG(ERROR) << "Could not create root isolate.";
154  return {};
155  }
156 
157  fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
158  if (!isolate->Shutdown()) {
159  FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
160  }
161  });
162 
163  if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
164  FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
165  << static_cast<int>(isolate->GetPhase());
166  return {};
167  }
168 
169  if (!isolate_configration->PrepareIsolate(*isolate.get())) {
170  FML_LOG(ERROR) << "Could not prepare isolate.";
171  return {};
172  }
173 
174  if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
175  FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
176  "invocation.";
177  return {};
178  }
179 
180  if (settings.root_isolate_create_callback) {
181  // Isolate callbacks always occur in isolate scope and before user code has
182  // had a chance to run.
183  tonic::DartState::Scope scope(isolate.get());
184  settings.root_isolate_create_callback(*isolate.get());
185  }
186 
187  if (!isolate->RunFromLibrary(dart_entrypoint_library, //
188  dart_entrypoint, //
189  settings.dart_entrypoint_args //
190  )) {
191  FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
192  return {};
193  }
194 
195  if (settings.root_isolate_shutdown_callback) {
196  isolate->AddIsolateShutdownCallback(
198  }
199 
200  shutdown_on_error.Release();
201 
202  return isolate;
203 }
204 
205 void DartIsolate::SpawnIsolateShutdownCallback(
206  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
207  std::shared_ptr<DartIsolate>* isolate_data) {
208  DartIsolate::DartIsolateShutdownCallback(isolate_group_data, isolate_data);
209 }
210 
211 std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
212  const Settings& settings,
213  fml::RefPtr<const DartSnapshot> isolate_snapshot,
214  std::unique_ptr<PlatformConfiguration> platform_configuration,
215  Flags flags,
216  const fml::closure& isolate_create_callback,
217  const fml::closure& isolate_shutdown_callback,
218  const UIDartState::Context& context,
219  const DartIsolate* spawning_isolate) {
220  TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate");
221 
222  // The child isolate preparer is null but will be set when the isolate is
223  // being prepared to run.
224  auto isolate_group_data =
225  std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
226  std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
227  settings, // settings
228  std::move(isolate_snapshot), // isolate snapshot
229  context.advisory_script_uri, // advisory URI
230  context.advisory_script_entrypoint, // advisory entrypoint
231  nullptr, // child isolate preparer
232  isolate_create_callback, // isolate create callback
233  isolate_shutdown_callback // isolate shutdown callback
234  )));
235 
236  auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
237  std::shared_ptr<DartIsolate>(new DartIsolate(
238  settings, // settings
239  true, // is_root_isolate
240  std::move(context) // context
241  )));
242 
243  DartErrorString error;
244  Dart_Isolate vm_isolate = nullptr;
245  auto isolate_flags = flags.Get();
246 
247  IsolateMaker isolate_maker;
248  // TODO(74520): Remove IsRunningPrecompiledCode conditional once isolate
249  // groups are supported by JIT.
250  if (spawning_isolate && DartVM::IsRunningPrecompiledCode()) {
251  isolate_maker = [spawning_isolate](
252  std::shared_ptr<DartIsolateGroupData>*
253  isolate_group_data,
254  std::shared_ptr<DartIsolate>* isolate_data,
255  Dart_IsolateFlags* flags, char** error) {
256  return Dart_CreateIsolateInGroup(
257  /*group_member=*/spawning_isolate->isolate(),
258  /*name=*/(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
259  /*shutdown_callback=*/
260  reinterpret_cast<Dart_IsolateShutdownCallback>(
261  DartIsolate::SpawnIsolateShutdownCallback),
262  /*cleanup_callback=*/
263  reinterpret_cast<Dart_IsolateCleanupCallback>(
264  DartIsolateCleanupCallback),
265  /*child_isolate_data=*/isolate_data,
266  /*error=*/error);
267  };
268  } else {
269  isolate_maker = [](std::shared_ptr<DartIsolateGroupData>*
270  isolate_group_data,
271  std::shared_ptr<DartIsolate>* isolate_data,
272  Dart_IsolateFlags* flags, char** error) {
273  return Dart_CreateIsolateGroup(
274  (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
275  (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
276  (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
277  (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(),
278  flags, isolate_group_data, isolate_data, error);
279  };
280  }
281 
282  vm_isolate = CreateDartIsolateGroup(std::move(isolate_group_data),
283  std::move(isolate_data), &isolate_flags,
284  error.error(), isolate_maker);
285 
286  if (error) {
287  FML_LOG(ERROR) << "CreateRootIsolate failed: " << error.str();
288  }
289 
290  if (vm_isolate == nullptr) {
291  return {};
292  }
293 
294  std::shared_ptr<DartIsolate>* root_isolate_data =
295  static_cast<std::shared_ptr<DartIsolate>*>(Dart_IsolateData(vm_isolate));
296 
297  (*root_isolate_data)
298  ->SetPlatformConfiguration(std::move(platform_configuration));
299 
300  return (*root_isolate_data)->GetWeakIsolatePtr();
301 }
302 
303 DartIsolate::DartIsolate(const Settings& settings,
304  bool is_root_isolate,
305  const UIDartState::Context& context)
306  : UIDartState(settings.task_observer_add,
307  settings.task_observer_remove,
308  settings.log_tag,
310  settings.log_message_callback,
312  is_root_isolate,
313  settings.enable_skparagraph,
314  settings.enable_display_list,
315  std::move(context)),
316  may_insecurely_connect_to_all_domains_(
318  domain_network_policy_(settings.domain_network_policy) {
319  phase_ = Phase::Uninitialized;
320 }
321 
324  FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
325  }
326 }
327 
329  return phase_;
330 }
331 
333  const char* service_id_buf = Dart_IsolateServiceId(isolate());
334  std::string service_id(service_id_buf);
335  free(const_cast<char*>(service_id_buf));
336  return service_id;
337 }
338 
339 bool DartIsolate::Initialize(Dart_Isolate dart_isolate) {
340  TRACE_EVENT0("flutter", "DartIsolate::Initialize");
341  if (phase_ != Phase::Uninitialized) {
342  return false;
343  }
344 
345  if (dart_isolate == nullptr) {
346  return false;
347  }
348 
349  if (Dart_CurrentIsolate() != dart_isolate) {
350  return false;
351  }
352 
353  // After this point, isolate scopes can be safely used.
354  SetIsolate(dart_isolate);
355 
356  // We are entering a new scope (for the first time since initialization) and
357  // we want to restore the current scope to null when we exit out of this
358  // method. This balances the implicit Dart_EnterIsolate call made by
359  // Dart_CreateIsolateGroup (which calls the Initialize).
360  Dart_ExitIsolate();
361 
363 
364  // For the root isolate set the "AppStartUp" as soon as the root isolate
365  // has been initialized. This is to ensure that all the timeline events
366  // that have the set user-tag will be listed user AppStartUp.
367  if (IsRootIsolate()) {
368  tonic::DartApiScope api_scope;
369  Dart_SetCurrentUserTag(Dart_NewUserTag("AppStartUp"));
370  }
371 
372  SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner());
373 
374  if (tonic::LogIfError(
375  Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
376  return false;
377  }
378 
379  if (tonic::LogIfError(Dart_SetDeferredLoadHandler(OnDartLoadLibrary))) {
380  return false;
381  }
382 
383  if (!UpdateThreadPoolNames()) {
384  return false;
385  }
386 
387  phase_ = Phase::Initialized;
388  return true;
389 }
390 
392  return message_handling_task_runner_;
393 }
394 
396  intptr_t loading_unit_id,
397  std::unique_ptr<const fml::Mapping> snapshot_data,
398  std::unique_ptr<const fml::Mapping> snapshot_instructions) {
399  tonic::DartState::Scope scope(this);
400 
401  fml::RefPtr<DartSnapshot> dart_snapshot =
403  std::move(snapshot_data), std::move(snapshot_instructions));
404 
405  Dart_Handle result = Dart_DeferredLoadComplete(
406  loading_unit_id, dart_snapshot->GetDataMapping(),
407  dart_snapshot->GetInstructionsMapping());
408  if (tonic::LogIfError(result)) {
409  LoadLoadingUnitError(loading_unit_id, Dart_GetError(result),
410  /*transient*/ true);
411  return false;
412  }
413  loading_unit_snapshots_.insert(dart_snapshot);
414  return true;
415 }
416 
417 void DartIsolate::LoadLoadingUnitError(intptr_t loading_unit_id,
418  const std::string error_message,
419  bool transient) {
420  tonic::DartState::Scope scope(this);
421  Dart_Handle result = Dart_DeferredLoadCompleteError(
422  loading_unit_id, error_message.c_str(), transient);
423  tonic::LogIfError(result);
424 }
425 
426 void DartIsolate::SetMessageHandlingTaskRunner(
428  if (!IsRootIsolate() || !runner) {
429  return;
430  }
431 
432  message_handling_task_runner_ = runner;
433 
434  message_handler().Initialize([runner](std::function<void()> task) {
435 #ifdef OS_FUCHSIA
436  runner->PostTask([task = std::move(task)]() {
437  TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
438  task();
439  });
440 #else
441  auto task_queues = fml::MessageLoopTaskQueues::GetInstance();
442  task_queues->RegisterTask(
443  runner->GetTaskQueueId(),
444  [task = std::move(task)]() {
445  TRACE_EVENT0("flutter", "DartIsolate::HandleMessage");
446  task();
447  },
449 #endif
450  });
451 }
452 
453 // Updating thread names here does not change the underlying OS thread names.
454 // Instead, this is just additional metadata for the Observatory to show the
455 // thread name of the isolate.
456 bool DartIsolate::UpdateThreadPoolNames() const {
457  // TODO(chinmaygarde): This implementation does not account for multiple
458  // shells sharing the same (or subset of) threads.
459  const auto& task_runners = GetTaskRunners();
460 
461  if (auto task_runner = task_runners.GetRasterTaskRunner()) {
462  task_runner->PostTask(
463  [label = task_runners.GetLabel() + std::string{".raster"}]() {
464  Dart_SetThreadName(label.c_str());
465  });
466  }
467 
468  if (auto task_runner = task_runners.GetUITaskRunner()) {
469  task_runner->PostTask(
470  [label = task_runners.GetLabel() + std::string{".ui"}]() {
471  Dart_SetThreadName(label.c_str());
472  });
473  }
474 
475  if (auto task_runner = task_runners.GetIOTaskRunner()) {
476  task_runner->PostTask(
477  [label = task_runners.GetLabel() + std::string{".io"}]() {
478  Dart_SetThreadName(label.c_str());
479  });
480  }
481 
482  if (auto task_runner = task_runners.GetPlatformTaskRunner()) {
483  task_runner->PostTask(
484  [label = task_runners.GetLabel() + std::string{".platform"}]() {
485  Dart_SetThreadName(label.c_str());
486  });
487  }
488 
489  return true;
490 }
491 
492 bool DartIsolate::LoadLibraries() {
493  TRACE_EVENT0("flutter", "DartIsolate::LoadLibraries");
494  if (phase_ != Phase::Initialized) {
495  return false;
496  }
497 
498  tonic::DartState::Scope scope(this);
499 
500  DartIO::InitForIsolate(may_insecurely_connect_to_all_domains_,
501  domain_network_policy_);
502 
504 
505  const bool is_service_isolate = Dart_IsServiceIsolate(isolate());
506 
507  DartRuntimeHooks::Install(IsRootIsolate() && !is_service_isolate,
509 
510  if (!is_service_isolate) {
512  "ui", std::make_unique<tonic::DartClassProvider>(this, "dart:ui"));
513  }
514 
515  phase_ = Phase::LibrariesSetup;
516  return true;
517 }
518 
520  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
521  if (phase_ != Phase::LibrariesSetup) {
522  return false;
523  }
524 
525  tonic::DartState::Scope scope(this);
526 
527  if (Dart_IsNull(Dart_RootLibrary())) {
528  return false;
529  }
530 
531  if (!MarkIsolateRunnable()) {
532  return false;
533  }
534 
535  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
536  GetIsolateGroupData().SetChildIsolatePreparer([](DartIsolate* isolate) {
537  return isolate->PrepareForRunningFromPrecompiledCode();
538  });
539  }
540 
541  const fml::closure& isolate_create_callback =
542  GetIsolateGroupData().GetIsolateCreateCallback();
543  if (isolate_create_callback) {
544  isolate_create_callback();
545  }
546 
547  phase_ = Phase::Ready;
548  return true;
549 }
550 
551 bool DartIsolate::LoadKernel(std::shared_ptr<const fml::Mapping> mapping,
552  bool last_piece) {
553  if (!Dart_IsKernel(mapping->GetMapping(), mapping->GetSize())) {
554  return false;
555  }
556 
557  // Mapping must be retained until isolate shutdown.
558  kernel_buffers_.push_back(mapping);
559 
560  Dart_Handle library =
561  Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
562  if (tonic::LogIfError(library)) {
563  return false;
564  }
565 
566  if (!last_piece) {
567  // More to come.
568  return true;
569  }
570 
571  Dart_SetRootLibrary(library);
572  if (tonic::LogIfError(Dart_FinalizeLoading(false))) {
573  return false;
574  }
575  return true;
576 }
577 
579  std::shared_ptr<const fml::Mapping> mapping,
580  bool child_isolate,
581  bool last_piece) {
582  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
583  if (phase_ != Phase::LibrariesSetup) {
584  return false;
585  }
586 
588  return false;
589  }
590 
591  if (!mapping || mapping->GetSize() == 0) {
592  return false;
593  }
594 
595  tonic::DartState::Scope scope(this);
596 
597  if (!child_isolate || !Dart_IsVMFlagSet("--enable-isolate-groups")) {
598  // Use root library provided by kernel in favor of one provided by snapshot.
599  Dart_SetRootLibrary(Dart_Null());
600 
601  if (!LoadKernel(mapping, last_piece)) {
602  return false;
603  }
604  }
605 
606  if (!last_piece) {
607  // More to come.
608  return true;
609  }
610 
611  if (Dart_IsNull(Dart_RootLibrary())) {
612  return false;
613  }
614 
615  if (!MarkIsolateRunnable()) {
616  return false;
617  }
618 
619  // Child isolate shares root isolate embedder_isolate (lines 691 and 693
620  // below). Re-initializing child_isolate_preparer_ lambda while it is being
621  // executed leads to crashes.
622  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
623  GetIsolateGroupData().SetChildIsolatePreparer(
624  [buffers = kernel_buffers_](DartIsolate* isolate) {
625  for (uint64_t i = 0; i < buffers.size(); i++) {
626  bool last_piece = i + 1 == buffers.size();
627  const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
628  if (!isolate->PrepareForRunningFromKernel(buffer,
629  /*child_isolate=*/true,
630  last_piece)) {
631  return false;
632  }
633  }
634  return true;
635  });
636  }
637 
638  const fml::closure& isolate_create_callback =
639  GetIsolateGroupData().GetIsolateCreateCallback();
640  if (isolate_create_callback) {
641  isolate_create_callback();
642  }
643 
644  phase_ = Phase::Ready;
645 
646  return true;
647 }
648 
650  std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
651  const auto count = kernels.size();
652  if (count == 0) {
653  return false;
654  }
655 
656  for (size_t i = 0; i < count; ++i) {
657  bool last = (i == (count - 1));
658  if (!PrepareForRunningFromKernel(kernels[i], /*child_isolate=*/false,
659  last)) {
660  return false;
661  }
662  }
663 
664  return true;
665 }
666 
668  std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
669  std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
670  for (auto& kernel : kernels) {
671  shared_kernels.emplace_back(std::move(kernel));
672  }
673  return PrepareForRunningFromKernels(shared_kernels);
674 }
675 
676 bool DartIsolate::MarkIsolateRunnable() {
677  TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
678  if (phase_ != Phase::LibrariesSetup) {
679  return false;
680  }
681 
682  // This function may only be called from an active isolate scope.
683  if (Dart_CurrentIsolate() != isolate()) {
684  return false;
685  }
686 
687  // There must be no current isolate to mark an isolate as being runnable.
688  Dart_ExitIsolate();
689 
690  char* error = Dart_IsolateMakeRunnable(isolate());
691  if (error) {
692  FML_DLOG(ERROR) << error;
693  ::free(error);
694  // Failed. Restore the isolate.
695  Dart_EnterIsolate(isolate());
696  return false;
697  }
698  // Success. Restore the isolate.
699  Dart_EnterIsolate(isolate());
700  return true;
701 }
702 
703 [[nodiscard]] static bool InvokeMainEntrypoint(
704  Dart_Handle user_entrypoint_function,
705  Dart_Handle args) {
706  if (tonic::LogIfError(user_entrypoint_function)) {
707  FML_LOG(ERROR) << "Could not resolve main entrypoint function.";
708  return false;
709  }
710 
711  Dart_Handle start_main_isolate_function =
712  tonic::DartInvokeField(Dart_LookupLibrary(tonic::ToDart("dart:isolate")),
713  "_getStartMainIsolateFunction", {});
714 
715  if (tonic::LogIfError(start_main_isolate_function)) {
716  FML_LOG(ERROR) << "Could not resolve main entrypoint trampoline.";
717  return false;
718  }
719 
721  Dart_LookupLibrary(tonic::ToDart("dart:ui")), "_runMainZoned",
722  {start_main_isolate_function, user_entrypoint_function, args}))) {
723  FML_LOG(ERROR) << "Could not invoke the main entrypoint.";
724  return false;
725  }
726 
727  return true;
728 }
729 
730 static void InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle) {
731  TRACE_EVENT0("flutter", "InvokeDartPluginRegistrantIfAvailable");
732 
733  // The Dart plugin registrant is a static method with signature `void
734  // register()` within the class `_PluginRegistrant` generated by the Flutter
735  // tool.
736  //
737  // This method binds a plugin implementation to their platform
738  // interface based on the configuration of the app's pubpec.yaml, and the
739  // plugin's pubspec.yaml.
740  //
741  // Since this method may or may not be defined, check if the class is defined
742  // in the default library before calling the method.
743  Dart_Handle plugin_registrant =
744  ::Dart_GetClass(library_handle, tonic::ToDart("_PluginRegistrant"));
745 
746  if (Dart_IsError(plugin_registrant)) {
747  return;
748  }
749  tonic::LogIfError(tonic::DartInvokeField(plugin_registrant, "register", {}));
750 }
751 
752 bool DartIsolate::RunFromLibrary(std::optional<std::string> library_name,
753  std::optional<std::string> entrypoint,
754  const std::vector<std::string>& args) {
755  TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
756  if (phase_ != Phase::Ready) {
757  return false;
758  }
759 
760  tonic::DartState::Scope scope(this);
761 
762  auto library_handle =
763  library_name.has_value() && !library_name.value().empty()
764  ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
765  : ::Dart_RootLibrary();
766  auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
767  ? tonic::ToDart(entrypoint.value().c_str())
768  : tonic::ToDart("main");
769 
771 
772  auto user_entrypoint_function =
773  ::Dart_GetField(library_handle, entrypoint_handle);
774 
775  auto entrypoint_args = tonic::ToDart(args);
776 
777  if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
778  return false;
779  }
780 
781  phase_ = Phase::Running;
782 
783  return true;
784 }
785 
787  TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
788  // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
789  // cleanup callback which deletes the embedder side object of the dart isolate
790  // (a.k.a. this).
791  if (phase_ == Phase::Shutdown) {
792  return false;
793  }
794  phase_ = Phase::Shutdown;
795  Dart_Isolate vm_isolate = isolate();
796  // The isolate can be nullptr if this instance is the stub isolate data used
797  // during root isolate creation.
798  if (vm_isolate != nullptr) {
799  // We need to enter the isolate because Dart_ShutdownIsolate does not take
800  // the isolate to shutdown as a parameter.
801  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
802  Dart_EnterIsolate(vm_isolate);
803  Dart_ShutdownIsolate();
804  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
805  }
806  return true;
807 }
808 
809 Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
810  const char* package_root,
811  const char* package_config,
812  Dart_IsolateFlags* flags,
813  char** error) {
814  auto vm_data = DartVMRef::GetVMData();
815 
816  if (!vm_data) {
817  *error = fml::strdup(
818  "Could not access VM data to initialize isolates. This may be because "
819  "the VM has initialized shutdown on another thread already.");
820  return nullptr;
821  }
822 
823  const auto& settings = vm_data->GetSettings();
824 
825  if (!settings.enable_observatory) {
826  return nullptr;
827  }
828 
829  flags->load_vmservice_library = true;
830 
831 #if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
832  // TODO(68663): The service isolate in debug mode is always launched without
833  // sound null safety. Fix after the isolate snapshot data is created with the
834  // right flags.
835  flags->null_safety =
836  vm_data->GetIsolateSnapshot()->IsNullSafetyEnabled(nullptr);
837 #endif
838 
839  UIDartState::Context context(
840  TaskRunners("io.flutter." DART_VM_SERVICE_ISOLATE_NAME, nullptr, nullptr,
841  nullptr, nullptr));
842  context.advisory_script_uri = DART_VM_SERVICE_ISOLATE_NAME;
843  context.advisory_script_entrypoint = DART_VM_SERVICE_ISOLATE_NAME;
844  std::weak_ptr<DartIsolate> weak_service_isolate =
845  DartIsolate::CreateRootIsolate(vm_data->GetSettings(), //
846  vm_data->GetIsolateSnapshot(), //
847  nullptr, //
848  DartIsolate::Flags{flags}, //
849  nullptr, //
850  nullptr, //
851  context); //
852 
853  std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
854  if (!service_isolate) {
855  *error = fml::strdup("Could not create the service isolate.");
856  FML_DLOG(ERROR) << *error;
857  return nullptr;
858  }
859 
860  tonic::DartState::Scope scope(service_isolate);
862  settings.observatory_host, // server IP address
863  settings.observatory_port, // server observatory port
864  tonic::DartState::HandleLibraryTag, // embedder library tag handler
865  false, // disable websocket origin check
866  settings.disable_service_auth_codes, // disable VM service auth codes
867  settings.enable_service_port_fallback, // enable fallback to port 0
868  // when bind fails.
869  error // error (out)
870  )) {
871  // Error is populated by call to startup.
872  FML_DLOG(ERROR) << *error;
873  return nullptr;
874  }
875 
876  if (auto callback = vm_data->GetSettings().service_isolate_create_callback) {
877  callback();
878  }
879 
880  if (auto service_protocol = DartVMRef::GetServiceProtocol()) {
881  service_protocol->ToggleHooks(true);
882  } else {
883  FML_DLOG(ERROR)
884  << "Could not acquire the service protocol handlers. This might be "
885  "because the VM has already begun teardown on another thread.";
886  }
887 
888  return service_isolate->isolate();
889 }
890 
891 DartIsolateGroupData& DartIsolate::GetIsolateGroupData() {
892  std::shared_ptr<DartIsolateGroupData>* isolate_group_data =
893  static_cast<std::shared_ptr<DartIsolateGroupData>*>(
894  Dart_IsolateGroupData(isolate()));
895  return **isolate_group_data;
896 }
897 
898 const DartIsolateGroupData& DartIsolate::GetIsolateGroupData() const {
899  DartIsolate* non_const_this = const_cast<DartIsolate*>(this);
900  return non_const_this->GetIsolateGroupData();
901 }
902 
903 // |Dart_IsolateGroupCreateCallback|
904 Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
905  const char* advisory_script_uri,
906  const char* advisory_script_entrypoint,
907  const char* package_root,
908  const char* package_config,
909  Dart_IsolateFlags* flags,
910  std::shared_ptr<DartIsolate>* parent_isolate_data,
911  char** error) {
912  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCreateCallback");
913  if (parent_isolate_data == nullptr &&
914  strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
915  // The VM attempts to start the VM service for us on |Dart_Initialize|. In
916  // such a case, the callback data will be null and the script URI will be
917  // DART_VM_SERVICE_ISOLATE_NAME. In such cases, we just create the service
918  // isolate like normal but dont hold a reference to it at all. We also start
919  // this isolate since we will never again reference it from the engine.
920  return DartCreateAndStartServiceIsolate(package_root, //
921  package_config, //
922  flags, //
923  error //
924  );
925  }
926 
927  if (!parent_isolate_data) {
928  return nullptr;
929  }
930 
931  DartIsolateGroupData& parent_group_data =
932  (*parent_isolate_data)->GetIsolateGroupData();
933 
934  if (strncmp(advisory_script_uri, kFileUriPrefix.data(),
935  kFileUriPrefix.size())) {
936  std::string error_msg =
937  std::string("Unsupported isolate URI: ") + advisory_script_uri;
938  *error = fml::strdup(error_msg.c_str());
939  return nullptr;
940  }
941 
942  auto isolate_group_data =
943  std::make_unique<std::shared_ptr<DartIsolateGroupData>>(
944  std::shared_ptr<DartIsolateGroupData>(new DartIsolateGroupData(
945  parent_group_data.GetSettings(),
946  parent_group_data.GetIsolateSnapshot(), advisory_script_uri,
947  advisory_script_entrypoint,
948  parent_group_data.GetChildIsolatePreparer(),
949  parent_group_data.GetIsolateCreateCallback(),
950  parent_group_data.GetIsolateShutdownCallback())));
951 
952  TaskRunners null_task_runners(advisory_script_uri,
953  /* platform= */ nullptr,
954  /* raster= */ nullptr,
955  /* ui= */ nullptr,
956  /* io= */ nullptr);
957 
958  UIDartState::Context context(null_task_runners);
959  context.advisory_script_uri = advisory_script_uri;
960  context.advisory_script_entrypoint = advisory_script_entrypoint;
961  auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
962  std::shared_ptr<DartIsolate>(
963  new DartIsolate((*isolate_group_data)->GetSettings(), // settings
964  false, // is_root_isolate
965  context))); // context
966 
967  Dart_Isolate vm_isolate = CreateDartIsolateGroup(
968  std::move(isolate_group_data), std::move(isolate_data), flags, error,
969  [](std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
970  std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
971  char** error) {
972  return Dart_CreateIsolateGroup(
973  (*isolate_group_data)->GetAdvisoryScriptURI().c_str(),
974  (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
975  (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(),
976  (*isolate_group_data)
977  ->GetIsolateSnapshot()
978  ->GetInstructionsMapping(),
979  flags, isolate_group_data, isolate_data, error);
980  });
981 
982  if (*error) {
983  FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error;
984  }
985 
986  return vm_isolate;
987 }
988 
989 // |Dart_IsolateInitializeCallback|
990 bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data,
991  char** error) {
992  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateInitializeCallback");
993  Dart_Isolate isolate = Dart_CurrentIsolate();
994  if (isolate == nullptr) {
995  *error = fml::strdup("Isolate should be available in initialize callback.");
996  FML_DLOG(ERROR) << *error;
997  return false;
998  }
999 
1000  auto* isolate_group_data =
1001  static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1002  Dart_CurrentIsolateGroupData());
1003 
1004  TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(),
1005  /* platform= */ nullptr,
1006  /* raster= */ nullptr,
1007  /* ui= */ nullptr,
1008  /* io= */ nullptr);
1009 
1010  UIDartState::Context context(null_task_runners);
1011  context.advisory_script_uri = (*isolate_group_data)->GetAdvisoryScriptURI();
1012  context.advisory_script_entrypoint =
1013  (*isolate_group_data)->GetAdvisoryScriptEntrypoint();
1014  auto embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
1015  std::shared_ptr<DartIsolate>(
1016  new DartIsolate((*isolate_group_data)->GetSettings(), // settings
1017  false, // is_root_isolate
1018  context))); // context
1019 
1020  // root isolate should have been created via CreateRootIsolate
1021  if (!InitializeIsolate(*embedder_isolate, isolate, error)) {
1022  return false;
1023  }
1024 
1025  // The ownership of the embedder object is controlled by the Dart VM. So the
1026  // only reference returned to the caller is weak.
1027  *child_callback_data = embedder_isolate.release();
1028 
1029  Dart_EnterIsolate(isolate);
1030  return true;
1031 }
1032 
1033 Dart_Isolate DartIsolate::CreateDartIsolateGroup(
1034  std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
1035  std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
1036  Dart_IsolateFlags* flags,
1037  char** error,
1038  const DartIsolate::IsolateMaker& make_isolate) {
1039  TRACE_EVENT0("flutter", "DartIsolate::CreateDartIsolateGroup");
1040 
1041  // Create the Dart VM isolate and give it the embedder object as the baton.
1042  Dart_Isolate isolate =
1043  make_isolate(isolate_group_data.get(), isolate_data.get(), flags, error);
1044 
1045  if (isolate == nullptr) {
1046  return nullptr;
1047  }
1048 
1049  // Ownership of the isolate data objects has been transferred to the Dart VM.
1050  std::shared_ptr<DartIsolate> embedder_isolate(*isolate_data);
1051  isolate_group_data.release();
1052  isolate_data.release();
1053 
1054  if (!InitializeIsolate(std::move(embedder_isolate), isolate, error)) {
1055  return nullptr;
1056  }
1057 
1058  return isolate;
1059 }
1060 
1061 bool DartIsolate::InitializeIsolate(
1062  std::shared_ptr<DartIsolate> embedder_isolate,
1063  Dart_Isolate isolate,
1064  char** error) {
1065  TRACE_EVENT0("flutter", "DartIsolate::InitializeIsolate");
1066  if (!embedder_isolate->Initialize(isolate)) {
1067  *error = fml::strdup("Embedder could not initialize the Dart isolate.");
1068  FML_DLOG(ERROR) << *error;
1069  return false;
1070  }
1071 
1072  if (!embedder_isolate->LoadLibraries()) {
1073  *error = fml::strdup(
1074  "Embedder could not load libraries in the new Dart isolate.");
1075  FML_DLOG(ERROR) << *error;
1076  return false;
1077  }
1078 
1079  // Root isolates will be set up by the engine and the service isolate
1080  // (which is also a root isolate) by the utility routines in the VM.
1081  // However, secondary isolates will be run by the VM if they are
1082  // marked as runnable.
1083  if (!embedder_isolate->IsRootIsolate()) {
1084  auto child_isolate_preparer =
1085  embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer();
1086  FML_DCHECK(child_isolate_preparer);
1087  if (!child_isolate_preparer(embedder_isolate.get())) {
1088  *error = fml::strdup("Could not prepare the child isolate to run.");
1089  FML_DLOG(ERROR) << *error;
1090  return false;
1091  }
1092  }
1093 
1094  return true;
1095 }
1096 
1097 // |Dart_IsolateShutdownCallback|
1098 void DartIsolate::DartIsolateShutdownCallback(
1099  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1100  std::shared_ptr<DartIsolate>* isolate_data) {
1101  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateShutdownCallback");
1102  isolate_data->get()->OnShutdownCallback();
1103 }
1104 
1105 // |Dart_IsolateGroupCleanupCallback|
1106 void DartIsolate::DartIsolateGroupCleanupCallback(
1107  std::shared_ptr<DartIsolateGroupData>* isolate_data) {
1108  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCleanupCallback");
1109  delete isolate_data;
1110 }
1111 
1112 // |Dart_IsolateCleanupCallback|
1113 void DartIsolate::DartIsolateCleanupCallback(
1114  std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
1115  std::shared_ptr<DartIsolate>* isolate_data) {
1116  TRACE_EVENT0("flutter", "DartIsolate::DartIsolateCleanupCallback");
1117  delete isolate_data;
1118 }
1119 
1120 std::weak_ptr<DartIsolate> DartIsolate::GetWeakIsolatePtr() {
1121  return std::static_pointer_cast<DartIsolate>(shared_from_this());
1122 }
1123 
1125  shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1126 }
1127 
1128 void DartIsolate::OnShutdownCallback() {
1130  if (state != nullptr) {
1131  state->SetIsShuttingDown();
1132  }
1133 
1134  {
1135  tonic::DartApiScope api_scope;
1136  Dart_Handle sticky_error = Dart_GetStickyError();
1137  if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
1138  FML_LOG(ERROR) << Dart_GetError(sticky_error);
1139  }
1140  }
1141 
1142  shutdown_callbacks_.clear();
1143 
1144  const fml::closure& isolate_shutdown_callback =
1145  GetIsolateGroupData().GetIsolateShutdownCallback();
1146  if (isolate_shutdown_callback) {
1147  isolate_shutdown_callback();
1148  }
1149 }
1150 
1151 Dart_Handle DartIsolate::OnDartLoadLibrary(intptr_t loading_unit_id) {
1152  if (Current()->platform_configuration()) {
1154  loading_unit_id);
1155  return Dart_Null();
1156  }
1157  const std::string error_message =
1158  "Platform Configuration was null. Deferred library load request"
1159  "for loading unit id " +
1160  std::to_string(loading_unit_id) + " was not sent.";
1161  FML_LOG(ERROR) << error_message;
1162  return Dart_NewApiError(error_message.c_str());
1163 }
1164 
1165 DartIsolate::AutoFireClosure::AutoFireClosure(const fml::closure& closure)
1166  : closure_(closure) {}
1167 
1168 DartIsolate::AutoFireClosure::~AutoFireClosure() {
1169  if (closure_) {
1170  closure_();
1171  }
1172 }
1173 
1174 } // namespace flutter
PlatformConfigurationClient * client() const
Access to the platform configuration client (which typically is implemented by the RuntimeController)...
G_BEGIN_DECLS FlValue * args
ChildIsolatePreparer GetChildIsolatePreparer() const
Phase GetPhase() const
The current phase of the isolate. The engine represents all dart isolates as being in one of the know...
Dart_IsolateFlags Get() const
Definition: dart_isolate.cc:77
void SetIsolate(Dart_Isolate isolate)
Definition: dart_state.cc:35
const fml::closure & GetIsolateShutdownCallback() const
virtual TaskQueueId GetTaskQueueId()
Definition: task_runner.cc:38
void add_provider(const std::string &library_name, std::unique_ptr< DartClassProvider > provider)
static bool Startup(std::string server_ip, intptr_t server_port, Dart_LibraryTagHandler embedder_tag_handler, bool disable_origin_check, bool disable_service_auth_codes, bool enable_service_port_fallback, char **error)
Start the service isolate. This call may only be made in the Dart VM initiated isolate creation callb...
LogMessageCallback log_message_callback
Definition: settings.h:247
Dart_Isolate isolate()
Definition: dart_state.h:50
bool RunFromLibrary(std::optional< std::string > library_name, std::optional< std::string > entrypoint, const std::vector< std::string > &args)
Transition the root isolate to the Phase::Running phase and invoke the main entrypoint (the "main" me...
const uint8_t uint32_t uint32_t GError ** error
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
#define FML_DCHECK(condition)
Definition: logging.h:86
Phase
The engine represents all dart isolates as being in one of the known phases. By invoking various meth...
Definition: dart_isolate.h:92
std::vector< std::string > dart_entrypoint_args
Definition: settings.h:126
std::function< void(const DartIsolate &)> root_isolate_create_callback
Definition: settings.h:216
const Settings & GetSettings() const
constexpr char kFileUriPrefix[]
Definition: dart_vm.cc:124
bool enable_skparagraph
Definition: settings.h:189
static std::shared_ptr< ServiceProtocol > GetServiceProtocol()
uint32_t observatory_port
Definition: settings.h:171
static void Install(bool is_ui_isolate, const std::string &script_uri)
Dart_NativeFunction function
Definition: fuchsia.cc:51
static DartState * Current()
Definition: dart_state.cc:56
GAsyncResult * result
bool PrepareForRunningFromKernel(std::shared_ptr< const fml::Mapping > kernel, bool child_isolate, bool last_piece)
Prepare the isolate for running for a a list of kernel files.
static std::shared_ptr< const DartVMData > GetVMData()
#define FML_LOG(severity)
Definition: logging.h:65
static void InitForIsolate()
Definition: dart_ui.cc:90
fml::WeakPtr< ImageGeneratorRegistry > GetImageGeneratorRegistry() const
FlKeyEvent FlKeyResponderAsyncCallback callback
Dart_Handle DartInvokeField(Dart_Handle target, const char *name, std::initializer_list< Dart_Handle > args)
Definition: dart_invoke.cc:12
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id)=0
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
void SetNullSafetyEnabled(bool enabled)
Definition: dart_isolate.cc:73
UnhandledExceptionCallback unhandled_exception_callback
Definition: settings.h:242
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
std::function< void()> closure
Definition: closure.h:14
void AddIsolateShutdownCallback(const fml::closure &closure)
Registers a callback that will be invoked in isolate scope just before the isolate transitions to the...
fml::closure root_isolate_shutdown_callback
Definition: settings.h:222
bool IsRootIsolate() const
Definition: ui_dart_state.h:96
std::weak_ptr< DartIsolate > SpawnIsolate(const Settings &settings, std::unique_ptr< PlatformConfiguration > platform_configuration, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, std::string advisory_script_uri, std::string advisory_script_entrypoint, Flags flags, 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, std::unique_ptr< IsolateConfiguration > isolate_configration) const
Creates a running DartIsolate who shares as many resources as possible with the caller DartIsolate...
Definition: dart_isolate.cc:81
static fml::RefPtr< MessageLoopTaskQueues > GetInstance()
std::string domain_network_policy
Definition: settings.h:146
static void InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
Definition: dart_state.cc:79
DartClassLibrary & class_library()
Definition: dart_state.h:59
Represents an instance of a live isolate. An isolate is a separate Dart execution context...
Definition: dart_isolate.h:62
static std::shared_ptr< IsolateNameServer > GetIsolateNameServer()
bool enable_display_list
Definition: settings.h:192
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition: dart_vm.cc:202
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
Definition: ui_dart_state.h:43
PlatformConfiguration * platform_configuration() const
std::string observatory_host
Definition: settings.h:166
TaskObserverAdd task_observer_add
Definition: settings.h:212
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)
std::string GetServiceId()
Returns the ID for an isolate which is used to query the service protocol.
std::string advisory_script_entrypoint
Definition: ui_dart_state.h:88
bool disable_service_auth_codes
Definition: settings.h:175
bool LoadLoadingUnit(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
fml::RefPtr< flutter::SkiaUnrefQueue > GetSkiaUnrefQueue() const
const std::string & GetAdvisoryScriptURI() const
bool enable_observatory
Definition: settings.h:158
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, 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, std::unique_ptr< IsolateConfiguration > isolate_configration, 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...
UIDartState(TaskObserverAdd add_callback, TaskObserverRemove remove_callback, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, LogMessageCallback log_message_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_, bool enable_skparagraph, bool enable_display_list, const UIDartState::Context &context)
void Initialize(TaskDispatcher dispatcher)
fml::WeakPtr< ImageDecoder > GetImageDecoder() const
fml::WeakPtr< IOManager > GetIOManager() const
const fml::closure & GetIsolateCreateCallback() const
static const uint8_t buffer[]
bool may_insecurely_connect_to_all_domains
Definition: settings.h:144
const TaskRunners & GetTaskRunners() const
static void InitForIsolate(bool may_insecurely_connect_to_all_domains, std::string domain_network_policy)
Definition: dart_io.cc:18
#define FML_DLOG(severity)
Definition: logging.h:85
char * strdup(const char *str1)
fml::RefPtr< fml::TaskRunner > GetMessageHandlingTaskRunner() const
The task runner on which the Dart code for the root isolate is running. For the root isolate...
Dart_Handle ToDart(const T &object)
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
TaskObserverRemove task_observer_remove
Definition: settings.h:213
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
bool Shutdown()
Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isol...
bool PrepareForRunningFromKernels(std::vector< std::shared_ptr< const fml::Mapping >> kernels)
Prepare the isolate for running for a a list of kernel files.
std::weak_ptr< DartIsolate > GetWeakIsolatePtr()
A weak pointer to the Dart isolate instance. This instance may only be used on the task runner that c...
void SetIsShuttingDown()
Definition: dart_state.h:72
DartMessageHandler & message_handler()
Definition: dart_state.h:60
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
AtkStateType state
std::string log_tag
Definition: settings.h:251
bool PrepareForRunningFromPrecompiledCode()
Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for run...
static TimePoint Now()
Definition: time_point.cc:39
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(std::shared_ptr< const fml::Mapping > snapshot_data, std::shared_ptr< const fml::Mapping > snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
void LoadLoadingUnitError(intptr_t loading_unit_id, const std::string error_message, bool transient)
static UIDartState * Current()
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66
bool enable_service_port_fallback
Definition: settings.h:179
std::shared_ptr< VolatilePathTracker > GetVolatilePathTracker() const
fml::RefPtr< const DartSnapshot > GetIsolateSnapshot() const