Kaylee Lubick ef050da2b8 Use moved Skia Ganesh header files (flutter/engine#54833)
In http://review.skia.org/892736 and http://review.skia.org/893856, Skia
moved its Ganesh headers to align with the Graphite ones. This updates
Flutter to use those moved files.

All changes are mechanical and there is no API difference between the
headers (indeed, the old ones simply `#include` the new ones).

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [x] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
2024-09-04 07:09:51 -07:00

972 lines
50 KiB
C++

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_COMMON_PLATFORM_VIEW_H_
#define FLUTTER_SHELL_COMMON_PLATFORM_VIEW_H_
#include <functional>
#include <memory>
#include "flutter/common/graphics/texture.h"
#include "flutter/common/task_runners.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/surface.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/lib/ui/semantics/custom_accessibility_action.h"
#include "flutter/lib/ui/semantics/semantics_node.h"
#include "flutter/lib/ui/window/key_data_packet.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/lib/ui/window/pointer_data_packet.h"
#include "flutter/lib/ui/window/viewport_metrics.h"
#include "flutter/shell/common/platform_message_handler.h"
#include "flutter/shell/common/pointer_data_dispatcher.h"
#include "flutter/shell/common/vsync_waiter.h"
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
namespace impeller {
class Context;
} // namespace impeller
namespace flutter {
//------------------------------------------------------------------------------
/// @brief Platform views are created by the shell on the platform task
/// runner. Unless explicitly specified, all platform view methods
/// are called on the platform task runner as well. Platform views
/// are usually sub-classed on a per platform basis and the bulk of
/// the window system integration happens using that subclass. Since
/// most platform window toolkits are usually only safe to access on
/// a single "main" thread, any interaction that requires access to
/// the underlying platform's window toolkit is routed through the
/// platform view associated with that shell. This involves
/// operations like settings up and tearing down the render surface,
/// platform messages, interacting with accessibility features on
/// the platform, input events, etc.
///
class PlatformView {
public:
using AddViewCallback = std::function<void(bool added)>;
using RemoveViewCallback = std::function<void(bool removed)>;
//----------------------------------------------------------------------------
/// @brief Used to forward events from the platform view to interested
/// subsystems. This forwarding is done by the shell which sets
/// itself up as the delegate of the platform view.
///
class Delegate {
public:
using AddViewCallback = PlatformView::AddViewCallback;
using RemoveViewCallback = PlatformView::RemoveViewCallback;
using KeyDataResponse = std::function<void(bool)>;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] surface The surface
///
virtual void OnPlatformViewCreated(std::unique_ptr<Surface> surface) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
virtual void OnPlatformViewDestroyed() = 0;
//--------------------------------------------------------------------------
/// @brief Notifies the delegate that the platform needs to schedule a
/// frame to regenerate the layer tree and redraw the surface.
///
virtual void OnPlatformViewScheduleFrame() = 0;
/// @brief 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.
///
/// @param[in] view_id The view ID of the new view.
/// @param[in] viewport_metrics The initial viewport metrics for the view.
/// @param[in] callback The callback that's invoked once the shell
/// has attempted to add the view.
///
virtual void OnPlatformViewAddView(int64_t view_id,
const ViewportMetrics& viewport_metrics,
AddViewCallback callback) = 0;
/// @brief 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.
///
/// @param[in] view_id The view ID of the view to be removed.
/// @param[in] callback The callback that's invoked once the shell has
/// attempted to remove the view.
///
virtual void OnPlatformViewRemoveView(int64_t view_id,
RemoveViewCallback callback) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] closure The callback to execute on the next frame.
///
virtual void OnPlatformViewSetNextFrameCallback(
const fml::closure& closure) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The updated viewport metrics.
///
virtual void OnPlatformViewSetViewportMetrics(
int64_t view_id,
const ViewportMetrics& metrics) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] message The platform message to dispatch to the running
/// root isolate.
///
virtual void OnPlatformViewDispatchPlatformMessage(
std::unique_ptr<PlatformMessage> message) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] packet The pointer data packet containing multiple pointer
/// events.
///
virtual void OnPlatformViewDispatchPointerDataPacket(
std::unique_ptr<PointerDataPacket> packet) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] node_id The identifier of the accessibility node.
/// @param[in] action The accessibility related action performed on the
/// node of the specified ID.
/// @param[in] args An optional list of argument that apply to the
/// specified action.
///
virtual void OnPlatformViewDispatchSemanticsAction(
int32_t node_id,
SemanticsAction action,
fml::MallocMapping args) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] enabled Whether the accessibility tree is enabled or
/// disabled.
///
virtual void OnPlatformViewSetSemanticsEnabled(bool enabled) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] flags The features to enable in the accessibility tree.
///
virtual void OnPlatformViewSetAccessibilityFeatures(int32_t flags) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] texture The texture that is being updated by the embedder
/// but composited by Flutter in its own hierarchy.
///
virtual void OnPlatformViewRegisterTexture(
std::shared_ptr<Texture> texture) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] texture_id The identifier of the texture to unregister. If
/// the texture has not been previously registered,
/// this call does nothing.
///
virtual void OnPlatformViewUnregisterTexture(int64_t texture_id) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] texture_id The identifier of the texture that has been
/// updated.
///
virtual void OnPlatformViewMarkTextureFrameAvailable(
int64_t texture_id) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
///
/// @param[in] loading_unit_id The unique id of the deferred library's
/// loading unit.
///
/// @param[in] snapshot_data Dart snapshot data of the loading unit's
/// shared library.
///
/// @param[in] snapshot_data Dart snapshot instructions of the loading
/// unit's shared library.
///
virtual void LoadDartDeferredLibrary(
intptr_t loading_unit_id,
std::unique_ptr<const fml::Mapping> snapshot_data,
std::unique_ptr<const fml::Mapping> snapshot_instructions) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] loading_unit_id The unique id of the deferred library's
/// loading unit, as passed in by
/// RequestDartDeferredLibrary.
///
/// @param[in] error_message The error message that will appear in the
/// dart Future.
///
/// @param[in] transient A 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.
virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient) = 0;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] updated_asset_resolver The asset resolver to replace the
/// resolver of matching type with.
///
/// @param[in] type The type of AssetResolver to update. Only resolvers of
/// the specified type will be replaced by the updated
/// resolver.
///
virtual void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type) = 0;
//--------------------------------------------------------------------------
/// @brief Called by the platform view on the platform thread to get
/// the settings object associated with the platform view
/// instance.
///
/// @return The settings.
///
virtual const Settings& OnPlatformViewGetSettings() const = 0;
};
//----------------------------------------------------------------------------
/// @brief Creates a platform view with the specified delegate and task
/// runner. The base class by itself does not do much but is
/// suitable for use in test environments where full platform
/// integration may not be necessary. The platform view may only
/// be created, accessed and destroyed on the platform task
/// runner.
///
/// @param delegate The delegate. This is typically the shell.
/// @param[in] task_runners The task runners used by this platform view.
///
explicit PlatformView(Delegate& delegate, const TaskRunners& task_runners);
//----------------------------------------------------------------------------
/// @brief Destroys the platform view. The platform view is owned by the
/// shell and will be destroyed by the same on the platform tasks
/// runner.
///
virtual ~PlatformView();
//----------------------------------------------------------------------------
/// @brief Invoked by the shell to obtain a platform specific vsync
/// waiter. It is optional for platforms to override this method
/// and provide a custom vsync waiter because a timer based
/// fall-back waiter is used by default. However, it is highly
/// recommended that platform provide their own Vsync waiter as
/// the timer based fall-back will not render frames aligned with
/// vsync boundaries.
///
/// @attention If a timer based fall-back is used, a warning is logged to the
/// console. In case this method is overridden in a subclass, it
/// must return a valid vsync waiter. Returning null will lead to
/// internal errors. If a valid vsync waiter cannot be returned,
/// subclasses should just call the based class method instead.
///
/// @return A vsync waiter. If is an internal error to return a null
/// waiter.
///
virtual std::unique_ptr<VsyncWaiter> CreateVSyncWaiter();
//----------------------------------------------------------------------------
/// @brief Used by embedders to dispatch a platform message to a
/// running root isolate hosted by the engine. If an isolate is
/// not running, the message is dropped. If there is no one on the
/// other side listening on the channel, the message is dropped.
/// When a platform message is dropped, any response handles
/// associated with that message will be dropped as well. All
/// users of platform messages must assume that message may not be
/// delivered and/or their response handles may not be invoked.
/// Platform messages are not buffered.
///
/// For embedders that wish to respond to platform message
/// directed from the framework to the embedder, the
/// `HandlePlatformMessage` method may be overridden.
///
/// @see HandlePlatformMessage()
///
/// @param[in] message The platform message to deliver to the root isolate.
///
void DispatchPlatformMessage(std::unique_ptr<PlatformMessage> message);
//----------------------------------------------------------------------------
/// @brief Overridden by embedders to perform actions in response to
/// platform messages sent from the framework to the embedder.
/// Default implementation of this method simply returns an empty
/// response.
///
/// Embedders that wish to send platform messages to the framework
/// may use the `DispatchPlatformMessage` method. This method is
/// for messages that go the other way.
///
/// @see DispatchPlatformMessage()
///
/// @param[in] message The message
///
virtual void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message);
//----------------------------------------------------------------------------
/// @brief Used by embedders to dispatch an accessibility action to a
/// running isolate hosted by the engine.
///
/// @param[in] node_id The identifier of the accessibility node on which to
/// perform the action.
/// @param[in] action The action
/// @param[in] args The arguments
///
void DispatchSemanticsAction(int32_t node_id,
SemanticsAction action,
fml::MallocMapping args);
//----------------------------------------------------------------------------
/// @brief Used by embedder to notify the running isolate hosted by the
/// engine on the UI thread that the accessibility tree needs to
/// be generated.
///
/// @attention Subclasses may choose to override this method to perform
/// platform specific functions. However, they must call the base
/// class method at some point in their implementation.
///
/// @param[in] enabled Whether the accessibility tree needs to be generated.
///
virtual void SetSemanticsEnabled(bool enabled);
//----------------------------------------------------------------------------
/// @brief Used by the embedder to specify the features to enable in the
/// accessibility tree generated by the isolate. This information
/// is forwarded to the root isolate hosted by the engine on the
/// UI thread.
///
/// 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.
///
/// @attention Subclasses may choose to override this method to perform
/// platform specific functions. However, they must call the base
/// class method at some point in their implementation.
///
/// @param[in] flags The features to enable in the accessibility tree.
///
virtual void SetAccessibilityFeatures(int32_t flags);
//----------------------------------------------------------------------------
/// @brief Used by the framework to tell the embedder to apply the
/// specified semantics node updates. The default implementation
/// of this method does nothing.
///
/// @see SemanticsNode, SemticsNodeUpdates,
/// CustomAccessibilityActionUpdates
///
/// @param[in] updates A map with the stable semantics node identifier as
/// key and the node properties as the value.
/// @param[in] actions A map with the stable semantics node identifier as
/// key and the custom node action as the value.
///
virtual void UpdateSemantics(SemanticsNodeUpdates updates,
CustomAccessibilityActionUpdates actions);
//----------------------------------------------------------------------------
/// @brief Used by the framework to tell the embedder that it has
/// registered a listener on a given channel.
///
/// @param[in] name The name of the channel on which the listener has
/// set or cleared a listener.
/// @param[in] listening True if a listener has been set, false if it has
/// been cleared.
///
virtual void SendChannelUpdate(const std::string& name, bool listening);
//----------------------------------------------------------------------------
/// @brief Used by embedders to specify the updated viewport metrics for
/// a view. In response to this call, on the raster thread, the
/// rasterizer may need to be reconfigured to the updated viewport
/// dimensions. On the UI thread, the framework may need to start
/// generating a new frame for the updated viewport metrics as
/// well.
///
/// @param[in] view_id The ID for the view that `metrics` describes.
/// @param[in] metrics The updated viewport metrics.
///
void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
//----------------------------------------------------------------------------
/// @brief Used by embedders to notify the shell that a platform view
/// has been created. This notification is used to create a
/// rendering surface and pick the client rendering API to use to
/// render into this surface. No frames will be scheduled or
/// rendered before this call. The surface must remain valid till
/// the corresponding call to NotifyDestroyed.
///
void NotifyCreated();
//----------------------------------------------------------------------------
/// @brief Used by embedders to notify the shell that the platform view
/// has been destroyed. This notification used to collect the
/// rendering surface and all associated resources. Frame
/// scheduling is also suspended.
///
/// @attention Subclasses may choose to override this method to perform
/// platform specific functions. However, they must call the base
/// class method at some point in their implementation.
///
virtual void NotifyDestroyed();
//----------------------------------------------------------------------------
/// @brief Used by embedders to schedule a frame. In response to this
/// call, the framework may need to start generating a new frame.
///
void ScheduleFrame();
/// @brief Used by embedders to notify the shell of a new non-implicit view.
///
/// This method notifies the shell to allocate resources and inform
/// Dart about the view, and on success, schedules a new frame.
/// Finally, it invokes |callback| with whether the operation is
/// successful.
///
/// This operation is asynchronous; avoid using the view until
/// |callback| returns true. Callers should prepare resources for the
/// view (if any) in advance but be ready to clean up on failure.
///
/// The callback is called on a different thread.
///
/// Do not use for implicit views, which are added internally during
/// shell initialization. Adding |kFlutterImplicitViewId| or an
/// existing view ID will fail, indicated by |callback| returning
/// false.
///
/// @param[in] view_id The view ID of the new view.
/// @param[in] viewport_metrics The initial viewport metrics for the view.
/// @param[in] callback The callback that's invoked once the shell
/// has attempted to add the view.
///
void AddView(int64_t view_id,
const ViewportMetrics& viewport_metrics,
AddViewCallback callback);
/// @brief Used by embedders to notify the shell of a removed non-implicit
/// view.
///
/// This method notifies the shell to deallocate resources and inform
/// Dart about the removal. Finally, it invokes |callback| with
/// whether the operation is successful.
///
/// This operation is asynchronous. The embedder should not deallocate
/// resources until the |callback| is invoked.
///
/// The callback is called on a different thread.
///
/// Do not use for implicit views, which are never removed throughout
/// the lifetime of the app.
/// Removing |kFlutterImplicitViewId| or an
/// non-existent view ID will fail, indicated by |callback| returning
/// false.
///
/// @param[in] view_id The view ID of the view to be removed.
/// @param[in] callback The callback that's invoked once the shell has
/// attempted to remove the view.
///
void RemoveView(int64_t view_id, RemoveViewCallback callback);
//----------------------------------------------------------------------------
/// @brief Used by the shell to obtain a Skia GPU context that is capable
/// of operating on the IO thread. The context must be in the same
/// share-group as the Skia GPU context used on the render thread.
/// This context will always be used on the IO thread. Because it
/// is in the same share-group as the separate render thread
/// context, any GPU resources uploaded in this context will be
/// visible to the render thread context (synchronization of GPU
/// resources is managed by Skia).
///
/// If such context cannot be created on the IO thread, callers
/// may return `nullptr`. This will mean that all texture uploads
/// will be queued onto the render thread which will cause
/// performance issues. When this context is `nullptr`, an error
/// is logged to the console. It is highly recommended that all
/// platforms provide a resource context.
///
/// @attention Unlike all other methods on the platform view, this will be
/// called on IO task runner.
///
/// @return The Skia GPU context that is in the same share-group as the
/// main render thread GPU context. May be `nullptr` in case such
/// a context cannot be created.
///
virtual sk_sp<GrDirectContext> CreateResourceContext() const;
virtual std::shared_ptr<impeller::Context> GetImpellerContext() const;
//----------------------------------------------------------------------------
/// @brief Used by the shell to notify the embedder that the resource
/// context previously obtained via a call to
/// `CreateResourceContext()` is being collected. The embedder
/// is free to collect an platform specific resources
/// associated with this context.
///
/// @attention Unlike all other methods on the platform view, this will be
/// called on IO task runner.
///
virtual void ReleaseResourceContext() const;
//--------------------------------------------------------------------------
/// @brief Returns a platform-specific PointerDataDispatcherMaker so the
/// `Engine` can construct the PointerDataPacketDispatcher based
/// on platforms.
virtual PointerDataDispatcherMaker GetDispatcherMaker();
//----------------------------------------------------------------------------
/// @brief Returns a weak pointer to the platform view. Since the
/// platform view may only be created, accessed and destroyed
/// on the platform thread, any access to the platform view
/// from a non-platform task runner needs a weak pointer to
/// the platform view along with a reference to the platform
/// task runner. A task must be posted to the platform task
/// runner with the weak pointer captured in the same. The
/// platform view method may only be called in the posted task
/// once the weak pointer validity has been checked. This
/// method is used by callers to obtain that weak pointer.
///
/// @return The weak pointer to the platform view.
///
fml::WeakPtr<PlatformView> GetWeakPtr() const;
//----------------------------------------------------------------------------
/// @brief Gives embedders a chance to react to a "cold restart" of the
/// running isolate. The default implementation of this method
/// does nothing.
///
/// While a "hot restart" patches a running isolate, a "cold
/// restart" restarts the root isolate in a running shell.
///
virtual void OnPreEngineRestart() const;
//----------------------------------------------------------------------------
/// @brief Sets a callback that gets executed when the rasterizer renders
/// the next frame. 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. The callback is
/// executed on the render task runner and not the platform
/// task runner. It is the embedder's responsibility to
/// re-thread as necessary.
///
/// @attention The callback is executed on the render task runner and not the
/// platform task runner. Embedders must re-thread as necessary.
///
/// @param[in] closure The callback to execute on the render thread when the
/// next frame gets rendered.
///
void SetNextFrameCallback(const fml::closure& closure);
//----------------------------------------------------------------------------
/// @brief Dispatches pointer events from the embedder to the
/// framework. Each pointer data packet may contain multiple
/// pointer input events. Each call to this method wakes up
/// the UI thread.
///
/// @param[in] packet The pointer data packet to dispatch to the framework.
///
void DispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet);
//--------------------------------------------------------------------------
/// @brief Used by the embedder to specify a texture that it wants 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.
///
/// @attention This method must only be called once per texture. When the
/// texture is updated, calling `MarkTextureFrameAvailable`
/// with the specified texture identifier is sufficient to
/// make Flutter re-render the frame with the updated texture
/// composited in-line.
///
/// @see UnregisterTexture, MarkTextureFrameAvailable
///
/// @param[in] texture The texture that is being updated by the embedder
/// but composited by Flutter in its own hierarchy.
///
void RegisterTexture(std::shared_ptr<flutter::Texture> texture);
//--------------------------------------------------------------------------
/// @brief Used by the embedder to notify the rasterizer that it will
/// no longer attempt to composite the specified texture within
/// the layer tree. This allows the rasterizer to collect
/// associated resources.
///
/// @attention This call must only be called once per texture identifier.
///
/// @see RegisterTexture, MarkTextureFrameAvailable
///
/// @param[in] texture_id The identifier of the texture to unregister. If
/// the texture has not been previously registered,
/// this call does nothing.
///
void UnregisterTexture(int64_t texture_id);
//--------------------------------------------------------------------------
/// @brief Used by the embedder to notify the rasterizer that the context
/// of the previously registered texture have been updated.
/// 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 re-composited with all updated external textures.
/// Unlike the calls to register and unregister the texture,
/// this call must be made each time a new texture frame is
/// available.
///
/// @see RegisterTexture, UnregisterTexture
///
/// @param[in] texture_id The identifier of the texture that has been
/// updated.
///
void MarkTextureFrameAvailable(int64_t texture_id);
//--------------------------------------------------------------------------
/// @brief Directly invokes platform-specific APIs to compute the
/// locale the platform would have natively resolved to.
///
/// @param[in] supported_locale_data The vector of strings that represents
/// the locales supported by the app.
/// Each locale consists of three
/// strings: languageCode, countryCode,
/// and scriptCode in that order.
///
/// @return 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.
///
virtual std::unique_ptr<std::vector<std::string>>
ComputePlatformResolvedLocales(
const std::vector<std::string>& supported_locale_data);
virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder();
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] loading_unit_id The 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.
///
virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id);
//--------------------------------------------------------------------------
/// @brief 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 isolate after successful loading and released after
/// shutdown of the dart isolate. If loading fails, the mappings
/// will naturally go out of scope.
///
/// This method is paired with a RequestDartDeferredLibrary
/// invocation that provides the embedder with the loading unit id
/// of the deferred library to load.
///
///
/// @param[in] loading_unit_id The unique id of the deferred library's
/// loading unit, as passed in by
/// RequestDartDeferredLibrary.
///
/// @param[in] snapshot_data Dart snapshot data of the loading unit's
/// shared library.
///
/// @param[in] snapshot_data Dart snapshot instructions of the loading
/// unit's shared library.
///
virtual void LoadDartDeferredLibrary(
intptr_t loading_unit_id,
std::unique_ptr<const fml::Mapping> snapshot_data,
std::unique_ptr<const fml::Mapping> snapshot_instructions);
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] loading_unit_id The unique id of the deferred library's
/// loading unit, as passed in by
/// RequestDartDeferredLibrary.
///
/// @param[in] error_message The error message that will appear in the
/// dart Future.
///
/// @param[in] transient A 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.
///
virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
const std::string error_message,
bool transient);
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] updated_asset_resolver The asset resolver to replace the
/// resolver of matching type with.
///
/// @param[in] type The type of AssetResolver to update. Only resolvers of
/// the specified type will be replaced by the updated
/// resolver.
///
virtual void UpdateAssetResolverByType(
std::unique_ptr<AssetResolver> updated_asset_resolver,
AssetResolver::AssetResolverType type);
//--------------------------------------------------------------------------
/// @brief Creates an object that produces surfaces suitable for raster
/// snapshotting. The rasterizer will request this surface if no
/// on screen surface is currently available when an application
/// requests a snapshot, e.g. if `Scene.toImage` or
/// `Picture.toImage` are called while the application is in the
/// background.
///
/// Not all backends support this kind of surface usage, and the
/// default implementation returns nullptr. Platforms should
/// override this if they can support GPU operations in the
/// background and support GPU resource context usage.
///
virtual std::unique_ptr<SnapshotSurfaceProducer>
CreateSnapshotSurfaceProducer();
//--------------------------------------------------------------------------
/// @brief Specifies a delegate that will receive PlatformMessages from
/// Flutter to the host platform.
///
/// @details If this returns `null` that means PlatformMessages should be sent
/// to the PlatformView. That is to protect legacy behavior, any embedder
/// that wants to support executing Platform Channel handlers on background
/// threads should be returning a thread-safe PlatformMessageHandler instead.
virtual std::shared_ptr<PlatformMessageHandler> GetPlatformMessageHandler()
const;
//----------------------------------------------------------------------------
/// @brief Get the settings for this platform view instance.
///
/// @return The settings.
///
const Settings& GetSettings() const;
//--------------------------------------------------------------------------
/// @brief 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.
///
/// @param[in] unscaled_font_size The unscaled font size specified by the
/// app developer. The value is in logical
/// pixels, and is guaranteed to be finite and
/// non-negative.
/// @param[in] configuration_id The unique id of the configuration to use
/// for computing the scaled font size.
///
/// @return The scaled font size in logical pixels, or -1 if the given
/// configuration_id did not match a valid configuration.
///
virtual double GetScaledFontSize(double unscaled_font_size,
int configuration_id) const;
protected:
// This is the only method called on the raster task runner.
virtual std::unique_ptr<Surface> CreateRenderingSurface();
PlatformView::Delegate& delegate_;
const TaskRunners task_runners_;
fml::WeakPtrFactory<PlatformView> weak_factory_; // Must be the last member.
private:
FML_DISALLOW_COPY_AND_ASSIGN(PlatformView);
};
} // namespace flutter
#endif // FLUTTER_SHELL_COMMON_PLATFORM_VIEW_H_