-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Connect the FlutterEngine to the FlutterSceneDelegate #174910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
||
| FLUTTER_ASSERT_ARC | ||
|
|
||
| @interface FlutterSceneDelegate () <FlutterSceneLifeCycleProvider> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FlutterSceneLifeCycleProvider is a private protocol for now, but will later become public. It's purpose is to allow add-to-app developers who can't adopt the FlutterSceneDelegate to still be able to use plugin scene lifecycle events.
See app equivalent for example of future use case: https://docs.flutter.dev/add-to-app/ios/add-flutter-screen#if-you-cant-directly-make-flutterappdelegate-a-subclass
|
|
||
| - (instancetype)init { | ||
| if (self = [super init]) { | ||
| _sceneLifeCycleDelegate = [[FlutterPluginSceneLifeCycleDelegate alloc] init]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than storing the engines directly in the FlutterSceneDelegate, we store them in a FlutterPluginSceneLifeCycleDelegate object,
This is to handle the add-to-app case when they can't adopt the FlutterSceneDelegate. This way when the FlutterViewController connects, it can use the FlutterSceneLifeCycleProvider to access the FlutterPluginSceneLifeCycleDelegate to store the engines.
See app equivalent for example of future use case: https://docs.flutter.dev/add-to-app/ios/add-flutter-screen#if-you-cant-directly-make-flutterappdelegate-a-subclass
| #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifecycle.h" | ||
| #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" | ||
|
|
||
| FLUTTER_ASSERT_ARC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought there was no MRC code left in the ios embedder so we don't need this any more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that any builds that use the flutter_cflags_objc config should have ARC enabled, but that's not very clear from a glance. If someone were to add a new target or edit the configs, they may not know they need to do that. Due to that, I think it's safer to keep using FLUTTER_ASSERT_ARC.
flutter/engine/src/flutter/common/config.gni
Lines 71 to 75 in e25651b
| flutter_cflags_objc = [ | |
| "-Werror=overriding-method-mismatch", | |
| "-Werror=undeclared-selector", | |
| "-fobjc-arc", | |
| ] |
flutter/engine/src/flutter/shell/platform/darwin/ios/BUILD.gn
Lines 62 to 210 in e25651b
| source_set("flutter_framework_source") { | |
| visibility = [ ":*" ] | |
| cflags_objc = flutter_cflags_objc | |
| cflags_objcc = flutter_cflags_objcc | |
| defines = [ "FLUTTER_FRAMEWORK=1" ] | |
| public_configs = [ | |
| ":ios_gpu_configuration_config", | |
| "//flutter:config", | |
| ] | |
| configs += [ | |
| "//flutter/shell/platform/darwin/common:config", | |
| "//build/config/ios:ios_application_extension", | |
| ] | |
| sources = [ | |
| "framework/Source/FlutterAppDelegate.mm", | |
| "framework/Source/FlutterAppDelegate_Internal.h", | |
| "framework/Source/FlutterCallbackCache.mm", | |
| "framework/Source/FlutterCallbackCache_Internal.h", | |
| "framework/Source/FlutterChannelKeyResponder.h", | |
| "framework/Source/FlutterChannelKeyResponder.mm", | |
| "framework/Source/FlutterDartProject.mm", | |
| "framework/Source/FlutterDartProject_Internal.h", | |
| "framework/Source/FlutterDartVMServicePublisher.h", | |
| "framework/Source/FlutterDartVMServicePublisher.mm", | |
| "framework/Source/FlutterEmbedderKeyResponder.h", | |
| "framework/Source/FlutterEmbedderKeyResponder.mm", | |
| "framework/Source/FlutterEngine.mm", | |
| "framework/Source/FlutterEngineGroup.mm", | |
| "framework/Source/FlutterEngine_Internal.h", | |
| "framework/Source/FlutterHeadlessDartRunner.mm", | |
| "framework/Source/FlutterKeyPrimaryResponder.h", | |
| "framework/Source/FlutterKeySecondaryResponder.h", | |
| "framework/Source/FlutterKeyboardManager.h", | |
| "framework/Source/FlutterKeyboardManager.mm", | |
| "framework/Source/FlutterLaunchEngine.h", | |
| "framework/Source/FlutterLaunchEngine.m", | |
| "framework/Source/FlutterMetalLayer.h", | |
| "framework/Source/FlutterMetalLayer.mm", | |
| "framework/Source/FlutterOverlayView.h", | |
| "framework/Source/FlutterOverlayView.mm", | |
| "framework/Source/FlutterPlatformPlugin.h", | |
| "framework/Source/FlutterPlatformPlugin.mm", | |
| "framework/Source/FlutterPlatformViews.mm", | |
| "framework/Source/FlutterPlatformViewsController.h", | |
| "framework/Source/FlutterPlatformViewsController.mm", | |
| "framework/Source/FlutterPlatformViews_Internal.h", | |
| "framework/Source/FlutterPluginAppLifeCycleDelegate.mm", | |
| "framework/Source/FlutterRestorationPlugin.h", | |
| "framework/Source/FlutterRestorationPlugin.mm", | |
| "framework/Source/FlutterSceneDelegate.m", | |
| "framework/Source/FlutterSemanticsScrollView.h", | |
| "framework/Source/FlutterSemanticsScrollView.mm", | |
| "framework/Source/FlutterSharedApplication.h", | |
| "framework/Source/FlutterSharedApplication.mm", | |
| "framework/Source/FlutterSpellCheckPlugin.h", | |
| "framework/Source/FlutterSpellCheckPlugin.mm", | |
| "framework/Source/FlutterTextInputDelegate.h", | |
| "framework/Source/FlutterTextInputPlugin.h", | |
| "framework/Source/FlutterTextInputPlugin.mm", | |
| "framework/Source/FlutterTextureRegistryRelay.h", | |
| "framework/Source/FlutterTextureRegistryRelay.mm", | |
| "framework/Source/FlutterUndoManagerDelegate.h", | |
| "framework/Source/FlutterUndoManagerPlugin.h", | |
| "framework/Source/FlutterUndoManagerPlugin.mm", | |
| "framework/Source/FlutterView.h", | |
| "framework/Source/FlutterView.mm", | |
| "framework/Source/FlutterViewController.mm", | |
| "framework/Source/FlutterViewController_Internal.h", | |
| "framework/Source/FlutterViewResponder.h", | |
| "framework/Source/KeyCodeMap.g.mm", | |
| "framework/Source/KeyCodeMap_Internal.h", | |
| "framework/Source/SemanticsObject+UIFocusSystem.mm", | |
| "framework/Source/SemanticsObject.h", | |
| "framework/Source/SemanticsObject.mm", | |
| "framework/Source/TextInputSemanticsObject.h", | |
| "framework/Source/TextInputSemanticsObject.mm", | |
| "framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h", | |
| "framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.mm", | |
| "framework/Source/accessibility_bridge.h", | |
| "framework/Source/accessibility_bridge.mm", | |
| "framework/Source/overlay_layer_pool.h", | |
| "framework/Source/overlay_layer_pool.mm", | |
| "framework/Source/platform_message_response_darwin.h", | |
| "framework/Source/platform_message_response_darwin.mm", | |
| "framework/Source/profiler_metrics_ios.h", | |
| "framework/Source/profiler_metrics_ios.mm", | |
| "framework/Source/vsync_waiter_ios.h", | |
| "framework/Source/vsync_waiter_ios.mm", | |
| "ios_context.h", | |
| "ios_context.mm", | |
| "ios_context_metal_impeller.h", | |
| "ios_context_metal_impeller.mm", | |
| "ios_context_noop.h", | |
| "ios_context_noop.mm", | |
| "ios_external_texture_metal.h", | |
| "ios_external_texture_metal.mm", | |
| "ios_external_view_embedder.h", | |
| "ios_external_view_embedder.mm", | |
| "ios_surface.h", | |
| "ios_surface.mm", | |
| "ios_surface_metal_impeller.h", | |
| "ios_surface_metal_impeller.mm", | |
| "ios_surface_noop.h", | |
| "ios_surface_noop.mm", | |
| "platform_message_handler_ios.h", | |
| "platform_message_handler_ios.mm", | |
| "platform_view_ios.h", | |
| "platform_view_ios.mm", | |
| "rendering_api_selection.h", | |
| "rendering_api_selection.mm", | |
| ] | |
| sources += _flutter_framework_headers | |
| frameworks = [ | |
| "AudioToolbox.framework", | |
| "CoreMedia.framework", | |
| "CoreVideo.framework", | |
| "IOSurface.framework", | |
| "QuartzCore.framework", | |
| "WebKit.framework", | |
| "UIKit.framework", | |
| ] | |
| if (flutter_runtime_mode == "profile" || flutter_runtime_mode == "debug") { | |
| # This is required by the profiler_metrics_ios.mm to get GPU statistics. | |
| # Usage in release builds will cause rejection from the App Store. | |
| frameworks += [ "IOKit.framework" ] | |
| } | |
| deps = [ | |
| ":ios_gpu_configuration", | |
| "//flutter/common:common", | |
| "//flutter/common/graphics", | |
| "//flutter/fml", | |
| "//flutter/lib/ui", | |
| "//flutter/runtime", | |
| "//flutter/shell/common", | |
| "//flutter/shell/platform/common:common_cpp_input", | |
| "//flutter/shell/platform/darwin/common", | |
| "//flutter/shell/platform/darwin/common:framework_common", | |
| "//flutter/shell/platform/darwin/graphics", | |
| "//flutter/shell/platform/embedder:embedder_as_internal_library", | |
| "//flutter/shell/profiling:profiling", | |
| "//flutter/third_party/icu", | |
| "//flutter/third_party/spring_animation", | |
| ] | |
| public_deps = [ ":InternalFlutterSwift" ] | |
| } |
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifecycle.mm
Outdated
Show resolved
Hide resolved
| - (void)viewIsAppearing:(BOOL)animated { | ||
| TRACE_EVENT0("flutter", "viewIsAppearing"); | ||
| if (self.engine.viewController == self) { | ||
| // The earliest the view can access the scene is in viewIsAppearing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the UIWindowScene first becomes accessible to the view in [UIView didMoveToWindow] (when establishing the view hierarchy. UIWindow's initializer takes a UIWindowScene), and viewIsAppearing is called by the layout process so it's a bit later than that:
* frame #0: 0x000000018545a010 UIKitCore`-[UIViewController viewIsAppearing:]
frame #1: 0x0000000185449ab8 UIKitCore`-[UIViewController __viewIsAppearing:skipWindowCheck:] + 188
frame #2: 0x0000000186142cd4 UIKitCore`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1072
Not sure if that makes a difference tho.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The windowScene property is not readonly I guess that means a UIWindow can be moved to a different scene while the app is running? I think that is something that can happen in an add-to-app scenario? Also the viewController associated with the engine can be changed too (https://api.flutter.dev/ios-embedder/interface_flutter_engine.html#a9247723288f07f7f7cc6d85fb701fbdc), so the engine pointers associated with a scene may also need to be updated on those events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that the engine instance associated with a FlutterViewController can change, would it be better to change the addViewController API (currently private) to addEngine, also do we need a deleteEngine method if, say, two FlutterViewControllers with different UIWindowScenes can swap their engines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great feedback! Thanks for letting me know about didMoveToWindow, I didn't know about that!
In regards to the viewController moving engines - this will be handled by moving to didMoveToWindow actually! I also added a removeFlutterEngine method.
In regards to UIWindow moving scenes, there doesn't appear to be an API to detect when this happens. I added a comment with more of a explanation here:
flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifecycle.mm
Lines 66 to 74 in bab8f25
| // There aren't any events that inform us when a UIWindow changes scenes. | |
| // If a developer moves an entire UIWindow to a different scene and that window has a | |
| // FlutterView inside of it, its engine will still be in its original scene's | |
| // FlutterPluginSceneLifeCycleDelegate. The best we can do is move the engine to the correct | |
| // scene here. Due to this, when moving a UIWindow from one scene to another, its first scene | |
| // event may be lost. Since Flutter does not fully support multi-scene and this is an edge | |
| // case, this is a loss we can deal with. To workaround this, the developer can move the | |
| // UIView instead of the UIWindow, which will use willMoveToWindow to add/remove the engine from | |
| // the scene. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah the -[UIWindow setWindowScene:] setter posts a _UIWindow{Will, Did}MoveToSceneNotification notification and calls -[UIWindow _didMoveFromScene:toScene:] :(
The addFlutterEngine and removeFlutterEngine API won't be visible to app developers so they can't call these APIs in UIWindow.windowScene.didSet to manage the scene->engine mapping themselves right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
addFlutterEngineandremoveFlutterEngineAPI won't be visible to app developers so they can't call these APIs inUIWindow.windowScene.didSetto manage the scene->engine mapping themselves right?
Correct, these are private APIs
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm
Outdated
Show resolved
Hide resolved
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm
Outdated
Show resolved
Hide resolved
engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm
Outdated
Show resolved
Hide resolved
| } | ||
| } | ||
|
|
||
| - (void)updateEnginesInScene:(UIScene*)scene { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this is being called anywhere. Is this for future-use only or this should be called in the engines getter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for future-use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation LGTM.
However given the potential caveat (it looks like we can't reliably maintain the scene -> engine mapping since currently the window did change scene notification is private), I think it would probably be better if we keep week refs to all engines in an application instead, and determine which scene each engine belongs to when dispatching lifecycle event callbacks? It will be slower since lifecycle event dispatching is much more frequent than window changing scenes but realistically people probably won't have 1000 engines in the same app such that the performance difference becomes noticeable.
Please see my comment: flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifecycle.mm Lines 66 to 74 in bd8c4a5
I think this is an acceptable limitation for now, given that we don't explicitly support multi-scene.
Unfortunately, we can't rely on the application singleton to be available. For example, in iOS app extensions, the application is not accessible. |
Ah interesting. But even without access to an UIApplication instance, we can still use a class/global variable I think? We might need to create a global list of engines for proposal 2 in #174400 so I guess we'll come back and visit this later since everything is implementation details for now. EDIT: oh you did mention in that issue:
|
Roll Flutter from 8f94cb0d8f01 to 9ff2767f3cb6 (56 revisions) flutter/flutter@8f94cb0...9ff2767 2025-09-20 [email protected] Roll Fuchsia Linux SDK from 0_jKqLGnkILvQ5C8a... to CcCe3HpQtBYhTZscb... (flutter/flutter#175698) 2025-09-20 [email protected] Roll Dart SDK from e6e9248aee4f to 9e943fe076c8 (1 revision) (flutter/flutter#175697) 2025-09-20 [email protected] Add `menuController` to `DropdownMenu` (flutter/flutter#175039) 2025-09-20 [email protected] Roll Skia from 1dae085e2f31 to a38a531dec1d (3 revisions) (flutter/flutter#175694) 2025-09-20 [email protected] [a11y] TimePicker clock is unnecessarily announced (flutter/flutter#175570) 2025-09-20 [email protected] Roll Dart SDK from 78e68d1a7dbf to e6e9248aee4f (4 revisions) (flutter/flutter#175690) 2025-09-19 [email protected] Roll Skia from b56003bf2c20 to 1dae085e2f31 (1 revision) (flutter/flutter#175674) 2025-09-19 [email protected] Update `CODEOWNERS` (for dev-tooling) (flutter/flutter#175201) 2025-09-19 [email protected] [a11y-app] Add label to TextFormField in AutoCompleteUseCase. (flutter/flutter#175576) 2025-09-19 [email protected] Fix RadioGroup single selection check. (flutter/flutter#175654) 2025-09-19 [email protected] Roll Packages from f2a65fd to 3d5c419 (2 revisions) (flutter/flutter#175668) 2025-09-19 [email protected] Roll Skia from c74d2bdbd93c to b56003bf2c20 (2 revisions) (flutter/flutter#175665) 2025-09-19 [email protected] Add `CupertinoLinearActivityIndicator` (flutter/flutter#170108) 2025-09-19 [email protected] [ Widget Preview ] Don't update filtered preview set when selecting non-source files (flutter/flutter#175596) 2025-09-19 [email protected] Roll Dart SDK from 2c79803c97db to 78e68d1a7dbf (3 revisions) (flutter/flutter#175646) 2025-09-19 [email protected] Delete unused web_unicode library (flutter/flutter#174896) 2025-09-19 [email protected] Roll Skia from 684f3a831216 to c74d2bdbd93c (2 revisions) (flutter/flutter#175644) 2025-09-19 [email protected] Roll Skia from 462bdece17bf to 684f3a831216 (3 revisions) (flutter/flutter#175641) 2025-09-19 [email protected] Roll Skia from a2c38aa9df80 to 462bdece17bf (11 revisions) (flutter/flutter#175629) 2025-09-18 [email protected] fix(tool): Use merge-base for content hash in detached HEAD (flutter/flutter#175554) 2025-09-18 [email protected] [web] Unskip Cupertino datepicker golden tests in Skwasm (flutter/flutter#174666) 2025-09-18 [email protected] Update rules to include extension rules (flutter/flutter#175618) 2025-09-18 [email protected] [engine] Cleanup Fuchsia FDIO library dependencies (flutter/flutter#174847) 2025-09-18 [email protected] Make sure that a CloseButton doesn't crash in 0x0 environment (flutter/flutter#172902) 2025-09-18 [email protected] [ Tool ] Serve DevTools from DDS, remove ResidentDevToolsHandler (flutter/flutter#174580) 2025-09-18 [email protected] [engine][fuchsia] Update to Fuchsia API level 28 and roll latest GN SDK (flutter/flutter#175425) 2025-09-18 [email protected] Added a 36 device for Firebase Lab Testing (flutter/flutter#175613) 2025-09-18 [email protected] Roll Dart SDK from 09a101793af4 to 2c79803c97db (2 revisions) (flutter/flutter#175608) 2025-09-18 [email protected] Engine Support for Dynamic View Resizing (flutter/flutter#173610) 2025-09-18 [email protected] Roll Packages from fdee698 to f2a65fd (3 revisions) (flutter/flutter#175594) 2025-09-18 [email protected] Connect the FlutterEngine to the FlutterSceneDelegate (flutter/flutter#174910) 2025-09-18 [email protected] Roll Dart SDK from de5dd0f1530f to 09a101793af4 (2 revisions) (flutter/flutter#175583) 2025-09-18 [email protected] Roll Skia from 7b9fe91446ee to a2c38aa9df80 (1 revision) (flutter/flutter#175579) 2025-09-18 [email protected] Roll Skia from ab1b10547461 to 7b9fe91446ee (4 revisions) (flutter/flutter#175569) 2025-09-18 [email protected] [a11y-app] Fix form field label and error message (flutter/flutter#174831) 2025-09-18 [email protected] Fix InputDecoration does not apply errorStyle to error (flutter/flutter#174787) 2025-09-18 [email protected] Migrate to `WidgetPropertyResolver` (flutter/flutter#175397) 2025-09-18 [email protected] Migrate to WidgetState (flutter/flutter#175396) 2025-09-18 [email protected] Roll Skia from 79ec8dfcd9d4 to ab1b10547461 (17 revisions) (flutter/flutter#175561) 2025-09-18 [email protected] Removes NOTICES from licenses input (flutter/flutter#174967) 2025-09-18 [email protected] Roll Dart SDK from 116f7fe72839 to de5dd0f1530f (2 revisions) (flutter/flutter#175557) 2025-09-17 [email protected] [reland][web] Refactor renderers to use the same frontend code #174588 (flutter/flutter#175392) 2025-09-17 [email protected] feat: Enable WidgetStateColor to be used in ChipThemeData.deleteIconColor (flutter/flutter#171646) 2025-09-17 [email protected] Filter out unexpected process logs on iOS with better regex matching. (flutter/flutter#175452) 2025-09-17 [email protected] CupertinoContextMenu child respects available screen width (flutter/flutter#175300) 2025-09-17 [email protected] Correct documentation in PredictiveBackFullscreenPageTransitionsBuilder (flutter/flutter#174362) ...
Once the `FlutterViewController` is able to get its `UIWindowScene`, pass itself to the `FlutterSceneDelegate` through the `FlutterSceneLifeCycleProvider` protocol. The scene will store the `FlutterEngine` in a weak pointer array. This is an incremental change towards flutter#174398. Fixes flutter#174395. ## 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], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Once the `FlutterViewController` is able to get its `UIWindowScene`, pass itself to the `FlutterSceneDelegate` through the `FlutterSceneLifeCycleProvider` protocol. The scene will store the `FlutterEngine` in a weak pointer array. This is an incremental change towards flutter#174398. Fixes flutter#174395. ## 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], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Once the `FlutterViewController` is able to get its `UIWindowScene`, pass itself to the `FlutterSceneDelegate` through the `FlutterSceneLifeCycleProvider` protocol. The scene will store the `FlutterEngine` in a weak pointer array. This is an incremental change towards flutter#174398. Fixes flutter#174395. ## 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], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Once the
FlutterViewControlleris able to get itsUIWindowScene, pass itself to theFlutterSceneDelegatethrough theFlutterSceneLifeCycleProviderprotocol. The scene will store theFlutterEnginein a weak pointer array.This is an incremental change towards #174398.
Fixes #174395.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.