Skip to content

iOS: Re-enable rendering on willEnterForeground - #191350

Merged
RobertOdrowaz merged 7 commits into
flutter:masterfrom
RobertOdrowaz:fix/191349-ios-lifecycle
Oct 11, 2026
Merged

RobertOdrowaz merged 7 commits into
flutter:masterfrom
RobertOdrowaz:fix/191349-ios-lifecycle

Conversation

@RobertOdrowaz

@RobertOdrowaz RobertOdrowaz commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

This PR changes the moment the rendering is re-enabled after the app was in the background.

Currently, the rendering is enabled only after the app enters the "active" state. This means that if something covers the app right after it returns from the background, e.g. a biometric prompt, the app visible under the prompt doesn't render new frames. This results in the app showing the frozen last frame from before going into background until the biometric prompt is dismissed.

This PR changes the logic so that rendering is re-enabled when the app enters foreground, even if it's foreground inactive, so that the app content is updated normally.

NOTE: It used to work this way until this PR flutter-team-archive/engine#7450, this was changed to match the rendering disabling logic that was moved to the willResignActive callback. The disabling was moved back to thedidEnterBackground callback in this PR flutter-team-archive/engine#25196, so I believe the re-enabling can be safely moved back to willEnterForeground.

#191349

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. 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.

@github-actions github-actions Bot added platform-ios iOS applications specifically engine flutter/engine related. See also e: labels. team-ios Owned by iOS platform team labels Aug 19, 2026
@RobertOdrowaz
RobertOdrowaz marked this pull request as ready for review August 19, 2026 11:26
@RobertOdrowaz
RobertOdrowaz requested a review from a team as a code owner August 19, 2026 11:26
@RobertOdrowaz RobertOdrowaz changed the title Reneable surface updating on will enter foreground Re-eneable rendering on will enter foreground Aug 19, 2026
@flutter-dashboard

Copy link
Copy Markdown

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request moves the surface update logic, which is triggered when the viewport physical width is non-zero, from the appOrSceneBecameActive method to the appOrSceneWillEnterForeground method in FlutterViewController.mm. There are no review comments, and I have no additional feedback to provide.

@hellohuanlin hellohuanlin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable. Can you add some tests?

Is the crashing behavior described in flutter-team-archive/engine#7450 not valid anymore? (cc: @cbracken)

@cbracken
cbracken self-requested a review August 20, 2026 07:31
@cbracken

cbracken commented Aug 20, 2026 •

Copy link
Copy Markdown
Member

Thanks for sending this!

As noted in the commit description, the reason I landed flutter-team-archive/engine#7450 was because Apple explicitly documented that this was required, and because we were seeing real-world crash reports because we were violating those guidelines.

Now, it's worth noting those guidelines were GLES guidelines and we no longer have a GLES backend. It's entirely possible that Metal loosens this up a bit but I think I'd want a citation from Apple's documentation before we commit.

As @hellohuanlin mentioned, we'll need a test. Its past end of my workday in Japan but I can test this out on a variety of hardware tomorrow as a sanity check.

Also on a personal note, I really hope we can land this, it was pretty disheartening having to land the patch you referenced, back at the time.

@RobertOdrowaz

Copy link
Copy Markdown
Contributor Author

I will look for docs regarding metal, but this PR wouldn't violate the mentioned guidelines. The guidelines recommend restarting the work on willEnterForeground and that's what I want to do.

In your app’s applicationWillEnterForeground: method, re-create any objects and restart your animation timer.

@cbracken

cbracken commented Aug 20, 2026 •

Copy link
Copy Markdown
Member

Sorry, I had too many tabs open and was looking at the wrong PR 😂

I just did some digging in the code and your change is consistent with the current behaviour under application lifecycle which was last updated here: flutter-team-archive/engine#25196

Documentation

Found some related to behaviour when backgrounded that clearly indicates the boundary line is backgrounded, which implies that this is safe, but that seems true either way given the PR I linked above.

https://developer.apple.com/documentation/metal/preparing-your-metal-app-to-run-in-the-background

When UIKit calls your app delegate’s applicationDidEnterBackground(_:) method, make sure Metal has scheduled all command buffers you’ve already committed before your app returns control to the system.

After your app moves into the background, if Metal sees a new command buffer from your app, it returns an error, rather than scheduling the command buffer. [MTLCommandBufferStatus.error / MTLCommandBufferError.Code.notPermitted]

So worst case is a rejected command buffer, not a crash. I'll fix my comment here, which was written on outdated info:

// This is process-level state that controls whether or not it's safe to submit work to the GPU.
// Submitting GPU work while the app is backgrounded results in immediate process termination.

This change SGTM once there's a test in place. I suspect we have a test for the app lifecycle equivalent of this that you could copy/paste/adapt. :)

@hellohuanlin

Copy link
Copy Markdown
Contributor

From triage:

If you are not able to come up with a test, feel free to ask for a test exemption with basis of reverting back to the original behavior, and this is more of testing UIKit behavior rather than flutter.

@RobertOdrowaz

Copy link
Copy Markdown
Contributor Author

I didn't find any test that I could adapt for this. There are integration tests around the iOS lifecycle, but none are similar, and I don't see an easy way to test this since we need to force the app into a foreground inactive state. So, since it's an option, I will go ahead and request an exception

@jmagman jmagman added the CICD Run CI/CD label Aug 21, 2026
hellohuanlin
hellohuanlin previously approved these changes Aug 24, 2026
@RobertOdrowaz

Copy link
Copy Markdown
Contributor Author

@hellohuanlin I've update the unit tests for this and rebased on master because CI was failing. Please take a look again

@cbracken cbracken changed the title Re-eneable rendering on will enter foreground Re-enable rendering on will enter foreground Aug 27, 2026
@cbracken cbracken changed the title Re-enable rendering on will enter foreground Re-enable rendering on willEnterForeground Aug 27, 2026
@cbracken cbracken changed the title Re-enable rendering on willEnterForeground iOS: Re-enable rendering on willEnterForeground Aug 27, 2026
@RobertOdrowaz

Copy link
Copy Markdown
Contributor Author

@hellohuanlin Reminder, in case you've missed this PR

hellohuanlin
hellohuanlin previously approved these changes Sep 2, 2026
@RobertOdrowaz

Copy link
Copy Markdown
Contributor Author

@hellohuanlin thanks for the review. Can you take a look at the failed "Google testing"? In understand I cannot check the results myself

Internal smoke tests failed. Please contact a Google developer to help investigate the failure.

@hellohuanlin

Copy link
Copy Markdown
Contributor

It's time out. I kicked re-run

@cbracken cbracken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM stamp from a Japanese personal seal

@cbracken cbracken left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Google testing failures look real.

Investigating. If I were to guess, this is almost certainly related to moving [self surfaceUpdated:YES]; out of appOrSceneBecameActive and into appOrSceneWillEnterForeground:.

@cbracken cbracken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approval. You're good to land; we can add the guard in a followup PR.

@RobertOdrowaz
RobertOdrowaz added this pull request to the merge queue Oct 11, 2026
Merged via the queue into flutter:master with commit 331a852 Oct 11, 2026
18 checks passed
@RobertOdrowaz
RobertOdrowaz deleted the fix/191349-ios-lifecycle branch October 11, 2026 13:41
This was referenced Oct 11, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Oct 14, 2026
…#13220)

Manual roll Flutter from d03768eef055 to 4249ccbc18a3 (158 revisions)

Manual roll requested by [email protected]

flutter/flutter@d03768e...4249ccb

2026-10-12 [email protected] [AGP 9.1.0 Migration #8] Unify add-to-app module wiring on the variant API (flutter/flutter#193717)
2026-10-12 [email protected] [master] Update Flutter DEPS to Dart 5933cb486b4aef2f8cf6b9f89a5651c0d5b0955e (flutter/flutter#193982)
2026-10-12 [email protected] [Android] Fix use-after-free of SurfaceControl.Transaction in HCPP (flutter/flutter#192969)
2026-10-12 [email protected] [windows] Add OpenGL compositor tests against ANGLE at D3D11 feature level 10_0 (flutter/flutter#194114)
2026-10-12 [email protected] Fix HDR image packing for ios (flutter/flutter#192526)
2026-10-12 [email protected] Bump customer tests to pick up material_ui and cupertino_ui (flutter/flutter#194236)
2026-10-12 [email protected] Remove no-shuffle from text_field_test.dart (flutter/flutter#193550)
2026-10-12 [email protected] [web] Clip semantics DOM text labels to stop stealing taps (flutter/flutter#194011)
2026-10-12 [email protected] Roll Skia from 9b6ceba4728d to 17f6986c226c (6 revisions) (flutter/flutter#194232)
2026-10-12 [email protected] [web] Skip non-focusable containers in Focusable.focusAsRouteDefault (flutter/flutter#194138)
2026-10-12 [email protected] [web_paragraph] Honor kTextHeightNone in TextStyle and ParagraphStyle (flutter/flutter#193733)
2026-10-12 [email protected] Roll Skia from c88b49d1d6c7 to 9b6ceba4728d (4 revisions) (flutter/flutter#194226)
2026-10-12 [email protected] Migrate remaining test to macOS 26 (flutter/flutter#193825)
2026-10-12 [email protected] Roll Dart SDK from 047ca322aa9c to 221363557163 (1 revision) (flutter/flutter#194219)
2026-10-12 [email protected] [flutter_tools] Include dev_dependencies hooks for release integration tests (flutter/flutter#193436)
2026-10-12 [email protected] Roll Skia from d8afad1b1829 to c88b49d1d6c7 (1 revision) (flutter/flutter#194198)
2026-10-12 [email protected] Roll Skia from b23ddbff1265 to d8afad1b1829 (4 revisions) (flutter/flutter#194195)
2026-10-11 [email protected] Roll Skia from a168863e44ec to b23ddbff1265 (1 revision) (flutter/flutter#194185)
2026-10-11 [email protected] Roll Skia from 0c1d93abfa04 to a168863e44ec (1 revision) (flutter/flutter#194181)
2026-10-11 [email protected] iOS: Re-enable rendering on willEnterForeground (flutter/flutter#191350)
2026-10-11 [email protected] Roll Skia from 93c9d3ffda25 to 0c1d93abfa04 (1 revision) (flutter/flutter#194179)
2026-10-11 [email protected] Remove more instances of deprecated `withOpacity` (flutter/flutter#193559)
2026-10-11 [email protected] Fix another `parameter_assignments` warning (flutter/flutter#193669)
2026-10-11 [email protected] Roll Skia from 3136abef8f58 to 93c9d3ffda25 (1 revision) (flutter/flutter#194169)
2026-10-11 [email protected] [Impeller] Guard the sampler library caches with a mutex (flutter/flutter#193738)
2026-10-11 [email protected] Roll Dart SDK from e9c89888bcc1 to 047ca322aa9c (1 revision) (flutter/flutter#194157)
2026-10-10 [email protected] Roll Dart SDK from 787baa8aae78 to e9c89888bcc1 (2 revisions) (flutter/flutter#194141)
2026-10-10 [email protected] Fix OverlayPortal layout in shrink-wrapped overlays (flutter/flutter#193079)
2026-10-10 [email protected] Roll Skia from 353076e27b1c to 3136abef8f58 (1 revision) (flutter/flutter#194130)
2026-10-10 [email protected] Roll Dart SDK from 88a07589b1ff to 787baa8aae78 (1 revision) (flutter/flutter#194124)
2026-10-10 [email protected] Route windowing view lookups through WidgetsBinding (flutter/flutter#192666)
2026-10-10 [email protected] Roll Dart SDK from 2a06cab34715 to 88a07589b1ff (1 revision) (flutter/flutter#194117)
2026-10-10 [email protected] Roll Skia from f9043b7aa798 to 353076e27b1c (2 revisions) (flutter/flutter#194115)
2026-10-10 [email protected] Refactored PipelineLibraryGLES (flutter/flutter#193985)
2026-10-09 [email protected] add shorthands for scroll physics subclasses in framework (flutter/flutter#193082)
2026-10-09 [email protected] Roll Dart SDK from ba889e3cee8a to 2a06cab34715 (1 revision) (flutter/flutter#194105)
2026-10-09 [email protected] Roll Skia from 5ea03d8a53a6 to f9043b7aa798 (2 revisions) (flutter/flutter#194099)
2026-10-09 [email protected] Add docs for using bb and led with LUCI (flutter/flutter#193859)
2026-10-09 [email protected] Roll Skia from e329bb617820 to 5ea03d8a53a6 (5 revisions) (flutter/flutter#194087)
2026-10-09 [email protected] Roll Packages from 54706bd to d8d9e97 (5 revisions) (flutter/flutter#194080)
2026-10-09 [email protected] Move the Vulkan wrapped-texture helper out of the GPU surface (flutter/flutter#193001)
2026-10-09 [email protected] Roll Skia from 3e54bcf4c963 to e329bb617820 (1 revision) (flutter/flutter#194078)
2026-10-09 [email protected] Roll Dart SDK from 23f0308f9af8 to ba889e3cee8a (2 revisions) (flutter/flutter#194077)
2026-10-09 [email protected] Bump dartdoc to 9.0.11 (flutter/flutter#194076)
...
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

This PR changes the moment the rendering is re-enabled after the app was
in the background.

Currently, the rendering is enabled only after the app enters the
"active" state. This means that if something covers the app right after
it returns from the background, e.g. a biometric prompt, the app visible
under the prompt doesn't render new frames. This results in the app
showing the frozen last frame from before going into background until
the biometric prompt is dismissed.

This PR changes the logic so that rendering is re-enabled when the app
enters foreground, even if it's foreground inactive, so that the app
content is updated normally.

NOTE: It used to work this way until this PR
flutter-team-archive/engine#7450, this was
changed to match the rendering disabling logic that was moved to the
`willResignActive` callback. The disabling was moved back to
the`didEnterBackground` callback in this PR
flutter-team-archive/engine#25196, so I believe
the re-enabling can be safely moved back to `willEnterForeground`.

flutter#191349

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [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.
- [ ] 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].

If this change needs to override an active code freeze, provide a
comment explaining why. The code freeze workflow can be overridden by
code reviewers. See pinned issues for any active code freezes with
guidance.

**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
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[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

---------

Co-authored-by: Chris Bracken <[email protected]>
Co-authored-by: Victoria Ashworth <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-ios iOS applications specifically team-ios Owned by iOS platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants