Flutter Engine
flutter::RuntimeController Class Reference

#include <runtime_controller.h>

Inheritance diagram for flutter::RuntimeController:
flutter::PlatformConfigurationClient

Public Member Functions

 RuntimeController (RuntimeDelegate &p_client, DartVM *vm, fml::RefPtr< const DartSnapshot > p_isolate_snapshot, const std::function< void(int64_t)> &idle_notification_callback, const PlatformData &platform_data, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::shared_ptr< const fml::Mapping > p_persistent_isolate_data, const UIDartState::Context &context)
 Creates a new instance of a runtime controller. This is usually only done by the engine instance associated with the shell. More...
 
std::unique_ptr< RuntimeControllerSpawn (RuntimeDelegate &p_client, std::string advisory_script_uri, std::string advisory_script_entrypoint, const std::function< void(int64_t)> &idle_notification_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::shared_ptr< const fml::Mapping > persistent_isolate_data) const
 Create a RuntimeController that shares as many resources as possible with the calling RuntimeController such that together they occupy less memory. More...
 
 ~RuntimeController () override
 
bool LaunchRootIsolate (const Settings &settings, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, std::unique_ptr< IsolateConfiguration > isolate_configuration)
 Launches the isolate using the window data associated with this runtime controller. Before this call, the Dart isolate has not been initialized. On successful return, the caller can assume that the isolate is in the DartIsolate::Phase::Running phase. More...
 
std::unique_ptr< RuntimeControllerClone () const
 Clone the the runtime controller. Launching an isolate with a cloned runtime controller will use the same snapshots and copies all window data to the new instance. This is usually only used in the debug runtime mode to support the cold-restart scenario. More...
 
bool SetViewportMetrics (const ViewportMetrics &metrics)
 Forward the specified viewport metrics to the running isolate. If the isolate is not running, these metrics will be saved and flushed to the isolate when it starts. More...
 
bool SetLocales (const std::vector< std::string > &locale_data)
 Forward the specified locale data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetUserSettingsData (const std::string &data)
 Forward the user settings data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetLifecycleState (const std::string &data)
 Forward the lifecycle state data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool SetSemanticsEnabled (bool enabled)
 Notifies the running isolate about whether the semantics tree should be generated or not. If the isolate is not running, this preference will be saved and flushed to the isolate when it starts running. More...
 
bool SetAccessibilityFeatures (int32_t flags)
 Forward the preference of accessibility features that must be enabled in the semantics tree to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running. More...
 
bool BeginFrame (fml::TimePoint frame_time, uint64_t frame_number)
 Notifies the running isolate that it should start generating a new frame. More...
 
bool ReportTimings (std::vector< int64_t > timings)
 Dart code cannot fully measure the time it takes for a specific frame to be rendered. This is because Dart code only runs on the UI task runner. That is only a small part of the overall frame workload. The raster task runner frame workload is executed on a thread where Dart code cannot run (and hence instrument). Besides, due to the pipelined nature of rendering in Flutter, there may be multiple frame workloads being processed at any given time. However, for non-Timeline based profiling, it is useful for trace collection and processing to happen in Dart. To do this, the raster task runner frame workloads need to be instrumented separately. After a set number of these profiles have been gathered, they need to be reported back to Dart code. The engine reports this extra instrumentation information back to Dart code running on the engine by invoking this method at predefined intervals. More...
 
virtual bool NotifyIdle (int64_t deadline)
 Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified deadline. The VM uses this opportunity to perform garbage collection operations is a manner that interferes as little as possible with frame rendering. More...
 
virtual bool IsRootIsolateRunning ()
 Returns if the root isolate is running. The isolate must be transitioned to the running phase manually. The isolate can stop running if it terminates execution on its own. More...
 
virtual bool DispatchPlatformMessage (std::unique_ptr< PlatformMessage > message)
 Dispatch the specified platform message to running root isolate. More...
 
bool DispatchPointerDataPacket (const PointerDataPacket &packet)
 Dispatch the specified pointer data message to the running root isolate. More...
 
bool DispatchKeyDataPacket (const KeyDataPacket &packet, KeyDataResponse callback)
 Dispatch the specified pointer data message to the running root isolate. More...
 
bool DispatchSemanticsAction (int32_t id, SemanticsAction action, fml::MallocMapping args)
 Dispatch the semantics action to the specified accessibility node. More...
 
Dart_Port GetMainPort ()
 Gets the main port identifier of the root isolate. More...
 
std::string GetIsolateName ()
 Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from its advisory script URI, advisory main entrypoint and its main port name. For example, "main.dart$main-1234" where the script URI is "main.dart", the entrypoint is "main" and the port name "1234". Once launched, the isolate may re-christen itself using a name it selects via setIsolateDebugName in window.dart. This name is purely advisory and only used by instrumentation and reporting purposes. More...
 
bool HasLivePorts ()
 Returns if the root isolate has any live receive ports. More...
 
tonic::DartErrorHandleType GetLastError ()
 Get the last error encountered by the microtask queue. More...
 
std::optional< std::string > GetRootIsolateServiceID () const
 Get the service ID of the root isolate if the root isolate is running. More...
 
std::optional< uint32_t > GetRootIsolateReturnCode ()
 Get the return code specified by the root isolate (if one is present). More...
 
uint64_t GetRootIsolateGroup () const
 Get an identifier that represents the Dart isolate group the root isolate is in. More...
 
void LoadDartDeferredLibrary (intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
 Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully, the Dart future returned by the originating loadLibrary() call completes. More...
 
virtual void LoadDartDeferredLibraryError (intptr_t loading_unit_id, const std::string error_message, bool transient)
 Indicates to the dart VM that the request to load a deferred library with the specified loading unit id has failed. More...
 
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 deferred library identified by the specified loading unit id should be downloaded and loaded into the Dart VM via LoadDartDeferredLibrary More...
 
const fml::WeakPtr< IOManager > & GetIOManager () const
 
virtual DartVMGetDartVM () const
 
const fml::RefPtr< const DartSnapshot > & GetIsolateSnapshot () const
 
const PlatformDataGetPlatformData () const
 
const fml::RefPtr< SkiaUnrefQueue > & GetSkiaUnrefQueue () const
 
const fml::WeakPtr< SnapshotDelegate > & GetSnapshotDelegate () const
 

Protected Member Functions

 RuntimeController (RuntimeDelegate &p_client, TaskRunners task_runners)
 Constructor for Mocks. More...
 
- Protected Member Functions inherited from flutter::PlatformConfigurationClient
virtual ~PlatformConfigurationClient ()
 

Detailed Description

Represents an instance of a running root isolate with window bindings. In normal operation, a single instance of this object is owned by the engine per shell. This object may only be created, used, and collected on the UI task runner. Window state queried by the root isolate is stored by this object. In cold-restart scenarios, the engine may collect this before installing a new runtime controller in its place. The Clone method may be used by the engine to copy the currently accumulated window state so it can be referenced by the new runtime controller.

Definition at line 44 of file runtime_controller.h.

Constructor & Destructor Documentation

◆ RuntimeController() [1/2]

flutter::RuntimeController::RuntimeController ( RuntimeDelegate p_client,
DartVM vm,
fml::RefPtr< const DartSnapshot p_isolate_snapshot,
const std::function< void(int64_t)> &  idle_notification_callback,
const PlatformData platform_data,
const fml::closure isolate_create_callback,
const fml::closure isolate_shutdown_callback,
std::shared_ptr< const fml::Mapping p_persistent_isolate_data,
const UIDartState::Context context 
)

Creates a new instance of a runtime controller. This is usually only done by the engine instance associated with the shell.

Parameters
clientThe runtime delegate. This is usually the Engine instance.
vmA reference to a running Dart VM. The runtime controller must be collected before the VM is destroyed (this order is guaranteed by the shell).
[in]idle_notification_callbackThe idle notification callback. This allows callers to run native code in isolate scope when the VM is about to be notified that the engine is going to be idle.
[in]platform_dataThe window data (if exists).
[in]isolate_create_callbackThe isolate create callback. This allows callers to run native code in isolate scope on the UI task runner as soon as the root isolate has been created.
[in]isolate_shutdown_callbackThe isolate shutdown callback. This allows callers to run native code in isolate scoped on the UI task runner just as the root isolate is about to be torn down.
[in]persistent_isolate_dataUnstructured persistent read-only data that the root isolate can access in a synchronous manner.
[in]contextEngine-owned state which is accessed by the root dart isolate.

Definition at line 24 of file runtime_controller.cc.

Referenced by GetSnapshotDelegate().

34  : client_(p_client),
35  vm_(p_vm),
36  isolate_snapshot_(p_isolate_snapshot),
37  idle_notification_callback_(p_idle_notification_callback),
38  platform_data_(std::move(p_platform_data)),
39  isolate_create_callback_(p_isolate_create_callback),
40  isolate_shutdown_callback_(p_isolate_shutdown_callback),
41  persistent_isolate_data_(std::move(p_persistent_isolate_data)),
42  context_(p_context) {}

◆ ~RuntimeController()

flutter::RuntimeController::~RuntimeController ( )
override

Definition at line 66 of file runtime_controller.cc.

References FML_DCHECK, FML_DLOG, and result.

66  {
67  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
68  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
69  if (root_isolate) {
70  root_isolate->SetReturnCodeCallback(nullptr);
71  auto result = root_isolate->Shutdown();
72  if (!result) {
73  FML_DLOG(ERROR) << "Could not shutdown the root isolate.";
74  }
75  root_isolate_ = {};
76  }
77 }
#define FML_DCHECK(condition)
Definition: logging.h:86
GAsyncResult * result
#define FML_DLOG(severity)
Definition: logging.h:85

◆ RuntimeController() [2/2]

flutter::RuntimeController::RuntimeController ( RuntimeDelegate p_client,
TaskRunners  task_runners 
)
protected

Constructor for Mocks.

Definition at line 20 of file runtime_controller.cc.

22  : client_(p_client), vm_(nullptr), context_(task_runners) {}

Member Function Documentation

◆ BeginFrame()

bool flutter::RuntimeController::BeginFrame ( fml::TimePoint  frame_time,
uint64_t  frame_number 
)

Notifies the running isolate that it should start generating a new frame.

See also
Engine::BeginFrame for more context.
Parameters
[in]frame_timeThe point at which the current frame interval began. May be used by animation interpolators, physics simulations, etc.
Returns
If notification to begin frame rendering was delivered to the running isolate.

Definition at line 180 of file runtime_controller.cc.

181  {
182  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
183  platform_configuration->BeginFrame(frame_time, frame_number);
184  return true;
185  }
186 
187  return false;
188 }

◆ Clone()

std::unique_ptr< RuntimeController > flutter::RuntimeController::Clone ( ) const

Clone the the runtime controller. Launching an isolate with a cloned runtime controller will use the same snapshots and copies all window data to the new instance. This is usually only used in the debug runtime mode to support the cold-restart scenario.

Returns
A clone of the existing runtime controller.

Definition at line 87 of file runtime_controller.cc.

References flutter::PlatformData::accessibility_feature_flags_, flutter::PlatformData::lifecycle_state, flutter::PlatformData::locale_data, flutter::PlatformData::semantics_enabled, SetAccessibilityFeatures(), SetLifecycleState(), SetLocales(), SetSemanticsEnabled(), SetUserSettingsData(), SetViewportMetrics(), flutter::PlatformData::user_settings_data, and flutter::PlatformData::viewport_metrics.

87  {
88  return std::make_unique<RuntimeController>(client_, //
89  vm_, //
90  isolate_snapshot_, //
91  idle_notification_callback_, //
92  platform_data_, //
93  isolate_create_callback_, //
94  isolate_shutdown_callback_, //
95  persistent_isolate_data_, //
96  context_ //
97  );
98 }

◆ DispatchKeyDataPacket()

bool flutter::RuntimeController::DispatchKeyDataPacket ( const KeyDataPacket packet,
KeyDataResponse  callback 
)

Dispatch the specified pointer data message to the running root isolate.

Parameters
[in]packetThe key data message to dispatch to the isolate.
[in]callbackCalled when the framework has decided whether to handle this key data.
Returns
If the key data message was dispatched. This may fail is an isolate is not running.

Definition at line 241 of file runtime_controller.cc.

References TRACE_EVENT1.

242  {
243  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
244  TRACE_EVENT1("flutter", "RuntimeController::DispatchKeyDataPacket", "mode",
245  "basic");
246  uint64_t response_id =
247  platform_configuration->RegisterKeyDataResponse(std::move(callback));
248  platform_configuration->get_window(0)->DispatchKeyDataPacket(packet,
249  response_id);
250  return true;
251  }
252  return false;
253 }
FlKeyEvent FlKeyResponderAsyncCallback callback
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:94

◆ DispatchPlatformMessage()

bool flutter::RuntimeController::DispatchPlatformMessage ( std::unique_ptr< PlatformMessage message)
virtual

Dispatch the specified platform message to running root isolate.

Parameters
[in]messageThe message to dispatch to the isolate.
Returns
If the message was dispatched to the running root isolate. This may fail is an isolate is not running.

Definition at line 217 of file runtime_controller.cc.

References TRACE_EVENT1.

218  {
219  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
220  TRACE_EVENT1("flutter", "RuntimeController::DispatchPlatformMessage",
221  "mode", "basic");
222  platform_configuration->DispatchPlatformMessage(std::move(message));
223  return true;
224  }
225 
226  return false;
227 }
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:94

◆ DispatchPointerDataPacket()

bool flutter::RuntimeController::DispatchPointerDataPacket ( const PointerDataPacket packet)

Dispatch the specified pointer data message to the running root isolate.

Parameters
[in]packetThe pointer data message to dispatch to the isolate.
Returns
If the pointer data message was dispatched. This may fail is an isolate is not running.

Definition at line 229 of file runtime_controller.cc.

References TRACE_EVENT1.

230  {
231  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
232  TRACE_EVENT1("flutter", "RuntimeController::DispatchPointerDataPacket",
233  "mode", "basic");
234  platform_configuration->get_window(0)->DispatchPointerDataPacket(packet);
235  return true;
236  }
237 
238  return false;
239 }
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:94

◆ DispatchSemanticsAction()

bool flutter::RuntimeController::DispatchSemanticsAction ( int32_t  id,
SemanticsAction  action,
fml::MallocMapping  args 
)

Dispatch the semantics action to the specified accessibility node.

Parameters
[in]idThe identified of the accessibility node.
[in]actionThe semantics action to perform on the specified accessibility node.
[in]argsOptional data that applies to the specified action.
Returns
If the semantics action was dispatched. This may fail if an isolate is not running.

Definition at line 255 of file runtime_controller.cc.

References flutter::RuntimeDelegate::ComputePlatformResolvedLocale(), flutter::RuntimeDelegate::DefaultRouteName(), flutter::RuntimeDelegate::GetFontCollection(), flutter::RuntimeDelegate::HandlePlatformMessage(), flutter::RuntimeDelegate::Render(), flutter::RuntimeDelegate::ScheduleFrame(), flutter::PlatformData::semantics_enabled, flutter::RuntimeDelegate::SetNeedsReportTimings(), flutter::SemanticsUpdate::takeActions(), flutter::Scene::takeLayerTree(), flutter::SemanticsUpdate::takeNodes(), TRACE_EVENT1, flutter::RuntimeDelegate::UpdateIsolateDescription(), flutter::RuntimeDelegate::UpdateSemantics(), and value.

257  {
258  TRACE_EVENT1("flutter", "RuntimeController::DispatchSemanticsAction", "mode",
259  "basic");
260  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
261  platform_configuration->DispatchSemanticsAction(id, action,
262  std::move(args));
263  return true;
264  }
265 
266  return false;
267 }
SemanticsAction action
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
Definition: trace_event.h:94

◆ GetDartVM()

virtual DartVM* flutter::RuntimeController::GetDartVM ( ) const
inlinevirtual

Definition at line 541 of file runtime_controller.h.

541 { return vm_; }

◆ GetIOManager()

const fml::WeakPtr<IOManager>& flutter::RuntimeController::GetIOManager ( ) const
inline

Definition at line 537 of file runtime_controller.h.

References flutter::UIDartState::Context::io_manager.

537  {
538  return context_.io_manager;
539  }
fml::WeakPtr< IOManager > io_manager
The IO manager used by the isolate for asynchronous texture uploads.
Definition: ui_dart_state.h:67

◆ GetIsolateName()

std::string flutter::RuntimeController::GetIsolateName ( )

Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from its advisory script URI, advisory main entrypoint and its main port name. For example, "main.dart$main-1234" where the script URI is "main.dart", the entrypoint is "main" and the port name "1234". Once launched, the isolate may re-christen itself using a name it selects via setIsolateDebugName in window.dart. This name is purely advisory and only used by instrumentation and reporting purposes.

Returns
The debug name of the root isolate.

Definition at line 337 of file runtime_controller.cc.

337  {
338  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
339  return root_isolate ? root_isolate->debug_name() : "";
340 }

◆ GetIsolateSnapshot()

const fml::RefPtr<const DartSnapshot>& flutter::RuntimeController::GetIsolateSnapshot ( ) const
inline

Definition at line 543 of file runtime_controller.h.

543  {
544  return isolate_snapshot_;
545  }

◆ GetLastError()

tonic::DartErrorHandleType flutter::RuntimeController::GetLastError ( )

Get the last error encountered by the microtask queue.

Returns
The last error encountered by the microtask queue.

Definition at line 351 of file runtime_controller.cc.

References tonic::kNoError.

351  {
352  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
353  return root_isolate ? root_isolate->GetLastError() : tonic::kNoError;
354 }

◆ GetMainPort()

Dart_Port flutter::RuntimeController::GetMainPort ( )

Gets the main port identifier of the root isolate.

Returns
The main port identifier. If no root isolate is running, returns ILLEGAL_PORT.

Definition at line 332 of file runtime_controller.cc.

332  {
333  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
334  return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
335 }

◆ GetPlatformData()

const PlatformData& flutter::RuntimeController::GetPlatformData ( ) const
inline

Definition at line 547 of file runtime_controller.h.

547 { return platform_data_; }

◆ GetRootIsolateGroup()

uint64_t flutter::RuntimeController::GetRootIsolateGroup ( ) const

Get an identifier that represents the Dart isolate group the root isolate is in.

Returns
The root isolate isolate group identifier, zero if one can't be established.

Definition at line 423 of file runtime_controller.cc.

423  {
424  auto isolate = root_isolate_.lock();
425  if (isolate) {
426  auto isolate_scope = tonic::DartIsolateScope(isolate->isolate());
427  Dart_IsolateGroup isolate_group = Dart_CurrentIsolateGroup();
428  return reinterpret_cast<uint64_t>(isolate_group);
429  } else {
430  return 0;
431  }
432 }

◆ GetRootIsolateReturnCode()

std::optional< uint32_t > flutter::RuntimeController::GetRootIsolateReturnCode ( )

Get the return code specified by the root isolate (if one is present).

Returns
The root isolate return code if the isolate has specified one.

Definition at line 419 of file runtime_controller.cc.

419  {
420  return root_isolate_return_code_;
421 }

◆ GetRootIsolateServiceID()

std::optional< std::string > flutter::RuntimeController::GetRootIsolateServiceID ( ) const

Get the service ID of the root isolate if the root isolate is running.

Returns
The root isolate service id.

Definition at line 412 of file runtime_controller.cc.

412  {
413  if (auto isolate = root_isolate_.lock()) {
414  return isolate->GetServiceId();
415  }
416  return std::nullopt;
417 }

◆ GetSkiaUnrefQueue()

const fml::RefPtr<SkiaUnrefQueue>& flutter::RuntimeController::GetSkiaUnrefQueue ( ) const
inline

Definition at line 549 of file runtime_controller.h.

References flutter::UIDartState::Context::unref_queue.

549  {
550  return context_.unref_queue;
551  }
fml::RefPtr< SkiaUnrefQueue > unref_queue
Definition: ui_dart_state.h:71

◆ GetSnapshotDelegate()

const fml::WeakPtr<SnapshotDelegate>& flutter::RuntimeController::GetSnapshotDelegate ( ) const
inline

◆ HasLivePorts()

bool flutter::RuntimeController::HasLivePorts ( )

Returns if the root isolate has any live receive ports.

Returns
True if there are live receive ports, False otherwise. Return False if the root isolate is not running as well.

Definition at line 342 of file runtime_controller.cc.

342  {
343  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
344  if (!root_isolate) {
345  return false;
346  }
347  tonic::DartState::Scope scope(root_isolate);
348  return Dart_HasLivePorts();
349 }

◆ IsRootIsolateRunning()

bool flutter::RuntimeController::IsRootIsolateRunning ( )
virtual

Returns if the root isolate is running. The isolate must be transitioned to the running phase manually. The isolate can stop running if it terminates execution on its own.

Returns
True if root isolate running, False otherwise.

Definition at line 79 of file runtime_controller.cc.

References flutter::DartIsolate::Running.

79  {
80  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
81  if (root_isolate) {
82  return root_isolate->GetPhase() == DartIsolate::Phase::Running;
83  }
84  return false;
85 }

◆ LaunchRootIsolate()

bool flutter::RuntimeController::LaunchRootIsolate ( const Settings settings,
std::optional< std::string >  dart_entrypoint,
std::optional< std::string >  dart_entrypoint_library,
std::unique_ptr< IsolateConfiguration isolate_configuration 
)

Launches the isolate using the window data associated with this runtime controller. Before this call, the Dart isolate has not been initialized. On successful return, the caller can assume that the isolate is in the DartIsolate::Phase::Running phase.

This call will fail if a root isolate is already running. To re-create an isolate with the window data associated with this runtime controller, Clone this runtime controller and Launch an isolate in that runtime controller instead.

Parameters
[in]settingsThe per engine instance settings.
[in]dart_entrypointThe dart entrypoint. If std::nullopt or empty, main will be attempted.
[in]dart_entrypoint_libraryThe dart entrypoint library. If std::nullopt or empty, the core library will be attempted.
[in]isolate_configurationThe isolate configuration
Returns
If the isolate could be launched and guided to the DartIsolate::Phase::Running phase.

Definition at line 356 of file runtime_controller.cc.

References flutter::DartIsolate::CreateRunningRootIsolate(), FML_DCHECK, FML_DLOG, FML_LOG, and flutter::RuntimeDelegate::OnRootIsolateCreated().

360  {
361  if (root_isolate_.lock()) {
362  FML_LOG(ERROR) << "Root isolate was already running.";
363  return false;
364  }
365 
366  auto strong_root_isolate =
368  settings, //
369  isolate_snapshot_, //
370  std::make_unique<PlatformConfiguration>(this), //
371  DartIsolate::Flags{}, //
372  isolate_create_callback_, //
373  isolate_shutdown_callback_, //
374  dart_entrypoint, //
375  dart_entrypoint_library, //
376  std::move(isolate_configuration), //
377  context_, //
378  spawning_isolate_.lock().get()) //
379  .lock();
380 
381  if (!strong_root_isolate) {
382  FML_LOG(ERROR) << "Could not create root isolate.";
383  return false;
384  }
385 
386  // The root isolate ivar is weak.
387  root_isolate_ = strong_root_isolate;
388 
389  // Capture by `this` here is safe because the callback is made by the dart
390  // state itself. The isolate (and its Dart state) is owned by this object and
391  // it will be collected before this object.
392  strong_root_isolate->SetReturnCodeCallback(
393  [this](uint32_t code) { root_isolate_return_code_ = code; });
394 
395  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
396  tonic::DartState::Scope scope(strong_root_isolate);
397  platform_configuration->DidCreateIsolate();
398  if (!FlushRuntimeStateToIsolate()) {
399  FML_DLOG(ERROR) << "Could not set up initial isolate state.";
400  }
401  } else {
402  FML_DCHECK(false) << "RuntimeController created without window binding.";
403  }
404 
405  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
406 
407  client_.OnRootIsolateCreated();
408 
409  return true;
410 }
#define FML_DCHECK(condition)
Definition: logging.h:86
virtual void OnRootIsolateCreated()=0
#define FML_LOG(severity)
Definition: logging.h:65
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...
#define FML_DLOG(severity)
Definition: logging.h:85

◆ LoadDartDeferredLibrary()

void flutter::RuntimeController::LoadDartDeferredLibrary ( intptr_t  loading_unit_id,
std::unique_ptr< const fml::Mapping snapshot_data,
std::unique_ptr< const fml::Mapping snapshot_instructions 
)

Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully, the Dart future returned by the originating loadLibrary() call completes.

The Dart compiler may generate separate shared libraries files called 'loading units' when libraries are imported as deferred. Each of these shared libraries are identified by a unique loading unit id. Callers should open and resolve a SymbolMapping from the shared library. The Mappings should be moved into this method, as ownership will be assumed by the dart root isolate after successful loading and released after shutdown of the root isolate. The loading unit may not be used after isolate shutdown. If loading fails, the mappings will be released.

This method is paired with a RequestDartDeferredLibrary invocation that provides the embedder with the loading unit id of the deferred library to load.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit, as passed in by RequestDartDeferredLibrary.
[in]snapshot_dataDart snapshot data of the loading unit's shared library.
[in]snapshot_dataDart snapshot instructions of the loading unit's shared library.

Definition at line 434 of file runtime_controller.cc.

437  {
438  root_isolate_.lock()->LoadLoadingUnit(loading_unit_id,
439  std::move(snapshot_data),
440  std::move(snapshot_instructions));
441 }

◆ LoadDartDeferredLibraryError()

void flutter::RuntimeController::LoadDartDeferredLibraryError ( intptr_t  loading_unit_id,
const std::string  error_message,
bool  transient 
)
virtual

Indicates to the dart VM that the request to load a deferred library with the specified loading unit id has failed.

The dart future returned by the initiating loadLibrary() call will complete with an error.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit, as passed in by RequestDartDeferredLibrary.
[in]error_messageThe error message that will appear in the dart Future.
[in]transientA transient error is a failure due to temporary conditions such as no network. Transient errors allow the dart VM to re-request the same deferred library and and loading_unit_id again. Non-transient errors are permanent and attempts to re-request the library will instantly complete with an error.

Definition at line 443 of file runtime_controller.cc.

446  {
447  root_isolate_.lock()->LoadLoadingUnitError(loading_unit_id, error_message,
448  transient);
449 }

◆ NotifyIdle()

bool flutter::RuntimeController::NotifyIdle ( int64_t  deadline)
virtual

Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified deadline. The VM uses this opportunity to perform garbage collection operations is a manner that interferes as little as possible with frame rendering.

NotifyIdle is advisory. The VM may or may not run a garbage collection when this is called, and will eventually perform garbage collections even if it is not called or it is called with insufficient deadlines.

The garbage collection mechanism and its thresholds are internal implementation details and absolutely no guarantees are made about the threshold discussed below. This discussion is also an oversimplification but hopefully serves to calibrate expectations about GC behavior:

  • When the Dart VM and its root isolate are initialized, the memory consumed upto that point are treated as a baseline.
  • A fixed percentage of the memory consumed (~20%) over the baseline is treated as the hard threshold.
  • The memory in play is divided into old space and new space. The new space is typically very small and fills up rapidly.
  • The baseline plus the threshold is considered the old space while the small new space is a separate region (typically a few pages).
  • The total old space size minus the max new space size is treated as the soft threshold.
  • In a world where there is no call to NotifyIdle, when the total allocation exceeds the soft threshold, a concurrent mark is initiated in the VM. There is a “small” pause that occurs when the concurrent mark is initiated and another pause when the mark concludes and a sweep is initiated.
  • If the total allocations exceeds the the hard threshold, a “big” stop-the-world pause is initiated.
  • If after either the sweep after the concurrent mark, or, the stop-the-world pause, the consumption returns to be below the soft threshold, the dance begins anew.
  • If after both the “small” and “big” pauses, memory usage is still over the hard threshold, i.e, the objects are still reachable, that amount of memory is treated as the new baseline and a fixed percentage of the new baseline over the new baseline is now the new hard threshold.
  • Updating the baseline will continue till memory for the updated old space can be allocated from the operating system. These allocations will typically fail due to address space exhaustion on 32-bit systems and page table exhaustion on 64-bit systems.
  • NotifyIdle initiates the concurrent mark preemptively. The deadline is used by the VM to determine if the corresponding sweep can be performed within the deadline. This way, jank due to “small” pauses can be ameliorated.
  • There is no ability to stop a “big” pause on reaching the hard threshold in the old space. The best you can do is release (by making them unreachable) objects eagerly so that the are marked as unreachable in the concurrent mark initiated by either reaching the soft threshold or an explicit NotifyIdle.
  • If you are running out of memory, its because too many large objects were allocation and remained reachable such that the the old space kept growing till it could grow no more.
  • At the edges of allocation thresholds, failures can occur gracefully if the instigating allocation was made in the Dart VM or rather gracelessly if the allocation is made by some native component.
See also
Dart_TimelineGetMicros
Parameters
[in]deadlineThe deadline measures in microseconds against the system's monotonic time. The clock can be accessed via Dart_TimelineGetMicros.
Returns
If the idle notification was forwarded to the running isolate.

Definition at line 199 of file runtime_controller.cc.

References TRACE_EVENT0.

199  {
200  std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
201  if (!root_isolate) {
202  return false;
203  }
204 
205  tonic::DartState::Scope scope(root_isolate);
206 
207  Dart_NotifyIdle(deadline);
208 
209  // Idle notifications being in isolate scope are part of the contract.
210  if (idle_notification_callback_) {
211  TRACE_EVENT0("flutter", "EmbedderIdleNotification");
212  idle_notification_callback_(deadline);
213  }
214  return true;
215 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90

◆ ReportTimings()

bool flutter::RuntimeController::ReportTimings ( std::vector< int64_t >  timings)

Dart code cannot fully measure the time it takes for a specific frame to be rendered. This is because Dart code only runs on the UI task runner. That is only a small part of the overall frame workload. The raster task runner frame workload is executed on a thread where Dart code cannot run (and hence instrument). Besides, due to the pipelined nature of rendering in Flutter, there may be multiple frame workloads being processed at any given time. However, for non-Timeline based profiling, it is useful for trace collection and processing to happen in Dart. To do this, the raster task runner frame workloads need to be instrumented separately. After a set number of these profiles have been gathered, they need to be reported back to Dart code. The engine reports this extra instrumentation information back to Dart code running on the engine by invoking this method at predefined intervals.

See also
Engine::ReportTimings, FrameTiming
Parameters
[in]timingsCollection of FrameTiming::kCount * n timestamps for n frames whose timings have not been reported yet. A collection of integers is reported here for easier conversions to Dart objects. The timestamps are measured against the system monotonic clock measured in microseconds.

Definition at line 190 of file runtime_controller.cc.

190  {
191  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
192  platform_configuration->ReportTimings(std::move(timings));
193  return true;
194  }
195 
196  return false;
197 }

◆ RequestDartDeferredLibrary()

void flutter::RuntimeController::RequestDartDeferredLibrary ( intptr_t  loading_unit_id)
overridevirtual

Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the deferred library identified by the specified loading unit id should be downloaded and loaded into the Dart VM via LoadDartDeferredLibrary

Upon encountering errors or otherwise failing to load a loading unit with the specified id, the failure should be directly reported to dart by calling LoadDartDeferredLibraryFailure to ensure the waiting dart future completes with an error.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit. This id is to be passed back into LoadDartDeferredLibrary in order to identify which deferred library to load.

Implements flutter::PlatformConfigurationClient.

Definition at line 451 of file runtime_controller.cc.

References flutter::RuntimeDelegate::RequestDartDeferredLibrary().

451  {
452  return client_.RequestDartDeferredLibrary(loading_unit_id);
453 }
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id)=0

◆ SetAccessibilityFeatures()

bool flutter::RuntimeController::SetAccessibilityFeatures ( int32_t  flags)

Forward the preference of accessibility features that must be enabled in the semantics tree to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]flagsThe accessibility features that must be generated in the semantics tree.
Returns
If the preference of accessibility features was forwarded to the running isolate.

Definition at line 169 of file runtime_controller.cc.

References flutter::PlatformData::accessibility_feature_flags_, and flutter::flags.

Referenced by Clone().

169  {
170  platform_data_.accessibility_feature_flags_ = flags;
171  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
172  platform_configuration->UpdateAccessibilityFeatures(
173  platform_data_.accessibility_feature_flags_);
174  return true;
175  }
176 
177  return false;
178 }
int32_t accessibility_feature_flags_
Definition: platform_data.h:43
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

◆ SetLifecycleState()

bool flutter::RuntimeController::SetLifecycleState ( const std::string &  data)

Forward the lifecycle state data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]dataThe lifecycle state data.
Returns
If the lifecycle state data was forwarded to the running isolate.

Definition at line 145 of file runtime_controller.cc.

References flutter::PlatformData::lifecycle_state.

Referenced by Clone().

145  {
146  platform_data_.lifecycle_state = data;
147 
148  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
149  platform_configuration->UpdateLifecycleState(
150  platform_data_.lifecycle_state);
151  return true;
152  }
153 
154  return false;
155 }
std::string lifecycle_state
Definition: platform_data.h:40

◆ SetLocales()

bool flutter::RuntimeController::SetLocales ( const std::vector< std::string > &  locale_data)

Forward the specified locale data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]locale_dataThe locale data. This should consist of groups of 4 strings, each group representing a single locale.
Returns
If the locale data was forwarded to the running isolate.

Definition at line 121 of file runtime_controller.cc.

References flutter::PlatformData::locale_data.

Referenced by Clone().

122  {
123  platform_data_.locale_data = locale_data;
124 
125  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
126  platform_configuration->UpdateLocales(locale_data);
127  return true;
128  }
129 
130  return false;
131 }
std::vector< std::string > locale_data
Definition: platform_data.h:38

◆ SetSemanticsEnabled()

bool flutter::RuntimeController::SetSemanticsEnabled ( bool  enabled)

Notifies the running isolate about whether the semantics tree should be generated or not. If the isolate is not running, this preference will be saved and flushed to the isolate when it starts running.

Parameters
[in]enabledIndicates whether to generate the semantics tree.
Returns
If the semantics tree generation preference was forwarded to the running isolate.

Definition at line 157 of file runtime_controller.cc.

References flutter::PlatformData::semantics_enabled.

Referenced by Clone().

157  {
158  platform_data_.semantics_enabled = enabled;
159 
160  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
161  platform_configuration->UpdateSemanticsEnabled(
162  platform_data_.semantics_enabled);
163  return true;
164  }
165 
166  return false;
167 }

◆ SetUserSettingsData()

bool flutter::RuntimeController::SetUserSettingsData ( const std::string &  data)

Forward the user settings data to the running isolate. If the isolate is not running, this data will be saved and flushed to the isolate when it starts running.

Parameters
[in]dataThe user settings data.
Returns
If the user settings data was forwarded to the running isolate.

Definition at line 133 of file runtime_controller.cc.

References flutter::PlatformData::user_settings_data.

Referenced by Clone().

133  {
134  platform_data_.user_settings_data = data;
135 
136  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
137  platform_configuration->UpdateUserSettingsData(
138  platform_data_.user_settings_data);
139  return true;
140  }
141 
142  return false;
143 }
std::string user_settings_data
Definition: platform_data.h:39

◆ SetViewportMetrics()

bool flutter::RuntimeController::SetViewportMetrics ( const ViewportMetrics metrics)

Forward the specified viewport metrics to the running isolate. If the isolate is not running, these metrics will be saved and flushed to the isolate when it starts.

Parameters
[in]metricsThe window's viewport metrics.
Returns
If the window metrics were forwarded to the running isolate.

Definition at line 110 of file runtime_controller.cc.

References flutter::PlatformData::viewport_metrics.

Referenced by Clone().

110  {
111  platform_data_.viewport_metrics = metrics;
112 
113  if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
114  platform_configuration->get_window(0)->UpdateWindowMetrics(metrics);
115  return true;
116  }
117 
118  return false;
119 }
ViewportMetrics viewport_metrics
Definition: platform_data.h:33

◆ Spawn()

std::unique_ptr< RuntimeController > flutter::RuntimeController::Spawn ( RuntimeDelegate p_client,
std::string  advisory_script_uri,
std::string  advisory_script_entrypoint,
const std::function< void(int64_t)> &  idle_notification_callback,
const fml::closure isolate_create_callback,
const fml::closure isolate_shutdown_callback,
std::shared_ptr< const fml::Mapping persistent_isolate_data 
) const

Create a RuntimeController that shares as many resources as possible with the calling RuntimeController such that together they occupy less memory.

Returns
A RuntimeController with a running isolate.
See also
RuntimeController::RuntimeController

Definition at line 44 of file runtime_controller.cc.

References result.

51  {
52  auto result =
53  std::make_unique<RuntimeController>(p_client, //
54  vm_, //
55  isolate_snapshot_, //
56  p_idle_notification_callback, //
57  platform_data_, //
58  p_isolate_create_callback, //
59  p_isolate_shutdown_callback, //
60  p_persistent_isolate_data, //
61  context_); //
62  result->spawning_isolate_ = root_isolate_;
63  return result;
64 }
GAsyncResult * result

The documentation for this class was generated from the following files: