From 1c717014b63071035ff1697b9463691658483faf Mon Sep 17 00:00:00 2001 From: Tiger Date: Fri, 6 Jan 2023 20:04:21 +0800 Subject: [PATCH] Don't let display cutout safe area be affected by status bar Otherwise, we will get a big gap at the top edge of display while playing landscape games on a device with waterfall cutout. The original logic was to avoid that fullscreen apps will cut halfway into the status bar. However, for non-waterfall cases, it can be avoided by setting the height of display cutout the same as the height of status bar. For the waterfall cases, althrough apps cut halfway into the status bar, but they don't cut into the icons of status bar. This should be fine. This CL also removes ITYPEs from WindowLayout and WindowLayoutTests, and moves WindowLayoutTests to coretests. Fix: 264640845 Bug: 234093736 Test: atest WindowLayoutTests Change-Id: Iaec9bf50b45f8f6e27695a4267cf323ae640c680 --- core/java/android/view/WindowLayout.java | 25 +++------ .../src/android/view}/WindowLayoutTests.java | 52 +++++++++---------- 2 files changed, 32 insertions(+), 45 deletions(-) rename {services/tests/wmtests/src/com/android/server/wm => core/tests/coretests/src/android/view}/WindowLayoutTests.java (89%) diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java index 5ec52196d02cc..3b8298ed3627d 100644 --- a/core/java/android/view/WindowLayout.java +++ b/core/java/android/view/WindowLayout.java @@ -17,9 +17,9 @@ package android.view; import static android.view.InsetsSource.ID_IME; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.systemBars; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; @@ -109,14 +109,6 @@ public class WindowLayout { // Ensure that windows with a non-ALWAYS display cutout mode are laid out in // the cutout safe zone. final Rect displayFrame = state.getDisplayFrame(); - final InsetsSource statusBarSource = state.peekSource(ITYPE_STATUS_BAR); - if (statusBarSource != null && displayCutoutSafe.top > displayFrame.top) { - // Make sure that the zone we're avoiding for the cutout is at least as tall as the - // status bar; otherwise fullscreen apps will end up cutting halfway into the status - // bar. - displayCutoutSafeExceptMaybeBars.top = - Math.max(statusBarSource.getFrame().bottom, displayCutoutSafe.top); - } if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) { if (displayFrame.width() < displayFrame.height()) { displayCutoutSafeExceptMaybeBars.top = MIN_Y; @@ -131,7 +123,7 @@ public class WindowLayout { && (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) { final Insets systemBarsInsets = state.calculateInsets( - displayFrame, WindowInsets.Type.systemBars(), requestedVisibleTypes); + displayFrame, systemBars(), requestedVisibleTypes); if (systemBarsInsets.left > 0) { displayCutoutSafeExceptMaybeBars.left = MIN_X; } @@ -145,12 +137,11 @@ public class WindowLayout { displayCutoutSafeExceptMaybeBars.bottom = MAX_Y; } } - if (type == TYPE_INPUT_METHOD) { - final InsetsSource navSource = state.peekSource(ITYPE_NAVIGATION_BAR); - if (navSource != null && navSource.calculateInsets(displayFrame, true).bottom > 0) { - // The IME can always extend under the bottom cutout if the navbar is there. - displayCutoutSafeExceptMaybeBars.bottom = MAX_Y; - } + if (type == TYPE_INPUT_METHOD + && displayCutoutSafeExceptMaybeBars.bottom != MAX_Y + && state.calculateInsets(displayFrame, navigationBars(), true).bottom > 0) { + // The IME can always extend under the bottom cutout if the navbar is there. + displayCutoutSafeExceptMaybeBars.bottom = MAX_Y; } final boolean attachedInParent = attachedWindowFrame != null && !layoutInScreen; diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java b/core/tests/coretests/src/android/view/WindowLayoutTests.java similarity index 89% rename from services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java rename to core/tests/coretests/src/android/view/WindowLayoutTests.java index 731a2351fc4d7..5cac98daee80d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java +++ b/core/tests/coretests/src/android/view/WindowLayoutTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,11 +14,9 @@ * limitations under the License. */ -package com.android.server.wm; +package android.view; import static android.view.InsetsSource.ID_IME; -import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; -import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.navigationBars; @@ -39,13 +37,6 @@ import android.app.WindowConfiguration; import android.graphics.Insets; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; -import android.view.DisplayCutout; -import android.view.Gravity; -import android.view.InsetsSource; -import android.view.InsetsState; -import android.view.WindowInsets; -import android.view.WindowLayout; -import android.view.WindowManager; import android.window.ClientWindowFrames; import androidx.test.filters.SmallTest; @@ -72,6 +63,11 @@ public class WindowLayoutTests { new Rect(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT); private static final Insets WATERFALL_INSETS = Insets.of(6, 0, 12, 0); + private static final int ID_STATUS_BAR = InsetsSource.createId( + null /* owner */, 0 /* index */, statusBars()); + private static final int ID_NAVIGATION_BAR = InsetsSource.createId( + null /* owner */, 0 /* index */, navigationBars()); + private final WindowLayout mWindowLayout = new WindowLayout(); private final ClientWindowFrames mFrames = new ClientWindowFrames(); @@ -90,9 +86,9 @@ public class WindowLayoutTests { mAttrs = new WindowManager.LayoutParams(); mState = new InsetsState(); mState.setDisplayFrame(new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT)); - mState.getOrCreateSource(ITYPE_STATUS_BAR, statusBars()).setFrame( + mState.getOrCreateSource(ID_STATUS_BAR, statusBars()).setFrame( 0, 0, DISPLAY_WIDTH, STATUS_BAR_HEIGHT); - mState.getOrCreateSource(ITYPE_NAVIGATION_BAR, navigationBars()).setFrame( + mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars()).setFrame( 0, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT); mState.getDisplayCutoutSafe(mDisplayCutoutSafe); mWindowBounds = new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT); @@ -268,8 +264,8 @@ public class WindowLayoutTests { @Test public void fitInvisibleInsets() { - mState.setSourceVisible(ITYPE_STATUS_BAR, false); - mState.setSourceVisible(ITYPE_NAVIGATION_BAR, false); + mState.setSourceVisible(ID_STATUS_BAR, false); + mState.setSourceVisible(ID_NAVIGATION_BAR, false); computeFrames(); assertInsetByTopBottom(0, 0, mFrames.displayFrame); @@ -279,8 +275,8 @@ public class WindowLayoutTests { @Test public void fitInvisibleInsetsIgnoringVisibility() { - mState.setSourceVisible(ITYPE_STATUS_BAR, false); - mState.setSourceVisible(ITYPE_NAVIGATION_BAR, false); + mState.setSourceVisible(ID_STATUS_BAR, false); + mState.setSourceVisible(ID_NAVIGATION_BAR, false); mAttrs.setFitInsetsIgnoringVisibility(true); computeFrames(); @@ -324,11 +320,11 @@ public class WindowLayoutTests { mAttrs.setFitInsetsTypes(0); computeFrames(); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.displayFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.parentFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.frame); } @@ -365,17 +361,17 @@ public class WindowLayoutTests { @Test public void layoutInDisplayCutoutModeDefaultWithInvisibleSystemBars() { addDisplayCutout(); - mState.setSourceVisible(ITYPE_STATUS_BAR, false); - mState.setSourceVisible(ITYPE_NAVIGATION_BAR, false); + mState.setSourceVisible(ID_STATUS_BAR, false); + mState.setSourceVisible(ID_NAVIGATION_BAR, false); mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; mAttrs.setFitInsetsTypes(0); computeFrames(); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.displayFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.parentFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.frame); } @@ -398,11 +394,11 @@ public class WindowLayoutTests { mAttrs.setFitInsetsTypes(0); computeFrames(); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.displayFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.parentFrame); - assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0, + assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0, mFrames.frame); }