Make SHORT_EDGES mode only extends on the short edges

- In R, we allow long edge cutouts and therefore a new ALWAYS flag is
added which allow apps to be laid out in all edges. So now we have to
ensure apps with SHORT_EDGES mode to be laid out only in short edges.

- Set wallpapaer window to ALWAYS mode

Bug: 146876976
Test: atest DisplayPolicyLayoutTests
Test: atest WallpaperTests
Change-Id: Iaf820b5c8105927e61b30d389a659b9d28db3f94
This commit is contained in:
shawnlin
2020-02-11 20:45:35 +08:00
parent ed1e5bb875
commit 465b7dea75
5 changed files with 164 additions and 18 deletions

View File

@@ -3687,6 +3687,8 @@ public interface WindowManager extends ViewManager {
return "always";
case LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:
return "never";
case LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:
return "shortEdges";
default:
return "unknown(" + mode + ")";
}

View File

@@ -57,8 +57,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATIO
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
@@ -855,7 +855,7 @@ public class DisplayPolicy {
case TYPE_WALLPAPER:
// Dreams and wallpapers don't have an app window token and can thus not be
// letterboxed. Hence always let them extend under the cutout.
attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
break;
case TYPE_NOTIFICATION_SHADE:
// If the Keyguard is in a hidden state (occluded by another window), we force to
@@ -2298,15 +2298,24 @@ public class DisplayPolicy {
// cropped / shifted to the displayFrame in WindowState.
final boolean floatingInScreenWindow = !attrs.isFullscreen() && layoutInScreen
&& type != TYPE_BASE_APPLICATION;
// Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
// the cutout safe zone.
if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
|| cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
if (displayFrames.mDisplayWidth < displayFrames.mDisplayHeight) {
displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
} else {
displayCutoutSafeExceptMaybeBars.left = Integer.MIN_VALUE;
displayCutoutSafeExceptMaybeBars.right = Integer.MAX_VALUE;
}
}
if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
&& cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
&& (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
|| cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) {
// At the top we have the status bar, so apps that are
// LAYOUT_IN_SCREEN | LAYOUT_INSET_DECOR but not FULLSCREEN
// already expect that there's an inset there and we don't need to exclude
@@ -2314,7 +2323,8 @@ public class DisplayPolicy {
displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
}
if (layoutInScreen && layoutInsetDecor && !requestedHideNavigation
&& cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
&& (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
|| cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) {
// Same for the navigation bar.
switch (mNavigationBarPosition) {
case NAV_BAR_BOTTOM:

View File

@@ -174,6 +174,6 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase {
}
private static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) {
return displayInfoAndCutoutForRotation(rotation, withDisplayCutout).first;
return displayInfoAndCutoutForRotation(rotation, withDisplayCutout, false).first;
}
}

View File

@@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -91,6 +92,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
private WindowState mWindow;
private int mRotation = ROTATION_0;
private boolean mHasDisplayCutout;
private boolean mIsLongEdgeDisplayCutout;
private static final int DECOR_WINDOW_INSET = 50;
@Before
@@ -124,6 +126,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
updateDisplayFrames();
}
public void addLongEdgeDisplayCutout() {
mHasDisplayCutout = true;
mIsLongEdgeDisplayCutout = true;
updateDisplayFrames();
}
private void updateDisplayFrames() {
mFrames = createDisplayFrames();
mDisplayContent.mDisplayFrames = mFrames;
@@ -131,7 +139,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
private DisplayFrames createDisplayFrames() {
final Pair<DisplayInfo, WmDisplayCutout> info = displayInfoAndCutoutForRotation(mRotation,
mHasDisplayCutout);
mHasDisplayCutout, mIsLongEdgeDisplayCutout);
return new DisplayFrames(mDisplayContent.getDisplayId(), info.first, info.second);
}
@@ -375,6 +383,46 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_shortEdges() {
addDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_always() {
addDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
addDisplayCutout();
@@ -550,6 +598,88 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withLongEdgeDisplayCutout() {
addLongEdgeDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
public void layoutWindowLw_withLongEdgeDisplayCutout_never() {
addLongEdgeDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
public void layoutWindowLw_withLongEdgeDisplayCutout_shortEdges() {
addLongEdgeDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
public void layoutWindowLw_withLongEdgeDisplayCutout_always() {
addLongEdgeDisplayCutout();
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
addWindow(mWindow);
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
NAV_BAR_HEIGHT);
assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() {
assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_NONE);

View File

@@ -111,7 +111,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
}
static Pair<DisplayInfo, WmDisplayCutout> displayInfoAndCutoutForRotation(int rotation,
boolean withDisplayCutout) {
boolean withDisplayCutout, boolean isLongEdgeCutout) {
final DisplayInfo info = new DisplayInfo();
WmDisplayCutout cutout = null;
@@ -121,7 +121,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
info.rotation = rotation;
if (withDisplayCutout) {
cutout = WmDisplayCutout.computeSafeInsets(
displayCutoutForRotation(rotation), info.logicalWidth,
displayCutoutForRotation(rotation, isLongEdgeCutout), info.logicalWidth,
info.logicalHeight);
info.displayCutout = cutout.getDisplayCutout();
} else {
@@ -130,9 +130,13 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
return Pair.create(info, cutout);
}
private static DisplayCutout displayCutoutForRotation(int rotation) {
final RectF rectF =
new RectF(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT);
private static DisplayCutout displayCutoutForRotation(int rotation, boolean isLongEdgeCutout) {
RectF rectF = new RectF();
if (isLongEdgeCutout) {
rectF.set(0, DISPLAY_HEIGHT / 4, DISPLAY_CUTOUT_HEIGHT, DISPLAY_HEIGHT * 3 / 4);
} else {
rectF.set(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT);
}
final Matrix m = new Matrix();
transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m);
@@ -141,16 +145,16 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
int pos = -1;
switch (rotation) {
case ROTATION_0:
pos = BOUNDS_POSITION_TOP;
pos = isLongEdgeCutout ? BOUNDS_POSITION_LEFT : BOUNDS_POSITION_TOP;
break;
case ROTATION_90:
pos = BOUNDS_POSITION_LEFT;
pos = isLongEdgeCutout ? BOUNDS_POSITION_BOTTOM : BOUNDS_POSITION_LEFT;
break;
case ROTATION_180:
pos = BOUNDS_POSITION_BOTTOM;
pos = isLongEdgeCutout ? BOUNDS_POSITION_RIGHT : BOUNDS_POSITION_BOTTOM;
break;
case ROTATION_270:
pos = BOUNDS_POSITION_RIGHT;
pos = isLongEdgeCutout ? BOUNDS_POSITION_TOP : BOUNDS_POSITION_RIGHT;
break;
}