5#include "flutter/shell/common/engine.h"
13#include "flutter/common/settings.h"
14#include "flutter/fml/make_copyable.h"
15#include "flutter/fml/trace_event.h"
16#include "flutter/lib/snapshot/snapshot.h"
17#include "flutter/lib/ui/text/font_collection.h"
18#include "flutter/shell/common/animator.h"
19#include "flutter/shell/common/platform_view.h"
20#include "flutter/shell/common/shell.h"
22#include "rapidjson/document.h"
23#include "third_party/dart/runtime/include/dart_tools_api.h"
43 const std::shared_ptr<fml::ConcurrentTaskRunner>& image_decoder_task_runner,
46 std::unique_ptr<Animator> animator,
48 const std::shared_ptr<FontCollection>& font_collection,
49 std::unique_ptr<RuntimeController> runtime_controller,
50 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
55 font_collection_(font_collection),
58 image_decoder_task_runner,
60 gpu_disabled_switch)),
63 pointer_data_dispatcher_ = dispatcher_maker(*
this);
73 std::unique_ptr<Animator> animator,
77 std::shared_ptr<VolatilePathTracker> volatile_path_tracker,
78 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
82 vm.GetConcurrentWorkerTaskRunner(),
89 gpu_disabled_switch) {
90 runtime_controller_ = std::make_unique<RuntimeController>(
93 std::move(isolate_snapshot),
101 std::move(snapshot_delegate),
102 std::move(io_manager),
104 image_decoder_->GetWeakPtr(),
105 image_generator_registry_.GetWeakPtr(),
106 settings_.advisory_script_uri,
107 settings_.advisory_script_entrypoint,
108 std::move(volatile_path_tracker),
109 vm.GetConcurrentWorkerTaskRunner(),
110 settings_.enable_impeller,
119 std::unique_ptr<Animator> animator,
120 const std::string& initial_route,
123 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
const {
124 auto result = std::make_unique<Engine>(
128 runtime_controller_->GetDartVM()->GetConcurrentWorkerTaskRunner(),
135 gpu_disabled_switch);
136 result->runtime_controller_ = runtime_controller_->Spawn(
139 settings.advisory_script_entrypoint,
140 settings.idle_notification_callback,
145 result->GetImageDecoderWeakPtr(),
146 result->GetImageGeneratorRegistry(),
147 std::move(snapshot_delegate));
148 result->initial_route_ = initial_route;
149 result->asset_manager_ = asset_manager_;
156 return weak_factory_.GetWeakPtr();
160 TRACE_EVENT0(
"flutter",
"Engine::SetupDefaultFontManager");
165 return asset_manager_;
169 return image_decoder_->GetWeakPtr();
173 return image_generator_registry_.
GetWeakPtr();
177 const std::shared_ptr<AssetManager>& new_asset_manager) {
178 if (asset_manager_ && new_asset_manager &&
179 *asset_manager_ == *new_asset_manager) {
183 asset_manager_ = new_asset_manager;
185 if (!asset_manager_) {
191 font_collection_->RegisterFonts(asset_manager_);
195 font_collection_->RegisterTestFonts();
203 if (!configuration.
IsValid()) {
204 FML_LOG(
ERROR) <<
"Engine run configuration was invalid.";
208 runtime_controller_ = runtime_controller_->Clone();
214 if (!configuration.
IsValid()) {
215 FML_LOG(
ERROR) <<
"Engine run configuration was invalid.";
221#if (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
228 if (runtime_controller_->IsRootIsolateRunning()) {
235 auto root_isolate_create_callback = [&]() {
241 if (!runtime_controller_->LaunchRootIsolate(
243 root_isolate_create_callback,
252 auto service_id = runtime_controller_->GetRootIsolateServiceID();
253 if (service_id.has_value()) {
254 std::unique_ptr<PlatformMessage> service_id_message =
255 std::make_unique<flutter::PlatformMessage>(
257 HandlePlatformMessage(std::move(service_id_message));
264 runtime_controller_->BeginFrame(frame_time, frame_number);
268 runtime_controller_->ReportTimings(std::move(timings));
272 runtime_controller_->NotifyIdle(deadline);
277 runtime_controller_->NotifyDestroyed();
281 return runtime_controller_->GetRootIsolateReturnCode();
285 return runtime_controller_->GetMainPort();
289 return runtime_controller_->GetIsolateName();
293 return runtime_controller_->HasLivePorts();
297 return runtime_controller_->GetLastError();
303 runtime_controller_->AddView(view_id, view_metrics, std::move(
callback));
307 return runtime_controller_->RemoveView(view_id);
312 runtime_controller_->SetViewportMetrics(view_id, metrics);
317 std::string channel =
message->channel();
319 if (HandleLifecyclePlatformMessage(
message.get())) {
323 if (HandleLocalizationPlatformMessage(
message.get())) {
327 HandleSettingsPlatformMessage(
message.get());
329 }
else if (!runtime_controller_->IsRootIsolateRunning() &&
332 HandleNavigationPlatformMessage(std::move(
message));
336 if (runtime_controller_->IsRootIsolateRunning() &&
337 runtime_controller_->DispatchPlatformMessage(std::move(
message))) {
341 FML_DLOG(WARNING) <<
"Dropping platform message on channel: " << channel;
346 std::string
state(
reinterpret_cast<const char*
>(
data.GetMapping()),
352 if (
state ==
"AppLifecycleState.resumed" ||
353 state ==
"AppLifecycleState.inactive") {
356 runtime_controller_->SetInitialLifecycleState(
state);
361bool Engine::HandleNavigationPlatformMessage(
362 std::unique_ptr<PlatformMessage>
message) {
365 rapidjson::Document document;
366 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
368 if (document.HasParseError() || !document.IsObject()) {
371 auto root = document.GetObject();
372 auto method =
root.FindMember(
"method");
373 if (method->value !=
"setInitialRoute") {
377 initial_route_ =
route->value.GetString();
384 rapidjson::Document document;
385 document.Parse(
reinterpret_cast<const char*
>(
data.GetMapping()),
387 if (document.HasParseError() || !document.IsObject()) {
390 auto root = document.GetObject();
391 auto method =
root.FindMember(
"method");
392 if (method ==
root.MemberEnd()) {
395 const size_t strings_per_locale = 4;
396 if (method->value ==
"setLocale") {
398 auto args =
root.FindMember(
"args");
399 if (
args ==
root.MemberEnd() || !
args->value.IsArray()) {
403 if (
args->value.Size() % strings_per_locale != 0) {
406 std::vector<std::string> locale_data;
407 for (
size_t locale_index = 0; locale_index <
args->value.Size();
408 locale_index += strings_per_locale) {
409 if (!
args->value[locale_index].IsString() ||
410 !
args->value[locale_index + 1].IsString()) {
413 locale_data.push_back(
args->value[locale_index].GetString());
414 locale_data.push_back(
args->value[locale_index + 1].GetString());
415 locale_data.push_back(
args->value[locale_index + 2].GetString());
416 locale_data.push_back(
args->value[locale_index + 3].GetString());
419 return runtime_controller_->SetLocales(locale_data);
426 std::string jsonData(
reinterpret_cast<const char*
>(
data.GetMapping()),
428 if (runtime_controller_->SetUserSettingsData(jsonData)) {
434 std::unique_ptr<PointerDataPacket> packet,
435 uint64_t trace_flow_id) {
440 pointer_data_dispatcher_->DispatchPacket(std::move(packet), trace_flow_id);
446 runtime_controller_->DispatchSemanticsAction(node_id,
action,
451 runtime_controller_->SetSemanticsEnabled(enabled);
455 runtime_controller_->SetAccessibilityFeatures(
flags);
458std::string Engine::DefaultRouteName() {
459 if (!initial_route_.empty()) {
460 return initial_route_;
466 animator_->RequestFrame(regenerate_layer_trees);
470 animator_->OnAllViewsRendered();
473void Engine::Render(int64_t view_id,
474 std::unique_ptr<flutter::LayerTree> layer_tree,
475 float device_pixel_ratio) {
481 if (layer_tree->frame_size().isEmpty() || device_pixel_ratio <= 0.0f) {
485 animator_->Render(view_id, std::move(layer_tree), device_pixel_ratio);
493void Engine::HandlePlatformMessage(std::unique_ptr<PlatformMessage>
message) {
495 HandleAssetPlatformMessage(std::move(
message));
501void Engine::OnRootIsolateCreated() {
505void Engine::UpdateIsolateDescription(
const std::string isolate_name,
506 int64_t isolate_port) {
510std::unique_ptr<std::vector<std::string>> Engine::ComputePlatformResolvedLocale(
511 const std::vector<std::string>& supported_locale_data) {
515double Engine::GetScaledFontSize(
double unscaled_font_size,
516 int configuration_id)
const {
520void Engine::SetNeedsReportTimings(
bool needs_reporting) {
525 return *font_collection_;
529 uint64_t trace_flow_id) {
530 animator_->EnqueueTraceFlowId(trace_flow_id);
531 if (runtime_controller_) {
532 runtime_controller_->DispatchPointerDataPacket(*packet);
538 animator_->ScheduleSecondaryVsyncCallback(
id,
callback);
541void Engine::HandleAssetPlatformMessage(
542 std::unique_ptr<PlatformMessage>
message) {
548 std::string asset_name(
reinterpret_cast<const char*
>(
data.GetMapping()),
551 if (asset_manager_) {
552 std::unique_ptr<fml::Mapping> asset_mapping =
553 asset_manager_->GetAsMapping(asset_name);
555 response->Complete(std::move(asset_mapping));
560 response->CompleteEmpty();
564 return last_entry_point_;
568 return last_entry_point_library_;
572 return last_entry_point_args_;
576void Engine::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
580std::weak_ptr<PlatformMessageHandler> Engine::GetPlatformMessageHandler()
585void Engine::SendChannelUpdate(std::string
name,
bool listening) {
590 intptr_t loading_unit_id,
591 std::unique_ptr<const fml::Mapping> snapshot_data,
592 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
593 if (runtime_controller_->IsRootIsolateRunning()) {
594 runtime_controller_->LoadDartDeferredLibrary(
595 loading_unit_id, std::move(snapshot_data),
596 std::move(snapshot_instructions));
604 const std::string& error_message,
606 if (runtime_controller_->IsRootIsolateRunning()) {
607 runtime_controller_->LoadDartDeferredLibraryError(loading_unit_id,
608 error_message, transient);
613 return animator_->GetVsyncWaiter();
617 runtime_controller_->SetDisplays(displays);
622 runtime_controller_->ShutdownPlatformIsolates();
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 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(SemanticsNodeUpdates updates, CustomAccessibilityActionUpdates actions)=0
When the accessibility tree has been updated by the Flutter application, this new information needs t...
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 SetupDefaultFontManager()
Setup default font manager according to specific platform.
fml::WeakPtr< Engine > GetWeakPtr() const
bool RemoveView(int64_t view_id)
Notify the Flutter application that a view is no longer available.
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 OnAllViewsRendered() override
void DispatchSemanticsAction(int node_id, SemanticsAction action, fml::MallocMapping args)
Notifies the engine that the embedder encountered an accessibility related action on the specified no...
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 |Engine::Run| 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 |Engine::Run| was called.
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...
const std::vector< std::string > & GetLastEntrypointArgs() const
Get the last Entrypoint Arguments that was used in the RunConfiguration when |Engine::Run| 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...
fml::WeakPtr< ImageGeneratorRegistry > GetImageGeneratorRegistry()
Get the ImageGeneratorRegistry associated with the current engine.
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...
fml::WeakPtr< ImageDecoder > GetImageDecoderWeakPtr()
void ScheduleSecondaryVsyncCallback(uintptr_t id, const fml::closure &callback) override
Schedule a secondary callback to be executed right after the main VsyncWaiter::AsyncWaitForVsync call...
void NotifyDestroyed()
Notifies the engine that the attached flutter view has been destroyed. This enables the engine to not...
fml::WeakPtr< 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
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
A Mapping like NonOwnedMapping, but uses Free as its release proc.
static MallocMapping Copy(const T *begin, const T *end)
std::unique_ptr< RuntimeController > runtime_controller_
TaskRunners task_runners_
std::unique_ptr< Animator > animator_
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
Dart_NativeFunction function
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
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[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however route
static constexpr char kLifecycleChannel[]
std::function< void()> closure
bool prefetched_default_font_manager
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)