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"
28 context_(task_runners),
29 pointer_data_packet_converter_(*this) {}
35 const std::function<
void(int64_t)>& p_idle_notification_callback,
39 std::shared_ptr<const fml::Mapping> p_persistent_isolate_data,
43 isolate_snapshot_(
std::move(p_isolate_snapshot)),
44 idle_notification_callback_(p_idle_notification_callback),
45 platform_data_(p_platform_data),
46 isolate_create_callback_(p_isolate_create_callback),
47 isolate_shutdown_callback_(p_isolate_shutdown_callback),
48 persistent_isolate_data_(
std::move(p_persistent_isolate_data)),
50 pointer_data_packet_converter_(*this) {}
54 const std::string& advisory_script_uri,
55 const std::string& advisory_script_entrypoint,
56 const std::function<
void(int64_t)>& p_idle_notification_callback,
59 const std::shared_ptr<const fml::Mapping>& p_persistent_isolate_data,
65 std::move(snapshot_delegate),
66 std::move(io_manager),
68 std::move(image_decoder),
69 std::move(image_generator_registry),
71 advisory_script_entrypoint,
77 std::make_unique<RuntimeController>(p_client,
80 p_idle_notification_callback,
82 p_isolate_create_callback,
83 p_isolate_shutdown_callback,
84 p_persistent_isolate_data,
86 result->spawning_isolate_ = root_isolate_;
92 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
94 root_isolate->SetReturnCodeCallback(
nullptr);
95 auto result = root_isolate->Shutdown();
104 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
112 return std::make_unique<RuntimeController>(client_,
115 idle_notification_callback_,
117 isolate_create_callback_,
118 isolate_shutdown_callback_,
119 persistent_isolate_data_,
124bool RuntimeController::FlushRuntimeStateToIsolate() {
126 <<
"FlushRuntimeStateToIsolate is called more than once somehow.";
127 has_flushed_runtime_state_ =
true;
129 auto platform_configuration = GetPlatformConfigurationIfAvailable();
130 if (!platform_configuration) {
134 for (
auto const& [view_id, viewport_metrics] :
136 bool added = platform_configuration->AddView(view_id, viewport_metrics);
139 if (pending_add_view_callbacks_.find(view_id) !=
140 pending_add_view_callbacks_.end()) {
141 pending_add_view_callbacks_[view_id](added);
142 pending_add_view_callbacks_.erase(view_id);
147 <<
". The Dart isolate may be in an inconsistent state.";
151 FML_DCHECK(pending_add_view_callbacks_.empty());
166 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
167 if (!platform_configuration) {
168 FML_DCHECK(has_flushed_runtime_state_ ==
false);
170 if (pending_add_view_callbacks_.find(view_id) !=
171 pending_add_view_callbacks_.end()) {
172 FML_LOG(
ERROR) <<
"View #" << view_id <<
" is already pending creation.";
178 pending_add_view_callbacks_[view_id] = std::move(
callback);
182 FML_DCHECK(has_flushed_runtime_state_ || pending_add_view_callbacks_.empty());
185 bool added = platform_configuration->AddView(view_id, view_metrics);
199 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
200 if (!platform_configuration) {
201 FML_DCHECK(has_flushed_runtime_state_ ==
false);
202 if (pending_add_view_callbacks_.find(view_id) !=
203 pending_add_view_callbacks_.end()) {
204 pending_add_view_callbacks_[view_id](
false);
205 pending_add_view_callbacks_.erase(view_id);
211 return platform_configuration->RemoveView(view_id);
214bool RuntimeController::ViewExists(int64_t view_id)
const {
223 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
224 return platform_configuration->UpdateViewMetrics(view_id, metrics);
231 const std::vector<std::string>& locale_data) {
234 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
235 platform_configuration->UpdateLocales(locale_data);
245 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
246 platform_configuration->UpdateUserSettingsData(
257 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
258 platform_configuration->UpdateInitialLifecycleState(
269 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
270 platform_configuration->UpdateSemanticsEnabled(
280 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
281 platform_configuration->UpdateAccessibilityFeatures(
290 uint64_t frame_number) {
292 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
293 platform_configuration->BeginFrame(frame_time, frame_number);
301 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
302 platform_configuration->ReportTimings(std::move(timings));
318 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
334 if (idle_notification_callback_) {
342 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
355 std::unique_ptr<PlatformMessage>
message) {
356 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
357 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPlatformMessage");
358 platform_configuration->DispatchPlatformMessage(std::move(
message));
367 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
368 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPointerDataPacket");
369 std::unique_ptr<PointerDataPacket> converted_packet =
370 pointer_data_packet_converter_.
Convert(packet);
371 if (converted_packet->GetLength() != 0) {
372 platform_configuration->DispatchPointerDataPacket(*converted_packet);
383 TRACE_EVENT1(
"flutter",
"RuntimeController::DispatchSemanticsAction",
"mode",
385 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
386 platform_configuration->DispatchSemanticsAction(node_id,
action,
395RuntimeController::GetPlatformConfigurationIfAvailable() {
396 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
397 return root_isolate ? root_isolate->platform_configuration() :
nullptr;
401std::string RuntimeController::DefaultRouteName() {
406void RuntimeController::ScheduleFrame() {
410void RuntimeController::EndWarmUpFrame() {
415void RuntimeController::Render(int64_t view_id,
419 const ViewportMetrics* view_metrics =
421 if (view_metrics ==
nullptr) {
425 view_metrics->device_pixel_ratio);
426 rendered_views_during_frame_.insert(view_id);
427 CheckIfAllViewsRendered();
430void RuntimeController::MarkAsFrameBorder() {
431 rendered_views_during_frame_.clear();
434void RuntimeController::CheckIfAllViewsRendered() {
435 if (rendered_views_during_frame_.size() != 0 &&
436 rendered_views_during_frame_.size() ==
444void RuntimeController::UpdateSemantics(SemanticsUpdate*
update) {
451void RuntimeController::HandlePlatformMessage(
452 std::unique_ptr<PlatformMessage>
message) {
457FontCollection& RuntimeController::GetFontCollection() {
462std::shared_ptr<AssetManager> RuntimeController::GetAssetManager() {
467void RuntimeController::UpdateIsolateDescription(
const std::string isolate_name,
468 int64_t isolate_port) {
473void RuntimeController::SetNeedsReportTimings(
bool value) {
478std::shared_ptr<const fml::Mapping>
480 return persistent_isolate_data_;
484std::unique_ptr<std::vector<std::string>>
485RuntimeController::ComputePlatformResolvedLocale(
486 const std::vector<std::string>& supported_locale_data) {
491void RuntimeController::SendChannelUpdate(std::string
name,
bool listening) {
496 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
497 return root_isolate ? root_isolate->main_port() :
ILLEGAL_PORT;
501 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
502 return root_isolate ? root_isolate->debug_name() :
"";
506 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
515 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
522 std::optional<std::string> dart_entrypoint,
523 std::optional<std::string> dart_entrypoint_library,
524 const std::vector<std::string>& dart_entrypoint_args,
525 std::unique_ptr<IsolateConfiguration> isolate_configuration) {
526 if (root_isolate_.lock()) {
531 auto strong_root_isolate =
535 std::make_unique<PlatformConfiguration>(
this),
537 root_isolate_create_callback,
538 isolate_create_callback_,
539 isolate_shutdown_callback_,
540 std::move(dart_entrypoint),
541 std::move(dart_entrypoint_library),
542 dart_entrypoint_args,
543 std::move(isolate_configuration),
545 spawning_isolate_.lock().get())
548 if (!strong_root_isolate) {
554 strong_root_isolate->GetIsolateGroupData().SetPlatformMessageHandler(
555 strong_root_isolate->GetRootIsolateToken(),
559 root_isolate_ = strong_root_isolate;
564 strong_root_isolate->SetReturnCodeCallback(
565 [
this](uint32_t
code) { root_isolate_return_code_ =
code; });
567 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
569 platform_configuration->DidCreateIsolate();
570 if (!FlushRuntimeStateToIsolate()) {
571 FML_DLOG(
ERROR) <<
"Could not set up initial isolate state.";
574 FML_DCHECK(
false) <<
"RuntimeController created without window binding.";
585 if (
auto isolate = root_isolate_.lock()) {
586 return isolate->GetServiceId();
592 return root_isolate_return_code_;
596 auto isolate = root_isolate_.lock();
600 return reinterpret_cast<uint64_t
>(isolate_group);
607 intptr_t loading_unit_id,
608 std::unique_ptr<const fml::Mapping> snapshot_data,
609 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
610 root_isolate_.lock()->LoadLoadingUnit(loading_unit_id,
611 std::move(snapshot_data),
612 std::move(snapshot_instructions));
616 intptr_t loading_unit_id,
620 root_isolate_.lock()->LoadLoadingUnitError(loading_unit_id, error_message,
632 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
633 platform_configuration->UpdateDisplays(displays);
639double RuntimeController::GetScaledFontSize(
double unscaled_font_size,
640 int configuration_id)
const {
645 platform_isolate_manager_->ShutdownPlatformIsolates();
648RuntimeController::Locale::Locale(std::string language_code_,
649 std::string country_code_,
650 std::string script_code_,
651 std::string variant_code_)
652 : language_code(
std::move(language_code_)),
653 country_code(
std::move(country_code_)),
654 script_code(
std::move(script_code_)),
655 variant_code(
std::move(variant_code_)) {}
657RuntimeController::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...
std::unique_ptr< PointerDataPacket > Convert(const PointerDataPacket &packet)
Converts pointer data packet into a form that framework understands. The raw pointer data packet from...
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...
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...
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
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.
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.
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...
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....
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...
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....
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
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)
Dart_NativeFunction function
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
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)