Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Friends | List of all members
flutter::Shell Class Referencefinal

#include <shell.h>

Inheritance diagram for flutter::Shell:
flutter::PlatformView::Delegate flutter::Animator::Delegate flutter::Engine::Delegate flutter::Rasterizer::Delegate flutter::ServiceProtocol::Handler flutter::ResourceCacheLimitItem

Public Types

template<class T >
using CreateCallback = std::function< std::unique_ptr< T >(Shell &)>
 
typedef std::function< std::unique_ptr< Engine >(Engine::Delegate &delegate, const PointerDataDispatcherMaker &dispatcher_maker, DartVM &vm, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, const PlatformData &platform_data, Settings settings, std::unique_ptr< Animator > animator, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > unref_queue, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, std::shared_ptr< VolatilePathTracker > volatile_path_tracker, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch, impeller::RuntimeStageBackend runtime_stage_type)> EngineCreateCallback
 
- Public Types inherited from flutter::PlatformView::Delegate
using AddViewCallback = PlatformView::AddViewCallback
 
using RemoveViewCallback = PlatformView::RemoveViewCallback
 
using KeyDataResponse = std::function< void(bool)>
 
- Public Types inherited from flutter::ServiceProtocol::Handler
using ServiceProtocolMap = std::map< std::string_view, std::string_view >
 

Public Member Functions

 ~Shell ()
 Destroys the shell. This is a synchronous operation and synchronous barrier blocks are introduced on the various threads to ensure shutdown of all shell sub-components before this method returns.
 
std::unique_ptr< ShellSpawn (RunConfiguration run_configuration, const std::string &initial_route, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer) const
 Creates one Shell from another Shell where the created Shell takes the opportunity to share any internal components it can. This results is a Shell that has a smaller startup time cost and a smaller memory footprint than an Shell created with the Create function.
 
void RunEngine (RunConfiguration run_configuration)
 Starts an isolate for the given RunConfiguration.
 
void RunEngine (RunConfiguration run_configuration, const std::function< void(Engine::RunStatus)> &result_callback)
 Starts an isolate for the given RunConfiguration. The result_callback will be called with the status of the operation.
 
const SettingsGetSettings () const override
 
const TaskRunnersGetTaskRunners () const override
 If callers wish to interact directly with any shell subcomponents, they must (on the platform thread) obtain a task runner that the component is designed to run on and a weak pointer to that component. They may then post a task to that task runner, do the validity check on that task runner before performing any operation on that component. This accessor allows callers to access the task runners for this shell.
 
const fml::RefPtr< fml::RasterThreadMergerGetParentRasterThreadMerger () const override
 Getting the raster thread merger from parent shell, it can be a null RefPtr when it's a root Shell or the embedder_->SupportsDynamicThreadMerging() returns false.
 
fml::TaskRunnerAffineWeakPtr< RasterizerGetRasterizer () const
 Rasterizers may only be accessed on the raster task runner.
 
fml::WeakPtr< EngineGetEngine ()
 Engines may only be accessed on the UI thread. This method is deprecated, and implementers should instead use other API available on the Shell or the PlatformView.
 
fml::WeakPtr< PlatformViewGetPlatformView ()
 Platform views may only be accessed on the platform task runner.
 
fml::WeakPtr< ShellIOManagerGetIOManager ()
 The IO Manager may only be accessed on the IO task runner.
 
void NotifyLowMemoryWarning () const
 Used by embedders to notify that there is a low memory warning. The shell will attempt to purge caches. Current, only the rasterizer cache is purged.
 
bool IsSetup () const
 Used by embedders to check if all shell subcomponents are initialized. It is the embedder's responsibility to make this call before accessing any other shell method. A shell that is not set up must be discarded and another one created with updated settings.
 
Rasterizer::Screenshot Screenshot (Rasterizer::ScreenshotType type, bool base64_encode)
 Captures a screenshot and optionally Base64 encodes the data of the last layer tree rendered by the rasterizer in this shell.
 
fml::Status WaitForFirstFrame (fml::TimeDelta timeout)
 Pauses the calling thread until the first frame is presented.
 
bool ReloadSystemFonts ()
 Used by embedders to reload the system fonts in FontCollection. It also clears the cached font families and send system channel message to framework to rebuild affected widgets.
 
std::optional< DartErrorCodeGetUIIsolateLastError () const
 Used by embedders to get the last error from the Dart UI Isolate, if one exists.
 
bool EngineHasLivePorts () const
 Used by embedders to check if the Engine is running and has any live ports remaining. For example, the Flutter tester uses this method to check whether it should continue to wait for a running test or not.
 
std::shared_ptr< const fml::SyncSwitchGetIsGpuDisabledSyncSwitch () const override
 Accessor for the disable GPU SyncSwitch.
 
void SetGpuAvailability (GpuAvailability availability)
 Marks the GPU as available or unavailable.
 
DartVMGetDartVM ()
 Get a pointer to the Dart VM used by this running shell instance.
 
void OnDisplayUpdates (std::vector< std::unique_ptr< Display > > displays)
 Notifies the display manager of the updates.
 
double GetMainDisplayRefreshRate ()
 Queries the DisplayManager for the main display refresh rate.
 
void RegisterImageDecoder (ImageGeneratorFactory factory, int32_t priority)
 Install a new factory that can match against and decode image data.
 
const std::shared_ptr< PlatformMessageHandler > & GetPlatformMessageHandler () const override
 Returns the delegate object that handles PlatformMessage's from Flutter to the host platform (and its responses).
 
const std::weak_ptr< VsyncWaiterGetVsyncWaiter () const
 
const std::shared_ptr< fml::ConcurrentTaskRunnerGetConcurrentWorkerTaskRunner () const
 
- Public Member Functions inherited from flutter::PlatformView::Delegate
virtual void OnPlatformViewRegisterTexture (std::shared_ptr< Texture > texture)=0
 Notifies the delegate that the embedder has specified a texture that it want the rasterizer to composite within the Flutter layer tree. All textures must have a unique identifier. When the rasterizer encounters an external texture within its hierarchy, it gives the embedder a chance to update that texture on the raster thread before it composites the same on-screen.
 

Static Public Member Functions

static std::unique_ptr< ShellCreate (const PlatformData &platform_data, const TaskRunners &task_runners, Settings settings, const CreateCallback< PlatformView > &on_create_platform_view, const CreateCallback< Rasterizer > &on_create_rasterizer, bool is_gpu_disabled=false)
 Creates a shell instance using the provided settings. The callbacks to create the various shell subcomponents will be called on the appropriate threads before this method returns. If this is the first instance of a shell in the process, this call also bootstraps the Dart VM.
 
static std::pair< DartVMRef, fml::RefPtr< const DartSnapshot > > InferVmInitDataFromSettings (Settings &settings)
 

Private Member Functions

void OnPlatformViewCreated (std::unique_ptr< Surface > surface) override
 Notifies the delegate that the platform view was created with the given render surface. This surface is platform (iOS, Android) and client-rendering API (OpenGL, Software, Metal, Vulkan) specific. This is usually a sign to the rasterizer to set up and begin rendering to that surface.
 
void OnPlatformViewDestroyed () override
 Notifies the delegate that the platform view was destroyed. This is usually a sign to the rasterizer to suspend rendering a previously configured surface and collect any intermediate resources.
 
void OnPlatformViewScheduleFrame () override
 Notifies the delegate that the platform needs to schedule a frame to regenerate the layer tree and redraw the surface.
 
void OnPlatformViewAddView (int64_t view_id, const ViewportMetrics &viewport_metrics, AddViewCallback callback) override
 Allocate resources for a new non-implicit view and inform Dart about the view, and on success, schedules a new frame.
 
void OnPlatformViewRemoveView (int64_t view_id, RemoveViewCallback callback) override
 Deallocate resources for a removed view and inform Dart about the removal.
 
void OnPlatformViewSetViewportMetrics (int64_t view_id, const ViewportMetrics &metrics) override
 Notifies the delegate the viewport metrics of a view have been updated. The rasterizer will need to be reconfigured to render the frame in the updated viewport metrics.
 
void OnPlatformViewDispatchPlatformMessage (std::unique_ptr< PlatformMessage > message) override
 Notifies the delegate that the platform has dispatched a platform message from the embedder to the Flutter application. This message must be forwarded to the running isolate hosted by the engine on the UI thread.
 
void OnPlatformViewDispatchPointerDataPacket (std::unique_ptr< PointerDataPacket > packet) override
 Notifies the delegate that the platform view has encountered a pointer event. This pointer event needs to be forwarded to the running root isolate hosted by the engine on the UI thread.
 
void OnPlatformViewDispatchSemanticsAction (int32_t node_id, SemanticsAction action, fml::MallocMapping args) override
 Notifies the delegate that the platform view has encountered an accessibility related action on the specified node. This event must be forwarded to the running root isolate hosted by the engine on the UI thread.
 
void OnPlatformViewSetSemanticsEnabled (bool enabled) override
 Notifies the delegate that the embedder has expressed an opinion about whether the accessibility tree needs to be enabled or disabled. This information needs to be forwarded to the root isolate running on the UI thread.
 
void OnPlatformViewSetAccessibilityFeatures (int32_t flags) override
 Notifies the delegate that the embedder has expressed an opinion about the features to enable in the accessibility tree.
 
void OnPlatformViewRegisterTexture (std::shared_ptr< flutter::Texture > texture) override
 
void OnPlatformViewUnregisterTexture (int64_t texture_id) override
 Notifies the delegate that the embedder will no longer attempt to composite the specified texture within the layer tree. This allows the rasterizer to collect associated resources.
 
void OnPlatformViewMarkTextureFrameAvailable (int64_t texture_id) override
 Notifies the delegate that the embedder has updated the contents of the texture with the specified identifier. Typically, Flutter will only render a frame if there is an updated layer tree. However, in cases where the layer tree is static but one of the externally composited textures has been updated by the embedder, the embedder needs to notify the rasterizer to render a new frame. In such cases, the existing layer tree may be reused with the frame composited with all updated external textures.
 
void OnPlatformViewSetNextFrameCallback (const fml::closure &closure) override
 Notifies the delegate that the specified callback needs to be invoked after the rasterizer is done rendering the next frame. This callback will be called on the render thread and it is caller responsibility to perform any re-threading as necessary. Due to the asynchronous nature of rendering in Flutter, embedders usually add a placeholder over the contents in which Flutter is going to render when Flutter is first initialized. This callback may be used as a signal to remove that placeholder.
 
const SettingsOnPlatformViewGetSettings () const override
 Called by the platform view on the platform thread to get the settings object associated with the platform view instance.
 
void LoadDartDeferredLibrary (intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions) override
 Loads the dart shared library into the dart VM. When the dart library is loaded successfully, the dart future returned by the originating loadLibrary() call completes.
 
void LoadDartDeferredLibraryError (intptr_t loading_unit_id, const std::string error_message, bool transient) override
 Indicates to the dart VM that the request to load a deferred library with the specified loading unit id has failed.
 
void UpdateAssetResolverByType (std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type) override
 Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_asset_resolver. The matching AssetResolver is removed and replaced with updated_asset_resolvers.
 
void OnAnimatorBeginFrame (fml::TimePoint frame_target_time, uint64_t frame_number) override
 
void OnAnimatorNotifyIdle (fml::TimeDelta deadline) override
 
void OnAnimatorUpdateLatestFrameTargetTime (fml::TimePoint frame_target_time) override
 
void OnAnimatorDraw (std::shared_ptr< FramePipeline > pipeline) override
 
void OnAnimatorDrawLastLayerTrees (std::unique_ptr< FrameTimingsRecorder > frame_timings_recorder) override
 
void OnEngineUpdateSemantics (SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) override
 When the accessibility tree has been updated by the Flutter application, this new information needs to be conveyed to the underlying platform. The engine delegates this task to the shell via this call. The engine cannot access the underlying platform directly because of threading considerations. Most platform specific APIs to convey accessibility information are only safe to access on the platform task runner while the engine is running on the UI task runner.
 
void OnEngineHandlePlatformMessage (std::unique_ptr< PlatformMessage > message) override
 When the Flutter application has a message to send to the underlying platform, the message needs to be forwarded to the platform on the appropriate thread (via the platform task runner). The engine delegates this task to the shell via this method.
 
void OnPreEngineRestart () override
 Notifies the delegate that the root isolate of the application is about to be discarded and a new isolate with the same runtime started in its place. This should only happen in the Flutter "debug" runtime mode in the cold-restart scenario. The embedder may need to reset native resource in response to the restart.
 
void OnRootIsolateCreated () override
 Notifies the shell that the root isolate is created. Currently, this information is to add to the service protocol list of available root isolates running in the VM and their names so that the appropriate isolate can be selected in the tools for debugging and instrumentation.
 
void UpdateIsolateDescription (const std::string isolate_name, int64_t isolate_port) override
 Notifies the shell of the name of the root isolate and its port when that isolate is launched, restarted (in the cold-restart scenario) or the application itself updates the name of the root isolate (via PlatformDispatcher.setIsolateDebugName in platform_dispatcher.dart). The name of the isolate is meaningless to the engine but is used in instrumentation and tooling. Currently, this information is to update the service protocol list of available root isolates running in the VM and their names so that the appropriate isolate can be selected in the tools for debugging and instrumentation.
 
void SetNeedsReportTimings (bool value) override
 Notifies the shell that the application has an opinion about whether its frame timings need to be reported backed to it. Due to the asynchronous nature of rendering in Flutter, it is not possible for the application to determine the total time it took to render a specific frame. While the layer-tree is constructed on the UI thread, it needs to be rendering on the raster thread. Dart code cannot execute on this thread. So any instrumentation about the frame times gathered on this thread needs to be aggregated and sent back to the UI thread for processing in Dart.
 
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocale (const std::vector< std::string > &supported_locale_data) override
 Directly invokes platform-specific APIs to compute the locale the platform would have natively resolved to.
 
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 deferred library identified by the specified loading unit id should be downloaded and loaded into the Dart VM via LoadDartDeferredLibrary
 
fml::TimePoint GetCurrentTimePoint () override
 Returns the current fml::TimePoint. This method is primarily provided to allow tests to control Any methods that rely on advancing the clock.
 
void OnEngineChannelUpdate (std::string name, bool listening) override
 Invoked when a listener is registered on a platform channel.
 
double GetScaledFontSize (double unscaled_font_size, int configuration_id) const override
 Synchronously invokes platform-specific APIs to apply the system text scaling on the given unscaled font size.
 
void OnFrameRasterized (const FrameTiming &) override
 Notifies the delegate that a frame has been rendered. The rasterizer collects profiling information for each part of the frame workload. This profiling information is made available to the delegate for forwarding to subsystems interested in collecting such profiles. Currently, the shell (the delegate) forwards this to the engine where Dart code can react to this information.
 
fml::Milliseconds GetFrameBudget () override
 
fml::TimePoint GetLatestFrameTargetTime () const override
 
bool ShouldDiscardLayerTree (int64_t view_id, const flutter::LayerTree &tree) override
 
fml::RefPtr< fml::TaskRunnerGetServiceProtocolHandlerTaskRunner (std::string_view method) const override
 
bool HandleServiceProtocolMessage (std::string_view method, const ServiceProtocolMap &params, rapidjson::Document *response) override
 
ServiceProtocol::Handler::Description GetServiceProtocolDescription () const override
 
size_t GetResourceCacheLimit () override
 

Friends

class testing::ShellTest
 

Additional Inherited Members

- Protected Member Functions inherited from flutter::ResourceCacheLimitItem
virtual ~ResourceCacheLimitItem ()=default
 

Detailed Description

Perhaps the single most important class in the Flutter engine repository. When embedders create a Flutter application, they are referring to the creation of an instance of a shell. Creation and destruction of the shell is synchronous and the embedder only holds a unique pointer to the shell. The shell does not create the threads its primary components run on. Instead, it is the embedder's responsibility to create threads and give the shell task runners for those threads. Due to deterministic destruction of the shell, the embedder can terminate all threads immediately after collecting the shell. The shell must be created and destroyed on the same thread, but, different shells (i.e. a separate instances of a Flutter application) may be run on different threads simultaneously. The task runners themselves do not have to be unique. If all task runner references given to the shell during shell creation point to the same task runner, the Flutter application is effectively single threaded.

The shell is the central nervous system of the Flutter application. None of the shell components are thread safe and must be created, accessed and destroyed on the same thread. To interact with one another, the various components delegate to the shell for communication. Instead of using back pointers to the shell, a delegation pattern is used by all components that want to communicate with one another. Because of this, the shell implements the delegate interface for all these components.

All shell methods accessed by the embedder may only be called on the platform task runner. In case the embedder wants to directly access a shell subcomponent, it is the embedder's responsibility to acquire a weak pointer to that component and post a task to the task runner used by the component to access its methods. The shell must also be destroyed on the platform task runner.

There is no explicit API to bootstrap and shutdown the Dart VM. The first instance of the shell in the process bootstraps the Dart VM and the destruction of the last shell instance destroys the same. Since different shells may be created and destroyed on different threads. VM bootstrap may happen on one thread but its collection on another. This behavior is thread safe.

Definition at line 111 of file shell.h.

Member Typedef Documentation

◆ CreateCallback

template<class T >
using flutter::Shell::CreateCallback = std::function<std::unique_ptr<T>(Shell&)>

Definition at line 119 of file shell.h.

◆ EngineCreateCallback

typedef std::function<std::unique_ptr<Engine>( Engine::Delegate& delegate, const PointerDataDispatcherMaker& dispatcher_maker, DartVM& vm, fml::RefPtr<const DartSnapshot> isolate_snapshot, TaskRunners task_runners, const PlatformData& platform_data, Settings settings, std::unique_ptr<Animator> animator, fml::WeakPtr<IOManager> io_manager, fml::RefPtr<SkiaUnrefQueue> unref_queue, fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate, std::shared_ptr<VolatilePathTracker> volatile_path_tracker, const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch, impeller::RuntimeStageBackend runtime_stage_type)> flutter::Shell::EngineCreateCallback

Definition at line 135 of file shell.h.

Constructor & Destructor Documentation

◆ ~Shell()

flutter::Shell::~Shell ( )

Destroys the shell. This is a synchronous operation and synchronous barrier blocks are introduced on the various threads to ensure shutdown of all shell sub-components before this method returns.

Definition at line 527 of file shell.cc.

527 {
529 task_runners_.GetIOTaskRunner());
530
531 vm_->GetServiceProtocol()->RemoveHandler(this);
532
533 fml::AutoResetWaitableEvent platiso_latch, ui_latch, gpu_latch,
534 platform_latch, io_latch;
535
537 task_runners_.GetPlatformTaskRunner(),
538 fml::MakeCopyable([this, &platiso_latch]() mutable {
539 engine_->ShutdownPlatformIsolates();
540 platiso_latch.Signal();
541 }));
542 platiso_latch.Wait();
543
545 task_runners_.GetUITaskRunner(),
546 fml::MakeCopyable([this, &ui_latch]() mutable {
547 engine_.reset();
548 ui_latch.Signal();
549 }));
550 ui_latch.Wait();
551
553 task_runners_.GetRasterTaskRunner(),
555 [this, rasterizer = std::move(rasterizer_), &gpu_latch]() mutable {
556 rasterizer.reset();
557 this->weak_factory_gpu_.reset();
558 gpu_latch.Signal();
559 }));
560 gpu_latch.Wait();
561
563 task_runners_.GetIOTaskRunner(),
564 fml::MakeCopyable([io_manager = std::move(io_manager_),
565 platform_view = platform_view_.get(),
566 &io_latch]() mutable {
567 io_manager.reset();
568 if (platform_view) {
569 platform_view->ReleaseResourceContext();
570 }
571 io_latch.Signal();
572 }));
573
574 io_latch.Wait();
575
576 // The platform view must go last because it may be holding onto platform side
577 // counterparts to resources owned by subsystems running on other threads. For
578 // example, the NSOpenGLContext on the Mac.
580 task_runners_.GetPlatformTaskRunner(),
581 fml::MakeCopyable([platform_view = std::move(platform_view_),
582 &platform_latch]() mutable {
583 platform_view.reset();
584 platform_latch.Signal();
585 }));
586 platform_latch.Wait();
587}
std::unique_ptr< flutter::PlatformViewIOS > platform_view
std::shared_ptr< ServiceProtocol > GetServiceProtocol() const
The service protocol instance associated with this running Dart VM instance. This object manages nati...
Definition dart_vm.cc:537
void RemoveWorkerTaskRunner(const fml::RefPtr< fml::TaskRunner > &task_runner)
static PersistentCache * GetCacheForProcess()
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
internal::CopyableLambda< T > MakeCopyable(T lambda)

Member Function Documentation

◆ ComputePlatformResolvedLocale()

std::unique_ptr< std::vector< std::string > > flutter::Shell::ComputePlatformResolvedLocale ( const std::vector< std::string > &  supported_locale_data)
overrideprivatevirtual

Directly invokes platform-specific APIs to compute the locale the platform would have natively resolved to.

Parameters
[in]supported_locale_dataThe vector of strings that represents the locales supported by the app. Each locale consists of three strings: languageCode, countryCode, and scriptCode in that order.
Returns
A vector of 3 strings languageCode, countryCode, and scriptCode that represents the locale selected by the platform. Empty strings mean the value was unassigned. Empty vector represents a null locale.

Implements flutter::Engine::Delegate.

Definition at line 1475 of file shell.cc.

1476 {
1477 return platform_view_->ComputePlatformResolvedLocales(supported_locale_data);
1478}

◆ Create()

std::unique_ptr< Shell > flutter::Shell::Create ( const PlatformData platform_data,
const TaskRunners task_runners,
Settings  settings,
const CreateCallback< PlatformView > &  on_create_platform_view,
const CreateCallback< Rasterizer > &  on_create_rasterizer,
bool  is_gpu_disabled = false 
)
static

Creates a shell instance using the provided settings. The callbacks to create the various shell subcomponents will be called on the appropriate threads before this method returns. If this is the first instance of a shell in the process, this call also bootstraps the Dart VM.

Note
The root isolate which will run this Shell's Dart code takes its instructions from the passed in settings. This allows embedders to host multiple Shells with different Dart code.
Parameters
[in]task_runnersThe task runners
[in]settingsThe settings
[in]on_create_platform_viewThe callback that must return a platform view. This will be called on the platform task runner before this method returns.
[in]on_create_rasterizerThat callback that must provide a valid rasterizer. This will be called on the render task runner before this method returns.
[in]is_gpu_disabledThe default value for the switch that turns off the GPU.
Returns
A full initialized shell if the settings and callbacks are valid. The root isolate has been created but not yet launched. It may be launched by obtaining the engine weak pointer and posting a task onto the UI task runner with a valid run configuration to run the isolate. The embedder must always check the validity of the shell (using the IsSetup call) immediately after getting a pointer to it.

Definition at line 167 of file shell.cc.

173 {
174 // This must come first as it initializes tracing.
175 PerformInitializationTasks(settings);
176
177 TRACE_EVENT0("flutter", "Shell::Create");
178
179 auto [vm, isolate_snapshot] = InferVmInitDataFromSettings(settings);
180 auto resource_cache_limit_calculator =
181 std::make_shared<ResourceCacheLimitCalculator>(
182 settings.resource_cache_max_bytes_threshold);
183
184 return CreateWithSnapshot(platform_data, //
185 task_runners, //
186 /*parent_thread_merger=*/nullptr, //
187 /*parent_io_manager=*/nullptr, //
188 resource_cache_limit_calculator, //
189 settings, //
190 std::move(vm), //
191 std::move(isolate_snapshot), //
192 on_create_platform_view, //
193 on_create_rasterizer, //
194 CreateEngine, is_gpu_disabled);
195}
static std::pair< DartVMRef, fml::RefPtr< const DartSnapshot > > InferVmInitDataFromSettings(Settings &settings)
Definition shell.cc:151
#define TRACE_EVENT0(category_group, name)

◆ EngineHasLivePorts()

bool flutter::Shell::EngineHasLivePorts ( ) const

Used by embedders to check if the Engine is running and has any live ports remaining. For example, the Flutter tester uses this method to check whether it should continue to wait for a running test or not.

Returns
Returns if the shell has an engine and the engine has any live Dart ports.

Definition at line 713 of file shell.cc.

713 {
714 FML_DCHECK(is_set_up_);
716
717 if (!weak_engine_) {
718 return false;
719 }
720
721 return weak_engine_->UIIsolateHasLivePorts();
722}
virtual bool RunsTasksOnCurrentThread()
#define FML_DCHECK(condition)
Definition logging.h:103

◆ GetConcurrentWorkerTaskRunner()

const std::shared_ptr< fml::ConcurrentTaskRunner > flutter::Shell::GetConcurrentWorkerTaskRunner ( ) const

Definition at line 2316 of file shell.cc.

2316 {
2317 FML_DCHECK(vm_);
2318 if (!vm_) {
2319 return nullptr;
2320 }
2321 return vm_->GetConcurrentWorkerTaskRunner();
2322}
std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner() const
The task runner whose tasks may be executed concurrently on a pool of worker threads....
Definition dart_vm.cc:546

◆ GetCurrentTimePoint()

fml::TimePoint flutter::Shell::GetCurrentTimePoint ( )
overrideprivatevirtual

Returns the current fml::TimePoint. This method is primarily provided to allow tests to control Any methods that rely on advancing the clock.

Implements flutter::Engine::Delegate.

Definition at line 2299 of file shell.cc.

2299 {
2300 return fml::TimePoint::Now();
2301}
static TimePoint Now()
Definition time_point.cc:49

◆ GetDartVM()

DartVM * flutter::Shell::GetDartVM ( )

Get a pointer to the Dart VM used by this running shell instance.

Returns
The Dart VM pointer.

Definition at line 828 of file shell.cc.

828 {
829 return &vm_;
830}

◆ GetEngine()

fml::WeakPtr< Engine > flutter::Shell::GetEngine ( )

Engines may only be accessed on the UI thread. This method is deprecated, and implementers should instead use other API available on the Shell or the PlatformView.

Returns
A weak pointer to the engine.

Definition at line 813 of file shell.cc.

813 {
814 FML_DCHECK(is_set_up_);
815 return weak_engine_;
816}

◆ GetFrameBudget()

fml::Milliseconds flutter::Shell::GetFrameBudget ( )
overrideprivatevirtual

Time limit for a smooth frame.

See: DisplayManager::GetMainDisplayRefreshRate.

Implements flutter::Rasterizer::Delegate.

Definition at line 1628 of file shell.cc.

1628 {
1629 double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
1630 if (display_refresh_rate > 0) {
1631 return fml::RefreshRateToFrameBudget(display_refresh_rate);
1632 } else {
1634 }
1635}
constexpr Milliseconds kDefaultFrameBudget
Definition time_delta.h:21
Milliseconds RefreshRateToFrameBudget(T refresh_rate)
Definition time_delta.h:24

◆ GetIOManager()

fml::WeakPtr< ShellIOManager > flutter::Shell::GetIOManager ( )

The IO Manager may only be accessed on the IO task runner.

Returns
A weak pointer to the IO manager.

Definition at line 823 of file shell.cc.

823 {
824 FML_DCHECK(is_set_up_);
825 return io_manager_->GetWeakPtr();
826}

◆ GetIsGpuDisabledSyncSwitch()

std::shared_ptr< const fml::SyncSwitch > flutter::Shell::GetIsGpuDisabledSyncSwitch ( ) const
overridevirtual

Accessor for the disable GPU SyncSwitch.

Implements flutter::Rasterizer::Delegate.

Definition at line 2249 of file shell.cc.

2250 {
2251 return is_gpu_disabled_sync_switch_;
2252}

◆ GetLatestFrameTargetTime()

fml::TimePoint flutter::Shell::GetLatestFrameTargetTime ( ) const
overrideprivatevirtual

Target time for the latest frame. See also Shell::OnAnimatorBeginFrame for when this time gets updated.

Implements flutter::Rasterizer::Delegate.

Definition at line 1637 of file shell.cc.

1637 {
1638 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1639 FML_CHECK(latest_frame_target_time_.has_value())
1640 << "GetLatestFrameTargetTime called before OnAnimatorBeginFrame";
1641 // Covered by FML_CHECK().
1642 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
1643 return latest_frame_target_time_.value();
1644}
#define FML_CHECK(condition)
Definition logging.h:85

◆ GetMainDisplayRefreshRate()

double flutter::Shell::GetMainDisplayRefreshRate ( )

Queries the DisplayManager for the main display refresh rate.

Definition at line 1862 of file shell.cc.

1862 {
1863 return display_manager_->GetMainDisplayRefreshRate();
1864}

◆ GetParentRasterThreadMerger()

const fml::RefPtr< fml::RasterThreadMerger > flutter::Shell::GetParentRasterThreadMerger ( ) const
overridevirtual

Getting the raster thread merger from parent shell, it can be a null RefPtr when it's a root Shell or the embedder_->SupportsDynamicThreadMerging() returns false.

Returns
The raster thread merger used by the parent shell.

Implements flutter::Rasterizer::Delegate.

Definition at line 803 of file shell.cc.

804 {
805 return parent_raster_thread_merger_;
806}

◆ GetPlatformMessageHandler()

const std::shared_ptr< PlatformMessageHandler > & flutter::Shell::GetPlatformMessageHandler ( ) const
overridevirtual

Returns the delegate object that handles PlatformMessage's from Flutter to the host platform (and its responses).

Implements flutter::Engine::Delegate.

Definition at line 2304 of file shell.cc.

2304 {
2305 return platform_message_handler_;
2306}

◆ GetPlatformView()

fml::WeakPtr< PlatformView > flutter::Shell::GetPlatformView ( )

Platform views may only be accessed on the platform task runner.

Returns
A weak pointer to the platform view.

Definition at line 818 of file shell.cc.

818 {
819 FML_DCHECK(is_set_up_);
820 return weak_platform_view_;
821}

◆ GetRasterizer()

fml::TaskRunnerAffineWeakPtr< Rasterizer > flutter::Shell::GetRasterizer ( ) const

Rasterizers may only be accessed on the raster task runner.

Returns
A weak pointer to the rasterizer.

Definition at line 808 of file shell.cc.

808 {
809 FML_DCHECK(is_set_up_);
810 return weak_rasterizer_;
811}

◆ GetResourceCacheLimit()

size_t flutter::Shell::GetResourceCacheLimit ( )
inlineoverrideprivatevirtual

Implements flutter::ResourceCacheLimitItem.

Definition at line 778 of file shell.h.

778{ return resource_cache_limit_; };

◆ GetScaledFontSize()

double flutter::Shell::GetScaledFontSize ( double  unscaled_font_size,
int  configuration_id 
) const
overrideprivatevirtual

Synchronously invokes platform-specific APIs to apply the system text scaling on the given unscaled font size.

Platforms that support this feature (currently it's only implemented for Android SDK level 34+) will send a valid configuration_id to potential callers, before this method can be called.

Parameters
[in]unscaled_font_sizeThe unscaled font size specified by the app developer. The value is in logical pixels, and is guaranteed to be finite and non-negative.
[in]configuration_idThe unique id of the configuration to use for computing the scaled font size.
Returns
The scaled font size in logical pixels, or -1 when the given configuration_id did not match a valid configuration.

Implements flutter::Engine::Delegate.

Definition at line 1534 of file shell.cc.

1535 {
1536 return platform_view_->GetScaledFontSize(unscaled_font_size,
1537 configuration_id);
1538}

◆ GetServiceProtocolDescription()

ServiceProtocol::Handler::Description flutter::Shell::GetServiceProtocolDescription ( ) const
overrideprivatevirtual

Implements flutter::ServiceProtocol::Handler.

Definition at line 1679 of file shell.cc.

1680 {
1682
1683 if (!weak_engine_) {
1684 return ServiceProtocol::Handler::Description();
1685 }
1686
1687 return {
1688 weak_engine_->GetUIIsolateMainPort(),
1689 weak_engine_->GetUIIsolateName(),
1690 };
1691}

◆ GetServiceProtocolHandlerTaskRunner()

fml::RefPtr< fml::TaskRunner > flutter::Shell::GetServiceProtocolHandlerTaskRunner ( std::string_view  method) const
overrideprivatevirtual

Implements flutter::ServiceProtocol::Handler.

Definition at line 1656 of file shell.cc.

1657 {
1658 FML_DCHECK(is_set_up_);
1659 auto found = service_protocol_handlers_.find(method);
1660 if (found != service_protocol_handlers_.end()) {
1661 return found->second.first;
1662 }
1663 return task_runners_.GetUITaskRunner();
1664}

◆ GetSettings()

const Settings & flutter::Shell::GetSettings ( ) const
overridevirtual
Returns
The settings used to launch this shell.

Implements flutter::Rasterizer::Delegate.

Definition at line 795 of file shell.cc.

795 {
796 return settings_;
797}

◆ GetTaskRunners()

const TaskRunners & flutter::Shell::GetTaskRunners ( ) const
overridevirtual

If callers wish to interact directly with any shell subcomponents, they must (on the platform thread) obtain a task runner that the component is designed to run on and a weak pointer to that component. They may then post a task to that task runner, do the validity check on that task runner before performing any operation on that component. This accessor allows callers to access the task runners for this shell.

Returns
The task runners current in use by the shell.

Implements flutter::Rasterizer::Delegate.

Definition at line 799 of file shell.cc.

799 {
800 return task_runners_;
801}

◆ GetUIIsolateLastError()

std::optional< DartErrorCode > flutter::Shell::GetUIIsolateLastError ( ) const

Used by embedders to get the last error from the Dart UI Isolate, if one exists.

Returns
Returns the last error code from the UI Isolate.

Definition at line 693 of file shell.cc.

693 {
694 FML_DCHECK(is_set_up_);
696
697 if (!weak_engine_) {
698 return std::nullopt;
699 }
700 switch (weak_engine_->GetUIIsolateLastError()) {
707 case tonic::kNoError:
709 }
711}
@ CompilationError
The Dart error code for a compilation error.
@ ApiError
The Dart error code for an API error.
@ NoError
No error has occurred.
@ UnknownError
The Dart error code for an unknown error.
@ kApiErrorType
Definition dart_error.h:70
@ kCompilationErrorType
Definition dart_error.h:71
@ kUnknownErrorType
Definition dart_error.h:69
@ kNoError
Definition dart_error.h:68

◆ GetVsyncWaiter()

const std::weak_ptr< VsyncWaiter > flutter::Shell::GetVsyncWaiter ( ) const

Definition at line 2308 of file shell.cc.

2308 {
2309 if (!engine_) {
2310 return {};
2311 }
2312 return engine_->GetVsyncWaiter();
2313}

◆ HandleServiceProtocolMessage()

bool flutter::Shell::HandleServiceProtocolMessage ( std::string_view  method,
const ServiceProtocolMap params,
rapidjson::Document *  response 
)
overrideprivatevirtual

Implements flutter::ServiceProtocol::Handler.

Definition at line 1667 of file shell.cc.

1670 {
1671 auto found = service_protocol_handlers_.find(method);
1672 if (found != service_protocol_handlers_.end()) {
1673 return found->second.second(params, response);
1674 }
1675 return false;
1676}
const EmbeddedViewParams * params

◆ InferVmInitDataFromSettings()

std::pair< DartVMRef, fml::RefPtr< const DartSnapshot > > flutter::Shell::InferVmInitDataFromSettings ( Settings settings)
static

Definition at line 151 of file shell.cc.

151 {
152 // Always use the `vm_snapshot` and `isolate_snapshot` provided by the
153 // settings to launch the VM. If the VM is already running, the snapshot
154 // arguments are ignored.
155 auto vm_snapshot = DartSnapshot::VMSnapshotFromSettings(settings);
156 auto isolate_snapshot = DartSnapshot::IsolateSnapshotFromSettings(settings);
157 auto vm = DartVMRef::Create(settings, vm_snapshot, isolate_snapshot);
158
159 // If the settings did not specify an `isolate_snapshot`, fall back to the
160 // one the VM was launched with.
161 if (!isolate_snapshot) {
162 isolate_snapshot = vm->GetVMData()->GetIsolateSnapshot();
163 }
164 return {std::move(vm), isolate_snapshot};
165}
static fml::RefPtr< const DartSnapshot > VMSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the core snapshot.
static fml::RefPtr< const DartSnapshot > IsolateSnapshotFromSettings(const Settings &settings)
From the fields present in the given settings object, infer the isolate snapshot.
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)

◆ IsSetup()

bool flutter::Shell::IsSetup ( ) const

Used by embedders to check if all shell subcomponents are initialized. It is the embedder's responsibility to make this call before accessing any other shell method. A shell that is not set up must be discarded and another one created with updated settings.

Returns
Returns if the shell has been set up. Once set up, this does not change for the life-cycle of the shell.

Definition at line 724 of file shell.cc.

724 {
725 return is_set_up_;
726}

◆ LoadDartDeferredLibrary()

void flutter::Shell::LoadDartDeferredLibrary ( intptr_t  loading_unit_id,
std::unique_ptr< const fml::Mapping snapshot_data,
std::unique_ptr< const fml::Mapping snapshot_instructions 
)
overrideprivatevirtual

Loads the dart shared library into the dart VM. When the dart library is loaded successfully, the dart future returned by the originating loadLibrary() call completes.

The Dart compiler may generate separate shared libraries files called 'loading units' when libraries are imported as deferred. Each of these shared libraries are identified by a unique loading unit id. Callers should open and resolve a SymbolMapping from the shared library. The Mappings should be moved into this method, as ownership will be assumed by the dart root isolate after successful loading and released after shutdown of the root isolate. The loading unit may not be used after isolate shutdown. If loading fails, the mappings will be released.

This method is paired with a RequestDartDeferredLibrary invocation that provides the embedder with the loading unit id of the deferred library to load.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit.
[in]snapshot_dataDart snapshot data of the loading unit's shared library.
[in]snapshot_dataDart snapshot instructions of the loading unit's shared library.

Implements flutter::PlatformView::Delegate.

Definition at line 1480 of file shell.cc.

1483 {
1485 [engine = engine_->GetWeakPtr(), loading_unit_id,
1486 data = std::move(snapshot_data),
1487 instructions = std::move(snapshot_instructions)]() mutable {
1488 if (engine) {
1489 engine->LoadDartDeferredLibrary(loading_unit_id, std::move(data),
1490 std::move(instructions));
1491 }
1492 }));
1493}
virtual void PostTask(const fml::closure &task) override
FlutterEngine engine
Definition main.cc:68
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ LoadDartDeferredLibraryError()

void flutter::Shell::LoadDartDeferredLibraryError ( intptr_t  loading_unit_id,
const std::string  error_message,
bool  transient 
)
overrideprivatevirtual

Indicates to the dart VM that the request to load a deferred library with the specified loading unit id has failed.

The dart future returned by the initiating loadLibrary() call will complete with an error.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit, as passed in by RequestDartDeferredLibrary.
[in]error_messageThe error message that will appear in the dart Future.
[in]transientA transient error is a failure due to temporary conditions such as no network. Transient errors allow the dart VM to re-request the same deferred library and loading_unit_id again. Non-transient errors are permanent and attempts to re-request the library will instantly complete with an error.

Implements flutter::PlatformView::Delegate.

Definition at line 1495 of file shell.cc.

1497 {
1499 task_runners_.GetUITaskRunner(),
1500 [engine = weak_engine_, loading_unit_id, error_message, transient] {
1501 if (engine) {
1502 engine->LoadDartDeferredLibraryError(loading_unit_id, error_message,
1503 transient);
1504 }
1505 });
1506}

◆ NotifyLowMemoryWarning()

void flutter::Shell::NotifyLowMemoryWarning ( ) const

Used by embedders to notify that there is a low memory warning. The shell will attempt to purge caches. Current, only the rasterizer cache is purged.

Definition at line 633 of file shell.cc.

633 {
634 auto trace_id = fml::tracing::TraceNonce();
635 TRACE_EVENT_ASYNC_BEGIN0("flutter", "Shell::NotifyLowMemoryWarning",
636 trace_id);
637 // This does not require a current isolate but does require a running VM.
638 // Since a valid shell will not be returned to the embedder without a valid
639 // DartVMRef, we can be certain that this is a safe spot to assume a VM is
640 // running.
642
643 task_runners_.GetRasterTaskRunner()->PostTask(
644 [rasterizer = rasterizer_->GetWeakPtr(), trace_id = trace_id]() {
645 if (rasterizer) {
646 rasterizer->NotifyLowMemoryWarning();
647 }
648 TRACE_EVENT_ASYNC_END0("flutter", "Shell::NotifyLowMemoryWarning",
649 trace_id);
650 });
651 // The IO Manager uses resource cache limits of 0, so it is not necessary
652 // to purge them.
653}
DART_EXPORT void Dart_NotifyLowMemory(void)
size_t TraceNonce()
#define TRACE_EVENT_ASYNC_END0(category_group, name, id)
#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)

◆ OnAnimatorBeginFrame()

void flutter::Shell::OnAnimatorBeginFrame ( fml::TimePoint  frame_target_time,
uint64_t  frame_number 
)
overrideprivatevirtual

Implements flutter::Animator::Delegate.

Definition at line 1225 of file shell.cc.

1226 {
1227 FML_DCHECK(is_set_up_);
1229
1230 // record the target time for use by rasterizer.
1231 {
1232 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1233 latest_frame_target_time_.emplace(frame_target_time);
1234 }
1235 if (engine_) {
1236 engine_->BeginFrame(frame_target_time, frame_number);
1237 }
1238}

◆ OnAnimatorDraw()

void flutter::Shell::OnAnimatorDraw ( std::shared_ptr< FramePipeline pipeline)
overrideprivatevirtual

Implements flutter::Animator::Delegate.

Definition at line 1267 of file shell.cc.

1267 {
1268 FML_DCHECK(is_set_up_);
1269
1271 [&waiting_for_first_frame = waiting_for_first_frame_,
1272 &waiting_for_first_frame_condition = waiting_for_first_frame_condition_,
1273 rasterizer = rasterizer_->GetWeakPtr(),
1274 weak_pipeline = std::weak_ptr<FramePipeline>(pipeline)]() mutable {
1275 if (rasterizer) {
1276 std::shared_ptr<FramePipeline> pipeline = weak_pipeline.lock();
1277 if (pipeline) {
1278 rasterizer->Draw(pipeline);
1279 }
1280
1281 if (waiting_for_first_frame.load()) {
1282 waiting_for_first_frame.store(false);
1283 waiting_for_first_frame_condition.notify_all();
1284 }
1285 }
1286 }));
1287}

◆ OnAnimatorDrawLastLayerTrees()

void flutter::Shell::OnAnimatorDrawLastLayerTrees ( std::unique_ptr< FrameTimingsRecorder frame_timings_recorder)
overrideprivatevirtual

Implements flutter::Animator::Delegate.

Definition at line 1290 of file shell.cc.

1291 {
1292 FML_DCHECK(is_set_up_);
1293
1294 auto task = fml::MakeCopyable(
1295 [rasterizer = rasterizer_->GetWeakPtr(),
1296 frame_timings_recorder = std::move(frame_timings_recorder)]() mutable {
1297 if (rasterizer) {
1298 rasterizer->DrawLastLayerTrees(std::move(frame_timings_recorder));
1299 }
1300 });
1301
1302 task_runners_.GetRasterTaskRunner()->PostTask(task);
1303}

◆ OnAnimatorNotifyIdle()

void flutter::Shell::OnAnimatorNotifyIdle ( fml::TimeDelta  deadline)
overrideprivatevirtual

Implements flutter::Animator::Delegate.

Definition at line 1241 of file shell.cc.

1241 {
1242 FML_DCHECK(is_set_up_);
1244
1245 if (engine_) {
1246 engine_->NotifyIdle(deadline);
1247 volatile_path_tracker_->OnFrame();
1248 }
1249}

◆ OnAnimatorUpdateLatestFrameTargetTime()

void flutter::Shell::OnAnimatorUpdateLatestFrameTargetTime ( fml::TimePoint  frame_target_time)
overrideprivatevirtual

Implements flutter::Animator::Delegate.

Definition at line 1251 of file shell.cc.

1252 {
1253 FML_DCHECK(is_set_up_);
1254
1255 // record the target time for use by rasterizer.
1256 {
1257 std::scoped_lock time_recorder_lock(time_recorder_mutex_);
1258 if (!latest_frame_target_time_) {
1259 latest_frame_target_time_ = frame_target_time;
1260 } else if (latest_frame_target_time_ < frame_target_time) {
1261 latest_frame_target_time_ = frame_target_time;
1262 }
1263 }
1264}

◆ OnDisplayUpdates()

void flutter::Shell::OnDisplayUpdates ( std::vector< std::unique_ptr< Display > >  displays)

Notifies the display manager of the updates.

Definition at line 2279 of file shell.cc.

2279 {
2280 FML_DCHECK(is_set_up_);
2282
2283 std::vector<DisplayData> display_data;
2284 display_data.reserve(displays.size());
2285 for (const auto& display : displays) {
2286 display_data.push_back(display->GetDisplayData());
2287 }
2288 task_runners_.GetUITaskRunner()->PostTask(
2289 [engine = engine_->GetWeakPtr(),
2290 display_data = std::move(display_data)]() {
2291 if (engine) {
2292 engine->SetDisplays(display_data);
2293 }
2294 });
2295
2296 display_manager_->HandleDisplayUpdates(std::move(displays));
2297}

◆ OnEngineChannelUpdate()

void flutter::Shell::OnEngineChannelUpdate ( std::string  name,
bool  listening 
)
overrideprivatevirtual

Invoked when a listener is registered on a platform channel.

Parameters
[in]nameThe name of the platform channel to which a listener has been registered or cleared.
[in]listeningWhether the listener has been set (true) or cleared (false).

Implements flutter::Engine::Delegate.

Definition at line 1380 of file shell.cc.

1380 {
1381 FML_DCHECK(is_set_up_);
1382
1383 task_runners_.GetPlatformTaskRunner()->PostTask(
1384 [view = platform_view_->GetWeakPtr(), name = std::move(name), listening] {
1385 if (view) {
1386 view->SendChannelUpdate(name, listening);
1387 }
1388 });
1389}
DEF_SWITCHES_START aot vmservice shared library name
Definition switches.h:32

◆ OnEngineHandlePlatformMessage()

void flutter::Shell::OnEngineHandlePlatformMessage ( std::unique_ptr< PlatformMessage message)
overrideprivatevirtual

When the Flutter application has a message to send to the underlying platform, the message needs to be forwarded to the platform on the appropriate thread (via the platform task runner). The engine delegates this task to the shell via this method.

See also
PlatformView::HandlePlatformMessage
Parameters
[in]messageThe message from the Flutter application to send to the underlying platform.

Implements flutter::Engine::Delegate.

Definition at line 1321 of file shell.cc.

1322 {
1323 FML_DCHECK(is_set_up_);
1325
1326 if (message->channel() == kSkiaChannel) {
1327 HandleEngineSkiaMessage(std::move(message));
1328 return;
1329 }
1330
1331 if (platform_message_handler_) {
1332 if (route_messages_through_platform_thread_ &&
1333 !platform_message_handler_
1334 ->DoesHandlePlatformMessageOnPlatformThread()) {
1335#if _WIN32
1336 // On Windows capturing a TaskRunner with a TaskRunner will cause an
1337 // uncaught exception in process shutdown because of the deletion order of
1338 // global variables. See also
1339 // https://github.com/flutter/flutter/issues/111575.
1340 // This won't be an issue until Windows supports background platform
1341 // channels (https://github.com/flutter/flutter/issues/93945). Then this
1342 // can potentially be addressed by capturing a weak_ptr to an object that
1343 // retains the ui TaskRunner, instead of the TaskRunner directly.
1344 FML_DCHECK(false);
1345#endif
1346 // We route messages through the platform thread temporarily when the
1347 // shell is being initialized to be backwards compatible with setting
1348 // message handlers in the same event as starting the isolate, but after
1349 // it is started.
1350 auto ui_task_runner = task_runners_.GetUITaskRunner();
1352 [weak_platform_message_handler =
1353 std::weak_ptr<PlatformMessageHandler>(platform_message_handler_),
1354 message = std::move(message), ui_task_runner]() mutable {
1355 ui_task_runner->PostTask(
1356 fml::MakeCopyable([weak_platform_message_handler,
1357 message = std::move(message)]() mutable {
1358 auto platform_message_handler =
1359 weak_platform_message_handler.lock();
1360 if (platform_message_handler) {
1361 platform_message_handler->HandlePlatformMessage(
1362 std::move(message));
1363 }
1364 }));
1365 }));
1366 } else {
1367 platform_message_handler_->HandlePlatformMessage(std::move(message));
1368 }
1369 } else {
1370 task_runners_.GetPlatformTaskRunner()->PostTask(
1371 fml::MakeCopyable([view = platform_view_->GetWeakPtr(),
1372 message = std::move(message)]() mutable {
1373 if (view) {
1374 view->HandlePlatformMessage(std::move(message));
1375 }
1376 }));
1377 }
1378}
Win32Message message
constexpr char kSkiaChannel[]
Definition shell.cc:48

◆ OnEngineUpdateSemantics()

void flutter::Shell::OnEngineUpdateSemantics ( SemanticsNodeUpdates  updates,
CustomAccessibilityActionUpdates  actions 
)
overrideprivatevirtual

When the accessibility tree has been updated by the Flutter application, this new information needs to be conveyed to the underlying platform. The engine delegates this task to the shell via this call. The engine cannot access the underlying platform directly because of threading considerations. Most platform specific APIs to convey accessibility information are only safe to access on the platform task runner while the engine is running on the UI task runner.

See also
SemanticsNode, SemanticsNodeUpdates, CustomAccessibilityActionUpdates, PlatformView::UpdateSemantics
Parameters
[in]updatesA map with the stable semantics node identifier as key and the node properties as the value.
[in]actionsA map with the stable semantics node identifier as key and the custom node action as the value.

Implements flutter::Engine::Delegate.

Definition at line 1306 of file shell.cc.

1307 {
1308 FML_DCHECK(is_set_up_);
1310
1311 task_runners_.GetPlatformTaskRunner()->PostTask(
1312 [view = platform_view_->GetWeakPtr(), update = std::move(update),
1313 actions = std::move(actions)] {
1314 if (view) {
1315 view->UpdateSemantics(update, actions);
1316 }
1317 });
1318}

◆ OnFrameRasterized()

void flutter::Shell::OnFrameRasterized ( const FrameTiming frame_timing)
overrideprivatevirtual

Notifies the delegate that a frame has been rendered. The rasterizer collects profiling information for each part of the frame workload. This profiling information is made available to the delegate for forwarding to subsystems interested in collecting such profiles. Currently, the shell (the delegate) forwards this to the engine where Dart code can react to this information.

See also
FrameTiming
Parameters
[in]frame_timingInstrumentation information for each phase of the frame workload.

Implements flutter::Rasterizer::Delegate.

Definition at line 1560 of file shell.cc.

1560 {
1561 FML_DCHECK(is_set_up_);
1563
1564 // The C++ callback defined in settings.h and set by Flutter runner. This is
1565 // independent of the timings report to the Dart side.
1566 if (settings_.frame_rasterized_callback) {
1567 settings_.frame_rasterized_callback(timing);
1568 }
1569
1570 if (!needs_report_timings_) {
1571 return;
1572 }
1573
1574 size_t old_count = unreported_timings_.size();
1575 (void)old_count;
1576 for (auto phase : FrameTiming::kPhases) {
1577 unreported_timings_.push_back(
1578 timing.Get(phase).ToEpochDelta().ToMicroseconds());
1579 }
1580 unreported_timings_.push_back(timing.GetLayerCacheCount());
1581 unreported_timings_.push_back(timing.GetLayerCacheBytes());
1582 unreported_timings_.push_back(timing.GetPictureCacheCount());
1583 unreported_timings_.push_back(timing.GetPictureCacheBytes());
1584 unreported_timings_.push_back(timing.GetFrameNumber());
1585 FML_DCHECK(unreported_timings_.size() ==
1586 old_count + FrameTiming::kStatisticsCount);
1587
1588 // In tests using iPhone 6S with profile mode, sending a batch of 1 frame or a
1589 // batch of 100 frames have roughly the same cost of less than 0.1ms. Sending
1590 // a batch of 500 frames costs about 0.2ms. The 1 second threshold usually
1591 // kicks in before we reaching the following 100 frames threshold. The 100
1592 // threshold here is mainly for unit tests (so we don't have to write a
1593 // 1-second unit test), and make sure that our vector won't grow too big with
1594 // future 120fps, 240fps, or 1000fps displays.
1595 //
1596 // In the profile/debug mode, the timings are used by development tools which
1597 // require a latency of no more than 100ms. Hence we lower that 1-second
1598 // threshold to 100ms because performance overhead isn't that critical in
1599 // those cases.
1600 if (!first_frame_rasterized_ || UnreportedFramesCount() >= 100) {
1601 first_frame_rasterized_ = true;
1602 ReportTimings();
1603 } else if (!frame_timings_report_scheduled_) {
1604#if FLUTTER_RELEASE
1605 constexpr int kBatchTimeInMilliseconds = 1000;
1606#else
1607 constexpr int kBatchTimeInMilliseconds = 100;
1608#endif
1609
1610 // Also make sure that frame times get reported with a max latency of 1
1611 // second. Otherwise, the timings of last few frames of an animation may
1612 // never be reported until the next animation starts.
1613 frame_timings_report_scheduled_ = true;
1614 task_runners_.GetRasterTaskRunner()->PostDelayedTask(
1615 [self = weak_factory_gpu_->GetWeakPtr()]() {
1616 if (!self) {
1617 return;
1618 }
1619 self->frame_timings_report_scheduled_ = false;
1620 if (self->UnreportedFramesCount() > 0) {
1621 self->ReportTimings();
1622 }
1623 },
1624 fml::TimeDelta::FromMilliseconds(kBatchTimeInMilliseconds));
1625 }
1626}
static constexpr int kStatisticsCount
Definition settings.h:49
virtual void PostDelayedTask(const fml::closure &task, fml::TimeDelta delay)
static constexpr TimeDelta FromMilliseconds(int64_t millis)
Definition time_delta.h:46
FrameRasterizedCallback frame_rasterized_callback
Definition settings.h:331

◆ OnPlatformViewAddView()

void flutter::Shell::OnPlatformViewAddView ( int64_t  view_id,
const ViewportMetrics viewport_metrics,
AddViewCallback  callback 
)
overrideprivatevirtual

Allocate resources for a new non-implicit view and inform Dart about the view, and on success, schedules a new frame.

After the operation, |callback| should be invoked with whether the operation is successful.

Adding |kFlutterImplicitViewId| or an existing view ID should result in failure.

Parameters
[in]view_idThe view ID of the new view.
[in]viewport_metricsThe initial viewport metrics for the view.
[in]callbackThe callback that's invoked once the shell has attempted to add the view.

Implements flutter::PlatformView::Delegate.

Definition at line 2117 of file shell.cc.

2119 {
2120 TRACE_EVENT0("flutter", "Shell::AddView");
2121 FML_DCHECK(is_set_up_);
2124 << "Unexpected request to add the implicit view #"
2125 << kFlutterImplicitViewId << ". This view should never be added.";
2126
2127 task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), //
2128 viewport_metrics, //
2129 view_id, //
2130 callback = std::move(callback) //
2131 ] {
2132 if (engine) {
2133 engine->AddView(view_id, viewport_metrics, callback);
2134 }
2135 });
2136}
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
constexpr int64_t kFlutterImplicitViewId
Definition constants.h:35

◆ OnPlatformViewCreated()

void flutter::Shell::OnPlatformViewCreated ( std::unique_ptr< Surface surface)
overrideprivatevirtual

Notifies the delegate that the platform view was created with the given render surface. This surface is platform (iOS, Android) and client-rendering API (OpenGL, Software, Metal, Vulkan) specific. This is usually a sign to the rasterizer to set up and begin rendering to that surface.

Parameters
[in]surfaceThe surface

Implements flutter::PlatformView::Delegate.

Definition at line 833 of file shell.cc.

833 {
834 TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated");
835 FML_DCHECK(is_set_up_);
837
838 // Prevent any request to change the thread configuration for raster and
839 // platform queues while the platform view is being created.
840 //
841 // This prevents false positives such as this method starts assuming that the
842 // raster and platform queues have a given thread configuration, but then the
843 // configuration is changed by a task, and the assumption is no longer true.
844 //
845 // This incorrect assumption can lead to deadlock.
846 // See `should_post_raster_task` for more.
847 rasterizer_->DisableThreadMergerIfNeeded();
848
849 // The normal flow executed by this method is that the platform thread is
850 // starting the sequence and waiting on the latch. Later the UI thread posts
851 // raster_task to the raster thread which signals the latch. If the raster and
852 // the platform threads are the same this results in a deadlock as the
853 // raster_task will never be posted to the platform/raster thread that is
854 // blocked on a latch. To avoid the described deadlock, if the raster and the
855 // platform threads are the same, should_post_raster_task will be false, and
856 // then instead of posting a task to the raster thread, the ui thread just
857 // signals the latch and the platform/raster thread follows with executing
858 // raster_task.
859 const bool should_post_raster_task =
861
862 auto raster_task = fml::MakeCopyable(
863 [&waiting_for_first_frame = waiting_for_first_frame_, //
864 rasterizer = rasterizer_->GetWeakPtr(), //
865 surface = std::move(surface) //
866 ]() mutable {
867 if (rasterizer) {
868 // Enables the thread merger which may be used by the external view
869 // embedder.
870 rasterizer->EnableThreadMergerIfNeeded();
871 rasterizer->Setup(std::move(surface));
872 }
873
874 waiting_for_first_frame.store(true);
875 });
876
877 auto ui_task = [engine = engine_->GetWeakPtr()] {
878 if (engine) {
879 engine->ScheduleFrame();
880 }
881 };
882
883 // Threading: Capture platform view by raw pointer and not the weak pointer.
884 // We are going to use the pointer on the IO thread which is not safe with a
885 // weak pointer. However, we are preventing the platform view from being
886 // collected by using a latch.
887 auto* platform_view = platform_view_.get();
890
891 auto io_task = [io_manager = io_manager_->GetWeakPtr(), platform_view,
892 ui_task_runner = task_runners_.GetUITaskRunner(), ui_task,
893 raster_task_runner = task_runners_.GetRasterTaskRunner(),
894 raster_task, should_post_raster_task, &latch] {
895 if (io_manager && !io_manager->GetResourceContext()) {
896 sk_sp<GrDirectContext> resource_context =
897 platform_view->CreateResourceContext();
898 io_manager->NotifyResourceContextAvailable(resource_context);
899 }
900 // Step 1: Post a task on the UI thread to tell the engine that it has
901 // an output surface.
902 fml::TaskRunner::RunNowOrPostTask(ui_task_runner, ui_task);
903
904 // Step 2: Tell the raster thread that it should create a surface for
905 // its rasterizer.
906 if (should_post_raster_task) {
907 fml::TaskRunner::RunNowOrPostTask(raster_task_runner, raster_task);
908 }
909 latch.Signal();
910 };
911
912 fml::TaskRunner::RunNowOrPostTask(task_runners_.GetIOTaskRunner(), io_task);
913
914 latch.Wait();
915 if (!should_post_raster_task) {
916 // See comment on should_post_raster_task, in this case the raster_task
917 // wasn't executed, and we just run it here as the platform thread
918 // is the raster thread.
919 raster_task();
920 }
921}
VkSurfaceKHR surface
Definition main.cc:49

◆ OnPlatformViewDestroyed()

void flutter::Shell::OnPlatformViewDestroyed ( )
overrideprivatevirtual

Notifies the delegate that the platform view was destroyed. This is usually a sign to the rasterizer to suspend rendering a previously configured surface and collect any intermediate resources.

Implements flutter::PlatformView::Delegate.

Definition at line 924 of file shell.cc.

924 {
925 TRACE_EVENT0("flutter", "Shell::OnPlatformViewDestroyed");
926 FML_DCHECK(is_set_up_);
928
929 // Prevent any request to change the thread configuration for raster and
930 // platform queues while the platform view is being destroyed.
931 //
932 // This prevents false positives such as this method starts assuming that the
933 // raster and platform queues have a given thread configuration, but then the
934 // configuration is changed by a task, and the assumption is no longer true.
935 //
936 // This incorrect assumption can lead to deadlock.
937 rasterizer_->DisableThreadMergerIfNeeded();
938
939 // Notify the Dart VM that the PlatformView has been destroyed and some
940 // cleanup activity can be done (e.g: garbage collect the Dart heap).
941 task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr()]() {
942 if (engine) {
943 engine->NotifyDestroyed();
944 }
945 });
946
947 // Note:
948 // This is a synchronous operation because certain platforms depend on
949 // setup/suspension of all activities that may be interacting with the GPU in
950 // a synchronous fashion.
951 // The UI thread does not need to be serialized here - there is sufficient
952 // guardrailing in the rasterizer to allow the UI thread to post work to it
953 // even after the surface has been torn down.
954
956
957 auto io_task = [io_manager = io_manager_.get(), &latch]() {
958 // Execute any pending Skia object deletions while GPU access is still
959 // allowed.
960 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
962 [&] { io_manager->GetSkiaUnrefQueue()->Drain(); }));
963 // Step 4: All done. Signal the latch that the platform thread is waiting
964 // on.
965 latch.Signal();
966 };
967
968 auto raster_task = [rasterizer = rasterizer_->GetWeakPtr(),
969 io_task_runner = task_runners_.GetIOTaskRunner(),
970 io_task]() {
971 if (rasterizer) {
972 // Enables the thread merger which is required prior tearing down the
973 // rasterizer. If the raster and platform threads are merged, tearing down
974 // the rasterizer unmerges the threads.
975 rasterizer->EnableThreadMergerIfNeeded();
976 rasterizer->Teardown();
977 }
978 // Step 2: Tell the IO thread to complete its remaining work.
979 fml::TaskRunner::RunNowOrPostTask(io_task_runner, io_task);
980 };
981
982 // Step 1: Post a task to the Raster thread (possibly this thread) to tell the
983 // rasterizer the output surface is going away.
985 raster_task);
986 latch.Wait();
987 // On Android, the external view embedder may post a task to the platform
988 // thread, and wait until it completes if overlay surfaces must be released.
989 // However, the platform thread might be blocked when Dart is initializing.
990 // In this situation, calling TeardownExternalViewEmbedder is safe because no
991 // platform views have been created before Flutter renders the first frame.
992 // Overall, the longer term plan is to remove this implementation once
993 // https://github.com/flutter/flutter/issues/96679 is fixed.
994 rasterizer_->TeardownExternalViewEmbedder();
995}
Represents the 2 code paths available when calling |SyncSwitchExecute|.
Definition sync_switch.h:35
Handlers & SetIfFalse(const std::function< void()> &handler)
Sets the handler that will be executed if the |SyncSwitch| is false.

◆ OnPlatformViewDispatchPlatformMessage()

void flutter::Shell::OnPlatformViewDispatchPlatformMessage ( std::unique_ptr< PlatformMessage message)
overrideprivatevirtual

Notifies the delegate that the platform has dispatched a platform message from the embedder to the Flutter application. This message must be forwarded to the running isolate hosted by the engine on the UI thread.

Parameters
[in]messageThe platform message to dispatch to the running root isolate.

Implements flutter::PlatformView::Delegate.

Definition at line 1051 of file shell.cc.

1052 {
1053 FML_DCHECK(is_set_up_);
1054#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
1055 if (!task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()) {
1056 std::scoped_lock lock(misbehaving_message_channels_mutex_);
1057 auto inserted = misbehaving_message_channels_.insert(message->channel());
1058 if (inserted.second) {
1059 FML_LOG(ERROR)
1060 << "The '" << message->channel()
1061 << "' channel sent a message from native to Flutter on a "
1062 "non-platform thread. Platform channel messages must be sent on "
1063 "the platform thread. Failure to do so may result in data loss or "
1064 "crashes, and must be fixed in the plugin or application code "
1065 "creating that channel.\n"
1066 "See https://docs.flutter.dev/platform-integration/"
1067 "platform-channels#channels-and-platform-threading for more "
1068 "information.";
1069 }
1070 }
1071#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
1072
1073 // The static leak checker gets confused by the use of fml::MakeCopyable.
1074 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
1076 [engine = engine_->GetWeakPtr(), message = std::move(message)]() mutable {
1077 if (engine) {
1078 engine->DispatchPlatformMessage(std::move(message));
1079 }
1080 }));
1081}
#define FML_LOG(severity)
Definition logging.h:82
#define ERROR(message)

◆ OnPlatformViewDispatchPointerDataPacket()

void flutter::Shell::OnPlatformViewDispatchPointerDataPacket ( std::unique_ptr< PointerDataPacket packet)
overrideprivatevirtual

Notifies the delegate that the platform view has encountered a pointer event. This pointer event needs to be forwarded to the running root isolate hosted by the engine on the UI thread.

Parameters
[in]packetThe pointer data packet containing multiple pointer events.

Implements flutter::PlatformView::Delegate.

Definition at line 1084 of file shell.cc.

1085 {
1087 "flutter", "Shell::OnPlatformViewDispatchPointerDataPacket",
1088 /*flow_id_count=*/1, /*flow_ids=*/&next_pointer_flow_id_);
1089 TRACE_FLOW_BEGIN("flutter", "PointerEvent", next_pointer_flow_id_);
1090 FML_DCHECK(is_set_up_);
1092 task_runners_.GetUITaskRunner()->PostTask(
1093 fml::MakeCopyable([engine = weak_engine_, packet = std::move(packet),
1094 flow_id = next_pointer_flow_id_]() mutable {
1095 if (engine) {
1096 engine->DispatchPointerDataPacket(std::move(packet), flow_id);
1097 }
1098 }));
1099 next_pointer_flow_id_++;
1100}
#define TRACE_FLOW_BEGIN(category, name, id)
#define TRACE_EVENT0_WITH_FLOW_IDS(category_group, name, flow_id_count, flow_ids)

◆ OnPlatformViewDispatchSemanticsAction()

void flutter::Shell::OnPlatformViewDispatchSemanticsAction ( int32_t  node_id,
SemanticsAction  action,
fml::MallocMapping  args 
)
overrideprivatevirtual

Notifies the delegate that the platform view has encountered an accessibility related action on the specified node. This event must be forwarded to the running root isolate hosted by the engine on the UI thread.

Parameters
[in]node_idThe identifier of the accessibility node.
[in]actionThe accessibility related action performed on the node of the specified ID.
[in]argsAn optional list of argument that apply to the specified action.

Implements flutter::PlatformView::Delegate.

Definition at line 1103 of file shell.cc.

1105 {
1106 FML_DCHECK(is_set_up_);
1108
1109 task_runners_.GetUITaskRunner()->PostTask(
1110 fml::MakeCopyable([engine = engine_->GetWeakPtr(), node_id, action,
1111 args = std::move(args)]() mutable {
1112 if (engine) {
1113 engine->DispatchSemanticsAction(node_id, action, std::move(args));
1114 }
1115 }));
1116}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

◆ OnPlatformViewGetSettings()

const Settings & flutter::Shell::OnPlatformViewGetSettings ( ) const
overrideprivatevirtual

Called by the platform view on the platform thread to get the settings object associated with the platform view instance.

Returns
The settings.

Implements flutter::PlatformView::Delegate.

Definition at line 1220 of file shell.cc.

1220 {
1221 return settings_;
1222}

◆ OnPlatformViewMarkTextureFrameAvailable()

void flutter::Shell::OnPlatformViewMarkTextureFrameAvailable ( int64_t  texture_id)
overrideprivatevirtual

Notifies the delegate that the embedder has updated the contents of the texture with the specified identifier. Typically, Flutter will only render a frame if there is an updated layer tree. However, in cases where the layer tree is static but one of the externally composited textures has been updated by the embedder, the embedder needs to notify the rasterizer to render a new frame. In such cases, the existing layer tree may be reused with the frame composited with all updated external textures.

Parameters
[in]texture_idThe identifier of the texture that has been updated.

Implements flutter::PlatformView::Delegate.

Definition at line 1176 of file shell.cc.

1176 {
1177 FML_DCHECK(is_set_up_);
1179
1180 // Tell the rasterizer that one of its textures has a new frame available.
1181 task_runners_.GetRasterTaskRunner()->PostTask(
1182 [rasterizer = rasterizer_->GetWeakPtr(), texture_id]() {
1183 auto registry = rasterizer->GetTextureRegistry();
1184
1185 if (!registry) {
1186 return;
1187 }
1188
1189 auto texture = registry->GetTexture(texture_id);
1190
1191 if (!texture) {
1192 return;
1193 }
1194
1195 texture->MarkNewFrameAvailable();
1196 });
1197
1198 // Schedule a new frame without having to rebuild the layer tree.
1199 task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr()]() {
1200 if (engine) {
1201 engine->ScheduleFrame(false);
1202 }
1203 });
1204}
FlTexture * texture
int64_t texture_id

◆ OnPlatformViewRegisterTexture()

void flutter::Shell::OnPlatformViewRegisterTexture ( std::shared_ptr< flutter::Texture texture)
overrideprivate

Definition at line 1145 of file shell.cc.

1146 {
1147 FML_DCHECK(is_set_up_);
1149
1150 task_runners_.GetRasterTaskRunner()->PostTask(
1151 [rasterizer = rasterizer_->GetWeakPtr(), texture] {
1152 if (rasterizer) {
1153 if (auto registry = rasterizer->GetTextureRegistry()) {
1154 registry->RegisterTexture(texture);
1155 }
1156 }
1157 });
1158}

◆ OnPlatformViewRemoveView()

void flutter::Shell::OnPlatformViewRemoveView ( int64_t  view_id,
RemoveViewCallback  callback 
)
overrideprivatevirtual

Deallocate resources for a removed view and inform Dart about the removal.

After the operation, |callback| should be invoked with whether the operation is successful.

Removing |kFlutterImplicitViewId| or an non-existent view ID should result in failure.

Parameters
[in]view_idThe view ID of the view to be removed.
[in]callbackThe callback that's invoked once the shell has attempted to remove the view.

Implements flutter::PlatformView::Delegate.

Definition at line 2138 of file shell.cc.

2139 {
2140 TRACE_EVENT0("flutter", "Shell::RemoveView");
2141 FML_DCHECK(is_set_up_);
2144 << "Unexpected request to remove the implicit view #"
2145 << kFlutterImplicitViewId << ". This view should never be removed.";
2146
2147 expected_frame_sizes_.erase(view_id);
2148 task_runners_.GetUITaskRunner()->PostTask(
2149 [&task_runners = task_runners_, //
2150 engine = engine_->GetWeakPtr(), //
2151 rasterizer = rasterizer_->GetWeakPtr(), //
2152 view_id, //
2153 callback = std::move(callback) //
2154 ] {
2155 if (engine) {
2156 bool removed = engine->RemoveView(view_id);
2157 callback(removed);
2158 }
2159 // Don't wait for the raster task here, which only cleans up memory and
2160 // does not affect functionality. Make sure it is done after Dart
2161 // removes the view to avoid receiving another rasterization request
2162 // that adds back the view record.
2163 task_runners.GetRasterTaskRunner()->PostTask([rasterizer, view_id]() {
2164 if (rasterizer) {
2165 rasterizer->CollectView(view_id);
2166 }
2167 });
2168 });
2169}

◆ OnPlatformViewScheduleFrame()

void flutter::Shell::OnPlatformViewScheduleFrame ( )
overrideprivatevirtual

Notifies the delegate that the platform needs to schedule a frame to regenerate the layer tree and redraw the surface.

Implements flutter::PlatformView::Delegate.

Definition at line 998 of file shell.cc.

998 {
999 TRACE_EVENT0("flutter", "Shell::OnPlatformViewScheduleFrame");
1000 FML_DCHECK(is_set_up_);
1002
1003 task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr()]() {
1004 if (engine) {
1005 engine->ScheduleFrame();
1006 }
1007 });
1008}

◆ OnPlatformViewSetAccessibilityFeatures()

void flutter::Shell::OnPlatformViewSetAccessibilityFeatures ( int32_t  flags)
overrideprivatevirtual

Notifies the delegate that the embedder has expressed an opinion about the features to enable in the accessibility tree.

The engine does not care about the accessibility feature flags as all it does is forward this information from the embedder to the framework. However, curious readers may refer to AccessibilityFeatures in window.dart for currently supported accessibility feature flags.

Parameters
[in]flagsThe features to enable in the accessibility tree.

Implements flutter::PlatformView::Delegate.

Definition at line 1132 of file shell.cc.

1132 {
1133 FML_DCHECK(is_set_up_);
1135
1136 task_runners_.GetUITaskRunner()->PostTask(
1137 [engine = engine_->GetWeakPtr(), flags] {
1138 if (engine) {
1139 engine->SetAccessibilityFeatures(flags);
1140 }
1141 });
1142}
FlutterSemanticsFlag flags

◆ OnPlatformViewSetNextFrameCallback()

void flutter::Shell::OnPlatformViewSetNextFrameCallback ( const fml::closure closure)
overrideprivatevirtual

Notifies the delegate that the specified callback needs to be invoked after the rasterizer is done rendering the next frame. This callback will be called on the render thread and it is caller responsibility to perform any re-threading as necessary. Due to the asynchronous nature of rendering in Flutter, embedders usually add a placeholder over the contents in which Flutter is going to render when Flutter is first initialized. This callback may be used as a signal to remove that placeholder.

Attention
The callback will be invoked on the render thread and not the calling thread.
Parameters
[in]closureThe callback to execute on the next frame.

Implements flutter::PlatformView::Delegate.

Definition at line 1207 of file shell.cc.

1207 {
1208 FML_DCHECK(is_set_up_);
1210
1211 task_runners_.GetRasterTaskRunner()->PostTask(
1212 [rasterizer = rasterizer_->GetWeakPtr(), closure = closure]() {
1213 if (rasterizer) {
1214 rasterizer->SetNextFrameCallback(closure);
1215 }
1216 });
1217}

◆ OnPlatformViewSetSemanticsEnabled()

void flutter::Shell::OnPlatformViewSetSemanticsEnabled ( bool  enabled)
overrideprivatevirtual

Notifies the delegate that the embedder has expressed an opinion about whether the accessibility tree needs to be enabled or disabled. This information needs to be forwarded to the root isolate running on the UI thread.

Parameters
[in]enabledWhether the accessibility tree is enabled or disabled.

Implements flutter::PlatformView::Delegate.

Definition at line 1119 of file shell.cc.

1119 {
1120 FML_DCHECK(is_set_up_);
1122
1123 task_runners_.GetUITaskRunner()->PostTask(
1124 [engine = engine_->GetWeakPtr(), enabled] {
1125 if (engine) {
1126 engine->SetSemanticsEnabled(enabled);
1127 }
1128 });
1129}

◆ OnPlatformViewSetViewportMetrics()

void flutter::Shell::OnPlatformViewSetViewportMetrics ( int64_t  view_id,
const ViewportMetrics metrics 
)
overrideprivatevirtual

Notifies the delegate the viewport metrics of a view have been updated. The rasterizer will need to be reconfigured to render the frame in the updated viewport metrics.

Parameters
[in]view_idThe ID for the view that metrics describes.
[in]metricsThe updated viewport metrics.

Implements flutter::PlatformView::Delegate.

Definition at line 1011 of file shell.cc.

1012 {
1013 FML_DCHECK(is_set_up_);
1015
1016 if (metrics.device_pixel_ratio <= 0 || metrics.physical_width <= 0 ||
1017 metrics.physical_height <= 0) {
1018 // Ignore invalid view-port metrics.
1019 return;
1020 }
1021
1022 // This is the formula Android uses.
1023 // https://android.googlesource.com/platform/frameworks/base/+/39ae5bac216757bc201490f4c7b8c0f63006c6cd/libs/hwui/renderthread/CacheManager.cpp#45
1024 resource_cache_limit_ =
1025 metrics.physical_width * metrics.physical_height * 12 * 4;
1026 size_t resource_cache_max_bytes =
1027 resource_cache_limit_calculator_->GetResourceCacheMaxBytes();
1028 task_runners_.GetRasterTaskRunner()->PostTask(
1029 [rasterizer = rasterizer_->GetWeakPtr(), resource_cache_max_bytes] {
1030 if (rasterizer) {
1031 rasterizer->SetResourceCacheMaxBytes(resource_cache_max_bytes, false);
1032 }
1033 });
1034
1035 task_runners_.GetUITaskRunner()->PostTask(
1036 [engine = engine_->GetWeakPtr(), view_id, metrics]() {
1037 if (engine) {
1038 engine->SetViewportMetrics(view_id, metrics);
1039 }
1040 });
1041
1042 {
1043 std::scoped_lock<std::mutex> lock(resize_mutex_);
1044 expected_frame_sizes_[view_id] =
1045 SkISize::Make(metrics.physical_width, metrics.physical_height);
1046 device_pixel_ratio_ = metrics.device_pixel_ratio;
1047 }
1048}
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20

◆ OnPlatformViewUnregisterTexture()

void flutter::Shell::OnPlatformViewUnregisterTexture ( int64_t  texture_id)
overrideprivatevirtual

Notifies the delegate that the embedder will no longer attempt to composite the specified texture within the layer tree. This allows the rasterizer to collect associated resources.

Parameters
[in]texture_idThe identifier of the texture to unregister. If the texture has not been previously registered, this call does nothing.

Implements flutter::PlatformView::Delegate.

Definition at line 1161 of file shell.cc.

1161 {
1162 FML_DCHECK(is_set_up_);
1164
1165 task_runners_.GetRasterTaskRunner()->PostTask(
1166 [rasterizer = rasterizer_->GetWeakPtr(), texture_id]() {
1167 if (rasterizer) {
1168 if (auto registry = rasterizer->GetTextureRegistry()) {
1169 registry->UnregisterTexture(texture_id);
1170 }
1171 }
1172 });
1173}

◆ OnPreEngineRestart()

void flutter::Shell::OnPreEngineRestart ( )
overrideprivatevirtual

Notifies the delegate that the root isolate of the application is about to be discarded and a new isolate with the same runtime started in its place. This should only happen in the Flutter "debug" runtime mode in the cold-restart scenario. The embedder may need to reset native resource in response to the restart.

See also
PlatformView::OnPreEngineRestart

Implements flutter::Engine::Delegate.

Definition at line 1428 of file shell.cc.

1428 {
1429 FML_DCHECK(is_set_up_);
1431
1434 task_runners_.GetPlatformTaskRunner(),
1435 [view = platform_view_->GetWeakPtr(), &latch]() {
1436 if (view) {
1437 view->OnPreEngineRestart();
1438 }
1439 latch.Signal();
1440 });
1441 // This is blocking as any embedded platform views has to be flushed before
1442 // we re-run the Dart code.
1443 latch.Wait();
1444}

◆ OnRootIsolateCreated()

void flutter::Shell::OnRootIsolateCreated ( )
overrideprivatevirtual

Notifies the shell that the root isolate is created. Currently, this information is to add to the service protocol list of available root isolates running in the VM and their names so that the appropriate isolate can be selected in the tools for debugging and instrumentation.

Implements flutter::Engine::Delegate.

Definition at line 1447 of file shell.cc.

1447 {
1448 if (is_added_to_service_protocol_) {
1449 return;
1450 }
1451 auto description = GetServiceProtocolDescription();
1453 task_runners_.GetPlatformTaskRunner(),
1454 [self = weak_factory_.GetWeakPtr(),
1455 description = std::move(description)]() {
1456 if (self) {
1457 self->vm_->GetServiceProtocol()->AddHandler(self.get(), description);
1458 }
1459 });
1460 is_added_to_service_protocol_ = true;
1461}
ServiceProtocol::Handler::Description GetServiceProtocolDescription() const override
Definition shell.cc:1679

◆ RegisterImageDecoder()

void flutter::Shell::RegisterImageDecoder ( ImageGeneratorFactory  factory,
int32_t  priority 
)

Install a new factory that can match against and decode image data.

Parameters
[in]factoryCallback that produces ImageGenerators for compatible input data.
[in]priorityThe priority used to determine the order in which factories are tried. Higher values mean higher priority. The built-in Skia decoders are installed at priority 0, and so a priority > 0 takes precedent over the builtin decoders. When multiple decoders are added with the same priority, those which are added earlier take precedent.
See also
CreateCompatibleGenerator

Definition at line 1866 of file shell.cc.

1867 {
1869 FML_DCHECK(is_set_up_);
1870
1872 task_runners_.GetUITaskRunner(),
1873 [engine = engine_->GetWeakPtr(), factory = std::move(factory),
1874 priority]() {
1875 if (engine) {
1876 engine->GetImageGeneratorRegistry()->AddFactory(factory, priority);
1877 }
1878 });
1879}

◆ ReloadSystemFonts()

bool flutter::Shell::ReloadSystemFonts ( )

Used by embedders to reload the system fonts in FontCollection. It also clears the cached font families and send system channel message to framework to rebuild affected widgets.

Returns
Returns if shell reloads system fonts successfully.

Definition at line 2234 of file shell.cc.

2234 {
2235 FML_DCHECK(is_set_up_);
2237
2238 if (!engine_) {
2239 return false;
2240 }
2241 engine_->SetupDefaultFontManager();
2242 engine_->GetFontCollection().GetFontCollection()->ClearFontFamilyCache();
2243 // After system fonts are reloaded, we send a system channel message
2244 // to notify flutter framework.
2245 SendFontChangeNotification();
2246 return true;
2247}

◆ RequestDartDeferredLibrary()

void flutter::Shell::RequestDartDeferredLibrary ( intptr_t  loading_unit_id)
overrideprivatevirtual

Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the deferred library identified by the specified loading unit id should be downloaded and loaded into the Dart VM via LoadDartDeferredLibrary

Upon encountering errors or otherwise failing to load a loading unit with the specified id, the failure should be directly reported to dart by calling LoadDartDeferredLibraryFailure to ensure the waiting dart future completes with an error.

Parameters
[in]loading_unit_idThe unique id of the deferred library's loading unit. This id is to be passed back into LoadDartDeferredLibrary in order to identify which deferred library to load.

Implements flutter::Engine::Delegate.

Definition at line 1524 of file shell.cc.

1524 {
1525 task_runners_.GetPlatformTaskRunner()->PostTask(
1526 [view = platform_view_->GetWeakPtr(), loading_unit_id] {
1527 if (view) {
1528 view->RequestDartDeferredLibrary(loading_unit_id);
1529 }
1530 });
1531}

◆ RunEngine() [1/2]

void flutter::Shell::RunEngine ( RunConfiguration  run_configuration)

Starts an isolate for the given RunConfiguration.

Definition at line 655 of file shell.cc.

655 {
656 RunEngine(std::move(run_configuration), nullptr);
657}
void RunEngine(RunConfiguration run_configuration)
Starts an isolate for the given RunConfiguration.
Definition shell.cc:655

◆ RunEngine() [2/2]

void flutter::Shell::RunEngine ( RunConfiguration  run_configuration,
const std::function< void(Engine::RunStatus)> &  result_callback 
)

Starts an isolate for the given RunConfiguration. The result_callback will be called with the status of the operation.

Definition at line 659 of file shell.cc.

661 {
662 auto result = [platform_runner = task_runners_.GetPlatformTaskRunner(),
663 result_callback](Engine::RunStatus run_result) {
664 if (!result_callback) {
665 return;
666 }
667 platform_runner->PostTask(
668 [result_callback, run_result]() { result_callback(run_result); });
669 };
670 FML_DCHECK(is_set_up_);
672
674 task_runners_.GetUITaskRunner(),
676 [run_configuration = std::move(run_configuration),
677 weak_engine = weak_engine_, result]() mutable {
678 if (!weak_engine) {
679 FML_LOG(ERROR)
680 << "Could not launch engine with configuration - no engine.";
681 result(Engine::RunStatus::Failure);
682 return;
683 }
684 auto run_result = weak_engine->Run(std::move(run_configuration));
685 if (run_result == flutter::Engine::RunStatus::Failure) {
686 FML_LOG(ERROR) << "Could not launch engine with configuration.";
687 }
688
689 result(run_result);
690 }));
691}
RunStatus
Indicates the result of the call to Engine::Run.
Definition engine.h:78
GAsyncResult * result

◆ Screenshot()

Rasterizer::Screenshot flutter::Shell::Screenshot ( Rasterizer::ScreenshotType  type,
bool  base64_encode 
)

Captures a screenshot and optionally Base64 encodes the data of the last layer tree rendered by the rasterizer in this shell.

Parameters
[in]typeThe type of screenshot to capture.
[in]base64_encodeIf the screenshot data should be base64 encoded.
Returns
The screenshot result.

Definition at line 2171 of file shell.cc.

2173 {
2174 if (settings_.enable_impeller) {
2175 switch (screenshot_type) {
2177 FML_LOG(ERROR)
2178 << "Impeller backend cannot produce ScreenshotType::SkiaPicture.";
2179 return {};
2183 break;
2184 }
2185 }
2186 TRACE_EVENT0("flutter", "Shell::Screenshot");
2188 Rasterizer::Screenshot screenshot;
2190 task_runners_.GetRasterTaskRunner(), [&latch, //
2191 rasterizer = GetRasterizer(), //
2192 &screenshot, //
2193 screenshot_type, //
2194 base64_encode //
2195 ]() {
2196 if (rasterizer) {
2197 screenshot = rasterizer->ScreenshotLastLayerTree(screenshot_type,
2198 base64_encode);
2199 }
2200 latch.Signal();
2201 });
2202 latch.Wait();
2203 return screenshot;
2204}
fml::TaskRunnerAffineWeakPtr< Rasterizer > GetRasterizer() const
Rasterizers may only be accessed on the raster task runner.
Definition shell.cc:808

◆ SetGpuAvailability()

void flutter::Shell::SetGpuAvailability ( GpuAvailability  availability)

Marks the GPU as available or unavailable.

Definition at line 2254 of file shell.cc.

2254 {
2256 switch (availability) {
2258 is_gpu_disabled_sync_switch_->SetSwitch(false);
2259 return;
2263 task_runners_.GetIOTaskRunner(),
2264 [io_manager = io_manager_.get(), &latch]() {
2265 io_manager->GetSkiaUnrefQueue()->Drain();
2266 latch.Signal();
2267 });
2268 latch.Wait();
2269 }
2270 // FALLTHROUGH
2272 is_gpu_disabled_sync_switch_->SetSwitch(true);
2273 return;
2274 default:
2275 FML_DCHECK(false);
2276 }
2277}
@ kAvailable
Indicates that GPU operations should be permitted.

◆ SetNeedsReportTimings()

void flutter::Shell::SetNeedsReportTimings ( bool  needs_reporting)
overrideprivatevirtual

Notifies the shell that the application has an opinion about whether its frame timings need to be reported backed to it. Due to the asynchronous nature of rendering in Flutter, it is not possible for the application to determine the total time it took to render a specific frame. While the layer-tree is constructed on the UI thread, it needs to be rendering on the raster thread. Dart code cannot execute on this thread. So any instrumentation about the frame times gathered on this thread needs to be aggregated and sent back to the UI thread for processing in Dart.

When the application indicates that frame times need to be reported, it collects this information till a specified number of data points are gathered. Then this information is sent back to Dart code via Engine::ReportTimings.

This option is engine counterpart of the Window._setNeedsReportTimings in window.dart.

Parameters
[in]needs_reportingIf reporting information should be collected and send back to Dart.

Implements flutter::Engine::Delegate.

Definition at line 1470 of file shell.cc.

1470 {
1471 needs_report_timings_ = value;
1472}
uint8_t value

◆ ShouldDiscardLayerTree()

bool flutter::Shell::ShouldDiscardLayerTree ( int64_t  view_id,
const flutter::LayerTree tree 
)
overrideprivatevirtual

Implements flutter::Rasterizer::Delegate.

Definition at line 1647 of file shell.cc.

1648 {
1649 std::scoped_lock<std::mutex> lock(resize_mutex_);
1650 auto expected_frame_size = ExpectedFrameSize(view_id);
1651 return !expected_frame_size.isEmpty() &&
1652 tree.frame_size() != expected_frame_size;
1653}
const SkISize & frame_size() const
Definition layer_tree.h:58

◆ Spawn()

std::unique_ptr< Shell > flutter::Shell::Spawn ( RunConfiguration  run_configuration,
const std::string &  initial_route,
const CreateCallback< PlatformView > &  on_create_platform_view,
const CreateCallback< Rasterizer > &  on_create_rasterizer 
) const

Creates one Shell from another Shell where the created Shell takes the opportunity to share any internal components it can. This results is a Shell that has a smaller startup time cost and a smaller memory footprint than an Shell created with the Create function.

The new Shell is returned in a running state so RunEngine shouldn't be called again on the Shell. Once running, the second Shell is mostly independent from the original Shell and the original Shell doesn't need to keep running for the spawned Shell to keep functioning.

Parameters
[in]run_configurationA RunConfiguration used to run the Isolate associated with this new Shell. It doesn't have to be the same configuration as the current Shell but it needs to be in the same snapshot or AOT.
See also
http://flutter.dev/go/multiple-engines

Definition at line 589 of file shell.cc.

593 {
594 FML_DCHECK(task_runners_.IsValid());
595 // It's safe to store this value since it is set on the platform thread.
596 bool is_gpu_disabled = false;
599 .SetIfFalse([&is_gpu_disabled] { is_gpu_disabled = false; })
600 .SetIfTrue([&is_gpu_disabled] { is_gpu_disabled = true; }));
601 std::unique_ptr<Shell> result = CreateWithSnapshot(
602 PlatformData{}, task_runners_, rasterizer_->GetRasterThreadMerger(),
603 io_manager_, resource_cache_limit_calculator_, GetSettings(), vm_,
604 vm_->GetVMData()->GetIsolateSnapshot(), on_create_platform_view,
605 on_create_rasterizer,
606 [engine = this->engine_.get(), initial_route](
607 Engine::Delegate& delegate,
608 const PointerDataDispatcherMaker& dispatcher_maker, DartVM& vm,
609 const fml::RefPtr<const DartSnapshot>& isolate_snapshot,
610 const TaskRunners& task_runners, const PlatformData& platform_data,
611 const Settings& settings, std::unique_ptr<Animator> animator,
612 const fml::WeakPtr<IOManager>& io_manager,
613 const fml::RefPtr<SkiaUnrefQueue>& unref_queue,
615 const std::shared_ptr<VolatilePathTracker>& volatile_path_tracker,
616 const std::shared_ptr<fml::SyncSwitch>& is_gpu_disabled_sync_switch,
617 impeller::RuntimeStageBackend runtime_stage_backend) {
618 return engine->Spawn(
619 /*delegate=*/delegate,
620 /*dispatcher_maker=*/dispatcher_maker,
621 /*settings=*/settings,
622 /*animator=*/std::move(animator),
623 /*initial_route=*/initial_route,
624 /*io_manager=*/io_manager,
625 /*snapshot_delegate=*/std::move(snapshot_delegate),
626 /*gpu_disabled_switch=*/is_gpu_disabled_sync_switch);
627 },
628 is_gpu_disabled);
629 result->RunEngine(std::move(run_configuration));
630 return result;
631}
std::shared_ptr< const DartVMData > GetVMData() const
The VM and isolate snapshots used by this running Dart VM instance.
Definition dart_vm.cc:529
const Settings & GetSettings() const override
Definition shell.cc:795
std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const override
Accessor for the disable GPU SyncSwitch.
Definition shell.cc:2249
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.

◆ UpdateAssetResolverByType()

void flutter::Shell::UpdateAssetResolverByType ( std::unique_ptr< AssetResolver updated_asset_resolver,
AssetResolver::AssetResolverType  type 
)
overrideprivatevirtual

Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_asset_resolver. The matching AssetResolver is removed and replaced with updated_asset_resolvers.

AssetResolvers should be updated when the existing resolver becomes obsolete and a newer one becomes available that provides updated access to the same type of assets as the existing one. This update process is meant to be performed at runtime.

If a null resolver is provided, nothing will be done. If no matching resolver is found, the provided resolver will be added to the end of the AssetManager resolvers queue. The replacement only occurs with the first matching resolver. Any additional matching resolvers are untouched.

Parameters
[in]updated_asset_resolverThe asset resolver to replace the resolver of matching type with.
[in]typeThe type of AssetResolver to update. Only resolvers of the specified type will be replaced by the updated resolver.

Implements flutter::PlatformView::Delegate.

Definition at line 1508 of file shell.cc.

1510 {
1512 task_runners_.GetUITaskRunner(),
1514 [engine = weak_engine_, type,
1515 asset_resolver = std::move(updated_asset_resolver)]() mutable {
1516 if (engine) {
1517 engine->GetAssetManager()->UpdateResolverByType(
1518 std::move(asset_resolver), type);
1519 }
1520 }));
1521}

◆ UpdateIsolateDescription()

void flutter::Shell::UpdateIsolateDescription ( const std::string  isolate_name,
int64_t  isolate_port 
)
overrideprivatevirtual

Notifies the shell of the name of the root isolate and its port when that isolate is launched, restarted (in the cold-restart scenario) or the application itself updates the name of the root isolate (via PlatformDispatcher.setIsolateDebugName in platform_dispatcher.dart). The name of the isolate is meaningless to the engine but is used in instrumentation and tooling. Currently, this information is to update the service protocol list of available root isolates running in the VM and their names so that the appropriate isolate can be selected in the tools for debugging and instrumentation.

Parameters
[in]isolate_nameThe isolate name
[in]isolate_portThe isolate port

Implements flutter::Engine::Delegate.

Definition at line 1464 of file shell.cc.

1465 {
1466 Handler::Description description(isolate_port, isolate_name);
1467 vm_->GetServiceProtocol()->SetHandlerDescription(this, description);
1468}

◆ WaitForFirstFrame()

fml::Status flutter::Shell::WaitForFirstFrame ( fml::TimeDelta  timeout)

Pauses the calling thread until the first frame is presented.

Parameters
[in]timeoutThe duration to wait before timing out. If this duration would cause an overflow when added to std::chrono::steady_clock::now(), this method will wait indefinitely for the first frame.
Returns
'kOk' when the first frame has been presented before the timeout successfully, 'kFailedPrecondition' if called from the GPU or UI thread, 'kDeadlineExceeded' if there is a timeout.

Definition at line 2206 of file shell.cc.

2206 {
2207 FML_DCHECK(is_set_up_);
2208 if (task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread() ||
2209 task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()) {
2211 "WaitForFirstFrame called from thread that can't wait "
2212 "because it is responsible for generating the frame.");
2213 }
2214
2215 // Check for overflow.
2216 auto now = std::chrono::steady_clock::now();
2217 auto max_duration = std::chrono::steady_clock::time_point::max() - now;
2218 auto desired_duration = std::chrono::milliseconds(timeout.ToMilliseconds());
2219 auto duration =
2220 now + (desired_duration > max_duration ? max_duration : desired_duration);
2221
2222 std::unique_lock<std::mutex> lock(waiting_for_first_frame_mutex_);
2223 bool success = waiting_for_first_frame_condition_.wait_until(
2224 lock, duration, [&waiting_for_first_frame = waiting_for_first_frame_] {
2225 return !waiting_for_first_frame.load();
2226 });
2227 if (success) {
2228 return fml::Status();
2229 } else {
2231 }
2232}
double duration
Definition examples.cpp:30
timeout(deadline, cmd)

Friends And Related Symbol Documentation

◆ testing::ShellTest

friend class testing::ShellTest
friend

Definition at line 791 of file shell.h.


The documentation for this class was generated from the following files: