Skip to content

[Android] Add integration test for SystemUiMode transitions#187269

Merged
auto-submit[bot] merged 1 commit into
flutter:masterfrom
dbebawy:add-systemuimode-transition-tests-187265
Jun 24, 2026
Merged

[Android] Add integration test for SystemUiMode transitions#187269
auto-submit[bot] merged 1 commit into
flutter:masterfrom
dbebawy:add-systemuimode-transition-tests-187265

Conversation

@dbebawy

@dbebawy dbebawy commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a Flutter Driver integration test under dev/integration_tests/android_engine_test/ covering SystemUiMode transitions on Android. The test exposes a requestData handler that applies modes via SystemChrome.setEnabledSystemUIMode and reads the resulting decor-view systemUiVisibility flags via a new get_system_ui_visibility method on the existing native_driver method channel.

Closes #187265.

Why

#186723 was a P1 regression introduced by #183072 and fixed by #187207. The Mockito-based PlatformPluginTest unit tests verify which APIs are called on a mocked Window/View but cannot observe residual decorView state that bleeds across mode switches — which is the exact bug class the regression was. A device-level integration test closes that gap.

What the tests cover

Transition Assertion
immersiveSticky → edgeToEdge (regression case for #186723) FLAG_FULLSCREEN and FLAG_HIDE_NAVIGATION are cleared
immersive → edgeToEdge Same
leanBack → edgeToEdge Same
edgeToEdge → immersive IMMERSIVE | FULLSCREEN | HIDE_NAVIGATION set
edgeToEdge → immersiveSticky IMMERSIVE_STICKY | FULLSCREEN | HIDE_NAVIGATION set
edgeToEdge → leanBack FULLSCREEN | HIDE_NAVIGATION set, no immersive flags

All tests skip on API < 29 since edgeToEdge requires Android 10+.

Files

  • New: lib/system_ui_mode_transitions_main.dart — Flutter Driver entrypoint with mode-applying handler.
  • New: test_driver/system_ui_mode_transitions_main_test.dart — assertion suite.
  • Modified: NativeDriverSupportPlugin.kt — adds get_system_ui_visibility method that returns the decor view's systemUiVisibility int. Reading the deprecated field is the most direct signal of the regression class ([Regression] [Android] Failed to swtich SystemUIMode from immersiveSticky to edgeToEdge in Flutter 3.44.0 #186723 was specifically about flag bleed-through on this field).
  • Modified: README.md — adds the new entrypoint to the test list.

CI auto-discovery is via Glob('dev/integration_tests/android_engine_test/lib/**_main.dart') in dev/bots/suite_runners/run_android_engine_tests.dart — no separate registration needed.

Pre-launch Checklist

  • I read the Contributor Guide.
  • I read the Tree Hygiene wiki page.
  • I read and followed the Flutter Style Guide.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making.
  • All existing and new tests are passing.

Notes for reviewers

  • Marked as draft because I do not have a local Android emulator set up — flutter analyze is clean but I have not run the test end-to-end. CI is the source of truth.
  • The reason for reading the deprecated systemUiVisibility field on the native side (rather than WindowInsetsCompat.isVisible(...)) is that the regression was specifically about bit flags persisting on the decor view; the deprecated read gives a deterministic, version-independent signal. The production code still migrates to non-deprecated APIs for setting state per [Android] Use EdgeToEdge.enable/WindowCompat for edge-to-edge mode instead of deprecated View flags #183072.
  • SystemUiMode.manual is out of scope here (different API surface — takes a List<SystemUiOverlay>) and can follow up.

dbebawy added a commit to dbebawy/flutter that referenced this pull request May 29, 2026
dbebawy added a commit to dbebawy/flutter that referenced this pull request May 29, 2026
@dbebawy dbebawy force-pushed the add-systemuimode-transition-tests-187265 branch from 2125b5d to 77f82b1 Compare May 29, 2026 23:06
@dbebawy

dbebawy commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

Local verification — the test catches the regression

Rebased onto current upstream/master (13d0916522c), which contains both #183072 (the migration that introduced the regression) and #187207 (the fix). To prove the test actually catches the bug rather than just passing trivially, I ran it against both engine states on a real emulator (sdk_gphone64_arm64, Android 16 / API 36) using Impeller-Vulkan — the same backend CI uses.

Pre-fix engine (master at cbe057e187a, parent of #187207's merge)

3 tests FAIL, all caught by the new assertions:

00:01 +0 -1: SystemUiMode transitions immersiveSticky → edgeToEdge clears FULLSCREEN/HIDE_NAVIGATION (regression for #186723) [E]
  Expected: <0>
  Actual:   <6>     ← FLAG_HIDE_NAVIGATION (0x2) | FLAG_FULLSCREEN (0x4) persisted from prior immersiveSticky
00:01 +0 -2: SystemUiMode transitions immersive → edgeToEdge clears FULLSCREEN/HIDE_NAVIGATION [E]
  Expected: <0>
  Actual:   <6>
00:01 +0 -3: SystemUiMode transitions leanBack → edgeToEdge clears FULLSCREEN/HIDE_NAVIGATION [E]
  Expected: <0>
  Actual:   <6>
00:02 +3 -3: Some tests failed.

The remaining 3 edgeToEdge → immersive*/leanBack cells pass on the regressed engine (correctly — the bug only affects entering edge-to-edge).

Current master engine (with #187207)

All 6 pass:

00:02 +6: All tests passed!

Visual proof

App entrypoint instrumented with a green TOP STRIP, red body with mode label, and yellow BOTTOM STRIP. When system bars are visible, they overlay the strips; when hidden, the strips fill edge-to-edge. The immersive_mode_confirmations system toast was suppressed via adb shell settings put secure immersive_mode_confirmations confirmed.

The regression cell: immersiveSticky → edgeToEdge (#186723)

Before-fix (#183072 only — regressed) After-fix (#183072 + #187207)
regressed immersiveSticky → edgeToEdge fixed immersiveSticky → edgeToEdge

Both screens show mode label edgeToEdge. On the left (regressed), strips fill the entire screen — status bar and nav bar are still hidden, exactly as #186723 reported. On the right (fixed), the status bar (5:19, wifi/signal/battery) sits on the green TOP STRIP and the gesture-nav pill sits on the yellow BOTTOM STRIP — bars correctly restored.

immersive → edgeToEdge

Before-fix After-fix
regressed immersive → edgeToEdge fixed immersive → edgeToEdge

leanBack → edgeToEdge

Before-fix After-fix
regressed leanBack → edgeToEdge fixed leanBack → edgeToEdge

Confirming the pre-state (bars hidden before the switch)

For reference, here's immersiveSticky before the switch — same in both states, bars hidden, strips fully visible:

immersiveSticky

Note on the visual entrypoint

The colored strips + mode label app above is for capture only. The committed entrypoint stays minimal (ColoredBox body) — the visual instrumentation was a temporary local edit and is not in the diff.

Marking ready for review.

@dbebawy dbebawy marked this pull request as ready for review May 29, 2026 23:06

@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 adds integration tests to verify SystemUiMode transitions on Android, including a new test app, a companion test driver, and native driver support to retrieve system UI visibility flags. Feedback on the changes includes addressing a potential compilation error in Kotlin due to unsafe access of the nullable activity object, removing an unnecessary endOfFrame wait and its unused import in the Dart test harness, and avoiding the use of Timeout.none in the integration tests to prevent CI hangs.

@dbebawy dbebawy force-pushed the add-systemuimode-transition-tests-187265 branch from 77f82b1 to e0e9866 Compare May 30, 2026 02:42

@dbebawy dbebawy left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

All three review threads addressed and resolved:

  • Comment 1 (compile error claim): replied — it's a Kotlin smart-cast, not a compile error; same pattern used by every other branch in this method.
  • Comment 2 (SchedulerBinding.instance.endOfFrame): fix applied in commit e0e9866 — dropped the await and the unused scheduler.dart import. All 6 tests still pass.
  • Comment 3 (Timeout.none): replied — it's the established convention for every test in test_driver/.

End-to-end verification on a real Impeller-Vulkan emulator (Pixel API 36):

  • Pass against current master (with #187207).
  • Fail against pre-#187207 engine in a worktree, with the exact expected diagnostic Expected: <0>, Actual: <6> on all three new X → edgeToEdge cells — confirming the test catches the regression.

Ready for code-owner review.

@dbebawy

dbebawy commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

Friendly ping @reidbaker @gmackall @camsim99 @mboetger — this is the integration-test follow-up to #186723 / #187207 (per discussion on the original regression). All review threads resolved, and end-to-end verification posted above confirms the test catches the regression on a pre-#187207 engine (Expected: <0>, Actual: <6>). Ready for code-owner review when you have a moment.

@camsim99 camsim99 self-requested a review June 1, 2026 15:43
camsim99
camsim99 previously approved these changes Jun 1, 2026

@camsim99 camsim99 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.

LGTM, thanks for jumping on integration testing so quickly! I'm super excited to have these tests in place to help avoid regressions as we continue to improve our support for edge-to-edge.

@camsim99 camsim99 requested a review from mboetger June 1, 2026 20:34
@camsim99 camsim99 added the CICD Run CI/CD label Jun 1, 2026
@camsim99 camsim99 removed the request for review from mboetger June 1, 2026 20:35
@dbebawy dbebawy force-pushed the add-systemuimode-transition-tests-187265 branch 2 times, most recently from d871c3f to f0ec673 Compare June 1, 2026 21:31
@Piinks Piinks added the team-android Owned by Android platform team label Jun 1, 2026
@github-actions github-actions Bot removed team-android Owned by Android platform team CICD Run CI/CD labels Jun 1, 2026
@Piinks Piinks added platform-android Android applications specifically team-android Owned by Android platform team labels Jun 8, 2026
@camsim99 camsim99 requested review from camsim99 and mboetger June 9, 2026 21:27

@camsim99 camsim99 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.

LGTM thanks for the update! @mboetger for second review

@camsim99 camsim99 added the CICD Run CI/CD label Jun 15, 2026
@dbebawy dbebawy force-pushed the add-systemuimode-transition-tests-187265 branch from f0ec673 to 6664b54 Compare June 23, 2026 21:51
@github-actions github-actions Bot removed CICD Run CI/CD platform-android Android applications specifically labels Jun 23, 2026
@github-actions github-actions Bot added CICD Run CI/CD and removed team-android Owned by Android platform team labels Jun 23, 2026
Adds a Flutter Driver test under android_engine_test that drives
`SystemChrome.setEnabledSystemUIMode` through transition pairs and
asserts the resulting decor-view `systemUiVisibility` flags via a new
`get_system_ui_visibility` method on `native_driver`.

The regression-named test reproduces the
`immersiveSticky -> edgeToEdge` cell from flutter#186723 / fixed in flutter#187207:
without the fix, FLAG_FULLSCREEN and FLAG_HIDE_NAVIGATION from the
prior immersiveSticky call persist on the decor view, leaving the
system bars hidden under edgeToEdge.

Tests skip on API < 29 since edgeToEdge requires API 29+.

Closes flutter#187265
@dbebawy dbebawy force-pushed the add-systemuimode-transition-tests-187265 branch from 6664b54 to 38d853c Compare June 24, 2026 00:47
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 24, 2026
@camsim99 camsim99 added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD labels Jun 24, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Jun 24, 2026
Merged via the queue into flutter:master with commit 9f58a24 Jun 24, 2026
174 of 175 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 24, 2026
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
…187269)

## Summary

Adds a Flutter Driver integration test under
`dev/integration_tests/android_engine_test/` covering `SystemUiMode`
transitions on Android. The test exposes a `requestData` handler that
applies modes via `SystemChrome.setEnabledSystemUIMode` and reads the
resulting decor-view `systemUiVisibility` flags via a new
`get_system_ui_visibility` method on the existing `native_driver` method
channel.

Closes flutter#187265.

## Why

flutter#186723 was a P1 regression introduced by flutter#183072 and fixed by flutter#187207.
The Mockito-based `PlatformPluginTest` unit tests verify which APIs are
called on a mocked `Window`/`View` but cannot observe residual
`decorView` state that bleeds across mode switches — which is the exact
bug class the regression was. A device-level integration test closes
that gap.

## What the tests cover

| Transition | Assertion |
|------------|-----------|
| `immersiveSticky → edgeToEdge` (regression case for flutter#186723) |
`FLAG_FULLSCREEN` and `FLAG_HIDE_NAVIGATION` are cleared |
| `immersive → edgeToEdge` | Same |
| `leanBack → edgeToEdge` | Same |
| `edgeToEdge → immersive` | `IMMERSIVE \| FULLSCREEN \|
HIDE_NAVIGATION` set |
| `edgeToEdge → immersiveSticky` | `IMMERSIVE_STICKY \| FULLSCREEN \|
HIDE_NAVIGATION` set |
| `edgeToEdge → leanBack` | `FULLSCREEN \| HIDE_NAVIGATION` set, no
immersive flags |

All tests skip on API < 29 since `edgeToEdge` requires Android 10+.

## Files

- New: `lib/system_ui_mode_transitions_main.dart` — Flutter Driver
entrypoint with mode-applying handler.
- New: `test_driver/system_ui_mode_transitions_main_test.dart` —
assertion suite.
- Modified: `NativeDriverSupportPlugin.kt` — adds
`get_system_ui_visibility` method that returns the decor view's
`systemUiVisibility` int. Reading the deprecated field is the most
direct signal of the regression class (flutter#186723 was specifically about
flag bleed-through on this field).
- Modified: `README.md` — adds the new entrypoint to the test list.

CI auto-discovery is via
`Glob('dev/integration_tests/android_engine_test/lib/**_main.dart')` in
`dev/bots/suite_runners/run_android_engine_tests.dart` — no separate
registration needed.

## Pre-launch Checklist

- [x] I read the [Contributor
Guide](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview).
- [x] I read the [Tree
Hygiene](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md)
wiki page.
- [x] I read and followed the [Flutter Style
Guide](https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md).
- [x] I signed the [CLA](https://cla.developers.google.com/).
- [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.
- [x] All existing and new tests are passing.

## Notes for reviewers

- Marked as draft because I do not have a local Android emulator set up
— `flutter analyze` is clean but I have not run the test end-to-end. CI
is the source of truth.
- The reason for reading the deprecated `systemUiVisibility` field on
the native side (rather than `WindowInsetsCompat.isVisible(...)`) is
that the regression was specifically about bit flags persisting on the
decor view; the deprecated read gives a deterministic,
version-independent signal. The production code still migrates to
non-deprecated APIs for *setting* state per flutter#183072.
- `SystemUiMode.manual` is out of scope here (different API surface —
takes a `List<SystemUiOverlay>`) and can follow up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Add integration tests for SystemUiMode transitions

4 participants