| // 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/pointer_data_packet_converter.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/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_; |
| PointerDataPacketConverter pointer_data_packet_converter_; |
| 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_ |