This PR groups per-view information in `FlutterCompositor` into a private class, `ViewPresenter`. This makes it easier to manage per-view data and write view operations.
Part of https://github.com/flutter/flutter/issues/145874.
Currently, view presenters are never removed once created, since the macOS runner doesn't support removing views. This will be added in the future.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This PR connects the view ID provided by the rasterizer to `EmbedderExternalViewEmbedder`'s presenting call (see `embedder_external_view_embedder.cc`).
This PR also contains a refactor (which actually takes the majority of LOC) that moves the specification of view ID from `PrepareFlutterView` to `SubmitFlutterView`. The `flutter_view_id` parameter in `PrepareFlutterView` was added in https://github.com/flutter/engine/pull/46169. It turns out that we don't need the view ID throughout the preparation phase, so we can delay the specification to submission, which makes it feel cleaner.
### Tests
Existing tests are changed to verify that `SubmitFlutterView` receive the correct view ID.
The feature that `EmbedderExternalViewEmbedder` sends the view ID to the presenting API is not tested for now, because `EmbedderExternalViewEmbedder` is typically tested in `embedder_unittests`, but it requires the embedder API `AddView`. It will be tested in later changes to `EmbedderExternalViewEmbedder`.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
The previous PR https://github.com/flutter/flutter/issues/143420 rounds out the layers and rounds in the platform views. This results in missing pixel on the edge of the intersection when there's fractional coordinate (as shown in the screenshot below), because platform view is below the layers.
It turns out that we have to round out both platform view and layers, because:
- rounding in platform view rects will result in missing pixels on the edge of the intersection.
- rounding in layer rects will result in missing pixels on the edge of the layer that's on top of the platform view.
This PR simply skips the single (or partial) pixel on the edge, which is a special case, while still preserve the `roundOut` behavior for general non-edge cases.
Before the fix, notice a very thin gray line cutting through the purple box:
<img src="https://github.com/flutter/engine/assets/41930132/1482d81a-337e-4841-ac08-eff08bbc71ef" height="500">
Then after the fix, the gray line is gone:
<img src="https://github.com/flutter/engine/assets/41930132/0eddae69-ab62-4de6-8932-c67cc5aced73" height="500">
*List which issues are fixed by this PR. You must list at least one issue.*
https://github.com/flutter/flutter/issues/143420
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
No semantic changes, just consolidates static functions in FlutterViewController.mm local to the translation unit into a single contiguous block at the top.
Also includes three minor (non-semantic) changes:
* Corrects static function naming to UpperCamelCase
* Adds doc comments for `OnKeyboardLayoutChanged`
* Adds a mark to help highlight the static data/function block at the top of the file in Xcode.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This doesn't actually seem to be helping. For the most part, the frame time of the banners is steady with occassional spikes. Adding the framerate cap doesn't help the spikes, since those are in the 30+ ms frame time, and just results in everything else looking janky as well (especially if we dance around the cap, then we go 120 - 80)
Since this is based on an arbitrary number, from an arbitrary app, on an arbitrary point in time we should remove it and instead try to fix the performance problems
Address the performance of platform view due to an extra overlay. This overlay was added due to the following rounding problem:
> For example, if we interleave flutter widget and platform view in a list, and let's say we have a flutter widget (top = 0, bottom = 100.1), and a platform view below that widget (top = 100.1, bottom = 200). They are NOT supposed to be overlapping. However, after rounding out, we will get flutter widget (top = 0, bottom = 101), and platform view (top = 100, bottom 200). This will result in 1 pixel overlap as long as there's a floating point in the coord.
(Quote myself from the discussion below).
*List which issues are fixed by this PR. You must list at least one issue.*
Fixes https://github.com/flutter/flutter/issues/143420
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Creates and adds FlutterMacOS.xcframework to out/mac or out/host.
Creates and archives FlutterMacOS.xcframework when building mac_host_engine. Archives the xcframework in a new zipped folder at `darwin-x64/framework.zip`, `darwin-x64-profile/framework.zip`, `darwin-x64-release/framework.zip`.
The FlutterMacOS.framework is also still archived currently - I thought it'd be better to keep it archived so we don't have to worry about the tool breaking until we're ready to remove it.
Part of https://github.com/flutter/flutter/issues/126016.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This PR changes the format check on CI to use the command added in
https://github.com/flutter/engine/pull/50747.
Additionally, while making this change, I noticed that the CI check was
not checking the formatting of all files, and that as a result, files
were present in the repo with incorrect formatting. I have fixed the
formatting and fixed the check to always check all files.
Fixes https://github.com/flutter/flutter/issues/142488
- Only logs on iOS if Skia is used instead of Impeller.
- Logs on other platforms if Impeller is used instead of Skia.
- Uses "IMPORTANT" rather than "ERROR" for these logs. This will show up by default since flutter_tools sets ERROR and above as logs to show.
- Adds some tests.
- Makes INFO log print file paths the same as other verbosities.
Generated by https://github.com/flutter/engine/pull/48903 (`dart ./tools/header_guard_check/bin/main.dart --fix`).
As discussed with @cbracken and @jmagman, the guards are not technically needed on the Mac/iOS code, but they (a) do not hurt and (b) still provide value if for some reason `#include` is used instead of `#import` (though I suspect we could try to add that to the tool in the future as well).
Fixes https://github.com/flutter/flutter/issues/141571
Shell::Screenshot was impelemnted in a Skia-only way and would crash when invoked. Adds test coverage for the breaking path on iOS that ends up calling `FlutterView drawLayer`.
The AppKit state machine was not well understood before. Sometimes the engine would leave orphan PanZoomStart after a certain sequences including NSEventPhaseMayBegin
Now track each gesture's specific phase instead of boolean true/false which doesn't really accurately represent the system state.
Fixes https://github.com/flutter/flutter/issues/140730
FIxes https://github.com/flutter/flutter/issues/136622
We are embedding Flutter into MacOS app, and noticed that there is a
leak. `leaks` tool says there is a cycle reference:
```
12 (2.11K) ROOT CYCLE: <FlutterKeyboardManager 0x29ec55f40> [80]
8 (432 bytes) __strong _primaryResponders --> ROOT CYCLE: <NSMutableArray 0x29ec560a0> [64]
7 (368 bytes) ROOT CYCLE: <NSMutableArray (Storage) 0x29ec56140> [32]
4 (224 bytes) ROOT CYCLE: <FlutterEmbedderKeyResponder 0x29ec56310> [80]
1 (48 bytes) __strong _sendEvent --> ROOT CYCLE: <__NSMallocBlock__ 0x29ec56360> [48]
__strong [capture] --> CYCLE BACK TO <FlutterKeyboardManager 0x29ec55f40> [80]
1 (48 bytes) __strong _pendingResponses --> <NSMutableDictionary 0x29ec563c0> [48]
1 (48 bytes) __strong _pressingRecords --> <NSMutableDictionary 0x29ec56390> [48]
2 (112 bytes) <FlutterChannelKeyResponder 0x29ec56450> [48]
1 (64 bytes) __strong _channel --> <FlutterBasicMessageChannel 0x29ec564e0> [64]
2 (1.55K) __strong _layoutMap --> <NSMutableDictionary 0x29ec56630> [48]
1 (1.50K) <NSMutableDictionary (Storage) 0x123c34a00> [1536]
1 (64 bytes) __strong _pendingEvents --> <NSMutableArray 0x29ec565f0> [64]
```
This patch uses `weak` pointer to `self` instead of implicit `strong`.
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I added new tests to check the change I am making or feature I am
adding, or the PR is [test-exempt]. See [testing the engine] for
instructions on writing and running engine tests.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [x] All existing and new tests are passing.
We're on a version of clang that crashes a lot on macOS. This PR rolls
clang forward to a new release from the Fuchsia toolchain team. If it
does not fix the crash, we can roll back with
https://github.com/flutter/engine/pull/49249. Both rolling forward and
back require the fixes to the `.mm` file in this PR.
This PR implements `FlutterMetalLayer`, a drop-in (as far as Flutter is
concerned) replacement for `CAMetalLayer`. The biggest difference is
that `FlutterMetalLayer` can present frames from background thread
within a `CATransaction`.
`FlutterMetalLayer` is disabled by default. To opt-in, add the following
item to `Info.plist`:
```xml
<key>FLTUseFlutterMetalLayer</key>
<true/>
```
The performance seems quite good, consistent 120hz on iPhone 13 Pro.
Benefits
- presenting with transaction from background thread, which, down the
line, would allow for platform views without thread merging.
- fine control over how the surface is displayed - we can display single
surface on multiple `CALayers`, each showing different part, allowing
for performant implementation of unobstructed platform views.
Drawbacks
- this not being a metal layer makes working with metal instrument tools
more awkward
Create a `PrivacyInfo.xcprivacy` (this name is required) plist and move it to the top-level of the iOS framework bundle. `NSPrivacyTracking*` and `NSPrivacyCollectedDataTypes` keys are required, but the values are blank.
Apple [now requires](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files) that third-party frameworks must include this manifest to document usage of particular APIs and [how they are used](https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api).
> Starting in fall 2023, when you upload a new app or app update to App Store Connect that uses an API (including from third-party SDKs) that requires a reason, youâll receive a notice if you havenât provided an approved reason in your appâs privacy manifest. And starting in spring 2024, in order to upload your new app or app update to App Store Connect, youâll be required to include an approved reason in the appâs privacy manifest which accurately reflects how your app uses the API.
https://developer.apple.com/news/?id=z6fu1dcu
@stuartmorgan [audited](https://github.com/flutter/flutter/issues/131494#issuecomment-1852718759) the engine and third_party:
> * File timestamps:
>
> * `C617.1` for app state restoration in `FlutterAppDelegate.mm`.
> * `0A2A.1` for implementation of the relevant `File` wrappers.
> * System boot time:
>
> * `35F9.1` for various event timing and elapsed time calculations.
Note macOS frameworks do not need to declare `NSPrivacyAccessedAPITypes`.
I don't think this will require recipe or conductor codesign changes since this is a file copied as a resource into the framework, just as the modulemap and Info.plist aren't referenced anywhere.
I'm not quite sure how to test this other than letting it build and generate a `Generate Privacy Report` in a Flutter app in Xcode. There's no where we check that, say, the Info.plist is copied to the right place in Flutter.framework (even in flutter/flutter). When this rolls into the framework I will add a check to [ios_content_validation_test.dart](3da9bc1698/dev/devicelab/bin/tasks/ios_content_validation_test.dart)
On this PR the `PrivacyInfo.xcprivacy` was written to the expected location in the Flutter.framework:
d45cd08094/516/tree
Fixes https://github.com/flutter/flutter/issues/131494
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style