From 7ee7f178a27020d1b38e1c18fcff298b9f64392e Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Tue, 11 Jul 2023 19:32:41 +0000 Subject: [Status Bar] Set status bar window insets to status bar height always. This is needed for the animation shown when you tap the ongoing call chip in order to launch the call app. If we do *not* set the insets, then the insets will change during the animation, which will result in the animation being cancelled and show jank when launching the app. This CL is improvement of ag/23875866. That CL originally caused b/290300359, where the status bar height changed but the insets were *not* changed, so the insets were too small. This CL also adds the insets to the #applyHeight function, which is called when the status bar height changes. Bug: 283958440 Test: tap on ongoing call chip -> verify no jank during animation Test: status bar smoke test on phone (verify status bar in portrait and landscape, with and without ongoing call chip) Test: status bar smoke test on tablet (same as above) Test: status bar smoke test on foldable (same as above) Test: regression test for b/290300359: Boot foldable device while unfolded (no display cutout) > fold device (has display cutout now) > open app > verify there's no white/black bar showing between the status bar and the app (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4b89585868f4c95b2458bb1eef77587a896751a7) Merged-In: I35df87ef05cb75dcd551cc4899a0a9863fdcbcc7 Change-Id: I35df87ef05cb75dcd551cc4899a0a9863fdcbcc7 --- .../window/StatusBarWindowController.java | 35 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java index bcf3b0cbfc86..24987abd7a85 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java @@ -240,8 +240,10 @@ public class StatusBarWindowController { Insets.of(0, safeTouchRegionHeight, 0, 0)); } lp.providedInsets = new InsetsFrameProvider[] { - new InsetsFrameProvider(mInsetsSourceOwner, 0, statusBars()), - new InsetsFrameProvider(mInsetsSourceOwner, 0, tappableElement()), + new InsetsFrameProvider(mInsetsSourceOwner, 0, statusBars()) + .setInsetsSize(getInsets(height)), + new InsetsFrameProvider(mInsetsSourceOwner, 0, tappableElement()) + .setInsetsSize(getInsets(height)), gestureInsetsProvider }; return lp; @@ -306,12 +308,37 @@ public class StatusBarWindowController { mLpChanged.height = state.mIsLaunchAnimationRunning ? ViewGroup.LayoutParams.MATCH_PARENT : mBarHeight; for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) { + int height = SystemBarUtils.getStatusBarHeightForRotation(mContext, rot); mLpChanged.paramsForRotation[rot].height = - state.mIsLaunchAnimationRunning ? ViewGroup.LayoutParams.MATCH_PARENT : - SystemBarUtils.getStatusBarHeightForRotation(mContext, rot); + state.mIsLaunchAnimationRunning ? ViewGroup.LayoutParams.MATCH_PARENT : height; + // The status bar height could change at runtime if one display has a cutout while + // another doesn't (like some foldables). It could also change when using debug cutouts. + // So, we need to re-fetch the height and re-apply it to the insets each time to avoid + // bugs like b/290300359. + InsetsFrameProvider[] providers = mLpChanged.paramsForRotation[rot].providedInsets; + if (providers != null) { + for (InsetsFrameProvider provider : providers) { + provider.setInsetsSize(getInsets(height)); + } + } } } + /** + * Get the insets that should be applied to the status bar window given the current status bar + * height. + * + * The status bar window height can sometimes be full-screen (see {@link #applyHeight(State)}. + * However, the status bar *insets* should *not* be full-screen, because this would prevent apps + * from drawing any content and can cause animations to be cancelled (see b/283958440). Instead, + * the status bar insets should always be equal to the space occupied by the actual status bar + * content -- setting the insets correctly will prevent window manager from unnecessarily + * re-drawing this window and other windows. This method provides the correct insets. + */ + private Insets getInsets(int height) { + return Insets.of(0, height, 0, 0); + } + private void apply(State state) { if (!mIsAttached) { return; -- cgit v1.2.3