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);
381 TRACE_EVENT1(
"flutter",
"RuntimeController::DispatchSemanticsAction",
"mode",
383 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
384 platform_configuration->DispatchSemanticsAction(
view_id, node_id,
action,
393RuntimeController::GetPlatformConfigurationIfAvailable() {
394 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
395 return root_isolate ? root_isolate->platform_configuration() :
nullptr;
399std::string RuntimeController::DefaultRouteName() {
404void RuntimeController::ScheduleFrame() {
408void RuntimeController::EndWarmUpFrame() {
413void RuntimeController::Render(int64_t
view_id,
417 const ViewportMetrics* view_metrics =
419 if (view_metrics ==
nullptr) {
423 view_metrics->device_pixel_ratio);
424 rendered_views_during_frame_.insert(
view_id);
425 CheckIfAllViewsRendered();
428void RuntimeController::MarkAsFrameBorder() {
429 rendered_views_during_frame_.clear();
432void RuntimeController::CheckIfAllViewsRendered() {
433 if (rendered_views_during_frame_.size() != 0 &&
434 rendered_views_during_frame_.size() ==
458void RuntimeController::HandlePlatformMessage(
459 std::unique_ptr<PlatformMessage>
message) {
464FontCollection& RuntimeController::GetFontCollection() {
469std::shared_ptr<AssetManager> RuntimeController::GetAssetManager() {
474void RuntimeController::UpdateIsolateDescription(
const std::string isolate_name,
475 int64_t isolate_port) {
480void RuntimeController::SetNeedsReportTimings(
bool value) {
485std::shared_ptr<const fml::Mapping>
487 return persistent_isolate_data_;
491std::unique_ptr<std::vector<std::string>>
492RuntimeController::ComputePlatformResolvedLocale(
493 const std::vector<std::string>& supported_locale_data) {
498void RuntimeController::SendChannelUpdate(std::string
name,
bool listening) {
503 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
504 return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
508 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
509 return root_isolate ? root_isolate->debug_name() :
"";
513 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
518 return Dart_HasLivePorts();
522 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
526 return root_isolate->HasPendingMicrotasks();
530 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
537 std::optional<std::string> dart_entrypoint,
538 std::optional<std::string> dart_entrypoint_library,
539 const std::vector<std::string>& dart_entrypoint_args,
540 std::unique_ptr<IsolateConfiguration> isolate_configuration,
541 std::shared_ptr<NativeAssetsManager> native_assets_manager,
542 std::optional<int64_t> engine_id) {
543 if (root_isolate_.lock()) {
544 FML_LOG(ERROR) <<
"Root isolate was already running.";
548 auto strong_root_isolate =
552 std::make_unique<PlatformConfiguration>(
this),
554 root_isolate_create_callback,
555 isolate_create_callback_,
556 isolate_shutdown_callback_,
557 std::move(dart_entrypoint),
558 std::move(dart_entrypoint_library),
559 dart_entrypoint_args,
560 std::move(isolate_configuration),
562 spawning_isolate_.lock().get(),
563 std::move(native_assets_manager))
566 if (!strong_root_isolate) {
567 FML_LOG(ERROR) <<
"Could not create root isolate.";
572 strong_root_isolate->GetIsolateGroupData().SetPlatformMessageHandler(
573 strong_root_isolate->GetRootIsolateToken(),
577 root_isolate_ = strong_root_isolate;
582 strong_root_isolate->SetReturnCodeCallback(
583 [
this](uint32_t code) { root_isolate_return_code_ = code; });
585 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
587 platform_configuration->DidCreateIsolate();
588 if (!FlushRuntimeStateToIsolate()) {
589 FML_DLOG(ERROR) <<
"Could not set up initial isolate state.";
592 if (!platform_configuration->SetEngineId(*engine_id)) {
593 FML_DLOG(ERROR) <<
"Could not set engine identifier.";
597 FML_DCHECK(
false) <<
"RuntimeController created without window binding.";
608 if (
auto isolate = root_isolate_.lock()) {
609 return isolate->GetServiceId();
615 return root_isolate_return_code_;
619 auto isolate = root_isolate_.lock();
622 Dart_IsolateGroup isolate_group = Dart_CurrentIsolateGroup();
623 return reinterpret_cast<uint64_t
>(isolate_group);
630 intptr_t loading_unit_id,
631 std::unique_ptr<const fml::Mapping> snapshot_data,
632 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
633 root_isolate_.lock()->LoadLoadingUnit(loading_unit_id,
634 std::move(snapshot_data),
635 std::move(snapshot_instructions));
639 intptr_t loading_unit_id,
643 root_isolate_.lock()->LoadLoadingUnitError(loading_unit_id, error_message,
655 if (
auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
656 platform_configuration->UpdateDisplays(
displays);
662double RuntimeController::GetScaledFontSize(
double unscaled_font_size,
663 int configuration_id)
const {
667void RuntimeController::RequestViewFocusChange(
668 const ViewFocusChangeRequest& request) {
673 platform_isolate_manager_->ShutdownPlatformIsolates();
677 std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
679 root_isolate->SetOwnerToCurrentThread();
683RuntimeController::Locale::Locale(std::string language_code_,
684 std::string country_code_,
685 std::string script_code_,
686 std::string variant_code_)
687 : language_code(
std::move(language_code_)),
688 country_code(
std::move(country_code_)),
689 script_code(
std::move(script_code_)),
690 variant_code(
std::move(variant_code_)) {}
692RuntimeController::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,...
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 GBytes * message
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)