diff options
| author | 2022-09-05 17:08:14 +0000 | |
|---|---|---|
| committer | 2022-09-05 17:08:14 +0000 | |
| commit | 1a3b32ccd576073054d96f15ccc1920b84314d3b (patch) | |
| tree | 30ec7f5fa8084363cb6d2dd4746197347a5cd408 | |
| parent | db6e18a27aae67f11740c3d061de0ce622c847e9 (diff) | |
| parent | 955b79a8b3dfe73a7bf009063b8335ce0099bccf (diff) | |
Merge "Optimize screen decor insets calculation" into tm-qpr-dev am: cc6255bd91 am: 955b79a8b3
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19180946
Change-Id: I773d978cf8c1a92e2105be1786f3823bc3ffd0de
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
20 files changed, 356 insertions, 521 deletions
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 45d28da73c6b..9f426a176a08 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -351,20 +351,6 @@ public class InsetsState implements Parcelable { return insets; } - // TODO: Remove this once the task bar is treated as navigation bar. - public Insets calculateInsetsWithInternalTypes(Rect frame, @InternalInsetsType int[] types, - boolean ignoreVisibility) { - Insets insets = Insets.NONE; - for (int i = types.length - 1; i >= 0; i--) { - InsetsSource source = mSources[types[i]]; - if (source == null) { - continue; - } - insets = Insets.max(source.calculateInsets(frame, ignoreVisibility), insets); - } - return insets; - } - public Insets calculateInsets(Rect frame, @InsetsType int types, InsetsVisibilities overrideVisibilities) { Insets insets = Insets.NONE; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 63dcbf85ed32..be801182980d 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -357,7 +357,6 @@ import com.android.server.wm.ActivityMetricsLogger.TransitionInfoSnapshot; import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.WindowManagerService.H; import com.android.server.wm.utils.InsetUtils; -import com.android.server.wm.utils.WmDisplayCutout; import dalvik.annotation.optimization.NeverCompile; @@ -917,7 +916,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ private final Configuration mTmpConfig = new Configuration(); private final Rect mTmpBounds = new Rect(); - private final Rect mTmpOutNonDecorBounds = new Rect(); // Token for targeting this activity for assist purposes. final Binder assistToken = new Binder(); @@ -8143,10 +8141,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int orientation = parentBounds.height() >= parentBounds.width() ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; // Compute orientation from stable parent bounds (= parent bounds with insets applied) + final DisplayInfo di = isFixedRotationTransforming() + ? getFixedRotationTransformDisplayInfo() + : mDisplayContent.getDisplayInfo(); final Task task = getTask(); - task.calculateInsetFrames(mTmpOutNonDecorBounds /* outNonDecorBounds */, - outStableBounds /* outStableBounds */, parentBounds /* bounds */, - mDisplayContent.getDisplayInfo()); + task.calculateInsetFrames(mTmpBounds /* outNonDecorBounds */, + outStableBounds /* outStableBounds */, parentBounds /* bounds */, di); final int orientationWithInsets = outStableBounds.height() >= outStableBounds.width() ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; // If orientation does not match the orientation with insets applied, then a @@ -9708,10 +9708,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int dw = rotated ? display.mBaseDisplayHeight : display.mBaseDisplayWidth; final int dh = rotated ? display.mBaseDisplayWidth : display.mBaseDisplayHeight; - final WmDisplayCutout cutout = display.calculateDisplayCutoutForRotation(rotation); - policy.getNonDecorInsetsLw(rotation, dw, dh, cutout, mNonDecorInsets[rotation]); - mStableInsets[rotation].set(mNonDecorInsets[rotation]); - policy.convertNonDecorInsetsToStableInsets(mStableInsets[rotation], rotation); + final DisplayPolicy.DecorInsets.Info decorInfo = + policy.getDecorInsetsInfo(rotation, dw, dh); + mNonDecorInsets[rotation].set(decorInfo.mNonDecorInsets); + mStableInsets[rotation].set(decorInfo.mConfigInsets); if (unfilledContainerBounds == null) { continue; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 98c30b6c78d7..b10e4203f183 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1084,7 +1084,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * mDisplayMetrics.densityDpi / DENSITY_DEFAULT; isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY; mInsetsStateController = new InsetsStateController(this); - mDisplayFrames = new DisplayFrames(mDisplayId, mInsetsStateController.getRawInsetsState(), + mDisplayFrames = new DisplayFrames(mInsetsStateController.getRawInsetsState(), mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation), calculateRoundedCornersForRotation(mDisplayInfo.rotation), calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation)); @@ -1940,11 +1940,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private void startFixedRotationTransform(WindowToken token, int rotation) { mTmpConfiguration.unset(); final DisplayInfo info = computeScreenConfiguration(mTmpConfiguration, rotation); - final WmDisplayCutout cutout = calculateDisplayCutoutForRotation(rotation); + final DisplayCutout cutout = calculateDisplayCutoutForRotation(rotation); final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation); final PrivacyIndicatorBounds indicatorBounds = calculatePrivacyIndicatorBoundsForRotation(rotation); - final DisplayFrames displayFrames = new DisplayFrames(mDisplayId, new InsetsState(), info, + final DisplayFrames displayFrames = new DisplayFrames(new InsetsState(), info, cutout, roundedCorners, indicatorBounds); token.applyFixedRotationTransform(info, displayFrames, mTmpConfiguration); } @@ -2151,12 +2151,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight; // Update application display metrics. - final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation); - final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout(); + final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation); final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation); - final Rect appFrame = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation, - wmDisplayCutout); + final Rect appFrame = mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame; mDisplayInfo.rotation = rotation; mDisplayInfo.logicalWidth = dw; mDisplayInfo.logicalHeight = dh; @@ -2194,9 +2192,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mDisplayInfo; } - WmDisplayCutout calculateDisplayCutoutForRotation(int rotation) { + DisplayCutout calculateDisplayCutoutForRotation(int rotation) { return mDisplayCutoutCache.getOrCompute( - mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation); + mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation) + .getDisplayCutout(); } static WmDisplayCutout calculateDisplayCutoutForRotationAndDisplaySizeUncached( @@ -2267,9 +2266,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight; outConfig.windowConfiguration.setMaxBounds(0, 0, dw, dh); outConfig.windowConfiguration.setBounds(outConfig.windowConfiguration.getMaxBounds()); - - final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation); - computeScreenAppConfiguration(outConfig, dw, dh, rotation, wmDisplayCutout); + computeScreenAppConfiguration(outConfig, dw, dh, rotation); final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo); displayInfo.rotation = rotation; @@ -2278,7 +2275,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final Rect appBounds = outConfig.windowConfiguration.getAppBounds(); displayInfo.appWidth = appBounds.width(); displayInfo.appHeight = appBounds.height(); - final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout(); + final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation); displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout; computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig); @@ -2287,21 +2284,17 @@ 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, WmDisplayCutout wmDisplayCutout) { - final DisplayFrames displayFrames = - mDisplayPolicy.getSimulatedDisplayFrames(rotation, dw, dh, wmDisplayCutout); - final Rect appFrame = - mDisplayPolicy.getNonDecorDisplayFrameWithSimulatedFrame(displayFrames); + int rotation) { + final DisplayPolicy.DecorInsets.Info info = + mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh); // AppBounds at the root level should mirror the app screen size. - outConfig.windowConfiguration.setAppBounds(appFrame); + outConfig.windowConfiguration.setAppBounds(info.mNonDecorFrame); outConfig.windowConfiguration.setRotation(rotation); outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE; final float density = mDisplayMetrics.density; - final Point configSize = - mDisplayPolicy.getConfigDisplaySizeWithSimulatedFrame(displayFrames); - outConfig.screenWidthDp = (int) (configSize.x / density + 0.5f); - outConfig.screenHeightDp = (int) (configSize.y / density + 0.5f); + outConfig.screenWidthDp = (int) (info.mConfigFrame.width() / density + 0.5f); + outConfig.screenHeightDp = (int) (info.mConfigFrame.height() / density + 0.5f); outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale); outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale); @@ -2324,8 +2317,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp config.windowConfiguration.setWindowingMode(getWindowingMode()); config.windowConfiguration.setDisplayWindowingMode(getWindowingMode()); - computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation, - calculateDisplayCutoutForRotation(getRotation())); + computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation); config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK) | ((displayInfo.flags & Display.FLAG_ROUND) != 0 @@ -2434,9 +2426,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm, int dw, int dh) { - final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation); - final Rect nonDecorSize = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation, - wmDisplayCutout); + final Rect nonDecorSize = + mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame; dm.noncompatWidthPixels = nonDecorSize.width(); dm.noncompatHeightPixels = nonDecorSize.height(); float scale = CompatibilityInfo.computeCompatibleScaling(dm, null); @@ -2485,11 +2476,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh) { - // Get the display cutout at this rotation. - final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation); - // Get the app screen size at this rotation. - final Rect size = mDisplayPolicy.getNonDecorDisplayFrame(dw, dh, rotation, wmDisplayCutout); + final Rect size = mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame; // Compute the screen layout size class for this rotation. int longSize = size.width(); @@ -2505,19 +2493,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) { - final WmDisplayCutout wmDisplayCutout = calculateDisplayCutoutForRotation(rotation); - final Point size = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, wmDisplayCutout); - if (size.x < displayInfo.smallestNominalAppWidth) { - displayInfo.smallestNominalAppWidth = size.x; + final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo( + rotation, dw, dh); + final int w = info.mConfigFrame.width(); + final int h = info.mConfigFrame.height(); + if (w < displayInfo.smallestNominalAppWidth) { + displayInfo.smallestNominalAppWidth = w; } - if (size.x > displayInfo.largestNominalAppWidth) { - displayInfo.largestNominalAppWidth = size.x; + if (w > displayInfo.largestNominalAppWidth) { + displayInfo.largestNominalAppWidth = w; } - if (size.y < displayInfo.smallestNominalAppHeight) { - displayInfo.smallestNominalAppHeight = size.y; + if (h < displayInfo.smallestNominalAppHeight) { + displayInfo.smallestNominalAppHeight = h; } - if (size.y > displayInfo.largestNominalAppHeight) { - displayInfo.largestNominalAppHeight = size.y; + if (h > displayInfo.largestNominalAppHeight) { + displayInfo.largestNominalAppHeight = h; } } @@ -2788,14 +2778,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } private void updateDisplayFrames(boolean notifyInsetsChange) { - if (mDisplayFrames.update(mDisplayInfo, - calculateDisplayCutoutForRotation(mDisplayInfo.rotation), - calculateRoundedCornersForRotation(mDisplayInfo.rotation), - calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation))) { + if (updateDisplayFrames(mDisplayFrames, mDisplayInfo.rotation, + mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) { mInsetsStateController.onDisplayFramesUpdated(notifyInsetsChange); } } + boolean updateDisplayFrames(DisplayFrames displayFrames, int rotation, int w, int h) { + return displayFrames.update(rotation, w, h, + calculateDisplayCutoutForRotation(rotation), + calculateRoundedCornersForRotation(rotation), + calculatePrivacyIndicatorBoundsForRotation(rotation)); + } + @Override void onDisplayChanged(DisplayContent dc) { super.onDisplayChanged(dc); @@ -2958,6 +2953,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp + mBaseDisplayHeight + " on display:" + getDisplayId()); } } + if (mDisplayReady) { + mDisplayPolicy.mDecorInsets.invalidate(); + } } /** @@ -5594,7 +5592,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp outExclusionUnrestricted.setEmpty(); } final Region unhandled = Region.obtain(); - unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight); + unhandled.set(0, 0, mDisplayFrames.mWidth, mDisplayFrames.mHeight); final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES) .getSource().getFrame(); diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java index 7ca38b8fcc00..33641f72b2ff 100644 --- a/services/core/java/com/android/server/wm/DisplayFrames.java +++ b/services/core/java/com/android/server/wm/DisplayFrames.java @@ -30,8 +30,6 @@ import android.view.InsetsState; import android.view.PrivacyIndicatorBounds; import android.view.RoundedCorners; -import com.android.server.wm.utils.WmDisplayCutout; - import java.io.PrintWriter; /** @@ -39,8 +37,6 @@ import java.io.PrintWriter; * @hide */ public class DisplayFrames { - public final int mDisplayId; - public final InsetsState mInsetsState; /** @@ -54,48 +50,45 @@ public class DisplayFrames { */ public final Rect mDisplayCutoutSafe = new Rect(); - public int mDisplayWidth; - public int mDisplayHeight; + public int mWidth; + public int mHeight; public int mRotation; - public DisplayFrames(int displayId, InsetsState insetsState, DisplayInfo info, - WmDisplayCutout displayCutout, RoundedCorners roundedCorners, - PrivacyIndicatorBounds indicatorBounds) { - mDisplayId = displayId; + public DisplayFrames(InsetsState insetsState, DisplayInfo info, DisplayCutout cutout, + RoundedCorners roundedCorners, PrivacyIndicatorBounds indicatorBounds) { mInsetsState = insetsState; - update(info, displayCutout, roundedCorners, indicatorBounds); + update(info.rotation, info.logicalWidth, info.logicalHeight, cutout, roundedCorners, + indicatorBounds); + } + + DisplayFrames() { + mInsetsState = new InsetsState(); } /** - * This is called when {@link DisplayInfo} or {@link PrivacyIndicatorBounds} is updated. + * This is called if the display info may be changed, e.g. rotation, size, insets. * - * @param info the updated {@link DisplayInfo}. - * @param displayCutout the updated {@link DisplayCutout}. - * @param roundedCorners the updated {@link RoundedCorners}. - * @param indicatorBounds the updated {@link PrivacyIndicatorBounds}. * @return {@code true} if anything has been changed; {@code false} otherwise. */ - public boolean update(DisplayInfo info, @NonNull WmDisplayCutout displayCutout, + public boolean update(int rotation, int w, int h, @NonNull DisplayCutout displayCutout, @NonNull RoundedCorners roundedCorners, @NonNull PrivacyIndicatorBounds indicatorBounds) { final InsetsState state = mInsetsState; final Rect safe = mDisplayCutoutSafe; - final DisplayCutout cutout = displayCutout.getDisplayCutout(); - if (mDisplayWidth == info.logicalWidth && mDisplayHeight == info.logicalHeight - && mRotation == info.rotation - && state.getDisplayCutout().equals(cutout) + if (mRotation == rotation && mWidth == w && mHeight == h + && mInsetsState.getDisplayCutout().equals(displayCutout) && state.getRoundedCorners().equals(roundedCorners) && state.getPrivacyIndicatorBounds().equals(indicatorBounds)) { return false; } - mDisplayWidth = info.logicalWidth; - mDisplayHeight = info.logicalHeight; - mRotation = info.rotation; + mRotation = rotation; + mWidth = w; + mHeight = h; final Rect unrestricted = mUnrestricted; - unrestricted.set(0, 0, mDisplayWidth, mDisplayHeight); + unrestricted.set(0, 0, w, h); state.setDisplayFrame(unrestricted); - state.setDisplayCutout(cutout); + state.setDisplayCutout(displayCutout); state.setRoundedCorners(roundedCorners); state.setPrivacyIndicatorBounds(indicatorBounds); state.getDisplayCutoutSafe(safe); @@ -132,7 +125,6 @@ public class DisplayFrames { } public void dump(String prefix, PrintWriter pw) { - pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight - + " r=" + mRotation); + pw.println(prefix + "DisplayFrames w=" + mWidth + " h=" + mHeight + " r=" + mRotation); } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index d4eac8d3ad4b..cb5996035c4a 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -19,19 +19,15 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.Display.TYPE_INTERNAL; -import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT; import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_CLIMATE_BAR; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; import static android.view.InsetsState.ITYPE_STATUS_BAR; -import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; @@ -107,7 +103,6 @@ import android.content.Intent; 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; @@ -132,8 +127,6 @@ import android.view.InsetsSource; import android.view.InsetsState; import android.view.InsetsState.InternalInsetsType; import android.view.InsetsVisibilities; -import android.view.PrivacyIndicatorBounds; -import android.view.RoundedCorners; import android.view.Surface; import android.view.View; import android.view.ViewDebug; @@ -151,7 +144,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.ForceShowNavBarSettingsObserver; import com.android.internal.policy.GestureNavigationSettingsObserver; import com.android.internal.policy.ScreenDecorationsUtils; -import com.android.internal.policy.SystemBarUtils; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.statusbar.LetterboxDetails; import com.android.internal.util.ScreenshotHelper; @@ -166,7 +158,6 @@ import com.android.server.policy.WindowManagerPolicy.ScreenOnListener; import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.wallpaper.WallpaperManagerInternal; -import com.android.server.wm.utils.WmDisplayCutout; import java.io.PrintWriter; import java.util.ArrayList; @@ -242,6 +233,8 @@ public class DisplayPolicy { private final SystemGesturesPointerEventListener mSystemGestures; + final DecorInsets mDecorInsets; + private volatile int mLidState = LID_ABSENT; private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED; private volatile boolean mHdmiPlugged; @@ -266,7 +259,6 @@ public class DisplayPolicy { private WindowState mStatusBar = null; private volatile WindowState mNotificationShade; - private final int[] mStatusBarHeightForRotation = new int[4]; private WindowState mNavigationBar = null; @NavigationBarPosition private int mNavigationBarPosition = NAV_BAR_BOTTOM; @@ -353,7 +345,6 @@ public class DisplayPolicy { private static final Rect sTmpRect = new Rect(); private static final Rect sTmpRect2 = new Rect(); - private static final Rect sTmpLastParentFrame = new Rect(); private static final Rect sTmpDisplayCutoutSafe = new Rect(); private static final ClientWindowFrames sTmpClientFrames = new ClientWindowFrames(); @@ -391,16 +382,6 @@ public class DisplayPolicy { private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1; - // TODO (b/235842600): Use public type once we can treat task bar as navigation bar. - private static final int[] STABLE_TYPES = new int[]{ - ITYPE_TOP_DISPLAY_CUTOUT, ITYPE_RIGHT_DISPLAY_CUTOUT, ITYPE_BOTTOM_DISPLAY_CUTOUT, - ITYPE_LEFT_DISPLAY_CUTOUT, ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR, ITYPE_CLIMATE_BAR - }; - private static final int[] NON_DECOR_TYPES = new int[]{ - ITYPE_TOP_DISPLAY_CUTOUT, ITYPE_RIGHT_DISPLAY_CUTOUT, ITYPE_BOTTOM_DISPLAY_CUTOUT, - ITYPE_LEFT_DISPLAY_CUTOUT, ITYPE_NAVIGATION_BAR - }; - private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver; private final WindowManagerInternal.AppTransitionListener mAppTransitionListener; @@ -444,6 +425,7 @@ public class DisplayPolicy { : service.mAtmService.mSystemThread .getSystemUiContext(displayContent.getDisplayId()); mDisplayContent = displayContent; + mDecorInsets = new DecorInsets(displayContent); mLock = service.getWindowManagerLock(); final int displayId = displayContent.getDisplayId(); @@ -1226,7 +1208,7 @@ public class DisplayPolicy { Math.max(displayFrames.mDisplayCutoutSafe.left, 0); inOutFrame.left = 0; inOutFrame.top = 0; - inOutFrame.bottom = displayFrames.mDisplayHeight; + inOutFrame.bottom = displayFrames.mHeight; inOutFrame.right = leftSafeInset + mLeftGestureInset; }); mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win, @@ -1236,8 +1218,8 @@ public class DisplayPolicy { displayFrames.mUnrestricted.right); inOutFrame.left = rightSafeInset - mRightGestureInset; inOutFrame.top = 0; - inOutFrame.bottom = displayFrames.mDisplayHeight; - inOutFrame.right = displayFrames.mDisplayWidth; + inOutFrame.bottom = displayFrames.mHeight; + inOutFrame.right = displayFrames.mWidth; }); mDisplayContent.setInsetProvider(ITYPE_BOTTOM_TAPPABLE_ELEMENT, win, (displayFrames, windowContainer, inOutFrame) -> { @@ -1428,11 +1410,6 @@ public class DisplayPolicy { return Math.max(statusBarHeight, displayFrames.mDisplayCutoutSafe.top); } - @VisibleForTesting - int getStatusBarHeightForRotation(@Surface.Rotation int rotation) { - return SystemBarUtils.getStatusBarHeightForRotation(mUiContext, rotation); - } - WindowState getStatusBar() { return mStatusBar != null ? mStatusBar : mStatusBarAlt; } @@ -1928,25 +1905,11 @@ public class DisplayPolicy { final Resources res = getCurrentUserResources(); final int portraitRotation = displayRotation.getPortraitRotation(); - final int upsideDownRotation = displayRotation.getUpsideDownRotation(); - final int landscapeRotation = displayRotation.getLandscapeRotation(); - final int seascapeRotation = displayRotation.getSeascapeRotation(); if (hasStatusBar()) { - mStatusBarHeightForRotation[portraitRotation] = - mStatusBarHeightForRotation[upsideDownRotation] = - getStatusBarHeightForRotation(portraitRotation); - mStatusBarHeightForRotation[landscapeRotation] = - getStatusBarHeightForRotation(landscapeRotation); - mStatusBarHeightForRotation[seascapeRotation] = - getStatusBarHeightForRotation(seascapeRotation); mDisplayCutoutTouchableRegionSize = res.getDimensionPixelSize( R.dimen.display_cutout_touchable_region_size); } else { - mStatusBarHeightForRotation[portraitRotation] = - mStatusBarHeightForRotation[upsideDownRotation] = - mStatusBarHeightForRotation[landscapeRotation] = - mStatusBarHeightForRotation[seascapeRotation] = 0; mDisplayCutoutTouchableRegionSize = 0; } @@ -2052,33 +2015,9 @@ public class DisplayPolicy { } /** - * Return the display frame available after excluding any screen decorations that could never be - * removed in Honeycomb. That is, system bar or button bar. - * - * @return display frame excluding all non-decor insets. - */ - Rect getNonDecorDisplayFrame(int fullWidth, int fullHeight, int rotation, - WmDisplayCutout cutout) { - final DisplayFrames displayFrames = - getSimulatedDisplayFrames(rotation, fullWidth, fullHeight, cutout); - return getNonDecorDisplayFrameWithSimulatedFrame(displayFrames); - } - - Rect getNonDecorDisplayFrameWithSimulatedFrame(DisplayFrames displayFrames) { - final Rect nonDecorInsets = - getInsetsWithInternalTypes(displayFrames, NON_DECOR_TYPES).toRect(); - final Rect displayFrame = new Rect(displayFrames.mInsetsState.getDisplayFrame()); - displayFrame.inset(nonDecorInsets); - return displayFrame; - } - - /** * Get the Navigation Bar Frame height. This dimension is the height of the navigation bar that * is used for spacing to show additional buttons on the navigation bar (such as the ime - * switcher when ime is visible) while {@link #getNavigationBarHeight} is used for the visible - * height that we send to the app as content insets that can be smaller. - * <p> - * In car mode it will return the same height as {@link #getNavigationBarHeight} + * switcher when ime is visible). * * @param rotation specifies rotation to return dimension from * @return navigation bar frame height @@ -2091,26 +2030,6 @@ public class DisplayPolicy { } /** - * Return the available screen size that we should report for the - * configuration. This must be no larger than - * {@link #getNonDecorDisplayFrame(int, int, int, DisplayCutout)}; it may be smaller - * than that to account for more transient decoration like a status bar. - */ - public Point getConfigDisplaySize(int fullWidth, int fullHeight, int rotation, - WmDisplayCutout wmDisplayCutout) { - final DisplayFrames displayFrames = getSimulatedDisplayFrames(rotation, fullWidth, - fullHeight, wmDisplayCutout); - return getConfigDisplaySizeWithSimulatedFrame(displayFrames); - } - - Point getConfigDisplaySizeWithSimulatedFrame(DisplayFrames displayFrames) { - final Insets insets = getInsetsWithInternalTypes(displayFrames, STABLE_TYPES); - Rect configFrame = new Rect(displayFrames.mInsetsState.getDisplayFrame()); - configFrame.inset(insets); - return new Point(configFrame.width(), configFrame.height()); - } - - /** * Return corner radius in pixels that should be used on windows in order to cover the display. * * The radius is only valid for internal displays, since the corner radius of external displays @@ -2125,89 +2044,152 @@ public class DisplayPolicy { return mShowingDream; } - /** - * Calculates the stable insets if we already have the non-decor insets. - * - * @param inOutInsets The known non-decor insets. It will be modified to stable insets. - * @param rotation The current display rotation. - */ - void convertNonDecorInsetsToStableInsets(Rect inOutInsets, int rotation) { - inOutInsets.top = Math.max(inOutInsets.top, mStatusBarHeightForRotation[rotation]); - } + /** The latest insets and frames for screen configuration calculation. */ + static class DecorInsets { + static class Info { + /** + * The insets for the areas that could never be removed, i.e. display cutout and + * navigation bar. Note that its meaning is actually "decor insets". The "non" is just + * because it is used to calculate {@link #mNonDecorFrame}. + */ + final Rect mNonDecorInsets = new Rect(); + + /** + * The stable insets that can affect configuration. The sources are usually from + * display cutout, navigation bar, and status bar. + */ + final Rect mConfigInsets = new Rect(); + + /** The display frame available after excluding {@link #mNonDecorInsets}. */ + final Rect mNonDecorFrame = new Rect(); + + /** + * The available (stable) screen size that we should report for the configuration. + * This must be no larger than {@link #mNonDecorFrame}; it may be smaller than that + * to account for more transient decoration like a status bar. + */ + final Rect mConfigFrame = new Rect(); + + private boolean mNeedUpdate = true; + + void update(DisplayContent dc, int rotation, int w, int h) { + final DisplayFrames df = new DisplayFrames(); + dc.updateDisplayFrames(df, rotation, w, h); + dc.getDisplayPolicy().simulateLayoutDisplay(df); + final InsetsState insetsState = df.mInsetsState; + final Rect displayFrame = insetsState.getDisplayFrame(); + final Insets decor = calculateDecorInsetsWithInternalTypes(insetsState); + final Insets statusBar = insetsState.calculateInsets(displayFrame, + Type.statusBars(), true /* ignoreVisibility */); + mNonDecorInsets.set(decor.left, decor.top, decor.right, decor.bottom); + mConfigInsets.set(Math.max(statusBar.left, decor.left), + Math.max(statusBar.top, decor.top), + Math.max(statusBar.right, decor.right), + Math.max(statusBar.bottom, decor.bottom)); + mNonDecorFrame.set(displayFrame); + mNonDecorFrame.inset(mNonDecorInsets); + mConfigFrame.set(displayFrame); + mConfigFrame.inset(mConfigInsets); + mNeedUpdate = false; + } - /** - * Calculates the stable insets without running a layout. - * - * @param displayRotation the current display rotation - * @param displayWidth full display width - * @param displayHeight full display height - * @param displayCutout the current display cutout - * @param outInsets the insets to return - */ - public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight, - WmDisplayCutout displayCutout, Rect outInsets) { - final DisplayFrames displayFrames = getSimulatedDisplayFrames(displayRotation, - displayWidth, displayHeight, displayCutout); - getStableInsetsWithSimulatedFrame(displayFrames, outInsets); - } + void set(Info other) { + mNonDecorInsets.set(other.mNonDecorInsets); + mConfigInsets.set(other.mConfigInsets); + mNonDecorFrame.set(other.mNonDecorFrame); + mConfigFrame.set(other.mConfigFrame); + mNeedUpdate = false; + } - void getStableInsetsWithSimulatedFrame(DisplayFrames displayFrames, Rect outInsets) { - // Navigation bar, status bar, and cutout. - outInsets.set(getInsetsWithInternalTypes(displayFrames, STABLE_TYPES).toRect()); + @Override + public String toString() { + return "{nonDecorInsets=" + mNonDecorInsets + + ", configInsets=" + mConfigInsets + + ", nonDecorFrame=" + mNonDecorFrame + + ", configFrame=" + mConfigFrame + '}'; + } + } + + // TODO (b/235842600): Use public type once we can treat task bar as navigation bar. + static final int[] INTERNAL_DECOR_TYPES; + static { + final ArraySet<Integer> decorTypes = InsetsState.toInternalType( + Type.displayCutout() | Type.navigationBars()); + decorTypes.remove(ITYPE_EXTRA_NAVIGATION_BAR); + INTERNAL_DECOR_TYPES = new int[decorTypes.size()]; + for (int i = 0; i < INTERNAL_DECOR_TYPES.length; i++) { + INTERNAL_DECOR_TYPES[i] = decorTypes.valueAt(i); + } + } + + private final DisplayContent mDisplayContent; + private final Info[] mInfoForRotation = new Info[4]; + final Info mTmpInfo = new Info(); + + DecorInsets(DisplayContent dc) { + mDisplayContent = dc; + for (int i = mInfoForRotation.length - 1; i >= 0; i--) { + mInfoForRotation[i] = new Info(); + } + } + + Info get(int rotation, int w, int h) { + final Info info = mInfoForRotation[rotation]; + if (info.mNeedUpdate) { + info.update(mDisplayContent, rotation, w, h); + } + return info; + } + + /** Called when the screen decor insets providers have changed. */ + void invalidate() { + for (Info info : mInfoForRotation) { + info.mNeedUpdate = true; + } + } + + // TODO (b/235842600): Remove this method once we can treat task bar as navigation bar. + private static Insets calculateDecorInsetsWithInternalTypes(InsetsState state) { + final Rect frame = state.getDisplayFrame(); + Insets insets = Insets.NONE; + for (int i = INTERNAL_DECOR_TYPES.length - 1; i >= 0; i--) { + final InsetsSource source = state.peekSource(INTERNAL_DECOR_TYPES[i]); + if (source != null) { + insets = Insets.max(source.calculateInsets(frame, true /* ignoreVisibility */), + insets); + } + } + return insets; + } } /** - * Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system - * bar or button bar. See {@link #getNonDecorDisplayFrame}. - * - * @param displayRotation the current display rotation - * @param fullWidth the width of the display, including all insets - * @param fullHeight the height of the display, including all insets - * @param cutout the current display cutout - * @param outInsets the insets to return + * If the decor insets changes, the display configuration may be affected. The caller should + * call {@link DisplayContent#sendNewConfiguration()} if this method returns {@code true}. */ - public void getNonDecorInsetsLw(int displayRotation, int fullWidth, int fullHeight, - WmDisplayCutout cutout, Rect outInsets) { - final DisplayFrames displayFrames = - getSimulatedDisplayFrames(displayRotation, fullWidth, fullHeight, cutout); - getNonDecorInsetsWithSimulatedFrame(displayFrames, outInsets); - } - - void getNonDecorInsetsWithSimulatedFrame(DisplayFrames displayFrames, Rect outInsets) { - outInsets.set(getInsetsWithInternalTypes(displayFrames, NON_DECOR_TYPES).toRect()); - } - - DisplayFrames getSimulatedDisplayFrames(int displayRotation, int fullWidth, - int fullHeight, WmDisplayCutout cutout) { - final DisplayInfo info = new DisplayInfo(mDisplayContent.getDisplayInfo()); - info.rotation = displayRotation; - info.logicalWidth = fullWidth; - info.logicalHeight = fullHeight; - info.displayCutout = cutout.getDisplayCutout(); - final RoundedCorners roundedCorners = - mDisplayContent.calculateRoundedCornersForRotation(displayRotation); - final PrivacyIndicatorBounds indicatorBounds = - mDisplayContent.calculatePrivacyIndicatorBoundsForRotation(displayRotation); - final DisplayFrames displayFrames = new DisplayFrames(getDisplayId(), new InsetsState(), - info, cutout, roundedCorners, indicatorBounds); - simulateLayoutDisplay(displayFrames); - return displayFrames; - } - - @VisibleForTesting - Insets getInsets(DisplayFrames displayFrames, @InsetsType int type) { - final InsetsState state = displayFrames.mInsetsState; - final Insets insets = state.calculateInsets(state.getDisplayFrame(), type, - true /* ignoreVisibility */); - return insets; + boolean updateDecorInsetsInfoIfNeeded(WindowState win) { + if (!win.providesNonDecorInsets()) { + return false; + } + final DisplayFrames displayFrames = mDisplayContent.mDisplayFrames; + final int rotation = displayFrames.mRotation; + final int dw = displayFrames.mWidth; + final int dh = displayFrames.mHeight; + final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo; + newInfo.update(mDisplayContent, rotation, dw, dh); + final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh); + if (newInfo.mNonDecorFrame.equals(currentInfo.mNonDecorFrame)) { + return false; + } + mDecorInsets.invalidate(); + mDecorInsets.mInfoForRotation[rotation].set(newInfo); + // If the device is booting, let the boot procedure trigger the new configuration. + // Otherwise the display configuration needs to be recomputed now. + return mService.mDisplayEnabled; } - Insets getInsetsWithInternalTypes(DisplayFrames displayFrames, - @InternalInsetsType int[] types) { - final InsetsState state = displayFrames.mInsetsState; - final Insets insets = state.calculateInsetsWithInternalTypes(state.getDisplayFrame(), types, - true /* ignoreVisibility */); - return insets; + DecorInsets.Info getDecorInsetsInfo(int rotation, int w, int h) { + return mDecorInsets.get(rotation, w, h); } @NavigationBarPosition @@ -2850,6 +2832,11 @@ public class DisplayPolicy { pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); pw.print(prefix); pw.print("mRemoteInsetsControllerControlsSystemBars="); pw.println(mDisplayContent.getInsetsPolicy().getRemoteInsetsControllerControlsSystemBars()); + pw.print(prefix); pw.println("mDecorInsetsInfo:"); + for (int rotation = 0; rotation < mDecorInsets.mInfoForRotation.length; rotation++) { + final DecorInsets.Info info = mDecorInsets.mInfoForRotation[rotation]; + pw.println(prefixInner + Surface.rotationToString(rotation) + "=" + info); + } mSystemGestures.dump(pw, prefix); pw.print(prefix); pw.println("Looper state:"); diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index ed771c202c04..ac1fbc35325a 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -34,6 +34,7 @@ import android.os.Trace; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; +import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.InsetsState.InternalInsetsType; @@ -44,6 +45,7 @@ import com.android.server.inputmethod.InputMethodManagerInternal; import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.Consumer; +import java.util.function.Function; /** * Manages global window inset state in the system represented by {@link InsetsState}. @@ -86,8 +88,17 @@ class InsetsStateController { } }; + private final Function<Integer, WindowContainerInsetsSourceProvider> mSourceProviderFunc; + InsetsStateController(DisplayContent displayContent) { mDisplayContent = displayContent; + mSourceProviderFunc = type -> { + final InsetsSource source = mState.getSource(type); + if (type == ITYPE_IME) { + return new ImeInsetsSourceProvider(source, this, mDisplayContent); + } + return new WindowContainerInsetsSourceProvider(source, this, mDisplayContent); + }; } InsetsState getRawInsetsState() { @@ -115,15 +126,7 @@ class InsetsStateController { * @return The provider of a specific type. */ WindowContainerInsetsSourceProvider getSourceProvider(@InternalInsetsType int type) { - if (type == ITYPE_IME) { - return mProviders.computeIfAbsent(type, - key -> new ImeInsetsSourceProvider( - mState.getSource(key), this, mDisplayContent)); - } else { - return mProviders.computeIfAbsent(type, - key -> new WindowContainerInsetsSourceProvider(mState.getSource(key), this, - mDisplayContent)); - } + return mProviders.computeIfAbsent(type, mSourceProviderFunc); } ImeInsetsSourceProvider getImeSourceProvider() { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 8872b3526e8c..f09ad99bf9da 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -98,7 +98,6 @@ import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.util.function.pooled.PooledPredicate; import com.android.server.am.HostingRecord; import com.android.server.pm.parsing.pkg.AndroidPackage; -import com.android.server.wm.utils.WmDisplayCutout; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -298,10 +297,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { final Point mLastSurfaceSize = new Point(); - private final Rect mTmpInsets = new Rect(); private final Rect mTmpBounds = new Rect(); private final Rect mTmpFullBounds = new Rect(); + /** For calculating screenWidthDp and screenWidthDp, i.e. the area without the system bars. */ private final Rect mTmpStableBounds = new Rect(); + /** For calculating app bounds, i.e. the area without the nav bar and display cutout. */ private final Rect mTmpNonDecorBounds = new Rect(); //TODO(b/207481538) Remove once the infrastructure to support per-activity screenshot is @@ -2202,21 +2202,16 @@ class TaskFragment extends WindowContainer<WindowContainer> { DisplayInfo displayInfo) { outNonDecorBounds.set(bounds); outStableBounds.set(bounds); - final Task rootTask = getRootTaskFragment().asTask(); - if (rootTask == null || rootTask.mDisplayContent == null) { + if (mDisplayContent == null) { return; } mTmpBounds.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); - final DisplayPolicy policy = rootTask.mDisplayContent.getDisplayPolicy(); - final WmDisplayCutout cutout = - rootTask.mDisplayContent.calculateDisplayCutoutForRotation(displayInfo.rotation); - final DisplayFrames displayFrames = policy.getSimulatedDisplayFrames(displayInfo.rotation, - displayInfo.logicalWidth, displayInfo.logicalHeight, cutout); - policy.getNonDecorInsetsWithSimulatedFrame(displayFrames, mTmpInsets); - intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, mTmpInsets); - policy.getStableInsetsWithSimulatedFrame(displayFrames, mTmpInsets); - intersectWithInsetsIfFits(outStableBounds, mTmpBounds, mTmpInsets); + final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); + final DisplayPolicy.DecorInsets.Info info = policy.getDecorInsetsInfo( + displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight); + intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, info.mNonDecorInsets); + intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets); } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 236d0ddd067a..2f7c6e4284c9 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -318,7 +318,6 @@ import com.android.server.policy.WindowManagerPolicy; import com.android.server.policy.WindowManagerPolicy.ScreenOffListener; import com.android.server.power.ShutdownThread; import com.android.server.utils.PriorityDump; -import com.android.server.wm.utils.WmDisplayCutout; import dalvik.annotation.optimization.NeverCompile; @@ -1834,7 +1833,7 @@ public class WindowManagerService extends IWindowManager.Stub + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5)); if ((win.isVisibleRequestedOrAdding() && displayContent.updateOrientation()) - || win.providesNonDecorInsets()) { + || displayPolicy.updateDecorInsetsInfoIfNeeded(win)) { displayContent.sendNewConfiguration(); } @@ -2230,7 +2229,7 @@ public class WindowManagerService extends IWindowManager.Stub Arrays.fill(outActiveControls, null); } int result = 0; - boolean configChanged; + boolean configChanged = false; final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); @@ -2297,10 +2296,15 @@ public class WindowManagerService extends IWindowManager.Stub flagChanges = win.mAttrs.flags ^ attrs.flags; privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags; attrChanges = win.mAttrs.copyFrom(attrs); - if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED - | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) { + final boolean layoutChanged = + (attrChanges & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0; + if (layoutChanged || (attrChanges + & WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) { win.mLayoutNeeded = true; } + if (layoutChanged) { + configChanged = displayPolicy.updateDecorInsetsInfoIfNeeded(win); + } if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0 || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) { win.mActivityRecord.checkKeyguardFlagsChanged(); @@ -2504,7 +2508,7 @@ public class WindowManagerService extends IWindowManager.Stub } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: updateOrientation"); - configChanged = displayContent.updateOrientation(); + configChanged |= displayContent.updateOrientation(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (toBeDisplayed && win.mIsWallpaper) { @@ -7151,9 +7155,8 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent dc = mRoot.getDisplayContent(displayId); if (dc != null) { final DisplayInfo di = dc.getDisplayInfo(); - final WmDisplayCutout cutout = dc.calculateDisplayCutoutForRotation(di.rotation); - dc.getDisplayPolicy().getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, - cutout, outInsets); + outInsets.set(dc.getDisplayPolicy().getDecorInsetsInfo( + di.rotation, di.logicalWidth, di.logicalHeight).mConfigInsets); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2e7e78db9e05..2706a0465ed6 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2510,6 +2510,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.mSurfaceController, Debug.getCallers(5)); + final DisplayContent displayContent = getDisplayContent(); final long origId = Binder.clearCallingIdentity(); try { @@ -2564,7 +2565,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // Set up a replacement input channel since the app is now dead. // We need to catch tapping on the dead window to restart the app. openInputChannel(null); - getDisplayContent().getInputMonitor().updateInputWindowsLw(true /*force*/); + displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/); return; } @@ -2572,7 +2573,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // usually unnoticeable (e.g. covered by rotation animation) and the animation // bounds could be inconsistent, such as depending on when the window applies // its draw transaction with new rotation. - final boolean allowExitAnimation = !getDisplayContent().inTransition() + final boolean allowExitAnimation = !displayContent.inTransition() // There will be a new window so the exit animation may not be visible or // look weird if its orientation is changed. && !inRelaunchingActivity(); @@ -2622,18 +2623,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } removeImmediately(); - boolean sentNewConfig = false; - if (wasVisible) { - // Removing a visible window will effect the computed orientation - // So just update orientation if needed. - final DisplayContent displayContent = getDisplayContent(); - if (displayContent.updateOrientation()) { - displayContent.sendNewConfiguration(); - sentNewConfig = true; - } - } - if (!sentNewConfig && providesNonDecorInsets()) { - getDisplayContent().sendNewConfiguration(); + // Removing a visible window may affect the display orientation so just update it if + // needed. Also recompute configuration if it provides screen decor insets. + if ((wasVisible && displayContent.updateOrientation()) + || displayContent.getDisplayPolicy().updateDecorInsetsInfoIfNeeded(this)) { + displayContent.sendNewConfiguration(); } mWmService.updateFocusedWindowLocked(isFocused() ? UPDATE_FOCUS_REMOVING_FOCUS diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 25c8f145bd62..6ed84606176a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -158,7 +158,6 @@ import androidx.test.filters.MediumTest; import com.android.internal.R; import com.android.server.wm.ActivityRecord.State; -import com.android.server.wm.utils.WmDisplayCutout; import org.junit.Assert; import org.junit.Before; @@ -552,9 +551,9 @@ public class ActivityRecordTests extends WindowTestsBase { final Rect insets = new Rect(); final DisplayInfo displayInfo = task.mDisplayContent.getDisplayInfo(); final DisplayPolicy policy = task.mDisplayContent.getDisplayPolicy(); - policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, - displayInfo.logicalHeight, WmDisplayCutout.NO_CUTOUT, insets); - policy.convertNonDecorInsetsToStableInsets(insets, displayInfo.rotation); + + insets.set(policy.getDecorInsetsInfo(displayInfo.rotation, displayInfo.logicalWidth, + displayInfo.logicalHeight).mConfigInsets); Task.intersectWithInsetsIfFits(stableRect, stableRect, insets); final boolean isScreenPortrait = stableRect.width() <= stableRect.height(); @@ -594,9 +593,8 @@ public class ActivityRecordTests extends WindowTestsBase { final Rect insets = new Rect(); final DisplayInfo displayInfo = rootTask.mDisplayContent.getDisplayInfo(); final DisplayPolicy policy = rootTask.mDisplayContent.getDisplayPolicy(); - policy.getNonDecorInsetsLw(displayInfo.rotation, displayInfo.logicalWidth, - displayInfo.logicalHeight, WmDisplayCutout.NO_CUTOUT, insets); - policy.convertNonDecorInsetsToStableInsets(insets, displayInfo.rotation); + insets.set(policy.getDecorInsetsInfo(displayInfo.rotation, displayInfo.logicalWidth, + displayInfo.logicalHeight).mConfigInsets); Task.intersectWithInsetsIfFits(stableRect, stableRect, insets); final boolean isScreenPortrait = stableRect.width() <= stableRect.height(); @@ -2986,31 +2984,27 @@ public class ActivityRecordTests extends WindowTestsBase { } @Test - public void testCloseToSquareFixedOrientationPortrait() { + public void testCloseToSquareFixedOrientation() { // create a square display final DisplayContent squareDisplay = new TestDisplayContent.Builder(mAtm, 2000, 2000) .setSystemDecorations(true).build(); + // Add a decor insets provider window. + final WindowState navbar = createNavBarWithProvidedInsets(squareDisplay); + squareDisplay.getDisplayPolicy().updateDecorInsetsInfoIfNeeded(navbar); final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build(); // create a fixed portrait activity - final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task) + ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task) .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT).build(); - // check that both the configuration and app bounds are portrait + // The available space could be landscape because of decor insets, but the configuration + // should still respect the requested portrait orientation. assertEquals(ORIENTATION_PORTRAIT, activity.getConfiguration().orientation); assertTrue(activity.getConfiguration().windowConfiguration.getAppBounds().width() <= activity.getConfiguration().windowConfiguration.getAppBounds().height()); - } - - @Test - public void testCloseToSquareFixedOrientationLandscape() { - // create a square display - final DisplayContent squareDisplay = new TestDisplayContent.Builder(mAtm, 2000, 2000) - .setSystemDecorations(true).build(); - final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build(); // create a fixed landscape activity - final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task) + activity = new ActivityBuilder(mAtm).setTask(task) .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE).build(); // check that both the configuration and app bounds are landscape 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 aa5a74e962e6..0a59ae159390 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java @@ -25,13 +25,10 @@ import static org.hamcrest.Matchers.equalTo; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; -import android.util.Pair; import android.view.DisplayInfo; import androidx.test.filters.SmallTest; -import com.android.server.wm.utils.WmDisplayCutout; - import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; @@ -49,8 +46,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void portrait() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_0, false /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_0, false /* withCutout */); verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); @@ -59,8 +55,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void portrait_withCutout() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_0, true /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_0, true /* withCutout */); verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); verifyNonDecorInsets(di, 0, DISPLAY_CUTOUT_HEIGHT, 0, NAV_BAR_HEIGHT); @@ -69,8 +64,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void landscape() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_90, false /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_90, false /* withCutout */); if (mDisplayPolicy.navigationBarCanMove()) { verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); @@ -85,8 +79,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void landscape_withCutout() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_90, true /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_90, true /* withCutout */); if (mDisplayPolicy.navigationBarCanMove()) { verifyStableInsets(di, DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); @@ -101,8 +94,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void seascape() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_270, false /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_270, false /* withCutout */); if (mDisplayPolicy.navigationBarCanMove()) { verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0); @@ -117,8 +109,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void seascape_withCutout() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_270, true /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_270, true /* withCutout */); if (mDisplayPolicy.navigationBarCanMove()) { verifyStableInsets(di, NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0); @@ -133,8 +124,7 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void upsideDown() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_180, false /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_180, false /* withCutout */); verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT); @@ -143,34 +133,32 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { @Test public void upsideDown_withCutout() { - final Pair<DisplayInfo, WmDisplayCutout> di = - displayInfoForRotation(ROTATION_180, true /* withCutout */); + final DisplayInfo di = displayInfoForRotation(ROTATION_180, true /* withCutout */); verifyStableInsets(di, 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT); verifyNonDecorInsets(di, 0, 0, 0, NAV_BAR_HEIGHT + DISPLAY_CUTOUT_HEIGHT); verifyConsistency(di); } - private void verifyStableInsets(Pair<DisplayInfo, WmDisplayCutout> diPair, int left, int top, + private void verifyStableInsets(DisplayInfo di, int left, int top, int right, int bottom) { - mErrorCollector.checkThat("stableInsets", getStableInsetsLw(diPair.first, diPair.second), + mErrorCollector.checkThat("stableInsets", getStableInsets(di), equalTo(new Rect(left, top, right, bottom))); } - private void verifyNonDecorInsets(Pair<DisplayInfo, WmDisplayCutout> diPair, int left, int top, + private void verifyNonDecorInsets(DisplayInfo di, int left, int top, int right, int bottom) { mErrorCollector.checkThat("nonDecorInsets", - getNonDecorInsetsLw(diPair.first, diPair.second), equalTo(new Rect( - left, top, right, bottom))); + getNonDecorInsets(di), equalTo(new Rect(left, top, right, bottom))); } - private void verifyConsistency(Pair<DisplayInfo, WmDisplayCutout> diPair) { - final DisplayInfo di = diPair.first; - final WmDisplayCutout cutout = diPair.second; - verifyConsistency("configDisplay", di, getStableInsetsLw(di, cutout), - getConfigDisplayWidth(di, cutout), getConfigDisplayHeight(di, cutout)); - verifyConsistency("nonDecorDisplay", di, getNonDecorInsetsLw(di, cutout), - getNonDecorDisplayWidth(di, cutout), getNonDecorDisplayHeight(di, cutout)); + private void verifyConsistency(DisplayInfo di) { + final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo( + di.rotation, di.logicalWidth, di.logicalHeight); + verifyConsistency("configDisplay", di, info.mConfigInsets, + info.mConfigFrame.width(), info.mConfigFrame.height()); + verifyConsistency("nonDecorDisplay", di, info.mNonDecorInsets, + info.mNonDecorFrame.width(), info.mNonDecorFrame.height()); } private void verifyConsistency(String what, DisplayInfo di, Rect insets, int width, @@ -181,42 +169,18 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { equalTo(di.logicalHeight - insets.top - insets.bottom)); } - private Rect getStableInsetsLw(DisplayInfo di, WmDisplayCutout cutout) { - Rect result = new Rect(); - mDisplayPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, - cutout, result); - return result; - } - - private Rect getNonDecorInsetsLw(DisplayInfo di, WmDisplayCutout cutout) { - Rect result = new Rect(); - mDisplayPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, - cutout, result); - return result; - } - - private int getNonDecorDisplayWidth(DisplayInfo di, WmDisplayCutout cutout) { - return mDisplayPolicy.getNonDecorDisplayFrame(di.logicalWidth, di.logicalHeight, - di.rotation, cutout).width(); - } - - private int getNonDecorDisplayHeight(DisplayInfo di, WmDisplayCutout cutout) { - return mDisplayPolicy.getNonDecorDisplayFrame(di.logicalWidth, di.logicalHeight, - di.rotation, cutout).height(); - } - - private int getConfigDisplayWidth(DisplayInfo di, WmDisplayCutout cutout) { - return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight, - di.rotation, cutout).x; + private Rect getStableInsets(DisplayInfo di) { + return mDisplayPolicy.getDecorInsetsInfo( + di.rotation, di.logicalWidth, di.logicalHeight).mConfigInsets; } - private int getConfigDisplayHeight(DisplayInfo di, WmDisplayCutout cutout) { - return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight, - di.rotation, cutout).y; + private Rect getNonDecorInsets(DisplayInfo di) { + return mDisplayPolicy.getDecorInsetsInfo( + di.rotation, di.logicalWidth, di.logicalHeight).mNonDecorInsets; } - private static Pair<DisplayInfo, WmDisplayCutout> displayInfoForRotation(int rotation, - boolean withDisplayCutout) { - return displayInfoAndCutoutForRotation(rotation, withDisplayCutout, false); + private DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) { + return displayInfoAndCutoutForRotation( + rotation, withDisplayCutout, false /* isLongEdgeCutout */); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 6bdc2e35a7be..70b68c78f092 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -41,7 +41,6 @@ import static org.testng.Assert.expectThrows; import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; -import android.util.Pair; import android.view.DisplayInfo; import android.view.InsetsFrameProvider; import android.view.InsetsState; @@ -50,8 +49,6 @@ import android.view.RoundedCorners; import androidx.test.filters.SmallTest; -import com.android.server.wm.utils.WmDisplayCutout; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -123,7 +120,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { private void updateDisplayFrames() { mFrames = createDisplayFrames( mDisplayContent.getInsetsStateController().getRawInsetsState()); - mDisplayBounds.set(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight); + mDisplayBounds.set(0, 0, mFrames.mWidth, mFrames.mHeight); mDisplayContent.mDisplayFrames = mFrames; mDisplayContent.setBounds(mDisplayBounds); mDisplayPolicy.layoutWindowLw(mNavBarWindow, null, mFrames); @@ -131,13 +128,13 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { } private DisplayFrames createDisplayFrames(InsetsState insetsState) { - final Pair<DisplayInfo, WmDisplayCutout> info = displayInfoAndCutoutForRotation(mRotation, + final DisplayInfo info = displayInfoAndCutoutForRotation(mRotation, mHasDisplayCutout, mIsLongEdgeDisplayCutout); final RoundedCorners roundedCorners = mHasRoundedCorners ? mDisplayContent.calculateRoundedCornersForRotation(mRotation) : RoundedCorners.NO_ROUNDED_CORNERS; - return new DisplayFrames(mDisplayContent.getDisplayId(), - insetsState, info.first, info.second, roundedCorners, new PrivacyIndicatorBounds()); + return new DisplayFrames(insetsState, info, + info.displayCutout, roundedCorners, new PrivacyIndicatorBounds()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index 9cc665bd4cbe..262b141e6005 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.view.DisplayCutout.NO_CUTOUT; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; @@ -35,13 +36,12 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BA import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; -import static com.android.server.wm.utils.WmDisplayCutout.NO_CUTOUT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -286,10 +286,18 @@ public class DisplayPolicyTests extends WindowTestsBase { DisplayPolicy.isOverlappingWithNavBar(targetWin)); } - private WindowState createNavigationBarWindow() { - final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar"); - win.mHasSurface = true; - return win; + @Test + public void testUpdateDisplayConfigurationByDecor() { + final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent); + final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy(); + final DisplayInfo di = mDisplayContent.getDisplayInfo(); + final int prevScreenHeightDp = mDisplayContent.getConfiguration().screenHeightDp; + assertTrue(displayPolicy.updateDecorInsetsInfoIfNeeded(navbar)); + assertEquals(NAV_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation, + di.logicalWidth, di.logicalHeight).mConfigInsets.bottom); + mDisplayContent.sendNewConfiguration(); + assertNotEquals(prevScreenHeightDp, mDisplayContent.getConfiguration().screenHeightDp); + assertFalse(displayPolicy.updateDecorInsetsInfoIfNeeded(navbar)); } @SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD }) @@ -307,7 +315,7 @@ public class DisplayPolicyTests extends WindowTestsBase { mNavBarWindow.getControllableInsetProvider().setServerVisible(true); final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState(); mImeWindow.mAboveInsetsState.set(state); - mDisplayContent.mDisplayFrames = new DisplayFrames(mDisplayContent.getDisplayId(), + mDisplayContent.mDisplayFrames = new DisplayFrames( state, displayInfo, NO_CUTOUT, NO_ROUNDED_CORNERS, new PrivacyIndicatorBounds()); mDisplayContent.setInputMethodWindowLocked(mImeWindow); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java index 97b1c91d156a..fe890d56cbac 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java @@ -30,25 +30,14 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyInt; -import android.content.Context; -import android.content.ContextWrapper; -import android.content.pm.PackageManager; -import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.RectF; import android.os.Binder; -import android.os.IBinder; -import android.testing.TestableResources; -import android.util.Pair; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.WindowManagerGlobal; -import com.android.internal.R; -import com.android.server.wm.utils.WmDisplayCutout; - import org.junit.Before; public class DisplayPolicyTestsBase extends WindowTestsBase { @@ -69,23 +58,8 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { mDisplayPolicy = mDisplayContent.getDisplayPolicy(); spyOn(mDisplayPolicy); - - final TestContextWrapper context = new TestContextWrapper( - mDisplayPolicy.getContext(), mDisplayPolicy.getCurrentUserResources()); - final TestableResources resources = context.getResourceMocker(); - resources.addOverride(R.dimen.navigation_bar_height, NAV_BAR_HEIGHT); - resources.addOverride(R.dimen.navigation_bar_height_landscape, NAV_BAR_HEIGHT); - resources.addOverride(R.dimen.navigation_bar_width, NAV_BAR_HEIGHT); - resources.addOverride(R.dimen.navigation_bar_frame_height_landscape, NAV_BAR_HEIGHT); - resources.addOverride(R.dimen.navigation_bar_frame_height, NAV_BAR_HEIGHT); - doReturn(STATUS_BAR_HEIGHT).when(mDisplayPolicy).getStatusBarHeightForRotation(anyInt()); - doReturn(resources.getResources()).when(mDisplayPolicy).getCurrentUserResources(); doReturn(true).when(mDisplayPolicy).hasNavigationBar(); doReturn(true).when(mDisplayPolicy).hasStatusBar(); - - mDisplayContent.getDisplayRotation().configure(DISPLAY_WIDTH, DISPLAY_HEIGHT); - mDisplayPolicy.onConfigurationChanged(); - addWindow(mStatusBarWindow); addWindow(mNavBarWindow); @@ -101,24 +75,20 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { win.mHasSurface = true; } - static Pair<DisplayInfo, WmDisplayCutout> displayInfoAndCutoutForRotation(int rotation, - boolean withDisplayCutout, boolean isLongEdgeCutout) { - final DisplayInfo info = new DisplayInfo(); - WmDisplayCutout cutout = WmDisplayCutout.NO_CUTOUT; - + DisplayInfo displayInfoAndCutoutForRotation(int rotation, boolean withDisplayCutout, + boolean isLongEdgeCutout) { + final DisplayInfo info = mDisplayContent.getDisplayInfo(); final boolean flippedDimensions = rotation == ROTATION_90 || rotation == ROTATION_270; info.logicalWidth = flippedDimensions ? DISPLAY_HEIGHT : DISPLAY_WIDTH; info.logicalHeight = flippedDimensions ? DISPLAY_WIDTH : DISPLAY_HEIGHT; info.rotation = rotation; - if (withDisplayCutout) { - cutout = WmDisplayCutout.computeSafeInsets( - displayCutoutForRotation(rotation, isLongEdgeCutout), info.logicalWidth, - info.logicalHeight); - info.displayCutout = cutout.getDisplayCutout(); - } else { - info.displayCutout = null; - } - return Pair.create(info, cutout); + mDisplayContent.mInitialDisplayCutout = withDisplayCutout + ? displayCutoutForRotation(ROTATION_0, isLongEdgeCutout) + : DisplayCutout.NO_CUTOUT; + info.displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(rotation); + mDisplayContent.updateBaseDisplayMetrics(DISPLAY_WIDTH, DISPLAY_HEIGHT, + info.logicalDensityDpi, info.physicalXDpi, info.physicalYDpi); + return info; } private static DisplayCutout displayCutoutForRotation(int rotation, boolean isLongEdgeCutout) { @@ -152,33 +122,4 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { return DisplayCutout.fromBoundingRect((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom, pos); } - - static class TestContextWrapper extends ContextWrapper { - private final TestableResources mResourceMocker; - - TestContextWrapper(Context targetContext, Resources targetResources) { - super(targetContext); - mResourceMocker = new TestableResources(targetResources); - } - - @Override - public int checkPermission(String permission, int pid, int uid) { - return PackageManager.PERMISSION_GRANTED; - } - - @Override - public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { - return PackageManager.PERMISSION_GRANTED; - } - - @Override - public Resources getResources() { - return mResourceMocker.getResources(); - } - - TestableResources getResourceMocker() { - return mResourceMocker; - } - } - } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index 892b5f9d6753..89f71110f3c2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -20,6 +20,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.view.DisplayCutout.NO_CUTOUT; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED; @@ -68,7 +69,6 @@ import com.android.server.LocalServices; import com.android.server.UiThread; import com.android.server.policy.WindowManagerPolicy; import com.android.server.statusbar.StatusBarManagerInternal; -import com.android.server.wm.utils.WmDisplayCutout; import org.junit.After; import org.junit.AfterClass; @@ -1008,7 +1008,7 @@ public class DisplayRotationTests { mMockDisplayContent = mock(DisplayContent.class); mMockDisplayContent.isDefaultDisplay = mIsDefaultDisplay; when(mMockDisplayContent.calculateDisplayCutoutForRotation(anyInt())) - .thenReturn(WmDisplayCutout.NO_CUTOUT); + .thenReturn(NO_CUTOUT); when(mMockDisplayContent.getDefaultTaskDisplayArea()) .thenReturn(mock(TaskDisplayArea.class)); when(mMockDisplayContent.getWindowConfiguration()) diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 17387061a86e..646f43cbdb5c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -3133,8 +3133,8 @@ public class SizeCompatTests extends WindowTestsBase { } private static void resizeDisplay(DisplayContent displayContent, int width, int height) { - displayContent.mBaseDisplayWidth = width; - displayContent.mBaseDisplayHeight = height; + displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity, + displayContent.mBaseDisplayPhysicalXDpi, displayContent.mBaseDisplayPhysicalYDpi); final Configuration c = new Configuration(); displayContent.computeScreenConfiguration(c); displayContent.onRequestedOverrideConfigurationChanged(c); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index 6a7e388dc0b8..787827eceaf0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -36,7 +36,6 @@ import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_90; import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; @@ -692,12 +691,9 @@ public class TaskTests extends WindowTestsBase { // Setup the display with a top stable inset. The later assertion will ensure the inset is // excluded from screenHeightDp. final int statusBarHeight = 100; - final DisplayPolicy policy = display.getDisplayPolicy(); - doAnswer(invocationOnMock -> { - final Rect insets = invocationOnMock.<Rect>getArgument(0); - insets.top = statusBarHeight; - return null; - }).when(policy).convertNonDecorInsetsToStableInsets(any(), eq(ROTATION_0)); + final DisplayInfo di = display.getDisplayInfo(); + display.getDisplayPolicy().getDecorInsetsInfo(di.rotation, + di.logicalWidth, di.logicalHeight).mConfigInsets.top = statusBarHeight; // Without limiting to be inside the parent bounds, the out screen size should keep relative // to the input bounds. diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java index f5304d00faab..aa3ca18073c3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java @@ -18,13 +18,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; -import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT; -import static android.view.InsetsState.ITYPE_CLIMATE_BAR; -import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT; -import static android.view.InsetsState.ITYPE_STATUS_BAR; -import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT; import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -33,7 +26,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import android.annotation.Nullable; @@ -47,7 +39,6 @@ import android.util.DisplayMetrics; import android.view.Display; import android.view.DisplayCutout; import android.view.DisplayInfo; -import android.view.WindowInsets; import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry; @@ -209,26 +200,6 @@ class TestDisplayContent extends DisplayContent { doReturn(true).when(newDisplay).supportsSystemDecorations(); doReturn(true).when(displayPolicy).hasNavigationBar(); doReturn(NAV_BAR_BOTTOM).when(displayPolicy).navigationBarPosition(anyInt()); - doReturn(Insets.of(0, 0, 0, 20)).when(displayPolicy).getInsets(any(), - eq(WindowInsets.Type.displayCutout() | WindowInsets.Type.navigationBars())); - doReturn(Insets.of(0, 20, 0, 20)).when(displayPolicy).getInsets(any(), - eq(WindowInsets.Type.displayCutout() | WindowInsets.Type.navigationBars() - | WindowInsets.Type.statusBars())); - final int[] nonDecorTypes = new int[]{ - ITYPE_TOP_DISPLAY_CUTOUT, ITYPE_RIGHT_DISPLAY_CUTOUT, - ITYPE_BOTTOM_DISPLAY_CUTOUT, ITYPE_LEFT_DISPLAY_CUTOUT, ITYPE_NAVIGATION_BAR - }; - doReturn(Insets.of(0, 0, 0, 20)).when(displayPolicy).getInsetsWithInternalTypes( - any(), - eq(nonDecorTypes)); - final int[] stableTypes = new int[]{ - ITYPE_TOP_DISPLAY_CUTOUT, ITYPE_RIGHT_DISPLAY_CUTOUT, - ITYPE_BOTTOM_DISPLAY_CUTOUT, ITYPE_LEFT_DISPLAY_CUTOUT, - ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR, ITYPE_CLIMATE_BAR - }; - doReturn(Insets.of(0, 20, 0, 20)).when(displayPolicy).getInsetsWithInternalTypes( - any(), - eq(stableTypes)); } else { doReturn(false).when(displayPolicy).hasNavigationBar(); doReturn(false).when(displayPolicy).hasStatusBar(); @@ -241,11 +212,6 @@ class TestDisplayContent extends DisplayContent { displayPolicy.finishScreenTurningOn(); if (mStatusBarHeight > 0) { doReturn(true).when(displayPolicy).hasStatusBar(); - doAnswer(invocation -> { - Rect inOutInsets = (Rect) invocation.getArgument(0); - inOutInsets.top = mStatusBarHeight; - return null; - }).when(displayPolicy).convertNonDecorInsetsToStableInsets(any(), anyInt()); } Configuration c = new Configuration(); newDisplay.computeScreenConfiguration(c); diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index 82887135c73d..63335086859d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java @@ -52,6 +52,7 @@ import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.InsetsState; @@ -63,8 +64,6 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; -import com.android.server.wm.utils.WmDisplayCutout; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -164,8 +163,8 @@ public class WallpaperControllerTests extends WindowTestsBase { // Apply the fixed transform Configuration config = new Configuration(); final DisplayInfo info = dc.computeScreenConfiguration(config, Surface.ROTATION_0); - final WmDisplayCutout cutout = dc.calculateDisplayCutoutForRotation(Surface.ROTATION_0); - final DisplayFrames displayFrames = new DisplayFrames(dc.getDisplayId(), new InsetsState(), + final DisplayCutout cutout = dc.calculateDisplayCutoutForRotation(Surface.ROTATION_0); + final DisplayFrames displayFrames = new DisplayFrames(new InsetsState(), info, cutout, RoundedCorners.NO_ROUNDED_CORNERS, new PrivacyIndicatorBounds()); wallpaperWindow.mToken.applyFixedRotationTransform(info, displayFrames, config); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 6785979e2065..353b757e985e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -26,6 +26,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.os.Process.SYSTEM_UID; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.View.VISIBLE; import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; @@ -69,6 +70,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.graphics.Insets; import android.graphics.Rect; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManager; @@ -84,6 +86,7 @@ import android.view.DisplayInfo; import android.view.Gravity; import android.view.IDisplayWindowInsetsController; import android.view.IWindow; +import android.view.InsetsFrameProvider; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.InsetsVisibilities; @@ -419,6 +422,15 @@ class WindowTestsBase extends SystemServiceTestsBase { true /* ownerCanManageAppTokens */); } + WindowState createNavBarWithProvidedInsets(DisplayContent dc) { + final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, dc, "navbar"); + navbar.mAttrs.providedInsets = new InsetsFrameProvider[] { + new InsetsFrameProvider(ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, NAV_BAR_HEIGHT)) + }; + dc.getDisplayPolicy().addWindowLw(navbar, navbar.mAttrs); + return navbar; + } + WindowState createAppWindow(Task task, int type, String name) { final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent()); task.addChild(activity, 0); |