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 FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
6#define FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
7
8#include <memory>
9#include <vector>
10
11#include "flutter/assets/asset_manager.h"
12#include "flutter/common/task_runners.h"
13#include "flutter/flow/layers/layer_tree.h"
14#include "flutter/fml/macros.h"
15#include "flutter/fml/mapping.h"
16#include "flutter/lib/ui/io_manager.h"
17#include "flutter/lib/ui/painting/image_generator_registry.h"
18#include "flutter/lib/ui/text/font_collection.h"
19#include "flutter/lib/ui/ui_dart_state.h"
20#include "flutter/lib/ui/volatile_path_tracker.h"
21#include "flutter/lib/ui/window/platform_configuration.h"
22#include "flutter/lib/ui/window/pointer_data_packet.h"
23#include "flutter/runtime/dart_vm.h"
24#include "flutter/runtime/platform_data.h"
25#include "rapidjson/document.h"
26#include "rapidjson/stringbuffer.h"
27
28namespace flutter {
29
30class Scene;
31class RuntimeDelegate;
32class View;
33class Window;
34
35//------------------------------------------------------------------------------
36/// Represents an instance of a running root isolate with window bindings. In
37/// normal operation, a single instance of this object is owned by the engine
38/// per shell. This object may only be created, used, and collected on the UI
39/// task runner. Window state queried by the root isolate is stored by this
40/// object. In cold-restart scenarios, the engine may collect this before
41/// installing a new runtime controller in its place. The Clone method may be
42/// used by the engine to copy the currently accumulated window state so it can
43/// be referenced by the new runtime controller.
44///
45class RuntimeController : public PlatformConfigurationClient {
46 public:
47 //----------------------------------------------------------------------------
48 /// @brief Creates a new instance of a runtime controller. This is
49 /// usually only done by the engine instance associated with the
50 /// shell.
51 ///
52 /// @param client The runtime delegate. This is
53 /// usually the `Engine` instance.
54 /// @param vm A reference to a running Dart VM.
55 /// The runtime controller must be
56 /// collected before the VM is
57 /// destroyed (this order is
58 /// guaranteed by the shell).
59 /// @param[in] idle_notification_callback The idle notification callback.
60 /// This allows callers to run native
61 /// code in isolate scope when the VM
62 /// is about to be notified that the
63 /// engine is going to be idle.
64 /// @param[in] platform_data The window data (if exists).
65 /// @param[in] isolate_create_callback The isolate create callback. This
66 /// allows callers to run native code
67 /// in isolate scope on the UI task
68 /// runner as soon as the root isolate
69 /// has been created.
70 /// @param[in] isolate_shutdown_callback The isolate shutdown callback.
71 /// This allows callers to run native
72 /// code in isolate scoped on the UI
73 /// task runner just as the root
74 /// isolate is about to be torn down.
75 /// @param[in] persistent_isolate_data Unstructured persistent read-only
76 /// data that the root isolate can
77 /// access in a synchronous manner.
78 /// @param[in] context Engine-owned state which is
79 /// accessed by the root dart isolate.
80 ///
81 RuntimeController(
82 RuntimeDelegate& p_client,
83 DartVM* vm,
84 fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
85 const std::function<void(int64_t)>& idle_notification_callback,
86 const PlatformData& platform_data,
87 const fml::closure& isolate_create_callback,
88 const fml::closure& isolate_shutdown_callback,
89 std::shared_ptr<const fml::Mapping> p_persistent_isolate_data,
90 const UIDartState::Context& context);
91
92 //----------------------------------------------------------------------------
93 /// @brief Create a RuntimeController that shares as many resources as
94 /// possible with the calling RuntimeController such that together
95 /// they occupy less memory.
96 /// @return A RuntimeController with a running isolate.
97 /// @see RuntimeController::RuntimeController
98 ///
99 std::unique_ptr<RuntimeController> Spawn(
100 RuntimeDelegate& p_client,
101 std::string advisory_script_uri,
102 std::string advisory_script_entrypoint,
103 const std::function<void(int64_t)>& idle_notification_callback,
104 const fml::closure& isolate_create_callback,
105 const fml::closure& isolate_shutdown_callback,
106 const std::shared_ptr<const fml::Mapping>& persistent_isolate_data,
107 fml::WeakPtr<IOManager> io_manager,
108 fml::WeakPtr<ImageDecoder> image_decoder,
109 fml::WeakPtr<ImageGeneratorRegistry> image_generator_registry,
110 fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate) const;
111
112 // |PlatformConfigurationClient|
113 ~RuntimeController() override;
114
115 //----------------------------------------------------------------------------
116 /// @brief Launches the isolate using the window data associated with
117 /// this runtime controller. Before this call, the Dart isolate
118 /// has not been initialized. On successful return, the caller can
119 /// assume that the isolate is in the
120 /// `DartIsolate::Phase::Running` phase.
121 ///
122 /// This call will fail if a root isolate is already running. To
123 /// re-create an isolate with the window data associated with this
124 /// runtime controller, `Clone` this runtime controller and
125 /// Launch an isolate in that runtime controller instead.
126 ///
127 /// @param[in] settings The per engine instance settings.
128 /// @param[in] root_isolate_create_callback A callback invoked before the
129 /// root isolate has launched the Dart
130 /// program, but after it has been
131 /// created. This is called without
132 /// isolate scope, and after any root
133 /// isolate callback in the settings.
134 /// @param[in] dart_entrypoint The dart entrypoint. If
135 /// `std::nullopt` or empty, `main` will
136 /// be attempted.
137 /// @param[in] dart_entrypoint_library The dart entrypoint library. If
138 /// `std::nullopt` or empty, the core
139 /// library will be attempted.
140 /// @param[in] dart_entrypoint_args Arguments passed as a List<String>
141 /// to Dart's entrypoint function.
142 /// @param[in] isolate_configuration The isolate configuration
143 ///
144 /// @return If the isolate could be launched and guided to the
145 /// `DartIsolate::Phase::Running` phase.
146 ///
147 [[nodiscard]] bool LaunchRootIsolate(
148 const Settings& settings,
149 const fml::closure& root_isolate_create_callback,
150 std::optional<std::string> dart_entrypoint,
151 std::optional<std::string> dart_entrypoint_library,
152 const std::vector<std::string>& dart_entrypoint_args,
153 std::unique_ptr<IsolateConfiguration> isolate_configuration);
154
155 //----------------------------------------------------------------------------
156 /// @brief Clone the runtime controller. Launching an isolate with a
157 /// cloned runtime controller will use the same snapshots and
158 /// copies all window data to the new instance. This is usually
159 /// only used in the debug runtime mode to support the
160 /// cold-restart scenario.
161 ///
162 /// @return A clone of the existing runtime controller.
163 ///
164 std::unique_ptr<RuntimeController> Clone() const;
165
166 //----------------------------------------------------------------------------
167 /// @brief Forward the specified viewport metrics to the running isolate.
168 /// If the isolate is not running, these metrics will be saved and
169 /// flushed to the isolate when it starts.
170 ///
171 /// @param[in] view_id The ID for the view that `metrics` describes.
172 /// @param[in] metrics The window's viewport metrics.
173 ///
174 /// @return If the window metrics were forwarded to the running isolate.
175 ///
176 bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
177
178 //----------------------------------------------------------------------------
179 /// @brief Forward the specified display metrics to the running isolate.
180 /// If the isolate is not running, these metrics will be saved and
181 /// flushed to the isolate when it starts.
182 ///
183 /// @param[in] displays The available displays.
184 bool SetDisplays(const std::vector<DisplayData>& displays);
185
186 //----------------------------------------------------------------------------
187 /// @brief Forward the specified locale data to the running isolate. If
188 /// the isolate is not running, this data will be saved and
189 /// flushed to the isolate when it starts running.
190 ///
191 /// @deprecated The persistent isolate data must be used for this purpose
192 /// instead.
193 ///
194 /// @param[in] locale_data The locale data. This should consist of groups of
195 /// 4 strings, each group representing a single locale.
196 ///
197 /// @return If the locale data was forwarded to the running isolate.
198 ///
199 bool SetLocales(const std::vector<std::string>& locale_data);
200
201 //----------------------------------------------------------------------------
202 /// @brief Forward the user settings data to the running isolate. If the
203 /// isolate is not running, this data will be saved and flushed to
204 /// the isolate when it starts running.
205 ///
206 /// @deprecated The persistent isolate data must be used for this purpose
207 /// instead.
208 ///
209 /// @param[in] data The user settings data.
210 ///
211 /// @return If the user settings data was forwarded to the running
212 /// isolate.
213 ///
214 bool SetUserSettingsData(const std::string& data);
215
216 //----------------------------------------------------------------------------
217 /// @brief Forward the initial lifecycle state data to the running
218 /// isolate. If the isolate is not running, this data will be
219 /// saved and flushed to the isolate when it starts running.
220 /// After the isolate starts running, the current lifecycle
221 /// state is pushed to it via the "flutter/lifecycle" channel.
222 ///
223 /// @deprecated The persistent isolate data must be used for this purpose
224 /// instead.
225 ///
226 /// @param[in] data The lifecycle state data.
227 ///
228 /// @return If the lifecycle state data was forwarded to the running
229 /// isolate.
230 ///
231 bool SetInitialLifecycleState(const std::string& data);
232
233 //----------------------------------------------------------------------------
234 /// @brief Notifies the running isolate about whether the semantics tree
235 /// should be generated or not. If the isolate is not running,
236 /// this preference will be saved and flushed to the isolate when
237 /// it starts running.
238 ///
239 /// @param[in] enabled Indicates whether to generate the semantics tree.
240 ///
241 /// @return If the semantics tree generation preference was forwarded to
242 /// the running isolate.
243 ///
244 bool SetSemanticsEnabled(bool enabled);
245
246 //----------------------------------------------------------------------------
247 /// @brief Forward the preference of accessibility features that must be
248 /// enabled in the semantics tree to the running isolate. If the
249 /// isolate is not running, this data will be saved and flushed to
250 /// the isolate when it starts running.
251 ///
252 /// @param[in] flags The accessibility features that must be generated in
253 /// the semantics tree.
254 ///
255 /// @return If the preference of accessibility features was forwarded to
256 /// the running isolate.
257 ///
258 bool SetAccessibilityFeatures(int32_t flags);
259
260 //----------------------------------------------------------------------------
261 /// @brief Notifies the running isolate that it should start generating a
262 /// new frame.
263 ///
264 /// @see `Engine::BeginFrame` for more context.
265 ///
266 /// @param[in] frame_time The point at which the current frame interval
267 /// began. May be used by animation interpolators,
268 /// physics simulations, etc.
269 ///
270 /// @return If notification to begin frame rendering was delivered to the
271 /// running isolate.
272 ///
273 bool BeginFrame(fml::TimePoint frame_time, uint64_t frame_number);
274
275 //----------------------------------------------------------------------------
276 /// @brief Dart code cannot fully measure the time it takes for a
277 /// specific frame to be rendered. This is because Dart code only
278 /// runs on the UI task runner. That is only a small part of the
279 /// overall frame workload. The raster task runner frame workload
280 /// is executed on a thread where Dart code cannot run (and hence
281 /// instrument). Besides, due to the pipelined nature of rendering
282 /// in Flutter, there may be multiple frame workloads being
283 /// processed at any given time. However, for non-Timeline based
284 /// profiling, it is useful for trace collection and processing to
285 /// happen in Dart. To do this, the raster task runner frame
286 /// workloads need to be instrumented separately. After a set
287 /// number of these profiles have been gathered, they need to be
288 /// reported back to Dart code. The engine reports this extra
289 /// instrumentation information back to Dart code running on the
290 /// engine by invoking this method at predefined intervals.
291 ///
292 /// @see `Engine::ReportTimings`, `FrameTiming`
293 ///
294 /// @param[in] timings Collection of `FrameTiming::kCount` * `n` timestamps
295 /// for `n` frames whose timings have not been reported
296 /// yet. A collection of integers is reported here for
297 /// easier conversions to Dart objects. The timestamps
298 /// are measured against the system monotonic clock
299 /// measured in microseconds.
300 ///
301 bool ReportTimings(std::vector<int64_t> timings);
302
303 //----------------------------------------------------------------------------
304 /// @brief Notify the Dart VM that no frame workloads are expected on the
305 /// UI task runner till the specified deadline. The VM uses this
306 /// opportunity to perform garbage collection operations is a
307 /// manner that interferes as little as possible with frame
308 /// rendering.
309 ///
310 /// NotifyIdle is advisory. The VM may or may not run a garbage collection
311 /// when this is called, and will eventually perform garbage collections even
312 /// if it is not called or it is called with insufficient deadlines.
313 ///
314 /// The garbage collection mechanism and its thresholds are internal
315 /// implementation details and absolutely no guarantees are made about the
316 /// threshold discussed below. This discussion is also an oversimplification
317 /// but hopefully serves to calibrate expectations about GC behavior:
318 /// * When the Dart VM and its root isolate are initialized, the memory
319 /// consumed upto that point are treated as a baseline.
320 /// * A fixed percentage of the memory consumed (~20%) over the baseline is
321 /// treated as the hard threshold.
322 /// * The memory in play is divided into old space and new space. The new
323 /// space is typically very small and fills up rapidly.
324 /// * The baseline plus the threshold is considered the old space while the
325 /// small new space is a separate region (typically a few pages).
326 /// * The total old space size minus the max new space size is treated as the
327 /// soft threshold.
328 /// * In a world where there is no call to NotifyIdle, when the total
329 /// allocation exceeds the soft threshold, a concurrent mark is initiated in
330 /// the VM. There is a “small” pause that occurs when the concurrent mark is
331 /// initiated and another pause when the mark concludes and a sweep is
332 /// initiated.
333 /// * If the total allocations exceeds the hard threshold, a “big”
334 /// stop-the-world pause is initiated.
335 /// * If after either the sweep after the concurrent mark, or, the
336 /// stop-the-world pause, the consumption returns to be below the soft
337 /// threshold, the dance begins anew.
338 /// * If after both the “small” and “big” pauses, memory usage is still over
339 /// the hard threshold, i.e, the objects are still reachable, that amount of
340 /// memory is treated as the new baseline and a fixed percentage of the new
341 /// baseline over the new baseline is now the new hard threshold.
342 /// * Updating the baseline will continue till memory for the updated old
343 /// space can be allocated from the operating system. These allocations will
344 /// typically fail due to address space exhaustion on 32-bit systems and
345 /// page table exhaustion on 64-bit systems.
346 /// * NotifyIdle initiates the concurrent mark preemptively. The deadline is
347 /// used by the VM to determine if the corresponding sweep can be performed
348 /// within the deadline. This way, jank due to “small” pauses can be
349 /// ameliorated.
350 /// * There is no ability to stop a “big” pause on reaching the hard threshold
351 /// in the old space. The best you can do is release (by making them
352 /// unreachable) objects eagerly so that the are marked as unreachable in
353 /// the concurrent mark initiated by either reaching the soft threshold or
354 /// an explicit NotifyIdle.
355 /// * If you are running out of memory, its because too many large objects
356 /// were allocation and remained reachable such that the old space kept
357 /// growing till it could grow no more.
358 /// * At the edges of allocation thresholds, failures can occur gracefully if
359 /// the instigating allocation was made in the Dart VM or rather gracelessly
360 /// if the allocation is made by some native component.
361 ///
362 /// @see `Dart_TimelineGetMicros`
363 ///
364 /// @bug The `deadline` argument must be converted to `std::chrono`
365 /// instead of a raw integer.
366 ///
367 /// @param[in] deadline The deadline is used by the VM to determine if the
368 /// corresponding sweep can be performed within the deadline.
369 ///
370 /// @return If the idle notification was forwarded to the running isolate.
371 ///
372 virtual bool NotifyIdle(fml::TimeDelta deadline);
373
374 //----------------------------------------------------------------------------
375 /// @brief Notify the Dart VM that the attached flutter view has been
376 /// destroyed. This gives the Dart VM to perform some cleanup
377 /// activities e.g: perform garbage collection to free up any
378 /// unused memory.
379 ///
380 /// NotifyDestroyed is advisory. The VM may or may not perform any clean up
381 /// activities.
382 ///
383 virtual bool NotifyDestroyed();
384
385 //----------------------------------------------------------------------------
386 /// @brief Returns if the root isolate is running. The isolate must be
387 /// transitioned to the running phase manually. The isolate can
388 /// stop running if it terminates execution on its own.
389 ///
390 /// @return True if root isolate running, False otherwise.
391 ///
392 virtual bool IsRootIsolateRunning();
393
394 //----------------------------------------------------------------------------
395 /// @brief Dispatch the specified platform message to running root
396 /// isolate.
397 ///
398 /// @param[in] message The message to dispatch to the isolate.
399 ///
400 /// @return If the message was dispatched to the running root isolate.
401 /// This may fail is an isolate is not running.
402 ///
403 virtual bool DispatchPlatformMessage(
404 std::unique_ptr<PlatformMessage> message);
405
406 //----------------------------------------------------------------------------
407 /// @brief Dispatch the specified pointer data message to the running
408 /// root isolate.
409 ///
410 /// @param[in] packet The pointer data message to dispatch to the isolate.
411 ///
412 /// @return If the pointer data message was dispatched. This may fail is
413 /// an isolate is not running.
414 ///
415 bool DispatchPointerDataPacket(const PointerDataPacket& packet);
416
417 //----------------------------------------------------------------------------
418 /// @brief Dispatch the semantics action to the specified accessibility
419 /// node.
420 ///
421 /// @param[in] node_id The identified of the accessibility node.
422 /// @param[in] action The semantics action to perform on the specified
423 /// accessibility node.
424 /// @param[in] args Optional data that applies to the specified action.
425 ///
426 /// @return If the semantics action was dispatched. This may fail if an
427 /// isolate is not running.
428 ///
429 bool DispatchSemanticsAction(int32_t node_id,
430 SemanticsAction action,
431 fml::MallocMapping args);
432
433 //----------------------------------------------------------------------------
434 /// @brief Gets the main port identifier of the root isolate.
435 ///
436 /// @return The main port identifier. If no root isolate is running,
437 /// returns `ILLEGAL_PORT`.
438 ///
439 Dart_Port GetMainPort();
440
441 //----------------------------------------------------------------------------
442 /// @brief Gets the debug name of the root isolate. But default, the
443 /// debug name of the isolate is derived from its advisory script
444 /// URI, advisory main entrypoint and its main port name. For
445 /// example, "main.dart$main-1234" where the script URI is
446 /// "main.dart", the entrypoint is "main" and the port name
447 /// "1234". Once launched, the isolate may re-christen itself
448 /// using a name it selects via `setIsolateDebugName` in
449 /// `window.dart`. This name is purely advisory and only used by
450 /// instrumentation and reporting purposes.
451 ///
452 /// @return The debug name of the root isolate.
453 ///
454 std::string GetIsolateName();
455
456 //----------------------------------------------------------------------------
457 /// @brief Returns if the root isolate has any live receive ports.
458 ///
459 /// @return True if there are live receive ports, False otherwise. Return
460 /// False if the root isolate is not running as well.
461 ///
462 bool HasLivePorts();
463
464 //----------------------------------------------------------------------------
465 /// @brief Get the last error encountered by the microtask queue.
466 ///
467 /// @return The last error encountered by the microtask queue.
468 ///
469 tonic::DartErrorHandleType GetLastError();
470
471 //----------------------------------------------------------------------------
472 /// @brief Get the service ID of the root isolate if the root isolate is
473 /// running.
474 ///
475 /// @return The root isolate service id.
476 ///
477 std::optional<std::string> GetRootIsolateServiceID() const;
478
479 //----------------------------------------------------------------------------
480 /// @brief Get the return code specified by the root isolate (if one is
481 /// present).
482 ///
483 /// @return The root isolate return code if the isolate has specified one.
484 ///
485 std::optional<uint32_t> GetRootIsolateReturnCode();
486
487 //----------------------------------------------------------------------------
488 /// @brief Get an identifier that represents the Dart isolate group the
489 /// root isolate is in.
490 ///
491 /// @return The root isolate group identifier, zero if one can't
492 /// be established.
493 uint64_t GetRootIsolateGroup() const;
494
495 //--------------------------------------------------------------------------
496 /// @brief Loads the Dart shared library into the Dart VM. When the
497 /// Dart library is loaded successfully, the Dart future
498 /// returned by the originating loadLibrary() call completes.
499 ///
500 /// The Dart compiler may generate separate shared libraries
501 /// files called 'loading units' when libraries are imported
502 /// as deferred. Each of these shared libraries are identified
503 /// by a unique loading unit id. Callers should open and resolve
504 /// a SymbolMapping from the shared library. The Mappings should
505 /// be moved into this method, as ownership will be assumed by the
506 /// dart root isolate after successful loading and released after
507 /// shutdown of the root isolate. The loading unit may not be
508 /// used after isolate shutdown. If loading fails, the mappings
509 /// will be released.
510 ///
511 /// This method is paired with a RequestDartDeferredLibrary
512 /// invocation that provides the embedder with the loading unit id
513 /// of the deferred library to load.
514 ///
515 ///
516 /// @param[in] loading_unit_id The unique id of the deferred library's
517 /// loading unit, as passed in by
518 /// RequestDartDeferredLibrary.
519 ///
520 /// @param[in] snapshot_data Dart snapshot data of the loading unit's
521 /// shared library.
522 ///
523 /// @param[in] snapshot_data Dart snapshot instructions of the loading
524 /// unit's shared library.
525 ///
526 void LoadDartDeferredLibrary(
527 intptr_t loading_unit_id,
528 std::unique_ptr<const fml::Mapping> snapshot_data,
529 std::unique_ptr<const fml::Mapping> snapshot_instructions);
530
531 //--------------------------------------------------------------------------
532 /// @brief Indicates to the dart VM that the request to load a deferred
533 /// library with the specified loading unit id has failed.
534 ///
535 /// The dart future returned by the initiating loadLibrary() call
536 /// will complete with an error.
537 ///
538 /// @param[in] loading_unit_id The unique id of the deferred library's
539 /// loading unit, as passed in by
540 /// RequestDartDeferredLibrary.
541 ///
542 /// @param[in] error_message The error message that will appear in the
543 /// dart Future.
544 ///
545 /// @param[in] transient A transient error is a failure due to
546 /// temporary conditions such as no network.
547 /// Transient errors allow the dart VM to
548 /// re-request the same deferred library and
549 /// loading_unit_id again. Non-transient
550 /// errors are permanent and attempts to
551 /// re-request the library will instantly
552 /// complete with an error.
553 virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
554 const std::string error_message,
555 bool transient);
556
557 // |PlatformConfigurationClient|
558 void RequestDartDeferredLibrary(intptr_t loading_unit_id) override;
559
560 // |PlatformConfigurationClient|
561 std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override;
562
563 const fml::WeakPtr<IOManager>& GetIOManager() const {
564 return context_.io_manager;
565 }
566
567 virtual DartVM* GetDartVM() const { return vm_; }
568
569 const fml::RefPtr<const DartSnapshot>& GetIsolateSnapshot() const {
570 return isolate_snapshot_;
571 }
572
573 const PlatformData& GetPlatformData() const { return platform_data_; }
574
575 const fml::RefPtr<SkiaUnrefQueue>& GetSkiaUnrefQueue() const {
576 return context_.unref_queue;
577 }
578
579 const fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>& GetSnapshotDelegate()
580 const {
581 return context_.snapshot_delegate;
582 }
583
584 std::weak_ptr<const DartIsolate> GetRootIsolate() const {
585 return root_isolate_;
586 }
587
588 protected:
589 /// Constructor for Mocks.
590 RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners);
591
592 private:
593 struct Locale {
594 Locale(std::string language_code_,
595 std::string country_code_,
596 std::string script_code_,
597 std::string variant_code_);
598
599 ~Locale();
600
601 std::string language_code;
602 std::string country_code;
603 std::string script_code;
604 std::string variant_code;
605 };
606
607 RuntimeDelegate& client_;
608 DartVM* const vm_;
609 fml::RefPtr<const DartSnapshot> isolate_snapshot_;
610 std::function<void(int64_t)> idle_notification_callback_;
611 PlatformData platform_data_;
612 std::weak_ptr<DartIsolate> root_isolate_;
613 std::weak_ptr<DartIsolate> spawning_isolate_;
614 std::optional<uint32_t> root_isolate_return_code_;
615 const fml::closure isolate_create_callback_;
616 const fml::closure isolate_shutdown_callback_;
617 std::shared_ptr<const fml::Mapping> persistent_isolate_data_;
618 UIDartState::Context context_;
619
620 PlatformConfiguration* GetPlatformConfigurationIfAvailable();
621
622 bool FlushRuntimeStateToIsolate();
623
624 // |PlatformConfigurationClient|
625 bool ImplicitViewEnabled() override;
626
627 // |PlatformConfigurationClient|
628 std::string DefaultRouteName() override;
629
630 // |PlatformConfigurationClient|
631 void ScheduleFrame() override;
632
633 // |PlatformConfigurationClient|
634 void Render(Scene* scene) override;
635
636 // |PlatformConfigurationClient|
637 void UpdateSemantics(SemanticsUpdate* update) override;
638
639 // |PlatformConfigurationClient|
640 void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) override;
641
642 // |PlatformConfigurationClient|
643 FontCollection& GetFontCollection() override;
644
645 // |PlatformConfigurationClient|
646 std::shared_ptr<AssetManager> GetAssetManager() override;
647
648 // |PlatformConfigurationClient|
649 void UpdateIsolateDescription(const std::string isolate_name,
650 int64_t isolate_port) override;
651
652 // |PlatformConfigurationClient|
653 void SetNeedsReportTimings(bool value) override;
654
655 // |PlatformConfigurationClient|
656 std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
657 const std::vector<std::string>& supported_locale_data) override;
658
659 FML_DISALLOW_COPY_AND_ASSIGN(RuntimeController);
660};
661
662} // namespace flutter
663
664#endif // FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
665

source code of flutter_engine/flutter/runtime/runtime_controller.h

Morty Proxy This is a proxified and sanitized view of the page, visit original site.