5#include "flutter/runtime/runtime_controller.h"
9#include "flutter/common/constants.h"
10#include "flutter/common/settings.h"
11#include "flutter/fml/message_loop.h"
12#include "flutter/fml/trace_event.h"
13#include "flutter/lib/ui/compositing/scene.h"
14#include "flutter/lib/ui/ui_dart_state.h"
15#include "flutter/lib/ui/window/platform_configuration.h"
16#include "flutter/lib/ui/window/viewport_metrics.h"
17#include "flutter/runtime/dart_isolate_group_data.h"
18#include "flutter/runtime/isolate_configuration.h"
19#include "flutter/runtime/runtime_delegate.h"
26 : client_(p_client), vm_(nullptr), context_(task_runners) {}
32 const std::function<
void(int64_t)>& p_idle_notification_callback,
36 std::shared_ptr<const fml::Mapping> p_persistent_isolate_data,
40 isolate_snapshot_(
std::move(p_isolate_snapshot)),
41 idle_notification_callback_(p_idle_notification_callback),
42 platform_data_(p_platform_data),
43 isolate_create_callback_(p_isolate_create_callback),
44 isolate_shutdown_callback_(p_isolate_shutdown_callback),
45 persistent_isolate_data_(
std::move(p_persistent_isolate_data)),
46 context_(p_context) {}
50 const std::string& advisory_script_uri,
51 const std::string& advisory_script_entrypoint,
52 const std::function<
void(int64_t)>& p_idle_notification_callback,
55 const std::shared_ptr<const fml::Mapping>& p_persistent_isolate_data,
61 std::move(snapshot_delegate),
62 std::move(io_manager),
64 std::move(image_decoder),
65 std::move(image_generator_registry),
67 advisory_script_entrypoint,
73 std::make_unique<RuntimeController>(p_client,
76 p_idle_notification_callback,
78 p_isolate_create_callback,
79 p_isolate_shutdown_callback,
80 p_persistent_isolate_data,
82 result->spawning_isolate_ = root_isolate_;
88 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
90 root_isolate->SetReturnCodeCallback(
nullptr);
91 auto result = root_isolate->Shutdown();
100 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
108 return std::make_unique<RuntimeController>(client_,
111 idle_notification_callback_,
113 isolate_create_callback_,
114 isolate_shutdown_callback_,
115 persistent_isolate_data_,
120bool RuntimeController::FlushRuntimeStateToIsolate() {
122 <<
"FlushRuntimeStateToIsolate is called more than once somehow.";
123 has_flushed_runtime_state_ =
true;
125 auto platform_configuration = GetPlatformConfigurationIfAvailable();
126 if (!platform_configuration) {
130 for (
auto const& [view_id, viewport_metrics] :
131 platform_data_.viewport_metrics_for_views) {
132 bool added = platform_configuration->AddView(view_id, viewport_metrics);
135 if (pending_add_view_callbacks_.find(view_id) !=
136 pending_add_view_callbacks_.end()) {
137 pending_add_view_callbacks_[view_id](added);
138 pending_add_view_callbacks_.erase(view_id);
143 <<
". The Dart isolate may be in an inconsistent state.";
147 FML_DCHECK(pending_add_view_callbacks_.empty());
162 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
163 if (!platform_configuration) {
164 FML_DCHECK(has_flushed_runtime_state_ ==
false);
166 if (pending_add_view_callbacks_.find(view_id) !=
167 pending_add_view_callbacks_.end()) {
168 FML_LOG(
ERROR) <<
"View #" << view_id <<
" is already pending creation.";
174 pending_add_view_callbacks_[view_id] = std::move(
callback);
178 FML_DCHECK(has_flushed_runtime_state_ || pending_add_view_callbacks_.empty());
181 bool added = platform_configuration->AddView(view_id, view_metrics);
195 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
196 if (!platform_configuration) {
197 FML_DCHECK(has_flushed_runtime_state_ ==
false);
198 if (pending_add_view_callbacks_.find(view_id) !=
199 pending_add_view_callbacks_.end()) {
200 pending_add_view_callbacks_[view_id](
false);
201 pending_add_view_callbacks_.erase(view_id);
207 return platform_configuration->RemoveView(view_id);
215 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
216 return platform_configuration->UpdateViewMetrics(view_id, metrics);
223 const std::vector<std::string>& locale_data) {
226 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
227 platform_configuration->UpdateLocales(locale_data);
237 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
238 platform_configuration->UpdateUserSettingsData(
249 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
250 platform_configuration->UpdateInitialLifecycleState(
261 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
262 platform_configuration->UpdateSemanticsEnabled(
272 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
273 platform_configuration->UpdateAccessibilityFeatures(
282 uint64_t frame_number) {
284 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
285 platform_configuration->BeginFrame(frame_time, frame_number);
293 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
294 platform_configuration->ReportTimings(std::move(timings));
310 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
326 if (idle_notification_callback_) {
334 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
347 std::unique_ptr<PlatformMessage>
message) {
348 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
349 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPlatformMessage");
350 platform_configuration->DispatchPlatformMessage(std::move(
message));
359 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
360 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPointerDataPacket");
361 platform_configuration->DispatchPointerDataPacket(packet);
371 TRACE_EVENT1(
"flutter",
"RuntimeController::DispatchSemanticsAction",
"mode",
373 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
374 platform_configuration->DispatchSemanticsAction(node_id,
action,
383RuntimeController::GetPlatformConfigurationIfAvailable() {
384 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
385 return root_isolate ? root_isolate->platform_configuration() :
nullptr;
409 if (view_metrics ==
nullptr) {
414 rendered_views_during_frame_.insert(view_id);
415 CheckIfAllViewsRendered();
418void RuntimeController::MarkAsFrameBorder() {
419 rendered_views_during_frame_.clear();
422void RuntimeController::CheckIfAllViewsRendered() {
423 if (rendered_views_during_frame_.size() != 0 &&
424 rendered_views_during_frame_.size() ==
440 std::unique_ptr<PlatformMessage>
message) {
456 int64_t isolate_port) {
466std::shared_ptr<const fml::Mapping>
468 return persistent_isolate_data_;
472std::unique_ptr<std::vector<std::string>>
474 const std::vector<std::string>& supported_locale_data) {
484 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
485 return root_isolate ? root_isolate->main_port() :
ILLEGAL_PORT;
489 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
490 return root_isolate ? root_isolate->debug_name() :
"";
494 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
503 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
510 std::optional<std::string> dart_entrypoint,
511 std::optional<std::string> dart_entrypoint_library,
512 const std::vector<std::string>& dart_entrypoint_args,
513 std::unique_ptr<IsolateConfiguration> isolate_configuration) {
514 if (root_isolate_.lock()) {
519 auto strong_root_isolate =
523 std::make_unique<PlatformConfiguration>(
this),
525 root_isolate_create_callback,
526 isolate_create_callback_,
527 isolate_shutdown_callback_,
528 std::move(dart_entrypoint),
529 std::move(dart_entrypoint_library),
530 dart_entrypoint_args,
531 std::move(isolate_configuration),
533 spawning_isolate_.lock().get())
536 if (!strong_root_isolate) {
542 strong_root_isolate->GetIsolateGroupData().SetPlatformMessageHandler(
543 strong_root_isolate->GetRootIsolateToken(),
547 root_isolate_ = strong_root_isolate;
552 strong_root_isolate->SetReturnCodeCallback(
553 [
this](uint32_t code) { root_isolate_return_code_ = code; });
555 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
557 platform_configuration->DidCreateIsolate();
558 if (!FlushRuntimeStateToIsolate()) {
559 FML_DLOG(
ERROR) <<
"Could not set up initial isolate state.";
562 FML_DCHECK(
false) <<
"RuntimeController created without window binding.";
573 if (
auto isolate = root_isolate_.lock()) {
574 return isolate->GetServiceId();
580 return root_isolate_return_code_;
584 auto isolate = root_isolate_.lock();
588 return reinterpret_cast<uint64_t
>(isolate_group);
595 intptr_t loading_unit_id,
596 std::unique_ptr<const fml::Mapping> snapshot_data,
597 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
598 root_isolate_.lock()->LoadLoadingUnit(loading_unit_id,
599 std::move(snapshot_data),
600 std::move(snapshot_instructions));
604 intptr_t loading_unit_id,
608 root_isolate_.lock()->LoadLoadingUnitError(loading_unit_id, error_message,
620 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
621 platform_configuration->UpdateDisplays(displays);
628 int configuration_id)
const {
633 platform_isolate_manager_->ShutdownPlatformIsolates();
636RuntimeController::Locale::Locale(std::string language_code_,
637 std::string country_code_,
638 std::string script_code_,
639 std::string variant_code_)
640 : language_code(
std::move(language_code_)),
641 country_code(
std::move(country_code_)),
642 script_code(
std::move(script_code_)),
643 variant_code(
std::move(variant_code_)) {}
645RuntimeController::Locale::~Locale() =
default;
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, const fml::RefPtr< const DartSnapshot > &isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, const fml::closure &root_isolate_create_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration, const UIDartState::Context &context, const DartIsolate *spawning_isolate=nullptr)
Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance ma...
Describes a running instance of the Dart VM. There may only be one running instance of the Dart VM in...
void AddView(int64_t view_id, const ViewportMetrics &view_metrics, AddViewCallback callback)
Notify the isolate that a new view is available.
~RuntimeController() override
bool SetAccessibilityFeatures(int32_t flags)
Forward the preference of accessibility features that must be enabled in the semantics tree to the ru...
virtual bool IsRootIsolateRunning()
Returns if the root isolate is running. The isolate must be transitioned to the running phase manuall...
Dart_Port GetMainPort()
Gets the main port identifier of the root isolate.
bool SetSemanticsEnabled(bool enabled)
Notifies the running isolate about whether the semantics tree should be generated or not....
bool SetViewportMetrics(int64_t view_id, const ViewportMetrics &metrics)
Forward the specified viewport metrics to the running isolate. If the isolate is not running,...
uint64_t GetRootIsolateGroup() const
Get an identifier that represents the Dart isolate group the root isolate is in.
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 asso...
void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port) override
Notifies this client of the name of the root isolate and its port when that isolate is launched,...
bool DispatchSemanticsAction(int32_t node_id, SemanticsAction action, fml::MallocMapping args)
Dispatch the semantics action to the specified accessibility node.
virtual bool NotifyIdle(fml::TimeDelta deadline)
Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified dead...
void ScheduleFrame() override
Requests that, at the next appropriate opportunity, a new frame be scheduled for rendering.
bool DispatchPointerDataPacket(const PointerDataPacket &packet)
Dispatch the specified pointer data message to the running root isolate.
bool SetInitialLifecycleState(const std::string &data)
Forward the initial lifecycle state data to the running isolate. If the isolate is not running,...
std::function< void(bool added)> AddViewCallback
void Render(int64_t view_id, Scene *scene, double width, double height) override
Updates the client's rendering on the GPU with the newly provided Scene.
bool SetLocales(const std::vector< std::string > &locale_data)
Forward the specified locale data to the running isolate. If the isolate is not running,...
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
bool SetDisplays(const std::vector< DisplayData > &displays)
Forward the specified display metrics to the running isolate. If the isolate is not running,...
bool HasLivePorts()
Returns if the root isolate has any live receive ports.
void EndWarmUpFrame() override
Called when a warm up frame has ended.
void SendChannelUpdate(std::string name, bool listening) override
Invoked when a listener is registered on a platform channel.
bool RemoveView(int64_t view_id)
Notify the isolate that a view is no longer available.
std::optional< std::string > GetRootIsolateServiceID() const
Get the service ID of the root isolate if the root isolate is running.
void HandlePlatformMessage(std::unique_ptr< PlatformMessage > message) override
When the Flutter application has a message to send to the underlying platform, the message needs to b...
std::shared_ptr< AssetManager > GetAssetManager() override
Returns the current collection of assets available on the platform.
double GetScaledFontSize(double unscaled_font_size, int configuration_id) const override
Synchronously invokes platform-specific APIs to apply the system text scaling on the given unscaled f...
std::string DefaultRouteName() override
The route or path that the embedder requested when the application was launched.
std::unique_ptr< RuntimeController > Spawn(RuntimeDelegate &p_client, const std::string &advisory_script_uri, const 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, const std::shared_ptr< const fml::Mapping > &persistent_isolate_data, fml::WeakPtr< IOManager > io_manager, fml::WeakPtr< ImageDecoder > image_decoder, fml::WeakPtr< ImageGeneratorRegistry > image_generator_registry, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate) const
Create a RuntimeController that shares as many resources as possible with the calling RuntimeControll...
bool ReportTimings(std::vector< int64_t > timings)
Dart code cannot fully measure the time it takes for a specific frame to be rendered....
virtual bool NotifyDestroyed()
Notify the Dart VM that the attached flutter view has been destroyed. This gives the Dart VM to perfo...
void UpdateSemantics(SemanticsUpdate *update) override
Receives an updated semantics tree from the Framework.
bool LaunchRootIsolate(const Settings &settings, const fml::closure &root_isolate_create_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration)
Launches the isolate using the window data associated with this runtime controller....
void SetNeedsReportTimings(bool value) override
Notifies this client that the application has an opinion about whether its frame timings need to be r...
virtual bool DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Dispatch the specified platform message to running root isolate.
tonic::DartErrorHandleType GetLastError()
Get the last error encountered by the microtask queue.
bool SetUserSettingsData(const std::string &data)
Forward the user settings data to the running isolate. If the isolate is not running,...
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,...
std::unique_ptr< RuntimeController > Clone() const
Clone the runtime controller. Launching an isolate with a cloned runtime controller will use the same...
FontCollection & GetFontCollection() override
Returns the current collection of fonts available on the platform.
void ShutdownPlatformIsolates()
Shuts down all registered platform isolates. Must be called from the platform thread.
bool BeginFrame(fml::TimePoint frame_time, uint64_t frame_number)
Notifies the running isolate that it should start generating a new frame.
std::optional< uint32_t > GetRootIsolateReturnCode()
Get the return code specified by the root isolate (if one is present).
std::shared_ptr< const fml::Mapping > GetPersistentIsolateData() override
The embedder can specify data that the isolate can request synchronously on launch....
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocale(const std::vector< std::string > &supported_locale_data) override
Directly invokes platform-specific APIs to compute the locale the platform would have natively resolv...
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 ...
std::string GetIsolateName()
Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from i...
virtual std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocale(const std::vector< std::string > &supported_locale_data)=0
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id)=0
virtual double GetScaledFontSize(double unscaled_font_size, int configuration_id) const =0
virtual std::string DefaultRouteName()=0
virtual std::weak_ptr< PlatformMessageHandler > GetPlatformMessageHandler() const =0
virtual void HandlePlatformMessage(std::unique_ptr< PlatformMessage > message)=0
virtual void SetNeedsReportTimings(bool value)=0
virtual void UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions)=0
virtual std::shared_ptr< AssetManager > GetAssetManager()=0
virtual void OnRootIsolateCreated()=0
virtual FontCollection & GetFontCollection()=0
virtual void Render(int64_t view_id, std::unique_ptr< flutter::LayerTree > layer_tree, float device_pixel_ratio)=0
virtual void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port)=0
virtual void OnAllViewsRendered()=0
virtual void SendChannelUpdate(std::string name, bool listening)=0
virtual void ScheduleFrame(bool regenerate_layer_trees=true)=0
std::unique_ptr< flutter::LayerTree > takeLayerTree(uint64_t width, uint64_t height)
PlatformConfiguration * platform_configuration() const
static UIDartState * Current()
A Mapping like NonOwnedMapping, but uses Free as its release proc.
constexpr int64_t ToMicroseconds() const
static constexpr TimeDelta FromMilliseconds(int64_t millis)
static constexpr TimeDelta FromMicroseconds(int64_t micros)
@ Dart_PerformanceMode_Latency
struct _Dart_IsolateGroup * Dart_IsolateGroup
DART_EXPORT void Dart_NotifyIdle(int64_t deadline)
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)
DART_EXPORT void Dart_NotifyDestroyed(void)
DART_EXPORT Dart_IsolateGroup Dart_CurrentIsolateGroup(void)
DART_EXPORT bool Dart_HasLivePorts(void)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_DCHECK(condition)
DEF_SWITCHES_START aot vmservice shared library name
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
std::function< void()> closure
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
fml::RefPtr< SkiaUnrefQueue > unref_queue
const TaskRunners task_runners
std::shared_ptr< VolatilePathTracker > volatile_path_tracker
Cache for tracking path volatility.
bool enable_impeller
Whether Impeller is enabled or not.
impeller::RuntimeStageBackend runtime_stage_backend
The expected backend for runtime stage shaders.
std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner
double device_pixel_ratio
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)