1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef COMMON_PLATFORM_VIEW_H_ |
6 | #define COMMON_PLATFORM_VIEW_H_ |
7 | |
8 | #include <functional> |
9 | #include <memory> |
10 | |
11 | #include "flutter/common/graphics/texture.h" |
12 | #include "flutter/common/task_runners.h" |
13 | #include "flutter/flow/embedded_views.h" |
14 | #include "flutter/flow/surface.h" |
15 | #include "flutter/fml/macros.h" |
16 | #include "flutter/fml/mapping.h" |
17 | #include "flutter/fml/memory/weak_ptr.h" |
18 | #include "flutter/lib/ui/semantics/custom_accessibility_action.h" |
19 | #include "flutter/lib/ui/semantics/semantics_node.h" |
20 | #include "flutter/lib/ui/window/key_data_packet.h" |
21 | #include "flutter/lib/ui/window/platform_message.h" |
22 | #include "flutter/lib/ui/window/pointer_data_packet.h" |
23 | #include "flutter/lib/ui/window/pointer_data_packet_converter.h" |
24 | #include "flutter/lib/ui/window/viewport_metrics.h" |
25 | #include "flutter/shell/common/platform_message_handler.h" |
26 | #include "flutter/shell/common/pointer_data_dispatcher.h" |
27 | #include "flutter/shell/common/vsync_waiter.h" |
28 | #include "third_party/skia/include/gpu/GrDirectContext.h" |
29 | |
30 | namespace impeller { |
31 | |
32 | class Context; |
33 | |
34 | } // namespace impeller |
35 | |
36 | namespace flutter { |
37 | |
38 | //------------------------------------------------------------------------------ |
39 | /// @brief Platform views are created by the shell on the platform task |
40 | /// runner. Unless explicitly specified, all platform view methods |
41 | /// are called on the platform task runner as well. Platform views |
42 | /// are usually sub-classed on a per platform basis and the bulk of |
43 | /// the window system integration happens using that subclass. Since |
44 | /// most platform window toolkits are usually only safe to access on |
45 | /// a single "main" thread, any interaction that requires access to |
46 | /// the underlying platform's window toolkit is routed through the |
47 | /// platform view associated with that shell. This involves |
48 | /// operations like settings up and tearing down the render surface, |
49 | /// platform messages, interacting with accessibility features on |
50 | /// the platform, input events, etc. |
51 | /// |
52 | class PlatformView { |
53 | public: |
54 | //---------------------------------------------------------------------------- |
55 | /// @brief Used to forward events from the platform view to interested |
56 | /// subsystems. This forwarding is done by the shell which sets |
57 | /// itself up as the delegate of the platform view. |
58 | /// |
59 | class Delegate { |
60 | public: |
61 | using KeyDataResponse = std::function<void(bool)>; |
62 | //-------------------------------------------------------------------------- |
63 | /// @brief Notifies the delegate that the platform view was created |
64 | /// with the given render surface. This surface is platform |
65 | /// (iOS, Android) and client-rendering API (OpenGL, Software, |
66 | /// Metal, Vulkan) specific. This is usually a sign to the |
67 | /// rasterizer to set up and begin rendering to that surface. |
68 | /// |
69 | /// @param[in] surface The surface |
70 | /// |
71 | virtual void OnPlatformViewCreated(std::unique_ptr<Surface> surface) = 0; |
72 | |
73 | //-------------------------------------------------------------------------- |
74 | /// @brief Notifies the delegate that the platform view was destroyed. |
75 | /// This is usually a sign to the rasterizer to suspend |
76 | /// rendering a previously configured surface and collect any |
77 | /// intermediate resources. |
78 | /// |
79 | virtual void OnPlatformViewDestroyed() = 0; |
80 | |
81 | //-------------------------------------------------------------------------- |
82 | /// @brief Notifies the delegate that the platform needs to schedule a |
83 | /// frame to regenerate the layer tree and redraw the surface. |
84 | /// |
85 | virtual void OnPlatformViewScheduleFrame() = 0; |
86 | |
87 | //-------------------------------------------------------------------------- |
88 | /// @brief Notifies the delegate that the specified callback needs to |
89 | /// be invoked after the rasterizer is done rendering the next |
90 | /// frame. This callback will be called on the render thread and |
91 | /// it is caller responsibility to perform any re-threading as |
92 | /// necessary. Due to the asynchronous nature of rendering in |
93 | /// Flutter, embedders usually add a placeholder over the |
94 | /// contents in which Flutter is going to render when Flutter is |
95 | /// first initialized. This callback may be used as a signal to |
96 | /// remove that placeholder. |
97 | /// |
98 | /// @attention The callback will be invoked on the render thread and not |
99 | /// the calling thread. |
100 | /// |
101 | /// @param[in] closure The callback to execute on the next frame. |
102 | /// |
103 | virtual void OnPlatformViewSetNextFrameCallback( |
104 | const fml::closure& closure) = 0; |
105 | |
106 | //-------------------------------------------------------------------------- |
107 | /// @brief Notifies the delegate the viewport metrics of a view have |
108 | /// been updated. The rasterizer will need to be reconfigured to |
109 | /// render the frame in the updated viewport metrics. |
110 | /// |
111 | /// @param[in] view_id The ID for the view that `metrics` describes. |
112 | /// @param[in] metrics The updated viewport metrics. |
113 | /// |
114 | virtual void OnPlatformViewSetViewportMetrics( |
115 | int64_t view_id, |
116 | const ViewportMetrics& metrics) = 0; |
117 | |
118 | //-------------------------------------------------------------------------- |
119 | /// @brief Notifies the delegate that the platform has dispatched a |
120 | /// platform message from the embedder to the Flutter |
121 | /// application. This message must be forwarded to the running |
122 | /// isolate hosted by the engine on the UI thread. |
123 | /// |
124 | /// @param[in] message The platform message to dispatch to the running |
125 | /// root isolate. |
126 | /// |
127 | virtual void OnPlatformViewDispatchPlatformMessage( |
128 | std::unique_ptr<PlatformMessage> message) = 0; |
129 | |
130 | //-------------------------------------------------------------------------- |
131 | /// @brief Notifies the delegate that the platform view has encountered |
132 | /// a pointer event. This pointer event needs to be forwarded to |
133 | /// the running root isolate hosted by the engine on the UI |
134 | /// thread. |
135 | /// |
136 | /// @param[in] packet The pointer data packet containing multiple pointer |
137 | /// events. |
138 | /// |
139 | virtual void OnPlatformViewDispatchPointerDataPacket( |
140 | std::unique_ptr<PointerDataPacket> packet) = 0; |
141 | |
142 | //-------------------------------------------------------------------------- |
143 | /// @brief Notifies the delegate that the platform view has encountered |
144 | /// an accessibility related action on the specified node. This |
145 | /// event must be forwarded to the running root isolate hosted |
146 | /// by the engine on the UI thread. |
147 | /// |
148 | /// @param[in] node_id The identifier of the accessibility node. |
149 | /// @param[in] action The accessibility related action performed on the |
150 | /// node of the specified ID. |
151 | /// @param[in] args An optional list of argument that apply to the |
152 | /// specified action. |
153 | /// |
154 | virtual void OnPlatformViewDispatchSemanticsAction( |
155 | int32_t node_id, |
156 | SemanticsAction action, |
157 | fml::MallocMapping args) = 0; |
158 | |
159 | //-------------------------------------------------------------------------- |
160 | /// @brief Notifies the delegate that the embedder has expressed an |
161 | /// opinion about whether the accessibility tree needs to be |
162 | /// enabled or disabled. This information needs to be forwarded |
163 | /// to the root isolate running on the UI thread. |
164 | /// |
165 | /// @param[in] enabled Whether the accessibility tree is enabled or |
166 | /// disabled. |
167 | /// |
168 | virtual void OnPlatformViewSetSemanticsEnabled(bool enabled) = 0; |
169 | |
170 | //-------------------------------------------------------------------------- |
171 | /// @brief Notifies the delegate that the embedder has expressed an |
172 | /// opinion about the features to enable in the accessibility |
173 | /// tree. |
174 | /// |
175 | /// The engine does not care about the accessibility feature |
176 | /// flags as all it does is forward this information from the |
177 | /// embedder to the framework. However, curious readers may |
178 | /// refer to `AccessibilityFeatures` in `window.dart` for |
179 | /// currently supported accessibility feature flags. |
180 | /// |
181 | /// @param[in] flags The features to enable in the accessibility tree. |
182 | /// |
183 | virtual void OnPlatformViewSetAccessibilityFeatures(int32_t flags) = 0; |
184 | |
185 | //-------------------------------------------------------------------------- |
186 | /// @brief Notifies the delegate that the embedder has specified a |
187 | /// texture that it want the rasterizer to composite within the |
188 | /// Flutter layer tree. All textures must have a unique |
189 | /// identifier. When the rasterizer encounters an external |
190 | /// texture within its hierarchy, it gives the embedder a chance |
191 | /// to update that texture on the raster thread before it |
192 | /// composites the same on-screen. |
193 | /// |
194 | /// @param[in] texture The texture that is being updated by the embedder |
195 | /// but composited by Flutter in its own hierarchy. |
196 | /// |
197 | virtual void OnPlatformViewRegisterTexture( |
198 | std::shared_ptr<Texture> texture) = 0; |
199 | |
200 | //-------------------------------------------------------------------------- |
201 | /// @brief Notifies the delegate that the embedder will no longer |
202 | /// attempt to composite the specified texture within the layer |
203 | /// tree. This allows the rasterizer to collect associated |
204 | /// resources. |
205 | /// |
206 | /// @param[in] texture_id The identifier of the texture to unregister. If |
207 | /// the texture has not been previously registered, |
208 | /// this call does nothing. |
209 | /// |
210 | virtual void OnPlatformViewUnregisterTexture(int64_t texture_id) = 0; |
211 | |
212 | //-------------------------------------------------------------------------- |
213 | /// @brief Notifies the delegate that the embedder has updated the |
214 | /// contents of the texture with the specified identifier. |
215 | /// Typically, Flutter will only render a frame if there is an |
216 | /// updated layer tree. However, in cases where the layer tree |
217 | /// is static but one of the externally composited textures has |
218 | /// been updated by the embedder, the embedder needs to notify |
219 | /// the rasterizer to render a new frame. In such cases, the |
220 | /// existing layer tree may be reused with the frame composited |
221 | /// with all updated external textures. |
222 | /// |
223 | /// @param[in] texture_id The identifier of the texture that has been |
224 | /// updated. |
225 | /// |
226 | virtual void OnPlatformViewMarkTextureFrameAvailable( |
227 | int64_t texture_id) = 0; |
228 | |
229 | //-------------------------------------------------------------------------- |
230 | /// @brief Loads the dart shared library into the dart VM. When the |
231 | /// dart library is loaded successfully, the dart future |
232 | /// returned by the originating loadLibrary() call completes. |
233 | /// |
234 | /// The Dart compiler may generate separate shared libraries |
235 | /// files called 'loading units' when libraries are imported |
236 | /// as deferred. Each of these shared libraries are identified |
237 | /// by a unique loading unit id. Callers should open and resolve |
238 | /// a SymbolMapping from the shared library. The Mappings should |
239 | /// be moved into this method, as ownership will be assumed by |
240 | /// the dart root isolate after successful loading and released |
241 | /// after shutdown of the root isolate. The loading unit may not |
242 | /// be used after isolate shutdown. If loading fails, the |
243 | /// mappings will be released. |
244 | /// |
245 | /// This method is paired with a RequestDartDeferredLibrary |
246 | /// invocation that provides the embedder with the loading unit |
247 | /// id of the deferred library to load. |
248 | /// |
249 | /// |
250 | /// @param[in] loading_unit_id The unique id of the deferred library's |
251 | /// loading unit. |
252 | /// |
253 | /// @param[in] snapshot_data Dart snapshot data of the loading unit's |
254 | /// shared library. |
255 | /// |
256 | /// @param[in] snapshot_data Dart snapshot instructions of the loading |
257 | /// unit's shared library. |
258 | /// |
259 | virtual void LoadDartDeferredLibrary( |
260 | intptr_t loading_unit_id, |
261 | std::unique_ptr<const fml::Mapping> snapshot_data, |
262 | std::unique_ptr<const fml::Mapping> snapshot_instructions) = 0; |
263 | |
264 | //-------------------------------------------------------------------------- |
265 | /// @brief Indicates to the dart VM that the request to load a deferred |
266 | /// library with the specified loading unit id has failed. |
267 | /// |
268 | /// The dart future returned by the initiating loadLibrary() |
269 | /// call will complete with an error. |
270 | /// |
271 | /// @param[in] loading_unit_id The unique id of the deferred library's |
272 | /// loading unit, as passed in by |
273 | /// RequestDartDeferredLibrary. |
274 | /// |
275 | /// @param[in] error_message The error message that will appear in the |
276 | /// dart Future. |
277 | /// |
278 | /// @param[in] transient A transient error is a failure due to |
279 | /// temporary conditions such as no network. |
280 | /// Transient errors allow the dart VM to |
281 | /// re-request the same deferred library and |
282 | /// loading_unit_id again. Non-transient |
283 | /// errors are permanent and attempts to |
284 | /// re-request the library will instantly |
285 | /// complete with an error. |
286 | virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id, |
287 | const std::string error_message, |
288 | bool transient) = 0; |
289 | |
290 | //-------------------------------------------------------------------------- |
291 | /// @brief Replaces the asset resolver handled by the engine's |
292 | /// AssetManager of the specified `type` with |
293 | /// `updated_asset_resolver`. The matching AssetResolver is |
294 | /// removed and replaced with `updated_asset_resolvers`. |
295 | /// |
296 | /// AssetResolvers should be updated when the existing resolver |
297 | /// becomes obsolete and a newer one becomes available that |
298 | /// provides updated access to the same type of assets as the |
299 | /// existing one. This update process is meant to be performed |
300 | /// at runtime. |
301 | /// |
302 | /// If a null resolver is provided, nothing will be done. If no |
303 | /// matching resolver is found, the provided resolver will be |
304 | /// added to the end of the AssetManager resolvers queue. The |
305 | /// replacement only occurs with the first matching resolver. |
306 | /// Any additional matching resolvers are untouched. |
307 | /// |
308 | /// @param[in] updated_asset_resolver The asset resolver to replace the |
309 | /// resolver of matching type with. |
310 | /// |
311 | /// @param[in] type The type of AssetResolver to update. Only resolvers of |
312 | /// the specified type will be replaced by the updated |
313 | /// resolver. |
314 | /// |
315 | virtual void UpdateAssetResolverByType( |
316 | std::unique_ptr<AssetResolver> updated_asset_resolver, |
317 | AssetResolver::AssetResolverType type) = 0; |
318 | |
319 | //-------------------------------------------------------------------------- |
320 | /// @brief Called by the platform view on the platform thread to get |
321 | /// the settings object associated with the platform view |
322 | /// instance. |
323 | /// |
324 | /// @return The settings. |
325 | /// |
326 | virtual const Settings& OnPlatformViewGetSettings() const = 0; |
327 | }; |
328 | |
329 | //---------------------------------------------------------------------------- |
330 | /// @brief Creates a platform view with the specified delegate and task |
331 | /// runner. The base class by itself does not do much but is |
332 | /// suitable for use in test environments where full platform |
333 | /// integration may not be necessary. The platform view may only |
334 | /// be created, accessed and destroyed on the platform task |
335 | /// runner. |
336 | /// |
337 | /// @param delegate The delegate. This is typically the shell. |
338 | /// @param[in] task_runners The task runners used by this platform view. |
339 | /// |
340 | explicit PlatformView(Delegate& delegate, const TaskRunners& task_runners); |
341 | |
342 | //---------------------------------------------------------------------------- |
343 | /// @brief Destroys the platform view. The platform view is owned by the |
344 | /// shell and will be destroyed by the same on the platform tasks |
345 | /// runner. |
346 | /// |
347 | virtual ~PlatformView(); |
348 | |
349 | //---------------------------------------------------------------------------- |
350 | /// @brief Invoked by the shell to obtain a platform specific vsync |
351 | /// waiter. It is optional for platforms to override this method |
352 | /// and provide a custom vsync waiter because a timer based |
353 | /// fall-back waiter is used by default. However, it is highly |
354 | /// recommended that platform provide their own Vsync waiter as |
355 | /// the timer based fall-back will not render frames aligned with |
356 | /// vsync boundaries. |
357 | /// |
358 | /// @attention If a timer based fall-back is used, a warning is logged to the |
359 | /// console. In case this method is overridden in a subclass, it |
360 | /// must return a valid vsync waiter. Returning null will lead to |
361 | /// internal errors. If a valid vsync waiter cannot be returned, |
362 | /// subclasses should just call the based class method instead. |
363 | /// |
364 | /// @return A vsync waiter. If is an internal error to return a null |
365 | /// waiter. |
366 | /// |
367 | virtual std::unique_ptr<VsyncWaiter> CreateVSyncWaiter(); |
368 | |
369 | //---------------------------------------------------------------------------- |
370 | /// @brief Used by embedders to dispatch a platform message to a |
371 | /// running root isolate hosted by the engine. If an isolate is |
372 | /// not running, the message is dropped. If there is no one on the |
373 | /// other side listening on the channel, the message is dropped. |
374 | /// When a platform message is dropped, any response handles |
375 | /// associated with that message will be dropped as well. All |
376 | /// users of platform messages must assume that message may not be |
377 | /// delivered and/or their response handles may not be invoked. |
378 | /// Platform messages are not buffered. |
379 | /// |
380 | /// For embedders that wish to respond to platform message |
381 | /// directed from the framework to the embedder, the |
382 | /// `HandlePlatformMessage` method may be overridden. |
383 | /// |
384 | /// @see HandlePlatformMessage() |
385 | /// |
386 | /// @param[in] message The platform message to deliver to the root isolate. |
387 | /// |
388 | void DispatchPlatformMessage(std::unique_ptr<PlatformMessage> message); |
389 | |
390 | //---------------------------------------------------------------------------- |
391 | /// @brief Overridden by embedders to perform actions in response to |
392 | /// platform messages sent from the framework to the embedder. |
393 | /// Default implementation of this method simply returns an empty |
394 | /// response. |
395 | /// |
396 | /// Embedders that wish to send platform messages to the framework |
397 | /// may use the `DispatchPlatformMessage` method. This method is |
398 | /// for messages that go the other way. |
399 | /// |
400 | /// @see DispatchPlatformMessage() |
401 | /// |
402 | /// @param[in] message The message |
403 | /// |
404 | virtual void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message); |
405 | |
406 | //---------------------------------------------------------------------------- |
407 | /// @brief Used by embedders to dispatch an accessibility action to a |
408 | /// running isolate hosted by the engine. |
409 | /// |
410 | /// @param[in] node_id The identifier of the accessibility node on which to |
411 | /// perform the action. |
412 | /// @param[in] action The action |
413 | /// @param[in] args The arguments |
414 | /// |
415 | void DispatchSemanticsAction(int32_t node_id, |
416 | SemanticsAction action, |
417 | fml::MallocMapping args); |
418 | |
419 | //---------------------------------------------------------------------------- |
420 | /// @brief Used by embedder to notify the running isolate hosted by the |
421 | /// engine on the UI thread that the accessibility tree needs to |
422 | /// be generated. |
423 | /// |
424 | /// @attention Subclasses may choose to override this method to perform |
425 | /// platform specific functions. However, they must call the base |
426 | /// class method at some point in their implementation. |
427 | /// |
428 | /// @param[in] enabled Whether the accessibility tree needs to be generated. |
429 | /// |
430 | virtual void SetSemanticsEnabled(bool enabled); |
431 | |
432 | //---------------------------------------------------------------------------- |
433 | /// @brief Used by the embedder to specify the features to enable in the |
434 | /// accessibility tree generated by the isolate. This information |
435 | /// is forwarded to the root isolate hosted by the engine on the |
436 | /// UI thread. |
437 | /// |
438 | /// The engine does not care about the accessibility feature flags |
439 | /// as all it does is forward this information from the embedder |
440 | /// to the framework. However, curious readers may refer to |
441 | /// `AccessibilityFeatures` in `window.dart` for currently |
442 | /// supported accessibility feature flags. |
443 | /// |
444 | /// @attention Subclasses may choose to override this method to perform |
445 | /// platform specific functions. However, they must call the base |
446 | /// class method at some point in their implementation. |
447 | /// |
448 | /// @param[in] flags The features to enable in the accessibility tree. |
449 | /// |
450 | virtual void SetAccessibilityFeatures(int32_t flags); |
451 | |
452 | //---------------------------------------------------------------------------- |
453 | /// @brief Used by the framework to tell the embedder to apply the |
454 | /// specified semantics node updates. The default implementation |
455 | /// of this method does nothing. |
456 | /// |
457 | /// @see SemanticsNode, SemticsNodeUpdates, |
458 | /// CustomAccessibilityActionUpdates |
459 | /// |
460 | /// @param[in] updates A map with the stable semantics node identifier as |
461 | /// key and the node properties as the value. |
462 | /// @param[in] actions A map with the stable semantics node identifier as |
463 | /// key and the custom node action as the value. |
464 | /// |
465 | virtual void UpdateSemantics(SemanticsNodeUpdates updates, |
466 | CustomAccessibilityActionUpdates actions); |
467 | |
468 | //---------------------------------------------------------------------------- |
469 | /// @brief Used by embedders to specify the updated viewport metrics for |
470 | /// a view. In response to this call, on the raster thread, the |
471 | /// rasterizer may need to be reconfigured to the updated viewport |
472 | /// dimensions. On the UI thread, the framework may need to start |
473 | /// generating a new frame for the updated viewport metrics as |
474 | /// well. |
475 | /// |
476 | /// @param[in] view_id The ID for the view that `metrics` describes. |
477 | /// @param[in] metrics The updated viewport metrics. |
478 | /// |
479 | void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); |
480 | |
481 | //---------------------------------------------------------------------------- |
482 | /// @brief Used by embedders to notify the shell that a platform view |
483 | /// has been created. This notification is used to create a |
484 | /// rendering surface and pick the client rendering API to use to |
485 | /// render into this surface. No frames will be scheduled or |
486 | /// rendered before this call. The surface must remain valid till |
487 | /// the corresponding call to NotifyDestroyed. |
488 | /// |
489 | void NotifyCreated(); |
490 | |
491 | //---------------------------------------------------------------------------- |
492 | /// @brief Used by embedders to notify the shell that the platform view |
493 | /// has been destroyed. This notification used to collect the |
494 | /// rendering surface and all associated resources. Frame |
495 | /// scheduling is also suspended. |
496 | /// |
497 | /// @attention Subclasses may choose to override this method to perform |
498 | /// platform specific functions. However, they must call the base |
499 | /// class method at some point in their implementation. |
500 | /// |
501 | virtual void NotifyDestroyed(); |
502 | |
503 | //---------------------------------------------------------------------------- |
504 | /// @brief Used by embedders to schedule a frame. In response to this |
505 | /// call, the framework may need to start generating a new frame. |
506 | /// |
507 | void ScheduleFrame(); |
508 | |
509 | //---------------------------------------------------------------------------- |
510 | /// @brief Used by the shell to obtain a Skia GPU context that is capable |
511 | /// of operating on the IO thread. The context must be in the same |
512 | /// share-group as the Skia GPU context used on the render thread. |
513 | /// This context will always be used on the IO thread. Because it |
514 | /// is in the same share-group as the separate render thread |
515 | /// context, any GPU resources uploaded in this context will be |
516 | /// visible to the render thread context (synchronization of GPU |
517 | /// resources is managed by Skia). |
518 | /// |
519 | /// If such context cannot be created on the IO thread, callers |
520 | /// may return `nullptr`. This will mean that all texture uploads |
521 | /// will be queued onto the render thread which will cause |
522 | /// performance issues. When this context is `nullptr`, an error |
523 | /// is logged to the console. It is highly recommended that all |
524 | /// platforms provide a resource context. |
525 | /// |
526 | /// @attention Unlike all other methods on the platform view, this will be |
527 | /// called on IO task runner. |
528 | /// |
529 | /// @return The Skia GPU context that is in the same share-group as the |
530 | /// main render thread GPU context. May be `nullptr` in case such |
531 | /// a context cannot be created. |
532 | /// |
533 | virtual sk_sp<GrDirectContext> CreateResourceContext() const; |
534 | |
535 | virtual std::shared_ptr<impeller::Context> GetImpellerContext() const; |
536 | |
537 | //---------------------------------------------------------------------------- |
538 | /// @brief Used by the shell to notify the embedder that the resource |
539 | /// context previously obtained via a call to |
540 | /// `CreateResourceContext()` is being collected. The embedder |
541 | /// is free to collect an platform specific resources |
542 | /// associated with this context. |
543 | /// |
544 | /// @attention Unlike all other methods on the platform view, this will be |
545 | /// called on IO task runner. |
546 | /// |
547 | virtual void ReleaseResourceContext() const; |
548 | |
549 | //-------------------------------------------------------------------------- |
550 | /// @brief Returns a platform-specific PointerDataDispatcherMaker so the |
551 | /// `Engine` can construct the PointerDataPacketDispatcher based |
552 | /// on platforms. |
553 | virtual PointerDataDispatcherMaker GetDispatcherMaker(); |
554 | |
555 | //---------------------------------------------------------------------------- |
556 | /// @brief Returns a weak pointer to the platform view. Since the |
557 | /// platform view may only be created, accessed and destroyed |
558 | /// on the platform thread, any access to the platform view |
559 | /// from a non-platform task runner needs a weak pointer to |
560 | /// the platform view along with a reference to the platform |
561 | /// task runner. A task must be posted to the platform task |
562 | /// runner with the weak pointer captured in the same. The |
563 | /// platform view method may only be called in the posted task |
564 | /// once the weak pointer validity has been checked. This |
565 | /// method is used by callers to obtain that weak pointer. |
566 | /// |
567 | /// @return The weak pointer to the platform view. |
568 | /// |
569 | fml::WeakPtr<PlatformView> GetWeakPtr() const; |
570 | |
571 | //---------------------------------------------------------------------------- |
572 | /// @brief Gives embedders a chance to react to a "cold restart" of the |
573 | /// running isolate. The default implementation of this method |
574 | /// does nothing. |
575 | /// |
576 | /// While a "hot restart" patches a running isolate, a "cold |
577 | /// restart" restarts the root isolate in a running shell. |
578 | /// |
579 | virtual void OnPreEngineRestart() const; |
580 | |
581 | //---------------------------------------------------------------------------- |
582 | /// @brief Sets a callback that gets executed when the rasterizer renders |
583 | /// the next frame. Due to the asynchronous nature of |
584 | /// rendering in Flutter, embedders usually add a placeholder |
585 | /// over the contents in which Flutter is going to render when |
586 | /// Flutter is first initialized. This callback may be used as |
587 | /// a signal to remove that placeholder. The callback is |
588 | /// executed on the render task runner and not the platform |
589 | /// task runner. It is the embedder's responsibility to |
590 | /// re-thread as necessary. |
591 | /// |
592 | /// @attention The callback is executed on the render task runner and not the |
593 | /// platform task runner. Embedders must re-thread as necessary. |
594 | /// |
595 | /// @param[in] closure The callback to execute on the render thread when the |
596 | /// next frame gets rendered. |
597 | /// |
598 | void SetNextFrameCallback(const fml::closure& closure); |
599 | |
600 | //---------------------------------------------------------------------------- |
601 | /// @brief Dispatches pointer events from the embedder to the |
602 | /// framework. Each pointer data packet may contain multiple |
603 | /// pointer input events. Each call to this method wakes up |
604 | /// the UI thread. |
605 | /// |
606 | /// @param[in] packet The pointer data packet to dispatch to the framework. |
607 | /// |
608 | void DispatchPointerDataPacket(std::unique_ptr<PointerDataPacket> packet); |
609 | |
610 | //-------------------------------------------------------------------------- |
611 | /// @brief Used by the embedder to specify a texture that it wants the |
612 | /// rasterizer to composite within the Flutter layer tree. All |
613 | /// textures must have a unique identifier. When the |
614 | /// rasterizer encounters an external texture within its |
615 | /// hierarchy, it gives the embedder a chance to update that |
616 | /// texture on the raster thread before it composites the same |
617 | /// on-screen. |
618 | /// |
619 | /// @attention This method must only be called once per texture. When the |
620 | /// texture is updated, calling `MarkTextureFrameAvailable` |
621 | /// with the specified texture identifier is sufficient to |
622 | /// make Flutter re-render the frame with the updated texture |
623 | /// composited in-line. |
624 | /// |
625 | /// @see UnregisterTexture, MarkTextureFrameAvailable |
626 | /// |
627 | /// @param[in] texture The texture that is being updated by the embedder |
628 | /// but composited by Flutter in its own hierarchy. |
629 | /// |
630 | void RegisterTexture(std::shared_ptr<flutter::Texture> texture); |
631 | |
632 | //-------------------------------------------------------------------------- |
633 | /// @brief Used by the embedder to notify the rasterizer that it will |
634 | /// no longer attempt to composite the specified texture within |
635 | /// the layer tree. This allows the rasterizer to collect |
636 | /// associated resources. |
637 | /// |
638 | /// @attention This call must only be called once per texture identifier. |
639 | /// |
640 | /// @see RegisterTexture, MarkTextureFrameAvailable |
641 | /// |
642 | /// @param[in] texture_id The identifier of the texture to unregister. If |
643 | /// the texture has not been previously registered, |
644 | /// this call does nothing. |
645 | /// |
646 | void UnregisterTexture(int64_t texture_id); |
647 | |
648 | //-------------------------------------------------------------------------- |
649 | /// @brief Used by the embedder to notify the rasterizer that the context |
650 | /// of the previously registered texture have been updated. |
651 | /// Typically, Flutter will only render a frame if there is an |
652 | /// updated layer tree. However, in cases where the layer tree |
653 | /// is static but one of the externally composited textures |
654 | /// has been updated by the embedder, the embedder needs to |
655 | /// notify the rasterizer to render a new frame. In such |
656 | /// cases, the existing layer tree may be reused with the |
657 | /// frame re-composited with all updated external textures. |
658 | /// Unlike the calls to register and unregister the texture, |
659 | /// this call must be made each time a new texture frame is |
660 | /// available. |
661 | /// |
662 | /// @see RegisterTexture, UnregisterTexture |
663 | /// |
664 | /// @param[in] texture_id The identifier of the texture that has been |
665 | /// updated. |
666 | /// |
667 | void MarkTextureFrameAvailable(int64_t texture_id); |
668 | |
669 | //-------------------------------------------------------------------------- |
670 | /// @brief Directly invokes platform-specific APIs to compute the |
671 | /// locale the platform would have natively resolved to. |
672 | /// |
673 | /// @param[in] supported_locale_data The vector of strings that represents |
674 | /// the locales supported by the app. |
675 | /// Each locale consists of three |
676 | /// strings: languageCode, countryCode, |
677 | /// and scriptCode in that order. |
678 | /// |
679 | /// @return A vector of 3 strings languageCode, countryCode, and |
680 | /// scriptCode that represents the locale selected by the |
681 | /// platform. Empty strings mean the value was unassigned. Empty |
682 | /// vector represents a null locale. |
683 | /// |
684 | virtual std::unique_ptr<std::vector<std::string>> |
685 | ComputePlatformResolvedLocales( |
686 | const std::vector<std::string>& supported_locale_data); |
687 | |
688 | virtual std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder(); |
689 | |
690 | //-------------------------------------------------------------------------- |
691 | /// @brief Invoked when the dart VM requests that a deferred library |
692 | /// be loaded. Notifies the engine that the deferred library |
693 | /// identified by the specified loading unit id should be |
694 | /// downloaded and loaded into the Dart VM via |
695 | /// `LoadDartDeferredLibrary` |
696 | /// |
697 | /// Upon encountering errors or otherwise failing to load a |
698 | /// loading unit with the specified id, the failure should be |
699 | /// directly reported to dart by calling |
700 | /// `LoadDartDeferredLibraryFailure` to ensure the waiting dart |
701 | /// future completes with an error. |
702 | /// |
703 | /// @param[in] loading_unit_id The unique id of the deferred library's |
704 | /// loading unit. This id is to be passed |
705 | /// back into LoadDartDeferredLibrary |
706 | /// in order to identify which deferred |
707 | /// library to load. |
708 | /// |
709 | virtual void RequestDartDeferredLibrary(intptr_t loading_unit_id); |
710 | |
711 | //-------------------------------------------------------------------------- |
712 | /// @brief Loads the Dart shared library into the Dart VM. When the |
713 | /// Dart library is loaded successfully, the Dart future |
714 | /// returned by the originating loadLibrary() call completes. |
715 | /// |
716 | /// The Dart compiler may generate separate shared libraries |
717 | /// files called 'loading units' when libraries are imported |
718 | /// as deferred. Each of these shared libraries are identified |
719 | /// by a unique loading unit id. Callers should open and resolve |
720 | /// a SymbolMapping from the shared library. The Mappings should |
721 | /// be moved into this method, as ownership will be assumed by the |
722 | /// dart isolate after successful loading and released after |
723 | /// shutdown of the dart isolate. If loading fails, the mappings |
724 | /// will naturally go out of scope. |
725 | /// |
726 | /// This method is paired with a RequestDartDeferredLibrary |
727 | /// invocation that provides the embedder with the loading unit id |
728 | /// of the deferred library to load. |
729 | /// |
730 | /// |
731 | /// @param[in] loading_unit_id The unique id of the deferred library's |
732 | /// loading unit, as passed in by |
733 | /// RequestDartDeferredLibrary. |
734 | /// |
735 | /// @param[in] snapshot_data Dart snapshot data of the loading unit's |
736 | /// shared library. |
737 | /// |
738 | /// @param[in] snapshot_data Dart snapshot instructions of the loading |
739 | /// unit's shared library. |
740 | /// |
741 | virtual void LoadDartDeferredLibrary( |
742 | intptr_t loading_unit_id, |
743 | std::unique_ptr<const fml::Mapping> snapshot_data, |
744 | std::unique_ptr<const fml::Mapping> snapshot_instructions); |
745 | |
746 | //-------------------------------------------------------------------------- |
747 | /// @brief Indicates to the dart VM that the request to load a deferred |
748 | /// library with the specified loading unit id has failed. |
749 | /// |
750 | /// The dart future returned by the initiating loadLibrary() call |
751 | /// will complete with an error. |
752 | /// |
753 | /// @param[in] loading_unit_id The unique id of the deferred library's |
754 | /// loading unit, as passed in by |
755 | /// RequestDartDeferredLibrary. |
756 | /// |
757 | /// @param[in] error_message The error message that will appear in the |
758 | /// dart Future. |
759 | /// |
760 | /// @param[in] transient A transient error is a failure due to |
761 | /// temporary conditions such as no network. |
762 | /// Transient errors allow the dart VM to |
763 | /// re-request the same deferred library and |
764 | /// loading_unit_id again. Non-transient |
765 | /// errors are permanent and attempts to |
766 | /// re-request the library will instantly |
767 | /// complete with an error. |
768 | /// |
769 | virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id, |
770 | const std::string error_message, |
771 | bool transient); |
772 | |
773 | //-------------------------------------------------------------------------- |
774 | /// @brief Replaces the asset resolver handled by the engine's |
775 | /// AssetManager of the specified `type` with |
776 | /// `updated_asset_resolver`. The matching AssetResolver is |
777 | /// removed and replaced with `updated_asset_resolvers`. |
778 | /// |
779 | /// AssetResolvers should be updated when the existing resolver |
780 | /// becomes obsolete and a newer one becomes available that |
781 | /// provides updated access to the same type of assets as the |
782 | /// existing one. This update process is meant to be performed |
783 | /// at runtime. |
784 | /// |
785 | /// If a null resolver is provided, nothing will be done. If no |
786 | /// matching resolver is found, the provided resolver will be |
787 | /// added to the end of the AssetManager resolvers queue. The |
788 | /// replacement only occurs with the first matching resolver. |
789 | /// Any additional matching resolvers are untouched. |
790 | /// |
791 | /// @param[in] updated_asset_resolver The asset resolver to replace the |
792 | /// resolver of matching type with. |
793 | /// |
794 | /// @param[in] type The type of AssetResolver to update. Only resolvers of |
795 | /// the specified type will be replaced by the updated |
796 | /// resolver. |
797 | /// |
798 | virtual void UpdateAssetResolverByType( |
799 | std::unique_ptr<AssetResolver> updated_asset_resolver, |
800 | AssetResolver::AssetResolverType type); |
801 | |
802 | //-------------------------------------------------------------------------- |
803 | /// @brief Creates an object that produces surfaces suitable for raster |
804 | /// snapshotting. The rasterizer will request this surface if no |
805 | /// on screen surface is currently available when an application |
806 | /// requests a snapshot, e.g. if `Scene.toImage` or |
807 | /// `Picture.toImage` are called while the application is in the |
808 | /// background. |
809 | /// |
810 | /// Not all backends support this kind of surface usage, and the |
811 | /// default implementation returns nullptr. Platforms should |
812 | /// override this if they can support GPU operations in the |
813 | /// background and support GPU resource context usage. |
814 | /// |
815 | virtual std::unique_ptr<SnapshotSurfaceProducer> |
816 | CreateSnapshotSurfaceProducer(); |
817 | |
818 | //-------------------------------------------------------------------------- |
819 | /// @brief Specifies a delegate that will receive PlatformMessages from |
820 | /// Flutter to the host platform. |
821 | /// |
822 | /// @details If this returns `null` that means PlatformMessages should be sent |
823 | /// to the PlatformView. That is to protect legacy behavior, any embedder |
824 | /// that wants to support executing Platform Channel handlers on background |
825 | /// threads should be returning a thread-safe PlatformMessageHandler instead. |
826 | virtual std::shared_ptr<PlatformMessageHandler> GetPlatformMessageHandler() |
827 | const; |
828 | |
829 | //---------------------------------------------------------------------------- |
830 | /// @brief Get the settings for this platform view instance. |
831 | /// |
832 | /// @return The settings. |
833 | /// |
834 | const Settings& GetSettings() const; |
835 | |
836 | protected: |
837 | // This is the only method called on the raster task runner. |
838 | virtual std::unique_ptr<Surface> CreateRenderingSurface(); |
839 | |
840 | PlatformView::Delegate& delegate_; |
841 | const TaskRunners task_runners_; |
842 | PointerDataPacketConverter pointer_data_packet_converter_; |
843 | fml::WeakPtrFactory<PlatformView> weak_factory_; // Must be the last member. |
844 | |
845 | private: |
846 | FML_DISALLOW_COPY_AND_ASSIGN(PlatformView); |
847 | }; |
848 | |
849 | } // namespace flutter |
850 | |
851 | #endif // COMMON_PLATFORM_VIEW_H_ |
852 | |