Fixed XiaoMi statusBar Bug (#161271)

Updated usages of statusBar() to systemBar() to fix XiaoMi statusBar
bug.

Fixes #132831 

## 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].

<!-- 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
This commit is contained in:
jesswrd 2025-01-14 16:12:58 -08:00 committed by GitHub
parent a328b36f39
commit d8322207df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 9 deletions

View File

@ -689,14 +689,7 @@ public class FlutterView extends FrameLayout
(SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) == 0;
if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) {
int mask = 0;
if (navigationBarVisible) {
mask = mask | android.view.WindowInsets.Type.navigationBars();
}
if (statusBarVisible) {
mask = mask | android.view.WindowInsets.Type.statusBars();
}
Insets uiInsets = insets.getInsets(mask);
Insets uiInsets = insets.getInsets(android.view.WindowInsets.Type.systemBars());
viewportMetrics.viewPaddingTop = uiInsets.top;
viewportMetrics.viewPaddingRight = uiInsets.right;
viewportMetrics.viewPaddingBottom = uiInsets.bottom;

View File

@ -330,6 +330,86 @@ public class FlutterViewTest {
validateViewportMetricPadding(viewportMetricsCaptor, 100, 100, 100, 100);
}
@SuppressWarnings("deprecation")
// getSystemUiVisibility
// This test uses the API 30+ Algorithm for window insets. This test requires API 34 or
// higher to use the systemOverlays inset. The legacy algorithm is
// set to -1 values, so it is clear if the wrong algorithm is used.
@Test
@TargetApi(34)
@Config(minSdk = 34)
public void reportSystemInsetWhenNotFullscreenForSystemBar() {
// Without custom shadows, the default system ui visibility flags is 0.
FlutterView flutterView = new FlutterView(ctx);
assertEquals(0, flutterView.getSystemUiVisibility());
FlutterEngine flutterEngine = spy(new FlutterEngine(ctx, mockFlutterLoader, mockFlutterJni));
FlutterRenderer flutterRenderer = spy(new FlutterRenderer(mockFlutterJni));
when(flutterEngine.getRenderer()).thenReturn(flutterRenderer);
flutterView.attachToFlutterEngine(flutterEngine);
ArgumentCaptor<FlutterRenderer.ViewportMetrics> viewportMetricsCaptor =
ArgumentCaptor.forClass(FlutterRenderer.ViewportMetrics.class);
verify(flutterRenderer).setViewportMetrics(viewportMetricsCaptor.capture());
// When we attach a new FlutterView to the engine without any system insets, the viewport
// metrics default to 0.
assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingTop);
// Then we simulate the system applying a statusBar inset.
WindowInsets statusBarwindowInsets =
new WindowInsets.Builder()
.setInsets(android.view.WindowInsets.Type.captionBar(), Insets.of(0, 50, 0, 0))
.setInsets(android.view.WindowInsets.Type.statusBars(), Insets.of(0, 100, 0, 0))
.build();
flutterView.onApplyWindowInsets(statusBarwindowInsets);
// Verify.
verify(flutterRenderer, times(3)).setViewportMetrics(viewportMetricsCaptor.capture());
// Confirm that the statusBar inset is used because it is the largest of the insets faked.
validateViewportMetricPadding(viewportMetricsCaptor, 0, 100, 0, 0);
clearInvocations(flutterRenderer);
// Then we simulate the system applying a navigationBar window inset.
WindowInsets navigationBarwindowInsets =
new WindowInsets.Builder()
.setInsets(android.view.WindowInsets.Type.systemOverlays(), Insets.of(0, 0, 0, 10))
.setInsets(android.view.WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 50))
.build();
flutterView.onApplyWindowInsets(navigationBarwindowInsets);
// Verify.
verify(flutterRenderer, times(2)).setViewportMetrics(viewportMetricsCaptor.capture());
// Confirm that the navigationBar inset is used because it is the largest of the insets faked.
validateViewportMetricPadding(viewportMetricsCaptor, 0, 0, 0, 50);
clearInvocations(flutterRenderer);
// Then we simulate the system applying a captionBar window inset.
WindowInsets captionBarwindowInsets =
new WindowInsets.Builder()
.setInsets(android.view.WindowInsets.Type.statusBars(), Insets.of(0, 20, 0, 0))
.setInsets(android.view.WindowInsets.Type.captionBar(), Insets.of(0, 60, 0, 0))
.build();
flutterView.onApplyWindowInsets(captionBarwindowInsets);
// Verify.
verify(flutterRenderer, times(2)).setViewportMetrics(viewportMetricsCaptor.capture());
// Confirm that the captionBar inset is used because it is the largest of the insets faked.
validateViewportMetricPadding(viewportMetricsCaptor, 0, 60, 0, 0);
clearInvocations(flutterRenderer);
// Then we simulate the system applying a systemOverlay window inset.
WindowInsets systemOverlayWindowInsets =
new WindowInsets.Builder()
.setInsets(android.view.WindowInsets.Type.statusBars(), Insets.of(0, 100, 0, 0))
.setInsets(android.view.WindowInsets.Type.systemOverlays(), Insets.of(0, 200, 0, 0))
.build();
flutterView.onApplyWindowInsets(systemOverlayWindowInsets);
// Verify.
verify(flutterRenderer, times(2)).setViewportMetrics(viewportMetricsCaptor.capture());
// Confirm that the systemOverlay inset is used because it is the largest of the insets faked.
validateViewportMetricPadding(viewportMetricsCaptor, 0, 200, 0, 0);
}
@SuppressWarnings("deprecation")
// getSystemUiVisibility
// This test uses the pre-API 30 Algorithm for window insets.
@ -1088,7 +1168,7 @@ public class FlutterViewTest {
new WindowInsets.Builder()
.setInsets(
android.view.WindowInsets.Type.navigationBars()
| android.view.WindowInsets.Type.statusBars(),
| android.view.WindowInsets.Type.systemBars(),
Insets.of(100, 100, 100, 100))
.build();
flutterView.onApplyWindowInsets(windowInsets);