From b356de42b082a8057ed5f25c6c9ad172b963e72d Mon Sep 17 00:00:00 2001 From: Yunfan Chen Date: Wed, 10 Nov 2021 18:03:56 +0900 Subject: [PATCH] [DO NOT MERGE] Make extra navigation bar count towards non decor frame The extra navigation bar should be treated in the same way as the navigation bar to avoid compatibility issue. There are devices only contain an alternative extra navigation bar but not the default navigation bar. The app may receive conflict information from the insets system and the window configuration in that case. Test: CtsWindowManagerDeviceTestCases (on device with task bar) Bug: 205496695 Change-Id: Idef3d09c723ffcd67372db29fc0cc51a59cc0aa1 --- .../com/android/server/wm/DisplayContent.java | 56 ++++---- .../com/android/server/wm/DisplayPolicy.java | 120 +++++++++++------- .../server/wm/WindowManagerService.java | 7 +- .../server/wm/DisplayPolicyInsetsTests.java | 16 +-- 4 files changed, 114 insertions(+), 85 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index d168902b648ac..c3ee339c56529 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2042,16 +2042,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout(); final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation); - final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, - displayCutout); - final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, + final Point appSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode, displayCutout); mDisplayInfo.rotation = rotation; mDisplayInfo.logicalWidth = dw; mDisplayInfo.logicalHeight = dh; mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity; - mDisplayInfo.appWidth = appWidth; - mDisplayInfo.appHeight = appHeight; + mDisplayInfo.appWidth = appSize.x; + mDisplayInfo.appHeight = appSize.y; if (isDefaultDisplay) { mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); @@ -2186,24 +2184,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** Compute configuration related to application without changing current display. */ private void computeScreenAppConfiguration(Configuration outConfig, int dw, int dh, int rotation, int uiMode, DisplayCutout displayCutout) { - final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, - displayCutout); - final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, + final Point appSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode, displayCutout); mDisplayPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect); final int leftInset = mTmpRect.left; final int topInset = mTmpRect.top; // AppBounds at the root level should mirror the app screen size. outConfig.windowConfiguration.setAppBounds(leftInset /* left */, topInset /* top */, - leftInset + appWidth /* right */, topInset + appHeight /* bottom */); + leftInset + appSize.x /* right */, topInset + appSize.y /* bottom */); outConfig.windowConfiguration.setRotation(rotation); outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; final float density = mDisplayMetrics.density; - outConfig.screenWidthDp = (int) (mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation, - uiMode, displayCutout) / density); - outConfig.screenHeightDp = (int) (mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation, - uiMode, displayCutout) / density); + final Point configSize = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, uiMode, + displayCutout); + outConfig.screenWidthDp = (int) (configSize.x / density); + outConfig.screenHeightDp = (int) (configSize.y / density); outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale); outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale); @@ -2342,10 +2338,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp DisplayMetrics dm, int dw, int dh) { final DisplayCutout displayCutout = calculateDisplayCutoutForRotation( rotation).getDisplayCutout(); - dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, - displayCutout); - dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, + final Point nonDecorSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode, displayCutout); + dm.noncompatWidthPixels = nonDecorSize.x; + dm.noncompatHeightPixels = nonDecorSize.y; float scale = CompatibilityInfo.computeCompatibleScaling(dm, null); int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f); if (curSize == 0 || size < curSize) { @@ -2397,12 +2393,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp rotation).getDisplayCutout(); // Get the app screen size at this rotation. - int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout); - int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout); + final Point size = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode, + displayCutout); // Compute the screen layout size class for this rotation. - int longSize = w; - int shortSize = h; + int longSize = size.x; + int shortSize = size.y; if (longSize < shortSize) { int tmp = longSize; longSize = shortSize; @@ -2417,21 +2413,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp int uiMode, int dw, int dh) { final DisplayCutout displayCutout = calculateDisplayCutoutForRotation( rotation).getDisplayCutout(); - final int width = mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode, + final Point size = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, uiMode, displayCutout); - if (width < displayInfo.smallestNominalAppWidth) { - displayInfo.smallestNominalAppWidth = width; + if (size.x < displayInfo.smallestNominalAppWidth) { + displayInfo.smallestNominalAppWidth = size.x; } - if (width > displayInfo.largestNominalAppWidth) { - displayInfo.largestNominalAppWidth = width; + if (size.x > displayInfo.largestNominalAppWidth) { + displayInfo.largestNominalAppWidth = size.x; } - final int height = mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode, - displayCutout); - if (height < displayInfo.smallestNominalAppHeight) { - displayInfo.smallestNominalAppHeight = height; + if (size.y < displayInfo.smallestNominalAppHeight) { + displayInfo.smallestNominalAppHeight = size.y; } - if (height > displayInfo.largestNominalAppHeight) { - displayInfo.largestNominalAppHeight = height; + if (size.y > displayInfo.largestNominalAppHeight) { + displayInfo.largestNominalAppHeight = size.y; } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index eab1aaf0d9fb8..ff40fab2b23b0 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -120,6 +120,7 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PixelFormat; +import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.gui.DropInputMode; @@ -2306,6 +2307,24 @@ public class DisplayPolicy { } } + private int getAltBarWidth(@InternalInsetsType int insetsType) { + final InsetsSource source = mDisplayContent.getInsetsStateController().getRawInsetsState() + .peekSource(insetsType); + if (source == null) { + return 0; + } + return source.getFrame().width(); + } + + private int getAltBarHeight(@InternalInsetsType int insetsType) { + final InsetsSource source = mDisplayContent.getInsetsStateController().getRawInsetsState() + .peekSource(insetsType); + if (source == null) { + return 0; + } + return source.getFrame().height(); + } + void notifyDisplayReady() { mHandler.post(() -> { final int displayId = getDisplayId(); @@ -2321,26 +2340,6 @@ public class DisplayPolicy { }); } - /** - * Return the display width available after excluding any screen - * decorations that could never be removed in Honeycomb. That is, system bar or - * button bar. - */ - public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode, - DisplayCutout displayCutout) { - int width = fullWidth; - if (hasNavigationBar()) { - final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation); - if (navBarPosition == NAV_BAR_LEFT || navBarPosition == NAV_BAR_RIGHT) { - width -= getNavigationBarWidth(rotation, uiMode, navBarPosition); - } - } - if (displayCutout != null) { - width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight(); - } - return width; - } - private int getNavigationBarHeight(int rotation, int uiMode) { if (INSETS_LAYOUT_GENERALIZATION) { if (mNavigationBar == null) { @@ -2388,43 +2387,59 @@ public class DisplayPolicy { } /** - * Return the display height available after excluding any screen + * Return the display size available after excluding any screen * decorations that could never be removed in Honeycomb. That is, system bar or * button bar. */ - public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode, + Point getNonDecorDisplaySize(int fullWidth, int fullHeight, int rotation, int uiMode, DisplayCutout displayCutout) { + int width = fullWidth; int height = fullHeight; + int navBarReducedHeight = 0; + int navBarReducedWidth = 0; + final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation); if (hasNavigationBar()) { - final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation); if (navBarPosition == NAV_BAR_BOTTOM) { - height -= getNavigationBarHeight(rotation, uiMode); + navBarReducedHeight = getNavigationBarHeight(rotation, uiMode); + } else if (navBarPosition == NAV_BAR_LEFT || navBarPosition == NAV_BAR_RIGHT) { + navBarReducedWidth = getNavigationBarWidth(rotation, uiMode, navBarPosition); } } + if (mExtraNavBarAlt != null) { + final LayoutParams altBarParams = mExtraNavBarAlt.getLayoutingAttrs(rotation); + final int altBarPosition = getAltBarPosition(altBarParams); + if (altBarPosition == ALT_BAR_BOTTOM || altBarPosition == ALT_BAR_TOP) { + if (altBarPosition == navBarPosition) { + navBarReducedHeight = Math.max(navBarReducedHeight, + getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR)); + } else { + navBarReducedHeight += getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR); + } + } else if (altBarPosition == ALT_BAR_LEFT || altBarPosition == ALT_BAR_RIGHT) { + if (altBarPosition == navBarPosition) { + navBarReducedWidth = Math.max(navBarReducedWidth, + getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR)); + } else { + navBarReducedWidth += getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR); + } + } + } + height -= navBarReducedHeight; + width -= navBarReducedWidth; if (displayCutout != null) { height -= displayCutout.getSafeInsetTop() + displayCutout.getSafeInsetBottom(); + width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight(); } - return height; + return new Point(width, height); } /** - * Return the available screen width that we should report for the + * Return the available screen size that we should report for the * configuration. This must be no larger than - * {@link #getNonDecorDisplayWidth(int, int, int, int, DisplayCutout)}; it may be smaller + * {@link #getNonDecorDisplaySize(int, int, int, int, DisplayCutout)}; it may be smaller * than that to account for more transient decoration like a status bar. */ - public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode, - DisplayCutout displayCutout) { - return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayCutout); - } - - /** - * Return the available screen height that we should report for the - * configuration. This must be no larger than - * {@link #getNonDecorDisplayHeight(int, int, int, int, DisplayCutout)}; it may be smaller - * than that to account for more transient decoration like a status bar. - */ - public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode, + Point getConfigDisplaySize(int fullWidth, int fullHeight, int rotation, int uiMode, DisplayCutout displayCutout) { // There is a separate status bar at the top of the display. We don't count that as part // of the fixed decor, since it can hide; however, for purposes of configurations, @@ -2436,8 +2451,9 @@ public class DisplayPolicy { // bar height. statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop()); } - return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayCutout) - - statusBarHeight; + final Point nonDecorSize = getNonDecorDisplaySize(fullWidth, fullHeight, rotation, + uiMode, displayCutout); + return new Point(nonDecorSize.x, nonDecorSize.y - statusBarHeight); } /** @@ -2485,7 +2501,7 @@ public class DisplayPolicy { /** * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system - * bar or button bar. See {@link #getNonDecorDisplayWidth}. + * bar or button bar. See {@link #getNonDecorDisplaySize}. * * @param displayRotation the current display rotation * @param displayWidth the current display width @@ -2497,7 +2513,7 @@ public class DisplayPolicy { DisplayCutout displayCutout, Rect outInsets) { outInsets.setEmpty(); - // Only navigation bar + // Only navigation bar and extra navigation bar if (hasNavigationBar()) { final int uiMode = mService.mPolicy.getUiMode(); int position = navigationBarPosition(displayWidth, displayHeight, displayRotation); @@ -2509,6 +2525,24 @@ public class DisplayPolicy { outInsets.left = getNavigationBarWidth(displayRotation, uiMode, position); } } + if (mExtraNavBarAlt != null) { + final LayoutParams extraNavLayoutParams = + mExtraNavBarAlt.getLayoutingAttrs(displayRotation); + final int position = getAltBarPosition(extraNavLayoutParams); + if (position == ALT_BAR_BOTTOM) { + outInsets.bottom = Math.max(outInsets.bottom, + getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR)); + } else if (position == ALT_BAR_RIGHT) { + outInsets.right = Math.max(outInsets.right, + getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR)); + } else if (position == ALT_BAR_LEFT) { + outInsets.left = Math.max(outInsets.left, + getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR)); + } else if (position == ALT_BAR_TOP) { + outInsets.top = Math.max(outInsets.top, + getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR)); + } + } if (displayCutout != null) { outInsets.left += displayCutout.getSafeInsetLeft(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index df295ee23825b..d27b0e0a6491d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6136,9 +6136,10 @@ public class WindowManagerService extends IWindowManager.Stub + " callers=" + Debug.getCallers(3)); return NAV_BAR_INVALID; } - displayContent.performLayout(false /* initial */, - false /* updateInputWindows */); - return displayContent.getDisplayPolicy().getNavBarPosition(); + return displayContent.getDisplayPolicy().navigationBarPosition( + displayContent.mBaseDisplayWidth, + displayContent.mBaseDisplayHeight, + displayContent.getDisplayRotation().getRotation()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java index 004e45a8be4bc..b2b844b94d431 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java @@ -180,23 +180,23 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { } private int getNonDecorDisplayWidth(DisplayInfo di) { - return mDisplayPolicy.getNonDecorDisplayWidth(di.logicalWidth, di.logicalHeight, - di.rotation, 0 /* ui */, di.displayCutout); + return mDisplayPolicy.getNonDecorDisplaySize(di.logicalWidth, di.logicalHeight, + di.rotation, 0 /* ui */, di.displayCutout).x; } private int getNonDecorDisplayHeight(DisplayInfo di) { - return mDisplayPolicy.getNonDecorDisplayHeight(di.logicalWidth, di.logicalHeight, - di.rotation, 0 /* ui */, di.displayCutout); + return mDisplayPolicy.getNonDecorDisplaySize(di.logicalWidth, di.logicalHeight, + di.rotation, 0 /* ui */, di.displayCutout).y; } private int getConfigDisplayWidth(DisplayInfo di) { - return mDisplayPolicy.getConfigDisplayWidth(di.logicalWidth, di.logicalHeight, - di.rotation, 0 /* ui */, di.displayCutout); + return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight, + di.rotation, 0 /* ui */, di.displayCutout).x; } private int getConfigDisplayHeight(DisplayInfo di) { - return mDisplayPolicy.getConfigDisplayHeight(di.logicalWidth, di.logicalHeight, - di.rotation, 0 /* ui */, di.displayCutout); + return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight, + di.rotation, 0 /* ui */, di.displayCutout).y; } private static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) {