| // 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/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_ |