This PR introduces a `NativeAssetsManifest.json` next to the `AssetManifest.json` and `FontManifest.json`. This removes the need for embedding the native assets mapping inside the kernel file and will enable decoupling native assets building and bundling from the kernel compilation in flutter tools. This will then allow us to remove dry-run from the build hook protocol.
(It also means all isolate groups will have the same native assets. However, since Flutter does not support `Isolate.spawnUri` from kernel files anyways, this is not a regression.)
This manifest is parsed eagerly on startup by the engine in a manner similar to how the font manifest is parsed. The manifest contents need to be available in the callback for resolving assets, which does not have access to the engine. Therefore the parsed manifest is `NativeAssetsManager` stored in the `IsolateGroupData`. The engine passes it in on isolate group creation, and the FFI callbacks access it from the isolate group data.
Issue:
* https://github.com/flutter/flutter/issues/154425
Related PRs:
* https://dart-review.googlesource.com/c/sdk/+/388161
Follow up work:
* This PR does not yet remove the engine callbacks registered via the dart_api that rely on kernel embedding. If we were to do that in this PR, it would require a manual roll of the engine into flutter/flutter with the PR that switches flutter_tools to emit the native assets manifest instead of embedding in kernel, and a manual roll into g3 to switch emitting a manifest instead of embedding in kernel. A TODO is left in the code for those callbacks to be removed.
## Testing
Most of this PR cannot be tested in isolation. The code in this PR is heavily exercised in the follow up flutter_tools PR which creates the `NativeAssetsManifest.json` and removes the embedding of native assets in kernel files.
* This PR adds a unit test for parsing the JSON manifest.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Flutter_tester has a task observer that checks whether the test's Dart code has finished execution. If Dart no longer has live ports but does have pending microtasks, then flutter_tester should continue running and force a drain of the microtask queue.
Fixes https://github.com/flutter/flutter/issues/158129
ui.Canvas and ui.SceneBuilder now use the DlPath object directly from the ui.Path object. This results in increased sharing of the wrapper objects which then increases the sharing of both the converted Impeller paths and Skia's volatile flag.
The VolatilePathTracker mechanism is deleted and rather than count the number of frames that a path is stable for, instead we count the number of times it is used for rendering. If a path is used 100 times in a single frame, it will become non-volatile and start being cached almost immediately. The cached Impeller paths are now also tracked for all instances of the same path, rather than for each call site that originated from a DisplayList dispatch.
This is a re-land of https://github.com/flutter/engine/pull/55006, except that we special case the navigation channel to immediately dispatch its message if the isolate is not yet running.
This preserves the existing behavior relied upon by several iOS add2app tests, as well as the still used embedder v1 - and potentially undicovered future embedders.
This is a refactor that moves the `PointerDataPacketConverter` from `PlatformView` to `RuntimeController`.
This change is made for the following reasons:
- Currently, the pointer data conversion contains no platform specific logic (because the current converter's only responsibility is to make the event sequence conform Flutter's protocol). Therefore these logics should reside in a platform-independent place.
- The converter typically converts one event to many. It's better to have this conversion later than earlier.
- It removes a member from `PlatformView`, making it closer to a pure virtual class.
The reason to choose `RuntimeController` as the destination is because `RuntimeController` manages a map for views, which is required for the converter to implement a later patch https://github.com/flutter/engine/pull/51925.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This is a prototype of the [PlatformIsolate
API](https://github.com/flutter/flutter/issues/136314).
**UPDATE (Jan 25):** The PR is ready for review. PTAL.
The `PlatformIsolate` creation flow is:
1. `PlatformIsolate.spawn` running on parent isolate
(platform_isolate.dart)
a. Create `isolateReadyPort`
b. `PlatformIsolateNativeApi::Spawn` (platform_isolate.cc)
c. `DartIsolate::CreatePlatformIsolate` (dart_isolate.cc)
d. Isolate created. Entry point invocation task dispatched to platform
thread
e. `PlatformIsolate.spawn` returns a `Future<Isolate>`
2. On the platform thread, `_platformIsolateMain` is invoked in the
platform isolate
a. Create `entryPointPort`
b. Send `Isolate.current` metadata and `entryPointPort` back to the
parent isolate via `isolateReadyPort`
3. Back in the parent isolate, `isolateReadyPort.handler` is invoked
a. Send the user's `entryPoint` and `message` to the platform isolate
via `entryPointPort`
b. Use received isolate metadata to create a new `Isolate` representing
the platform isolate and complete the `Future<Isolate>`
4. In the platform isolate, `entryPointPort.handler` is invoked
a. Run the user's `entryPoint(message)`
The engine shutdown flow is handled by `PlatformIsolateManager`, which
maintains a set of running platform isolates.
This reverts commit 87171e73397f7edfd4c145fbaebdd7208954debf.
Internal performance test shows that this PR negatively affects startup time. I'll reland this PR in parts.
b/307872797
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Towards https://github.com/flutter/flutter/issues/134501.
This PR makes the following changes to the public dart:ui API:
* It adds the `FlutterView.pysicalConstraints` property that describes max and min width and height for a view. The framework is allowed to size the `FlutterView` to any `Size` that meets these constraints.
* It adds an optional `size` argument to `FlutterView.render`. The framework provides the chosen `Size` that meets the aforementioned constraints to the `render` method. If the `FlutterView.pysicalConstraints` are tight (minHeight == maxHeight and minWidth == maxWidth) the argument is optional to remain backwards compatible. In all other cases, a `Size` must be provided.
* It adds a `ViewConstraints` class, which is basically the `dart:ui` version of `BoxConstraints` (This is similar to how we have `ViewPadding` in dart:ui to mirror `EdgeInsets` from the framework). It describes the constraints of a `FlutterView`, i.e. it powers the `FlutterView.pysicalConstraints` property.
This change does not wire anything up to the embedders. For now, `FlutterView.pysicalConstraints` just returns tight constraints for the embedder-provided size of the view (`FlutterView.physicalSize`) and the size provided to `FlutterView.render` is ignored (after it is checked that it meets the constrains).
This PR enables the framework to implement the new dynamic view sizing and embedders to separately expose the new functionality to their clients.
Presubmits will fail until https://github.com/flutter/flutter/pull/138565 is submitted to the framework.
**DO NOT SUBMIT until https://github.com/flutter/flutter/pull/138648 is ready.**
This PR relands https://github.com/flutter/engine/pull/44473.
The previous PR was immediately reverted after merging because we found that the PR could cause illegal renders to be skipped on debug builds but crash the app on release builds. This PR makes the `Animator::Render` skip illegal renders as well. This should not be the final shape of this feature, and thus a TODO is added.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Fixes https://github.com/flutter/flutter/issues/123307 - for Android, iOS, and Web, for the main display only (https://github.com/flutter/flutter/issues/125938 tracks supporting multiple displays, https://github.com/flutter/flutter/issues/125939 for desktop).
Desktop will need to be implemented for this, but given priority for a couple of our customers targetting foldable devices on Android I'm inclined to get this in before desktop can be finished.
The main concern for this right now is that on some Android foldable devices, setting a preferred orientation will cause letterboxing and the `MediaQuery` will _never_ get the full screen size when unfolded. This causes apps to think the screen is smaller than it is, as they've mainly been using `MediaQueryData.size` to figure this out. Android's recommendation is to not set a preferred orientation, and if you must to use the new method introduced in `ViewUtil.java` to calculate the maximal window size.
This introduces `PlatformDispatcher.implicitView`, a low-level primitive for the framework's bootstrapping. Most code, including the framework after bootstrapping, will use `View.of(context)` instead of this new API. This new primitive will let us deprecate the `window` global.
Goals:
1. **Enable multi-window**. The `PlatformDispatcher.implicitView` is nullable. If `null`, the app must create a window to get a view it can draw into.
2. **Backwards compatibility**. For "single window" apps, `PlatformDispatcher.instance.implicitView` should behave as similar to `window` as possible.
1. The `PlatformDispatcher.instance.implicitView.viewId` should be `0`.
1. The `PlatformDispatcher.instance.implicitView` must be available synchronously at root isolate startup. This allows the framework to determine if it can make single window assumptions at startup.
2. The `PlatformDispatcher.instance.implicitView` reference must not change after startup: if it is null at startup, it must always be null; if it is non-null at startup, it must always be non-null. If "single window" app enters headless mode, the implicit view must remain non-null.
In the future, the embedder will control whether an implicit view is created: mobile & legacy desktop apps will have an implicit view, multi-window desktop apps won't have an implicit view. This requires updating the engine's embedder API and is out-of-scope for this change. For now, all apps will have an implicit view.
Part of https://github.com/flutter/flutter/issues/120306
This patch also eliminates some extraneous tracing that is happening
every frame. It is possible to get the same trace calls by enabling
the API stream if needed.
Also refactors the NotifyIdle callsites to just always work in
TimeDeltas rather than converting back and forth between them and
TimePoints, which I think reads more clearly.
* Add calls to Dart_NotifyDestroyed when the flutter view is destroyed.
* Add unit test case.
* Format.
* Ensure the destroy task runs.
* Address code review comments.
This PR changes how embedder API's SendKeyData sends ui.KeyData to the framework. The packets are now sent over the existing platform messenger, reusing the entirety of its code path and functionalities while keeping the embedder API unchanged
Group together externally-managed UIDartState.
It's a frequent pattern to enable access to shell resources from the
framework via UIDartState. These handles are passed through several
other objects, where they lay mostly dormant. This refactor just aims
to ease maintenance of this state.
UIDartState is essentially just an easy to extend bus for dropping
off the shell kids in UIDartState, with constructors/operators that
remove the need for providing a full initializer lists in unittests.