19#include "rapidjson/document.h"
39 const std::shared_ptr<fml::ConcurrentTaskRunner>& image_decoder_task_runner,
42 std::unique_ptr<Animator> animator,
44 const std::shared_ptr<FontCollection>& font_collection,
45 std::unique_ptr<RuntimeController> runtime_controller,
46 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
51 font_collection_(font_collection),
54 image_decoder_task_runner,
56 gpu_disabled_switch)),
59 pointer_data_dispatcher_ = dispatcher_maker(*
this);
69 std::unique_ptr<Animator> animator,
73 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
74 const std::shared_future<impeller::RuntimeStageBackend>&
75 runtime_stage_backend)
78 vm.GetConcurrentWorkerTaskRunner(),
85 gpu_disabled_switch) {
86 runtime_controller_ = std::make_unique<RuntimeController>(
89 std::move(isolate_snapshot),
97 std::move(snapshot_delegate),
98 std::move(io_manager),
100 image_decoder_->GetWeakPtr(),
101 image_generator_registry_.GetWeakPtr(),
102 settings_.advisory_script_uri,
103 settings_.advisory_script_entrypoint,
105 .skia_deterministic_rendering_on_cpu,
106 vm.GetConcurrentWorkerTaskRunner(),
107 runtime_stage_backend,
108 settings_.enable_impeller,
109 settings_.enable_flutter_gpu
117 std::unique_ptr<Animator> animator,
118 const std::string& initial_route,
121 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
const {
122 auto result = std::make_unique<Engine>(
126 runtime_controller_->GetDartVM()->GetConcurrentWorkerTaskRunner(),
133 gpu_disabled_switch);
134 result->runtime_controller_ = runtime_controller_->Spawn(
143 result->GetImageDecoderWeakPtr(),
144 result->GetImageGeneratorRegistry(),
145 std::move(snapshot_delegate));
146 result->initial_route_ = initial_route;
147 result->asset_manager_ = asset_manager_;
154 return weak_factory_.GetWeakPtr();
158 TRACE_EVENT0(
"flutter",
"Engine::SetupDefaultFontManager");
163 return asset_manager_;
167 return image_decoder_->GetWeakPtr();
172 return image_generator_registry_.
GetWeakPtr();
176 const std::shared_ptr<AssetManager>& new_asset_manager) {
177 if (asset_manager_ && new_asset_manager &&
178 *asset_manager_ == *new_asset_manager) {
182 asset_manager_ = new_asset_manager;
184 if (!asset_manager_) {
190 font_collection_->RegisterFonts(asset_manager_);
194 font_collection_->RegisterTestFonts();
197 if (native_assets_manager_ ==
nullptr) {
198 native_assets_manager_ = std::make_shared<NativeAssetsManager>();
200 native_assets_manager_->RegisterNativeAssets(asset_manager_);
207 if (!configuration.
IsValid()) {
208 FML_LOG(ERROR) <<
"Engine run configuration was invalid.";
212 runtime_controller_ = runtime_controller_->Clone();
218 if (!configuration.
IsValid()) {
219 FML_LOG(ERROR) <<
"Engine run configuration was invalid.";
225#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
234 if (runtime_controller_->IsRootIsolateRunning()) {
241 auto root_isolate_create_callback = [&]() {
255 engine->runtime_controller_->SetRootIsolateOwnerToCurrentThread();
260 if (!runtime_controller_->LaunchRootIsolate(
262 root_isolate_create_callback,
267 native_assets_manager_,
273 auto service_id = runtime_controller_->GetRootIsolateServiceID();
274 if (service_id.has_value()) {
275 std::unique_ptr<PlatformMessage> service_id_message =
276 std::make_unique<flutter::PlatformMessage>(
278 HandlePlatformMessage(std::move(service_id_message));
289 <<
"Unable to move the UI task runner to the platform thread";
297 runtime_controller_->BeginFrame(frame_time, frame_number);
301 runtime_controller_->ReportTimings(std::move(timings));
305 runtime_controller_->NotifyIdle(deadline);
309 return runtime_controller_->GetRootIsolateReturnCode();
313 return runtime_controller_->GetMainPort();
317 return runtime_controller_->GetIsolateName();
321 return runtime_controller_->HasLivePorts();
325 return runtime_controller_->HasPendingMicrotasks();
329 return runtime_controller_->GetLastError();
334 std::function<
void(
bool added)>
callback) {
335 runtime_controller_->AddView(
view_id, view_metrics, std::move(
callback));
339 return runtime_controller_->RemoveView(
view_id);
343 return runtime_controller_->SendViewFocusEvent(event);
348 runtime_controller_->SetViewportMetrics(
view_id, metrics);
355 if (HandleLifecyclePlatformMessage(
message.get())) {
359 if (HandleLocalizationPlatformMessage(
message.get())) {
363 HandleSettingsPlatformMessage(
message.get());
365 }
else if (!runtime_controller_->IsRootIsolateRunning() &&
368 HandleNavigationPlatformMessage(std::move(
message));
372 if (runtime_controller_->IsRootIsolateRunning() &&
373 runtime_controller_->DispatchPlatformMessage(std::move(
message))) {
377 FML_DLOG(WARNING) <<
"Dropping platform message on channel: " <<
channel;
382 std::string state(
reinterpret_cast<const char*
>(
data.GetMapping()),
388 if (state ==
"AppLifecycleState.resumed" ||
389 state ==
"AppLifecycleState.inactive") {
392 runtime_controller_->SetInitialLifecycleState(state);
397bool Engine::HandleNavigationPlatformMessage(
398 std::unique_ptr<PlatformMessage>
message) {
401 rapidjson::Document document;
402 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
404 if (document.HasParseError() || !document.IsObject()) {
407 auto root = document.GetObject();
408 auto method = root.FindMember(
"method");
409 if (method->value !=
"setInitialRoute") {
412 auto route = root.FindMember(
"args");
413 initial_route_ = route->value.GetString();
420 rapidjson::Document document;
421 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
423 if (document.HasParseError() || !document.IsObject()) {
426 auto root = document.GetObject();
427 auto method = root.FindMember(
"method");
428 if (method == root.MemberEnd()) {
431 const size_t strings_per_locale = 4;
432 if (method->value ==
"setLocale") {
434 auto args = root.FindMember(
"args");
435 if (
args == root.MemberEnd() || !
args->value.IsArray()) {
439 if (
args->value.Size() % strings_per_locale != 0) {
442 std::vector<std::string> locale_data;
443 for (
size_t locale_index = 0; locale_index <
args->value.Size();
444 locale_index += strings_per_locale) {
445 if (!
args->value[locale_index].IsString() ||
446 !
args->value[locale_index + 1].IsString()) {
449 locale_data.push_back(
args->value[locale_index].GetString());
450 locale_data.push_back(
args->value[locale_index + 1].GetString());
451 locale_data.push_back(
args->value[locale_index + 2].GetString());
452 locale_data.push_back(
args->value[locale_index + 3].GetString());
455 return runtime_controller_->SetLocales(locale_data);
462 std::string jsonData(
reinterpret_cast<const char*
>(
data.GetMapping()),
464 if (runtime_controller_->SetUserSettingsData(jsonData)) {
470 std::unique_ptr<PointerDataPacket> packet,
471 uint64_t trace_flow_id) {
476 pointer_data_dispatcher_->DispatchPacket(std::move(packet), trace_flow_id);
483 runtime_controller_->DispatchSemanticsAction(
view_id, node_id,
action,
488 runtime_controller_->SetSemanticsEnabled(enabled);
492 runtime_controller_->SetAccessibilityFeatures(flags);
495std::string Engine::DefaultRouteName() {
496 if (!initial_route_.empty()) {
497 return initial_route_;
503 animator_->RequestFrame(regenerate_layer_trees);
507 animator_->OnAllViewsRendered();
510void Engine::Render(int64_t
view_id,
511 std::unique_ptr<flutter::LayerTree> layer_tree,
512 float device_pixel_ratio) {
518 if (layer_tree->frame_size().IsEmpty() || device_pixel_ratio <= 0.0f) {
522 animator_->Render(
view_id, std::move(layer_tree), device_pixel_ratio);
525void Engine::UpdateSemantics(int64_t
view_id,
532void Engine::SetApplicationLocale(std::string locale) {
536void Engine::SetSemanticsTreeEnabled(
bool enabled) {
540void Engine::HandlePlatformMessage(std::unique_ptr<PlatformMessage>
message) {
542 HandleAssetPlatformMessage(std::move(
message));
548void Engine::OnRootIsolateCreated() {
552void Engine::UpdateIsolateDescription(
const std::string isolate_name,
553 int64_t isolate_port) {
557std::unique_ptr<std::vector<std::string>> Engine::ComputePlatformResolvedLocale(
558 const std::vector<std::string>& supported_locale_data) {
562double Engine::GetScaledFontSize(
double unscaled_font_size,
563 int configuration_id)
const {
567void Engine::RequestViewFocusChange(
const ViewFocusChangeRequest& request) {
571void Engine::SetNeedsReportTimings(
bool needs_reporting) {
576 return *font_collection_;
580 uint64_t trace_flow_id) {
581 animator_->EnqueueTraceFlowId(trace_flow_id);
582 if (runtime_controller_) {
583 runtime_controller_->DispatchPointerDataPacket(*packet);
589 animator_->ScheduleSecondaryVsyncCallback(
id,
callback);
592void Engine::HandleAssetPlatformMessage(
593 std::unique_ptr<PlatformMessage>
message) {
599 std::string asset_name(
reinterpret_cast<const char*
>(
data.GetMapping()),
602 if (asset_manager_) {
603 std::unique_ptr<fml::Mapping> asset_mapping =
604 asset_manager_->GetAsMapping(asset_name);
606 response->Complete(std::move(asset_mapping));
611 response->CompleteEmpty();
615 return last_entry_point_;
619 return last_entry_point_library_;
623 return last_entry_point_args_;
627 return last_engine_id_;
631void Engine::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
635std::weak_ptr<PlatformMessageHandler> Engine::GetPlatformMessageHandler()
640void Engine::SendChannelUpdate(std::string
name,
bool listening) {
645 intptr_t loading_unit_id,
646 std::unique_ptr<const fml::Mapping> snapshot_data,
647 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
648 if (runtime_controller_->IsRootIsolateRunning()) {
649 runtime_controller_->LoadDartDeferredLibrary(
650 loading_unit_id, std::move(snapshot_data),
651 std::move(snapshot_instructions));
659 const std::string& error_message,
661 if (runtime_controller_->IsRootIsolateRunning()) {
662 runtime_controller_->LoadDartDeferredLibraryError(loading_unit_id,
663 error_message, transient);
668 return animator_->GetVsyncWaiter();
672 runtime_controller_->SetDisplays(
displays);
677 runtime_controller_->ShutdownPlatformIsolates();
681 runtime_controller_->FlushMicrotaskQueue();
Describes a running instance of the Dart VM. There may only be one running instance of the Dart VM in...
While the engine operates entirely on the UI task runner, it needs the capabilities of the other comp...
virtual double GetScaledFontSize(double unscaled_font_size, int configuration_id) const =0
Synchronously invokes platform-specific APIs to apply the system text scaling on the given unscaled f...
virtual void UpdateIsolateDescription(const std::string isolate_name, int64_t isolate_port)=0
Notifies the shell of the name of the root isolate and its port when that isolate is launched,...
virtual std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocale(const std::vector< std::string > &supported_locale_data)=0
Directly invokes platform-specific APIs to compute the locale the platform would have natively resolv...
virtual void OnEngineSetApplicationLocale(std::string locale)=0
Framework sets the application locale.
virtual void OnEngineSetSemanticsTreeEnabled(bool enabled)=0
When the Framework starts or stops generating semantics tree, this new information needs to be convey...
virtual void OnPreEngineRestart()=0
Notifies the delegate that the root isolate of the application is about to be discarded and a new iso...
virtual void OnEngineChannelUpdate(std::string name, bool listening)=0
Invoked when a listener is registered on a platform channel.
virtual void OnEngineHandlePlatformMessage(std::unique_ptr< PlatformMessage > message)=0
When the Flutter application has a message to send to the underlying platform, the message needs to b...
virtual const std::shared_ptr< PlatformMessageHandler > & GetPlatformMessageHandler() const =0
Returns the delegate object that handles PlatformMessage's from Flutter to the host platform (and its...
virtual void SetNeedsReportTimings(bool needs_reporting)=0
Notifies the shell that the application has an opinion about whether its frame timings need to be rep...
virtual void OnEngineUpdateSemantics(int64_t view_id, SemanticsNodeUpdates updates, CustomAccessibilityActionUpdates actions)=0
When the accessibility tree has been updated by the Flutter application, this new information needs t...
virtual void RequestViewFocusChange(const ViewFocusChangeRequest &request)=0
Notifies the client that the Flutter view focus state has changed and the platform view should be upd...
virtual void OnRootIsolateCreated()=0
Notifies the shell that the root isolate is created. Currently, this information is to add to the ser...
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id)=0
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
void SetAccessibilityFeatures(int32_t flags)
Notifies the engine that the embedder has expressed an opinion about where the flags to set on the ac...
void FlushMicrotaskQueue()
Flushes the microtask queue of the root isolate.
void SetupDefaultFontManager()
Setup default font manager according to specific platform.
bool RemoveView(int64_t view_id)
Notify the Flutter application that a view is no longer available.
fml::TaskRunnerAffineWeakPtr< ImageDecoder > GetImageDecoderWeakPtr()
void NotifyIdle(fml::TimeDelta deadline)
Notifies the engine that the UI task runner is not expected to undertake a new frame workload till a ...
void SetViewportMetrics(int64_t view_id, const ViewportMetrics &metrics)
Updates the viewport metrics for a view. The viewport metrics detail the size of the rendering viewpo...
void ReportTimings(std::vector< int64_t > timings)
Dart code cannot fully measure the time it takes for a specific frame to be rendered....
void DispatchSemanticsAction(int64_t view_id, int node_id, SemanticsAction action, fml::MallocMapping args)
Notifies the engine that the embedder encountered an accessibility related action on the specified no...
void OnAllViewsRendered() override
fml::TaskRunnerAffineWeakPtr< ImageGeneratorRegistry > GetImageGeneratorRegistry()
Get the ImageGeneratorRegistry associated with the current engine.
void ShutdownPlatformIsolates()
Shuts down all registered platform isolates. Must be called from the platform thread.
void SetDisplays(const std::vector< DisplayData > &displays)
Updates the display metrics for the currently running Flutter application.
const std::weak_ptr< VsyncWaiter > GetVsyncWaiter() const
void BeginFrame(fml::TimePoint frame_time, uint64_t frame_number)
Notifies the engine that it is time to begin working on a new frame previously scheduled via a call t...
tonic::DartErrorHandleType GetUIIsolateLastError()
Errors that are unhandled on the Dart message loop are kept for further inspection till the next unha...
FontCollection & GetFontCollection() override
std::shared_ptr< AssetManager > GetAssetManager() override
RunStatus Run(RunConfiguration configuration)
Moves the root isolate to the DartIsolate::Phase::Running phase on a successful call to this method.
std::string GetUIIsolateName()
Gets the debug name of the root isolate. By default, the debug name of the isolate is derived from it...
~Engine() override
Destroys the engine engine. Called by the shell on the UI task runner. The running root isolate is te...
const std::string & GetLastEntrypointLibrary() const
Get the last Entrypoint Library that was used in the RunConfiguration when |EngineRun| was called.
bool UpdateAssetManager(const std::shared_ptr< AssetManager > &asset_manager)
Updates the asset manager referenced by the root isolate of a Flutter application....
Dart_Port GetUIIsolateMainPort()
Gets the main port of the root isolate. Since the isolate is created immediately in the constructor o...
void DispatchPointerDataPacket(std::unique_ptr< PointerDataPacket > packet, uint64_t trace_flow_id)
Notifies the engine that the embedder has sent it a pointer data packet. A pointer data packet may co...
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 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,...
void AddView(int64_t view_id, const ViewportMetrics &view_metrics, std::function< void(bool added)> callback)
Notify the Flutter application that a new view is available.
void DoDispatchPacket(std::unique_ptr< PointerDataPacket > packet, uint64_t trace_flow_id) override
bool UIIsolateHasLivePorts()
It is an unexpected challenge to determine when a Dart application is "done". The application cannot ...
const std::string & GetLastEntrypoint() const
Get the last Entrypoint that was used in the RunConfiguration when |EngineRun| was called.
std::optional< int64_t > GetLastEngineId() const
Get the last Engine Id that was used in the RunConfiguration when |EngineRun| was called.
fml::TaskRunnerAffineWeakPtr< Engine > GetWeakPtr() const
RunStatus
Indicates the result of the call to Engine::Run.
bool Restart(RunConfiguration configuration)
Tears down an existing root isolate, reuses the components of that isolate and attempts to launch a n...
bool UIIsolateHasPendingMicrotasks()
Another signal of liveness is the presence of microtasks that have been queued by the application but...
const std::vector< std::string > & GetLastEntrypointArgs() const
Get the last Entrypoint Arguments that was used in the RunConfiguration when |EngineRun| was called....
std::unique_ptr< Engine > Spawn(Delegate &delegate, const PointerDataDispatcherMaker &dispatcher_maker, const Settings &settings, std::unique_ptr< Animator > animator, const std::string &initial_route, const fml::WeakPtr< IOManager > &io_manager, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch) const
Create a Engine that shares as many resources as possible with the calling Engine such that together ...
void SetSemanticsEnabled(bool enabled)
Notifies the engine that the embedder has expressed an opinion about whether the accessibility tree s...
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Notifies the engine that the embedder has sent it a message. This call originates in the platform vie...
Engine(Delegate &delegate, const PointerDataDispatcherMaker &dispatcher_maker, const std::shared_ptr< fml::ConcurrentTaskRunner > &image_decoder_task_runner, const TaskRunners &task_runners, const Settings &settings, std::unique_ptr< Animator > animator, const fml::WeakPtr< IOManager > &io_manager, const std::shared_ptr< FontCollection > &font_collection, std::unique_ptr< RuntimeController > runtime_controller, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch)
Creates an instance of the engine with a supplied RuntimeController. Use the other constructor except...
std::optional< uint32_t > GetUIIsolateReturnCode()
As described in the discussion for UIIsolateHasLivePorts, the "done-ness" of a Dart application is tr...
void ScheduleSecondaryVsyncCallback(uintptr_t id, const fml::closure &callback) override
Schedule a secondary callback to be executed right after the main VsyncWaiter::AsyncWaitForVsync call...
bool SendViewFocusEvent(const ViewFocusEvent &event)
Notify the Flutter application that the focus state of a native view has changed.
fml::TaskRunnerAffineWeakPtr< ImageGeneratorRegistry > GetWeakPtr() const
Specifies all the configuration required by the runtime library to launch the root isolate....
std::unique_ptr< IsolateConfiguration > TakeIsolateConfiguration()
The engine uses this to take the isolate configuration from the run configuration....
std::shared_ptr< AssetManager > GetAssetManager() const
const std::string & GetEntrypoint() const
const std::vector< std::string > & GetEntrypointArgs() const
std::optional< int64_t > GetEngineId() const
bool IsValid() const
A valid run configuration only guarantees that the engine should be able to find the assets and the i...
const std::string & GetEntrypointLibrary() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
A Mapping like NonOwnedMapping, but uses Free as its release proc.
static MallocMapping Copy(const T *begin, const T *end)
static MessageLoopTaskQueues * GetInstance()
bool Merge(TaskQueueId owner, TaskQueueId subsumed)
virtual void PostTask(const fml::closure &task) override
virtual TaskQueueId GetTaskQueueId()
std::unique_ptr< RuntimeController > runtime_controller_
TaskRunners task_runners_
std::unique_ptr< Animator > animator_
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)
static constexpr char kSettingsChannel[]
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
static constexpr char kLocalizationChannel[]
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
DEF_SWITCHES_START aot vmservice shared library name
static constexpr char kAssetChannel[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
static constexpr char kIsolateChannel[]
static constexpr char kNavigationChannel[]
static constexpr char kLifecycleChannel[]
std::function< void()> closure
std::string advisory_script_entrypoint
bool prefetched_default_font_manager
std::string advisory_script_uri
MergedPlatformUIThread merged_platform_ui_thread
uint32_t font_initialization_data
std::shared_ptr< const fml::Mapping > persistent_isolate_data
fml::closure isolate_shutdown_callback
fml::closure isolate_create_callback
std::function< void(int64_t)> idle_notification_callback
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
#define TRACE_FLOW_STEP(category, name, id)
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, flow_ids)