From 150c1a9e2f4622e1b72679e69f0df7d6f5790dd3 Mon Sep 17 00:00:00 2001 From: Tiger Date: Tue, 13 Jun 2023 17:22:44 +0800 Subject: [PATCH] Force consuming system bars if nav bar is shown forcibly This makes the decor view consumes the navigation bar insets, so the app content won't be overlapped with navigation bar. Fix: 276506304 Fix: 280915087 Test: Open immersive apps in kids mode. Make sure the app content won't be obscured by the visible navigation bar. Change-Id: Ica4339f4bf9a71fd524501e60a9f69fb53a0bb56 --- core/java/android/view/InsetsState.java | 3 ++- core/java/com/android/internal/policy/DecorView.java | 10 +++++++--- .../core/java/com/android/server/wm/DisplayPolicy.java | 3 ++- .../core/java/com/android/server/wm/InsetsPolicy.java | 8 ++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 5b974cdb2bca5..b55d25aa7013d 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -177,7 +177,8 @@ public class InsetsState implements Parcelable { if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) { compatInsetsTypes &= ~statusBars(); } - if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) { + if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode) + && !alwaysConsumeSystemBars) { compatInsetsTypes = 0; } diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 15f70f358d6e0..af1fdd79169ad 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1111,8 +1111,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind : controller.getSystemBarsAppearance(); if (insets != null) { - final boolean clearsCompatInsets = clearsCompatInsets(attrs.type, attrs.flags, - getResources().getConfiguration().windowConfiguration.getWindowingMode()); + mLastShouldAlwaysConsumeSystemBars = insets.shouldAlwaysConsumeSystemBars(); + + final boolean clearsCompatInsets = + clearsCompatInsets(attrs.type, attrs.flags, + getResources().getConfiguration().windowConfiguration + .getWindowingMode()) + && !mLastShouldAlwaysConsumeSystemBars; final Insets stableBarInsets = insets.getInsetsIgnoringVisibility( WindowInsets.Type.systemBars()); final Insets systemInsets = clearsCompatInsets @@ -1143,7 +1148,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind disallowAnimate |= (hasLeftStableInset != mLastHasLeftStableInset); mLastHasLeftStableInset = hasLeftStableInset; - mLastShouldAlwaysConsumeSystemBars = insets.shouldAlwaysConsumeSystemBars(); mLastSuppressScrimTypes = insets.getSuppressScrimTypes(); } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 65771d1ce3738..95c953a5cf2df 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -2368,7 +2368,8 @@ public class DisplayPolicy { // We need to force the consumption of the system bars if they are force shown or if they // are controlled by a remote insets controller. mForceConsumeSystemBars = mForceShowSystemBars - || mDisplayContent.getInsetsPolicy().remoteInsetsControllerControlsSystemBars(win); + || getInsetsPolicy().remoteInsetsControllerControlsSystemBars(win) + || getInsetsPolicy().forcesShowingNavigationBars(win); mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars()); diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index ddf96c53323de..daa823cf447fc 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -567,8 +567,7 @@ class InsetsPolicy { return focusedWin; } } - if (mPolicy.isForceShowNavigationBarEnabled() && focusedWin != null - && focusedWin.getActivityType() == ACTIVITY_TYPE_STANDARD) { + if (forcesShowingNavigationBars(focusedWin)) { // When "force show navigation bar" is enabled, it means both force visible is true, and // we are in 3-button navigation. In this mode, the navigation bar is forcibly shown // when activity type is ACTIVITY_TYPE_STANDARD which means Launcher or Recent could @@ -604,6 +603,11 @@ class InsetsPolicy { return focusedWin; } + boolean forcesShowingNavigationBars(WindowState win) { + return mPolicy.isForceShowNavigationBarEnabled() && win != null + && win.getActivityType() == ACTIVITY_TYPE_STANDARD; + } + /** * Determines whether the remote insets controller should take control of system bars for all * windows.