26 context_(task_runners),
27 pointer_data_packet_converter_(*this) {}
33 const std::function<
void(int64_t)>& p_idle_notification_callback,
37 std::shared_ptr<const fml::Mapping> p_persistent_isolate_data,
41 isolate_snapshot_(
std::move(p_isolate_snapshot)),
42 idle_notification_callback_(p_idle_notification_callback),
43 platform_data_(p_platform_data),
44 isolate_create_callback_(p_isolate_create_callback),
45 isolate_shutdown_callback_(p_isolate_shutdown_callback),
46 persistent_isolate_data_(
std::move(p_persistent_isolate_data)),
48 pointer_data_packet_converter_(*this) {}
52 const std::string& advisory_script_uri,
53 const std::string& advisory_script_entrypoint,
54 const std::function<
void(int64_t)>& p_idle_notification_callback,
57 const std::shared_ptr<const fml::Mapping>& p_persistent_isolate_data,
61 image_generator_registry,
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,
79 std::make_unique<RuntimeController>(p_client,
82 p_idle_notification_callback,
84 p_isolate_create_callback,
85 p_isolate_shutdown_callback,
86 p_persistent_isolate_data,
88 result->spawning_isolate_ = root_isolate_;
94 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
96 root_isolate->SetReturnCodeCallback(
nullptr);
97 auto result = root_isolate->Shutdown();
99 FML_DLOG(ERROR) <<
"Could not shutdown the root isolate.";
106 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
114 return std::make_unique<RuntimeController>(client_,
117 idle_notification_callback_,
119 isolate_create_callback_,
120 isolate_shutdown_callback_,
121 persistent_isolate_data_,
126bool RuntimeController::FlushRuntimeStateToIsolate() {
128 <<
"FlushRuntimeStateToIsolate is called more than once somehow.";
129 has_flushed_runtime_state_ =
true;
131 auto platform_configuration = GetPlatformConfigurationIfAvailable();
132 if (!platform_configuration) {
136 for (
auto const& [
view_id, viewport_metrics] :
137 platform_data_.viewport_metrics_for_views) {
138 bool added = platform_configuration->AddView(
view_id, viewport_metrics);
141 if (pending_add_view_callbacks_.find(
view_id) !=
142 pending_add_view_callbacks_.end()) {
143 pending_add_view_callbacks_[
view_id](added);
144 pending_add_view_callbacks_.erase(
view_id);
149 <<
". The Dart isolate may be in an inconsistent state.";
153 FML_DCHECK(pending_add_view_callbacks_.empty());
168 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
169 if (!platform_configuration) {
170 FML_DCHECK(has_flushed_runtime_state_ ==
false);
172 if (pending_add_view_callbacks_.find(
view_id) !=
173 pending_add_view_callbacks_.end()) {
174 FML_LOG(ERROR) <<
"View #" <<
view_id <<
" is already pending creation.";
184 FML_DCHECK(has_flushed_runtime_state_ || pending_add_view_callbacks_.empty());
187 bool added = platform_configuration->AddView(
view_id, view_metrics);
201 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
202 if (!platform_configuration) {
203 FML_DCHECK(has_flushed_runtime_state_ ==
false);
204 if (pending_add_view_callbacks_.find(
view_id) !=
205 pending_add_view_callbacks_.end()) {
206 pending_add_view_callbacks_[
view_id](
false);
207 pending_add_view_callbacks_.erase(
view_id);
213 return platform_configuration->RemoveView(
view_id);
217 auto* platform_configuration = GetPlatformConfigurationIfAvailable();
218 if (!platform_configuration) {
221 return platform_configuration->SendFocusEvent(event);
224bool RuntimeController::ViewExists(int64_t
view_id)
const {
233 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
234 return platform_configuration->UpdateViewMetrics(
view_id, metrics);
241 const std::vector<std::string>& locale_data) {
244 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
245 platform_configuration->UpdateLocales(locale_data);
255 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
256 platform_configuration->UpdateUserSettingsData(
267 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
268 platform_configuration->UpdateInitialLifecycleState(
279 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
280 platform_configuration->UpdateSemanticsEnabled(
290 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
291 platform_configuration->UpdateAccessibilityFeatures(
300 uint64_t frame_number) {
302 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
303 platform_configuration->BeginFrame(frame_time, frame_number);
311 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
312 platform_configuration->ReportTimings(std::move(timings));
328 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
335 Dart_PerformanceMode performance_mode =
337 if (performance_mode == Dart_PerformanceMode::Dart_PerformanceMode_Latency) {
344 if (idle_notification_callback_) {
352 std::unique_ptr<PlatformMessage>
message) {
353 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
354 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPlatformMessage");
355 platform_configuration->DispatchPlatformMessage(std::move(
message));
364 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
365 TRACE_EVENT0(
"flutter",
"RuntimeController::DispatchPointerDataPacket");
366 std::unique_ptr<PointerDataPacket> converted_packet =
367 pointer_data_packet_converter_.
Convert(packet);
368 if (converted_packet->GetLength() != 0) {
369 platform_configuration->DispatchPointerDataPacket(*converted_packet);
379 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
381 return platform_configuration->HitTest(
view_id, offset);
383 return {.has_platform_view =
false};
390 TRACE_EVENT1(
"flutter",
"RuntimeController::DispatchSemanticsAction",
"mode",
392 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
393 platform_configuration->DispatchSemanticsAction(
view_id, node_id,
action,
402RuntimeController::GetPlatformConfigurationIfAvailable() {
403 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
404 return root_isolate ? root_isolate->platform_configuration() :
nullptr;
408std::string RuntimeController::DefaultRouteName() {
413void RuntimeController::ScheduleFrame() {
417void RuntimeController::EndWarmUpFrame() {
422void RuntimeController::Render(int64_t
view_id,
426 const ViewportMetrics* view_metrics =
428 if (view_metrics ==
nullptr) {
432 view_metrics->device_pixel_ratio);
433 rendered_views_during_frame_.insert(
view_id);
434 CheckIfAllViewsRendered();
437void RuntimeController::MarkAsFrameBorder() {
438 rendered_views_during_frame_.clear();
441void RuntimeController::CheckIfAllViewsRendered() {
442 if (rendered_views_during_frame_.size() != 0 &&
443 rendered_views_during_frame_.size() ==
467void RuntimeController::HandlePlatformMessage(
468 std::unique_ptr<PlatformMessage>
message) {
473FontCollection& RuntimeController::GetFontCollection() {
478std::shared_ptr<AssetManager> RuntimeController::GetAssetManager() {
483void RuntimeController::UpdateIsolateDescription(
const std::string isolate_name,
484 int64_t isolate_port) {
489void RuntimeController::SetNeedsReportTimings(
bool value) {
494std::shared_ptr<const fml::Mapping>
496 return persistent_isolate_data_;
500std::unique_ptr<std::vector<std::string>>
501RuntimeController::ComputePlatformResolvedLocale(
502 const std::vector<std::string>& supported_locale_data) {
507void RuntimeController::SendChannelUpdate(std::string
name,
bool listening) {
512 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
513 return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
517 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
518 return root_isolate ? root_isolate->debug_name() :
"";
522 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
527 return Dart_HasLivePorts();
531 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
535 return root_isolate->HasPendingMicrotasks();
539 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
546 std::optional<std::string> dart_entrypoint,
547 std::optional<std::string> dart_entrypoint_library,
548 const std::vector<std::string>& dart_entrypoint_args,
549 std::unique_ptr<IsolateConfiguration> isolate_configuration,
550 std::shared_ptr<NativeAssetsManager> native_assets_manager,
551 std::optional<int64_t> engine_id) {
552 if (root_isolate_.lock()) {
553 FML_LOG(ERROR) <<
"Root isolate was already running.";
557 auto strong_root_isolate =
561 std::make_unique<PlatformConfiguration>(
this),
563 root_isolate_create_callback,
564 isolate_create_callback_,
565 isolate_shutdown_callback_,
566 std::move(dart_entrypoint),
567 std::move(dart_entrypoint_library),
568 dart_entrypoint_args,
569 std::move(isolate_configuration),
571 spawning_isolate_.lock().get(),
572 std::move(native_assets_manager))
575 if (!strong_root_isolate) {
576 FML_LOG(ERROR) <<
"Could not create root isolate.";
581 strong_root_isolate->GetIsolateGroupData().SetPlatformMessageHandler(
582 strong_root_isolate->GetRootIsolateToken(),
586 root_isolate_ = strong_root_isolate;
591 strong_root_isolate->SetReturnCodeCallback(
592 [
this](uint32_t code) { root_isolate_return_code_ = code; });
594 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
596 platform_configuration->DidCreateIsolate();
597 if (!FlushRuntimeStateToIsolate()) {
598 FML_DLOG(ERROR) <<
"Could not set up initial isolate state.";
601 if (!platform_configuration->SetEngineId(*engine_id)) {
602 FML_DLOG(ERROR) <<
"Could not set engine identifier.";
606 FML_DCHECK(
false) <<
"RuntimeController created without window binding.";
617 if (
auto isolate = root_isolate_.lock()) {
618 return isolate->GetServiceId();
624 return root_isolate_return_code_;
628 auto isolate = root_isolate_.lock();
631 Dart_IsolateGroup isolate_group = Dart_CurrentIsolateGroup();
632 return reinterpret_cast<uint64_t
>(isolate_group);
639 intptr_t loading_unit_id,
640 std::unique_ptr<const fml::Mapping> snapshot_data,
641 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
642 root_isolate_.lock()->LoadLoadingUnit(loading_unit_id,
643 std::move(snapshot_data),
644 std::move(snapshot_instructions));
648 intptr_t loading_unit_id,
652 root_isolate_.lock()->LoadLoadingUnitError(loading_unit_id, error_message,
664 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
665 platform_configuration->UpdateDisplays(
displays);
671double RuntimeController::GetScaledFontSize(
double unscaled_font_size,
672 int configuration_id)
const {
676void RuntimeController::RequestViewFocusChange(
677 const ViewFocusChangeRequest& request) {
682 platform_isolate_manager_->ShutdownPlatformIsolates();
686 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
688 root_isolate->SetOwnerToCurrentThread();
692RuntimeController::Locale::Locale(std::string language_code_,
693 std::string country_code_,
694 std::string script_code_,
695 std::string variant_code_)
696 : language_code(
std::move(language_code_)),
697 country_code(
std::move(country_code_)),
698 script_code(
std::move(script_code_)),
699 variant_code(
std::move(variant_code_)) {}
701RuntimeController::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, std::shared_ptr< NativeAssetsManager > native_assets_manager=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...
void SetRootIsolateOwnerToCurrentThread()
void SetSemanticsTreeEnabled(bool enabled) override
Notifies whether Framework starts generating semantics tree.
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...
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 HasPendingMicrotasks()
Returns if the root isolate has any pending microtasks.
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,...
HitTestResponse HitTest(int64_t view_id, const flutter::PointData offset)
Requests to perform framework hit test from the engine.
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.
virtual bool IsRootIsolateRunning() const
Returns if the root isolate is running. The isolate must be transitioned to the running phase manuall...
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, std::shared_ptr< NativeAssetsManager > native_assets_manager, std::optional< int64_t > engine_id)
Launches the isolate using the window data associated with this runtime controller....
bool ReportTimings(std::vector< int64_t > timings)
Dart code cannot fully measure the time it takes for a specific frame to be rendered....
bool DispatchSemanticsAction(int64_t view_id, int32_t node_id, SemanticsAction action, fml::MallocMapping args)
Dispatch the semantics action to the specified accessibility node.
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...
bool SendViewFocusEvent(const ViewFocusEvent &event)
Notify the isolate that the focus state of a native view has changed.
void ShutdownPlatformIsolates()
Shuts down all registered platform isolates. Must be called from the platform thread.
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::TaskRunnerAffineWeakPtr< ImageDecoder > image_decoder, fml::TaskRunnerAffineWeakPtr< ImageGeneratorRegistry > image_generator_registry, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate) const
Create a RuntimeController that shares as many resources as possible with the calling RuntimeControll...
void UpdateSemantics(int64_t view_id, SemanticsUpdate *update) override
Receives an updated semantics tree from the Framework.
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 ...
void SetApplicationLocale(std::string locale) override
Framework sets the application locale.
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 SetApplicationLocale(std::string locale)=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 UpdateSemantics(int64_t view_id, SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions)=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 RequestViewFocusChange(const ViewFocusChangeRequest &request)=0
virtual void SetSemanticsTreeEnabled(bool enabled)=0
virtual void ScheduleFrame(bool regenerate_layer_trees=true)=0
SemanticsNodeUpdates takeNodes()
CustomAccessibilityActionUpdates takeActions()
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)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply 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
bool enable_flutter_gpu
Whether flutter_gpu is enabled or not.
std::shared_future< impeller::RuntimeStageBackend > runtime_stage_backend
The runtime stage backend for fragment shaders.
const TaskRunners task_runners
bool enable_impeller
Whether Impeller is enabled or not.
std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner
bool deterministic_rendering_enabled
Whether deterministic rendering practices should be used.
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val)