Merge "Don't let display cutout safe area be affected by status bar"

This commit is contained in:
Tiger Huang
2023-02-03 06:04:35 +00:00
committed by Android (Google) Code Review
2 changed files with 32 additions and 45 deletions

View File

@@ -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;

View File

@@ -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);
}