Flutter Engine
 
Loading...
Searching...
No Matches
runtime_controller.h
Go to the documentation of this file.
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
14#include "flutter/fml/macros.h"
15#include "flutter/fml/mapping.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///
45/// When `RuntimeController` is created, it takes some time before the root
46/// isolate becomes ready. Operation during this gap is stored by
47/// `RuntimeController` and flushed to the Dart VM when the isolate becomes
48/// ready before the entrypoint function. See `PlatformData`.
49///
52 public:
53 /// A callback that's invoked after this `RuntimeController` attempts to
54 /// add a view to the Dart isolate.
55 ///
56 /// If the Dart isolate is not launched yet, this callback will be stored
57 /// and invoked after the isolate is launched.
58 ///
59 /// The `added` parameter is false if the add operation fails or was
60 /// cancelled while pending using `RemoveView`.
61 using AddViewCallback = std::function<void(bool added)>;
62
63 //----------------------------------------------------------------------------
64 /// @brief Creates a new instance of a runtime controller. This is
65 /// usually only done by the engine instance associated with the
66 /// shell.
67 ///
68 /// @param client The runtime delegate. This is
69 /// usually the `Engine` instance.
70 /// @param vm A reference to a running Dart VM.
71 /// The runtime controller must be
72 /// collected before the VM is
73 /// destroyed (this order is
74 /// guaranteed by the shell).
75 /// @param[in] idle_notification_callback The idle notification callback.
76 /// This allows callers to run native
77 /// code in isolate scope when the VM
78 /// is about to be notified that the
79 /// engine is going to be idle.
80 /// @param[in] platform_data The window data (if exists).
81 /// @param[in] isolate_create_callback The isolate create callback. This
82 /// allows callers to run native code
83 /// in isolate scope on the UI task
84 /// runner as soon as the root isolate
85 /// has been created.
86 /// @param[in] isolate_shutdown_callback The isolate shutdown callback.
87 /// This allows callers to run native
88 /// code in isolate scoped on the UI
89 /// task runner just as the root
90 /// isolate is about to be torn down.
91 /// @param[in] persistent_isolate_data Unstructured persistent read-only
92 /// data that the root isolate can
93 /// access in a synchronous manner.
94 /// @param[in] context Engine-owned state which is
95 /// accessed by the root dart isolate.
96 ///
98 RuntimeDelegate& p_client,
99 DartVM* vm,
100 fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
101 const std::function<void(int64_t)>& idle_notification_callback,
102 const PlatformData& platform_data,
103 const fml::closure& isolate_create_callback,
104 const fml::closure& isolate_shutdown_callback,
105 std::shared_ptr<const fml::Mapping> p_persistent_isolate_data,
106 const UIDartState::Context& context);
107
108 //----------------------------------------------------------------------------
109 /// @brief Create a RuntimeController that shares as many resources as
110 /// possible with the calling RuntimeController such that together
111 /// they occupy less memory.
112 /// @return A RuntimeController with a running isolate.
113 /// @see RuntimeController::RuntimeController
114 ///
115 std::unique_ptr<RuntimeController> Spawn(
116 RuntimeDelegate& p_client,
117 const std::string& advisory_script_uri,
118 const std::string& advisory_script_entrypoint,
119 const std::function<void(int64_t)>& idle_notification_callback,
120 const fml::closure& isolate_create_callback,
121 const fml::closure& isolate_shutdown_callback,
122 const std::shared_ptr<const fml::Mapping>& persistent_isolate_data,
123 fml::WeakPtr<IOManager> io_manager,
126 image_generator_registry,
127 fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate) const;
128
129 // |PlatformConfigurationClient|
130 ~RuntimeController() override;
131
132 //----------------------------------------------------------------------------
133 /// @brief Launches the isolate using the window data associated with
134 /// this runtime controller. Before this call, the Dart isolate
135 /// has not been initialized. On successful return, the caller can
136 /// assume that the isolate is in the
137 /// `DartIsolate::Phase::Running` phase.
138 ///
139 /// This call will fail if a root isolate is already running. To
140 /// re-create an isolate with the window data associated with this
141 /// runtime controller, `Clone` this runtime controller and
142 /// Launch an isolate in that runtime controller instead.
143 ///
144 /// @param[in] settings The per engine instance settings.
145 /// @param[in] root_isolate_create_callback A callback invoked before the
146 /// root isolate has launched the Dart
147 /// program, but after it has been
148 /// created. This is called without
149 /// isolate scope, and after any root
150 /// isolate callback in the settings.
151 /// @param[in] dart_entrypoint The dart entrypoint. If
152 /// `std::nullopt` or empty, `main` will
153 /// be attempted.
154 /// @param[in] dart_entrypoint_library The dart entrypoint library. If
155 /// `std::nullopt` or empty, the core
156 /// library will be attempted.
157 /// @param[in] dart_entrypoint_args Arguments passed as a List<String>
158 /// to Dart's entrypoint function.
159 /// @param[in] isolate_configuration The isolate configuration
160 /// @param[in] engine_id. Engine identifier to be passed to the
161 /// platform dispatcher.
162 ///
163 /// @return If the isolate could be launched and guided to the
164 /// `DartIsolate::Phase::Running` phase.
165 ///
166 [[nodiscard]] bool LaunchRootIsolate(
167 const Settings& settings,
168 const fml::closure& root_isolate_create_callback,
169 std::optional<std::string> dart_entrypoint,
170 std::optional<std::string> dart_entrypoint_library,
171 const std::vector<std::string>& dart_entrypoint_args,
172 std::unique_ptr<IsolateConfiguration> isolate_configuration,
173 std::shared_ptr<NativeAssetsManager> native_assets_manager,
174 std::optional<int64_t> engine_id);
175
176 //----------------------------------------------------------------------------
177 /// @brief Clone the runtime controller. Launching an isolate with a
178 /// cloned runtime controller will use the same snapshots and
179 /// copies all window data to the new instance. This is usually
180 /// only used in the debug runtime mode to support the
181 /// cold-restart scenario.
182 ///
183 /// @return A clone of the existing runtime controller.
184 ///
185 std::unique_ptr<RuntimeController> Clone() const;
186
187 //----------------------------------------------------------------------------
188 /// @brief Notify the isolate that a new view is available.
189 ///
190 /// A view must be added before other methods can refer to it,
191 /// including the implicit view. Adding a view that already exists
192 /// is an error.
193 ///
194 /// The `callback` is invoked when the add operation is attempted,
195 /// failed, or is cancelled.
196 ///
197 /// If the isolate is not running, the view add will be queued and
198 /// flushed to the isolate when it starts. Calling `RemoveView`
199 /// before the isolate is launched cancels the add operation.
200 ///
201 /// If the isolate is running, a frame will be scheduled.
202 ///
203 /// @param[in] view_id The ID of the new view.
204 /// @param[in] viewport_metrics The initial viewport metrics for the view.
205 /// @param[in] callback Callback that will be invoked after the add
206 /// operation is attempted or cancelled.
207 ///
208 void AddView(int64_t view_id,
209 const ViewportMetrics& view_metrics,
211
212 //----------------------------------------------------------------------------
213 /// @brief Notify the isolate that a view is no longer available.
214 ///
215 /// Views that are added before the isolate is started are
216 /// queued until the isolate is launched. If one of these
217 /// "pending" views are removed, the view add is cancelled:
218 /// the `AddViewCallback` will be invoked with an `added` of
219 /// false and `RemoveView` will return false.
220 ///
221 /// The implicit view (kFlutterImplicitViewId) should never be
222 /// removed. Doing so triggers an assertion.
223 ///
224 /// @param[in] view_id The ID of the view.
225 ///
226 /// @return If the remove view operation was forwarded to the running
227 /// isolate. False if the view does not exist. If the Dart isolate
228 /// is not running, then the pending view creation (if any) is
229 /// cancelled and the return value is always false.
230 bool RemoveView(int64_t view_id);
231
232 //----------------------------------------------------------------------------
233 /// @brief Notify the isolate that the focus state of a native view has
234 /// changed.
235 ///
236 /// @param[in] event The focus event describing the change.
237 bool SendViewFocusEvent(const ViewFocusEvent& event);
238
239 //----------------------------------------------------------------------------
240 /// @brief Forward the specified viewport metrics to the running isolate.
241 /// If the isolate is not running, these metrics will be saved and
242 /// flushed to the isolate when it starts.
243 ///
244 /// @param[in] view_id The ID for the view that `metrics` describes.
245 /// @param[in] metrics The window's viewport metrics.
246 ///
247 /// @return If the window metrics were forwarded to the running isolate.
248 ///
249 bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics);
250
251 //----------------------------------------------------------------------------
252 /// @brief Forward the specified display metrics to the running isolate.
253 /// If the isolate is not running, these metrics will be saved and
254 /// flushed to the isolate when it starts.
255 ///
256 /// @param[in] displays The available displays.
257 bool SetDisplays(const std::vector<DisplayData>& displays);
258
259 //----------------------------------------------------------------------------
260 /// @brief Forward the specified locale data to the running isolate. If
261 /// the isolate is not running, this data will be saved and
262 /// flushed to the isolate when it starts running.
263 ///
264 /// @deprecated The persistent isolate data must be used for this purpose
265 /// instead.
266 ///
267 /// @param[in] locale_data The locale data. This should consist of groups of
268 /// 4 strings, each group representing a single locale.
269 ///
270 /// @return If the locale data was forwarded to the running isolate.
271 ///
272 bool SetLocales(const std::vector<std::string>& locale_data);
273
274 //----------------------------------------------------------------------------
275 /// @brief Forward the user settings data to the running isolate. If the
276 /// isolate is not running, this data will be saved and flushed to
277 /// the isolate when it starts running.
278 ///
279 /// @deprecated The persistent isolate data must be used for this purpose
280 /// instead.
281 ///
282 /// @param[in] data The user settings data.
283 ///
284 /// @return If the user settings data was forwarded to the running
285 /// isolate.
286 ///
287 bool SetUserSettingsData(const std::string& data);
288
289 //----------------------------------------------------------------------------
290 /// @brief Forward the initial lifecycle state data to the running
291 /// isolate. If the isolate is not running, this data will be
292 /// saved and flushed to the isolate when it starts running.
293 /// After the isolate starts running, the current lifecycle
294 /// state is pushed to it via the "flutter/lifecycle" channel.
295 ///
296 /// @deprecated The persistent isolate data must be used for this purpose
297 /// instead.
298 ///
299 /// @param[in] data The lifecycle state data.
300 ///
301 /// @return If the lifecycle state data was forwarded to the running
302 /// isolate.
303 ///
304 bool SetInitialLifecycleState(const std::string& data);
305
306 //----------------------------------------------------------------------------
307 /// @brief Notifies the running isolate about whether the semantics tree
308 /// should be generated or not. If the isolate is not running,
309 /// this preference will be saved and flushed to the isolate when
310 /// it starts running.
311 ///
312 /// @param[in] enabled Indicates whether to generate the semantics tree.
313 ///
314 /// @return If the semantics tree generation preference was forwarded to
315 /// the running isolate.
316 ///
317 bool SetSemanticsEnabled(bool enabled);
318
319 //----------------------------------------------------------------------------
320 /// @brief Forward the preference of accessibility features that must be
321 /// enabled in the semantics tree to the running isolate. If the
322 /// isolate is not running, this data will be saved and flushed to
323 /// the isolate when it starts running.
324 ///
325 /// @param[in] flags The accessibility features that must be generated in
326 /// the semantics tree.
327 ///
328 /// @return If the preference of accessibility features was forwarded to
329 /// the running isolate.
330 ///
331 bool SetAccessibilityFeatures(int32_t flags);
332
333 //----------------------------------------------------------------------------
334 /// @brief Notifies the running isolate that it should start generating a
335 /// new frame.
336 ///
337 /// @see `Engine::BeginFrame` for more context.
338 ///
339 /// @param[in] frame_time The point at which the current frame interval
340 /// began. May be used by animation interpolators,
341 /// physics simulations, etc.
342 ///
343 /// @return If notification to begin frame rendering was delivered to the
344 /// running isolate.
345 ///
346 bool BeginFrame(fml::TimePoint frame_time, uint64_t frame_number);
347
348 //----------------------------------------------------------------------------
349 /// @brief Dart code cannot fully measure the time it takes for a
350 /// specific frame to be rendered. This is because Dart code only
351 /// runs on the UI task runner. That is only a small part of the
352 /// overall frame workload. The raster task runner frame workload
353 /// is executed on a thread where Dart code cannot run (and hence
354 /// instrument). Besides, due to the pipelined nature of rendering
355 /// in Flutter, there may be multiple frame workloads being
356 /// processed at any given time. However, for non-Timeline based
357 /// profiling, it is useful for trace collection and processing to
358 /// happen in Dart. To do this, the raster task runner frame
359 /// workloads need to be instrumented separately. After a set
360 /// number of these profiles have been gathered, they need to be
361 /// reported back to Dart code. The engine reports this extra
362 /// instrumentation information back to Dart code running on the
363 /// engine by invoking this method at predefined intervals.
364 ///
365 /// @see `Engine::ReportTimings`, `FrameTiming`
366 ///
367 /// @param[in] timings Collection of `FrameTiming::kCount` * `n` timestamps
368 /// for `n` frames whose timings have not been reported
369 /// yet. A collection of integers is reported here for
370 /// easier conversions to Dart objects. The timestamps
371 /// are measured against the system monotonic clock
372 /// measured in microseconds.
373 ///
374 bool ReportTimings(std::vector<int64_t> timings);
375
376 //----------------------------------------------------------------------------
377 /// @brief Notify the Dart VM that no frame workloads are expected on the
378 /// UI task runner till the specified deadline. The VM uses this
379 /// opportunity to perform garbage collection operations is a
380 /// manner that interferes as little as possible with frame
381 /// rendering.
382 ///
383 /// NotifyIdle is advisory. The VM may or may not run a garbage collection
384 /// when this is called, and will eventually perform garbage collections even
385 /// if it is not called or it is called with insufficient deadlines.
386 ///
387 /// The garbage collection mechanism and its thresholds are internal
388 /// implementation details and absolutely no guarantees are made about the
389 /// threshold discussed below. This discussion is also an oversimplification
390 /// but hopefully serves to calibrate expectations about GC behavior:
391 /// * When the Dart VM and its root isolate are initialized, the memory
392 /// consumed upto that point are treated as a baseline.
393 /// * A fixed percentage of the memory consumed (~20%) over the baseline is
394 /// treated as the hard threshold.
395 /// * The memory in play is divided into old space and new space. The new
396 /// space is typically very small and fills up rapidly.
397 /// * The baseline plus the threshold is considered the old space while the
398 /// small new space is a separate region (typically a few pages).
399 /// * The total old space size minus the max new space size is treated as the
400 /// soft threshold.
401 /// * In a world where there is no call to NotifyIdle, when the total
402 /// allocation exceeds the soft threshold, a concurrent mark is initiated in
403 /// the VM. There is a “small” pause that occurs when the concurrent mark is
404 /// initiated and another pause when the mark concludes and a sweep is
405 /// initiated.
406 /// * If the total allocations exceeds the hard threshold, a “big”
407 /// stop-the-world pause is initiated.
408 /// * If after either the sweep after the concurrent mark, or, the
409 /// stop-the-world pause, the consumption returns to be below the soft
410 /// threshold, the dance begins anew.
411 /// * If after both the “small” and “big” pauses, memory usage is still over
412 /// the hard threshold, i.e, the objects are still reachable, that amount of
413 /// memory is treated as the new baseline and a fixed percentage of the new
414 /// baseline over the new baseline is now the new hard threshold.
415 /// * Updating the baseline will continue till memory for the updated old
416 /// space can be allocated from the operating system. These allocations will
417 /// typically fail due to address space exhaustion on 32-bit systems and
418 /// page table exhaustion on 64-bit systems.
419 /// * NotifyIdle initiates the concurrent mark preemptively. The deadline is
420 /// used by the VM to determine if the corresponding sweep can be performed
421 /// within the deadline. This way, jank due to “small” pauses can be
422 /// ameliorated.
423 /// * There is no ability to stop a “big” pause on reaching the hard threshold
424 /// in the old space. The best you can do is release (by making them
425 /// unreachable) objects eagerly so that the are marked as unreachable in
426 /// the concurrent mark initiated by either reaching the soft threshold or
427 /// an explicit NotifyIdle.
428 /// * If you are running out of memory, its because too many large objects
429 /// were allocation and remained reachable such that the old space kept
430 /// growing till it could grow no more.
431 /// * At the edges of allocation thresholds, failures can occur gracefully if
432 /// the instigating allocation was made in the Dart VM or rather gracelessly
433 /// if the allocation is made by some native component.
434 ///
435 /// @see `Dart_TimelineGetMicros`
436 ///
437 /// @bug The `deadline` argument must be converted to `std::chrono`
438 /// instead of a raw integer.
439 ///
440 /// @param[in] deadline The deadline is used by the VM to determine if the
441 /// corresponding sweep can be performed within the deadline.
442 ///
443 /// @return If the idle notification was forwarded to the running isolate.
444 ///
445 virtual bool NotifyIdle(fml::TimeDelta deadline);
446
447 //----------------------------------------------------------------------------
448 /// @brief Returns if the root isolate is running. The isolate must be
449 /// transitioned to the running phase manually. The isolate can
450 /// stop running if it terminates execution on its own.
451 ///
452 /// @return True if root isolate running, False otherwise.
453 ///
454 virtual bool IsRootIsolateRunning() const;
455
456 //----------------------------------------------------------------------------
457 /// @brief Dispatch the specified platform message to running root
458 /// isolate.
459 ///
460 /// @param[in] message The message to dispatch to the isolate.
461 ///
462 /// @return If the message was dispatched to the running root isolate.
463 /// This may fail is an isolate is not running.
464 ///
465 virtual bool DispatchPlatformMessage(
466 std::unique_ptr<PlatformMessage> message);
467
468 //----------------------------------------------------------------------------
469 /// @brief Dispatch the specified pointer data message to the running
470 /// root isolate.
471 ///
472 /// @param[in] packet The pointer data message to dispatch to the isolate.
473 ///
474 /// @return If the pointer data message was dispatched. This may fail is
475 /// an isolate is not running.
476 ///
478
479 //----------------------------------------------------------------------------
480 /// @brief Dispatch the semantics action to the specified accessibility
481 /// node.
482 ///
483 /// @param[in] view_id The identifier of the view.
484 /// @param[in] node_id The identifier of the accessibility node.
485 /// @param[in] action The semantics action to perform on the specified
486 /// accessibility node.
487 /// @param[in] args Optional data that applies to the specified action.
488 ///
489 /// @return If the semantics action was dispatched. This may fail if an
490 /// isolate is not running.
491 ///
492 bool DispatchSemanticsAction(int64_t view_id,
493 int32_t node_id,
496
497 //----------------------------------------------------------------------------
498 /// @brief Gets the main port identifier of the root isolate.
499 ///
500 /// @return The main port identifier. If no root isolate is running,
501 /// returns `ILLEGAL_PORT`.
502 ///
503 Dart_Port GetMainPort();
504
505 //----------------------------------------------------------------------------
506 /// @brief Gets the debug name of the root isolate. But default, the
507 /// debug name of the isolate is derived from its advisory script
508 /// URI, advisory main entrypoint and its main port name. For
509 /// example, "main.dart$main-1234" where the script URI is
510 /// "main.dart", the entrypoint is "main" and the port name
511 /// "1234". Once launched, the isolate may re-christen itself
512 /// using a name it selects via `setIsolateDebugName` in
513 /// `window.dart`. This name is purely advisory and only used by
514 /// instrumentation and reporting purposes.
515 ///
516 /// @return The debug name of the root isolate.
517 ///
518 std::string GetIsolateName();
519
520 //----------------------------------------------------------------------------
521 /// @brief Returns if the root isolate has any live receive ports.
522 ///
523 /// @return True if there are live receive ports, False otherwise. Return
524 /// False if the root isolate is not running as well.
525 ///
526 bool HasLivePorts();
527
528 //----------------------------------------------------------------------------
529 /// @brief Returns if the root isolate has any pending microtasks.
530 ///
531 /// @return True if there are microtasks that have been queued but not
532 /// run, False otherwise. Return False if the root isolate is not
533 /// running as well.
534 ///
536
537 //----------------------------------------------------------------------------
538 /// @brief Get the last error encountered by the microtask queue.
539 ///
540 /// @return The last error encountered by the microtask queue.
541 ///
543
544 //----------------------------------------------------------------------------
545 /// @brief Get the service ID of the root isolate if the root isolate is
546 /// running.
547 ///
548 /// @return The root isolate service id.
549 ///
550 std::optional<std::string> GetRootIsolateServiceID() const;
551
552 //----------------------------------------------------------------------------
553 /// @brief Get the return code specified by the root isolate (if one is
554 /// present).
555 ///
556 /// @return The root isolate return code if the isolate has specified one.
557 ///
558 std::optional<uint32_t> GetRootIsolateReturnCode();
559
560 //----------------------------------------------------------------------------
561 /// @brief Get an identifier that represents the Dart isolate group the
562 /// root isolate is in.
563 ///
564 /// @return The root isolate group identifier, zero if one can't
565 /// be established.
566 uint64_t GetRootIsolateGroup() const;
567
568 //--------------------------------------------------------------------------
569 /// @brief Loads the Dart shared library into the Dart VM. When the
570 /// Dart library is loaded successfully, the Dart future
571 /// returned by the originating loadLibrary() call completes.
572 ///
573 /// The Dart compiler may generate separate shared libraries
574 /// files called 'loading units' when libraries are imported
575 /// as deferred. Each of these shared libraries are identified
576 /// by a unique loading unit id. Callers should open and resolve
577 /// a SymbolMapping from the shared library. The Mappings should
578 /// be moved into this method, as ownership will be assumed by the
579 /// dart root isolate after successful loading and released after
580 /// shutdown of the root isolate. The loading unit may not be
581 /// used after isolate shutdown. If loading fails, the mappings
582 /// will be released.
583 ///
584 /// This method is paired with a RequestDartDeferredLibrary
585 /// invocation that provides the embedder with the loading unit id
586 /// of the deferred library to load.
587 ///
588 ///
589 /// @param[in] loading_unit_id The unique id of the deferred library's
590 /// loading unit, as passed in by
591 /// RequestDartDeferredLibrary.
592 ///
593 /// @param[in] snapshot_data Dart snapshot data of the loading unit's
594 /// shared library.
595 ///
596 /// @param[in] snapshot_data Dart snapshot instructions of the loading
597 /// unit's shared library.
598 ///
600 intptr_t loading_unit_id,
601 std::unique_ptr<const fml::Mapping> snapshot_data,
602 std::unique_ptr<const fml::Mapping> snapshot_instructions);
603
604 //--------------------------------------------------------------------------
605 /// @brief Indicates to the dart VM that the request to load a deferred
606 /// library with the specified loading unit id has failed.
607 ///
608 /// The dart future returned by the initiating loadLibrary() call
609 /// will complete with an error.
610 ///
611 /// @param[in] loading_unit_id The unique id of the deferred library's
612 /// loading unit, as passed in by
613 /// RequestDartDeferredLibrary.
614 ///
615 /// @param[in] error_message The error message that will appear in the
616 /// dart Future.
617 ///
618 /// @param[in] transient A transient error is a failure due to
619 /// temporary conditions such as no network.
620 /// Transient errors allow the dart VM to
621 /// re-request the same deferred library and
622 /// loading_unit_id again. Non-transient
623 /// errors are permanent and attempts to
624 /// re-request the library will instantly
625 /// complete with an error.
626 virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id,
627 const std::string error_message,
628 bool transient);
629
630 // |PlatformConfigurationClient|
631 void RequestDartDeferredLibrary(intptr_t loading_unit_id) override;
632
633 // |PlatformConfigurationClient|
634 std::shared_ptr<const fml::Mapping> GetPersistentIsolateData() override;
635
636 // |PlatformConfigurationClient|
637 void UpdateSemantics(int64_t view_id, SemanticsUpdate* update) override;
638
639 // |PlatformConfigurationClient|
640 void SetApplicationLocale(std::string locale) override;
641
642 // |PlatformConfigurationClient|
643 void SetSemanticsTreeEnabled(bool enabled) override;
644
646 return context_.io_manager;
647 }
648
649 virtual DartVM* GetDartVM() const { return vm_; }
650
652 return isolate_snapshot_;
653 }
654
655 const PlatformData& GetPlatformData() const { return platform_data_; }
656
658 return context_.unref_queue;
659 }
660
665
666 std::weak_ptr<const DartIsolate> GetRootIsolate() const {
667 return root_isolate_;
668 }
669
671 if (auto isolate = root_isolate_.lock()) {
672 isolate->FlushMicrotasksNow();
673 }
674 }
675
676 std::shared_ptr<PlatformIsolateManager> GetPlatformIsolateManager() override {
677 return platform_isolate_manager_;
678 }
679
681
682 //--------------------------------------------------------------------------
683 /// @brief Shuts down all registered platform isolates. Must be called
684 /// from the platform thread.
685 ///
687
688 protected:
689 /// Constructor for Mocks.
690 RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners);
691
692 private:
693 struct Locale {
694 Locale(std::string language_code_,
695 std::string country_code_,
696 std::string script_code_,
697 std::string variant_code_);
698
699 ~Locale();
700
701 std::string language_code;
702 std::string country_code;
703 std::string script_code;
704 std::string variant_code;
705 };
706
707 RuntimeDelegate& client_;
708 DartVM* const vm_;
709 fml::RefPtr<const DartSnapshot> isolate_snapshot_;
710 std::function<void(int64_t)> idle_notification_callback_;
711 PlatformData platform_data_;
712 std::weak_ptr<DartIsolate> root_isolate_;
713 std::weak_ptr<DartIsolate> spawning_isolate_;
714 std::optional<uint32_t> root_isolate_return_code_;
715 const fml::closure isolate_create_callback_;
716 const fml::closure isolate_shutdown_callback_;
717 std::shared_ptr<const fml::Mapping> persistent_isolate_data_;
718 UIDartState::Context context_;
719 PointerDataPacketConverter pointer_data_packet_converter_;
720 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager_ =
721 std::shared_ptr<PlatformIsolateManager>(new PlatformIsolateManager());
722 bool has_flushed_runtime_state_ = false;
723
724 // Callbacks when `AddView` was called before the Dart isolate is launched.
725 //
726 // These views will be added when `FlushRuntimeStateToIsolate` is called.
727 // This is no longer used once the Dart isolate starts.
728 std::unordered_map<int64_t, AddViewCallback> pending_add_view_callbacks_;
729
730 // Tracks the views that have been called `Render` during a frame.
731 //
732 // If all views that have been registered by `AddView` have been called
733 // `Render`, then the runtime controller notifies the client of the end of
734 // frame immediately, allowing the client to submit the views to the pipeline
735 // a bit earlier than having to wait for the end of `BeginFrame`. See also
736 // `Animator::OnAllViewsRendered`.
737 //
738 // This mechanism fixes https://github.com/flutter/flutter/issues/144584 with
739 // option 2 and
740 // https://github.com/flutter/engine/pull/51186#issuecomment-1977820525 with
741 // option a in most cases, except if there are multiple views and only part of
742 // them are rendered.
743 // TODO(dkwingsmt): Fix these problems for all cases.
744 std::unordered_set<uint64_t> rendered_views_during_frame_;
745
746 void MarkAsFrameBorder();
747
748 void CheckIfAllViewsRendered();
749
750 PlatformConfiguration* GetPlatformConfigurationIfAvailable();
751
752 bool FlushRuntimeStateToIsolate();
753
754 // |PointerDataPacketConverter::Delegate|
755 bool ViewExists(int64_t view_id) const override;
756
757 // |PlatformConfigurationClient|
758 std::string DefaultRouteName() override;
759
760 // |PlatformConfigurationClient|
761 void ScheduleFrame() override;
762
763 // |PlatformConfigurationClient|
764 void EndWarmUpFrame() override;
765
766 // |PlatformConfigurationClient|
767 void Render(int64_t view_id,
768 Scene* scene,
769 double width,
770 double height) override;
771
772 // |PlatformConfigurationClient|
773 void HandlePlatformMessage(std::unique_ptr<PlatformMessage> message) override;
774
775 // |PlatformConfigurationClient|
776 FontCollection& GetFontCollection() override;
777
778 // |PlatformConfigurationClient|
779 std::shared_ptr<AssetManager> GetAssetManager() override;
780
781 // |PlatformConfigurationClient|
782 void UpdateIsolateDescription(const std::string isolate_name,
783 int64_t isolate_port) override;
784
785 // |PlatformConfigurationClient|
786 void SetNeedsReportTimings(bool value) override;
787
788 // |PlatformConfigurationClient|
789 std::unique_ptr<std::vector<std::string>> ComputePlatformResolvedLocale(
790 const std::vector<std::string>& supported_locale_data) override;
791
792 // |PlatformConfigurationClient|
793 void SendChannelUpdate(std::string name, bool listening) override;
794
795 // |PlatformConfigurationClient|
796 double GetScaledFontSize(double unscaled_font_size,
797 int configuration_id) const override;
798
799 // |PlatformConfigurationClient|
800 void RequestViewFocusChange(const ViewFocusChangeRequest& request) override;
801
802 FML_DISALLOW_COPY_AND_ASSIGN(RuntimeController);
803};
804
805} // namespace flutter
806
807#endif // FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
Describes a running instance of the Dart VM. There may only be one running instance of the Dart VM in...
Definition dart_vm.h:61
A client interface that the RuntimeController uses to define handlers for PlatformConfiguration reque...
void AddView(int64_t view_id, const ViewportMetrics &view_metrics, AddViewCallback callback)
Notify the isolate that a new view is available.
bool SetAccessibilityFeatures(int32_t flags)
Forward the preference of accessibility features that must be enabled in the semantics tree to the ru...
void SetSemanticsTreeEnabled(bool enabled) override
Notifies whether Framework starts generating semantics tree.
Dart_Port GetMainPort()
Gets the main port identifier of the root isolate.
bool SetSemanticsEnabled(bool enabled)
Notifies the running isolate about whether the semantics tree should be generated or not....
bool SetViewportMetrics(int64_t view_id, const ViewportMetrics &metrics)
Forward the specified viewport metrics to the running isolate. If the isolate is not running,...
uint64_t GetRootIsolateGroup() const
Get an identifier that represents the Dart isolate group the root isolate is in.
virtual bool NotifyIdle(fml::TimeDelta deadline)
Notify the Dart VM that no frame workloads are expected on the UI task runner till the specified dead...
bool HasPendingMicrotasks()
Returns if the root isolate has any pending microtasks.
std::weak_ptr< const DartIsolate > GetRootIsolate() const
bool DispatchPointerDataPacket(const PointerDataPacket &packet)
Dispatch the specified pointer data message to the running root isolate.
bool SetInitialLifecycleState(const std::string &data)
Forward the initial lifecycle state data to the running isolate. If the isolate is not running,...
std::function< void(bool added)> AddViewCallback
std::shared_ptr< PlatformIsolateManager > GetPlatformIsolateManager() override
bool SetLocales(const std::vector< std::string > &locale_data)
Forward the specified locale data to the running isolate. If the isolate is not running,...
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override
Invoked when the Dart VM requests that a deferred library be loaded. Notifies the engine that the def...
bool SetDisplays(const std::vector< DisplayData > &displays)
Forward the specified display metrics to the running isolate. If the isolate is not running,...
bool HasLivePorts()
Returns if the root isolate has any live receive ports.
bool RemoveView(int64_t view_id)
Notify the isolate that a view is no longer available.
std::optional< std::string > GetRootIsolateServiceID() const
Get the service ID of the root isolate if the root isolate is running.
const fml::RefPtr< const DartSnapshot > & GetIsolateSnapshot() const
const PlatformData & GetPlatformData() const
virtual bool IsRootIsolateRunning() const
Returns if the root isolate is running. The isolate must be transitioned to the running phase manuall...
bool LaunchRootIsolate(const Settings &settings, const fml::closure &root_isolate_create_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration, std::shared_ptr< NativeAssetsManager > native_assets_manager, std::optional< int64_t > engine_id)
Launches the isolate using the window data associated with this runtime controller....
bool ReportTimings(std::vector< int64_t > timings)
Dart code cannot fully measure the time it takes for a specific frame to be rendered....
const fml::RefPtr< SkiaUnrefQueue > & GetSkiaUnrefQueue() const
const fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > & GetSnapshotDelegate() const
bool DispatchSemanticsAction(int64_t view_id, int32_t node_id, SemanticsAction action, fml::MallocMapping args)
Dispatch the semantics action to the specified accessibility node.
virtual bool DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Dispatch the specified platform message to running root isolate.
tonic::DartErrorHandleType GetLastError()
Get the last error encountered by the microtask queue.
bool SetUserSettingsData(const std::string &data)
Forward the user settings data to the running isolate. If the isolate is not running,...
void LoadDartDeferredLibrary(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully,...
std::unique_ptr< RuntimeController > Clone() const
Clone the runtime controller. Launching an isolate with a cloned runtime controller will use the same...
bool SendViewFocusEvent(const ViewFocusEvent &event)
Notify the isolate that the focus state of a native view has changed.
void ShutdownPlatformIsolates()
Shuts down all registered platform isolates. Must be called from the platform thread.
std::unique_ptr< RuntimeController > Spawn(RuntimeDelegate &p_client, const std::string &advisory_script_uri, const std::string &advisory_script_entrypoint, const std::function< void(int64_t)> &idle_notification_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, const std::shared_ptr< const fml::Mapping > &persistent_isolate_data, fml::WeakPtr< IOManager > io_manager, fml::TaskRunnerAffineWeakPtr< ImageDecoder > image_decoder, fml::TaskRunnerAffineWeakPtr< ImageGeneratorRegistry > image_generator_registry, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate) const
Create a RuntimeController that shares as many resources as possible with the calling RuntimeControll...
void UpdateSemantics(int64_t view_id, SemanticsUpdate *update) override
Receives an updated semantics tree from the Framework.
virtual DartVM * GetDartVM() const
bool BeginFrame(fml::TimePoint frame_time, uint64_t frame_number)
Notifies the running isolate that it should start generating a new frame.
std::optional< uint32_t > GetRootIsolateReturnCode()
Get the return code specified by the root isolate (if one is present).
std::shared_ptr< const fml::Mapping > GetPersistentIsolateData() override
The embedder can specify data that the isolate can request synchronously on launch....
const fml::WeakPtr< IOManager > & GetIOManager() const
virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient)
Indicates to the dart VM that the request to load a deferred library with the specified loading unit ...
void SetApplicationLocale(std::string locale) override
Framework sets the application locale.
std::string GetIsolateName()
Gets the debug name of the root isolate. But default, the debug name of the isolate is derived from i...
A Mapping like NonOwnedMapping, but uses Free as its release proc.
Definition mapping.h:144
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
std::function< void()> closure
Definition closure.h:14
DartErrorHandleType
Definition dart_error.h:67
std::vector< FlutterEngineDisplay > * displays
int32_t height
int32_t width
The subset of state which is owned by the shell or engine and passed through the RuntimeController in...
fml::RefPtr< SkiaUnrefQueue > unref_queue
fml::WeakPtr< IOManager > io_manager
The IO manager used by the isolate for asynchronous texture uploads.
fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate