Remove legacy frames from WindowFrames and DisplayFrames
These frames are used for computing the legacy insets which won't be
used anymore. We should only maintain the new insets system now.
This CL also unhides Rect#inset APIs.
Bug: 149813814
Test: atest WindowFrameTests DisplayPolicyLayoutTests InsetsPolicyTest
SplashscreenTests ManifestLayoutTests WindowMetricsTests
WindowInsetsAnimationImeTests WindowInsetsControllerTests
WindowUntrustedTouchTest DisplayContentTests
Change-Id: I06e40be6342b2ae35f7cc3e6f4ebdbe68edf0499
diff --git a/core/api/current.txt b/core/api/current.txt
index ba52ccae..ca0eda5e 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -15483,6 +15483,8 @@
method @NonNull public String flattenToString();
method public int height();
method public void inset(int, int);
+ method public void inset(@NonNull android.graphics.Insets);
+ method public void inset(int, int, int, int);
method @CheckResult public boolean intersect(int, int, int, int);
method @CheckResult public boolean intersect(@NonNull android.graphics.Rect);
method public boolean intersects(int, int, int, int);
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index ac29f2e..41b2fb4 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -238,6 +238,22 @@
(legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0);
}
+ public Rect calculateInsets(Rect frame, @InsetsType int types, boolean ignoreVisibility) {
+ Insets insets = Insets.NONE;
+ for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
+ InsetsSource source = mSources[type];
+ if (source == null) {
+ continue;
+ }
+ int publicType = InsetsState.toPublicType(type);
+ if ((publicType & types) == 0) {
+ continue;
+ }
+ insets = Insets.max(source.calculateInsets(frame, ignoreVisibility), insets);
+ }
+ return insets.toRect();
+ }
+
public Rect calculateVisibleInsets(Rect frame, @SoftInputModeFlags int softInputMode) {
Insets insets = Insets.NONE;
for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index c077006..9c6e900 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1023,6 +1023,15 @@
}
mForceDecorViewVisibility = (mWindowAttributes.privateFlags
& PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
+
+ if (mView instanceof RootViewSurfaceTaker) {
+ PendingInsetsController pendingInsetsController =
+ ((RootViewSurfaceTaker) mView).providePendingInsetsController();
+ if (pendingInsetsController != null) {
+ pendingInsetsController.replayAndAttach(mInsetsController);
+ }
+ }
+
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
@@ -1160,14 +1169,6 @@
mFirstInputStage = nativePreImeStage;
mFirstPostImeInputStage = earlyPostImeStage;
mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
-
- if (mView instanceof RootViewSurfaceTaker) {
- PendingInsetsController pendingInsetsController =
- ((RootViewSurfaceTaker) mView).providePendingInsetsController();
- if (pendingInsetsController != null) {
- pendingInsetsController.replayAndAttach(mInsetsController);
- }
- }
}
}
}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 8b0cf3b..2168dd0 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -1344,6 +1344,9 @@
if ((types & NAVIGATION_BARS) != 0) {
result.append("navigationBars |");
}
+ if ((types & CAPTION_BAR) != 0) {
+ result.append("captionBar |");
+ }
if ((types & IME) != 0) {
result.append("ime |");
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index ce52a35..32a40d9 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -239,9 +239,9 @@
message DisplayFramesProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional .android.graphics.RectProto stable_bounds = 1;
- optional .android.graphics.RectProto dock = 2;
- optional .android.graphics.RectProto current = 3;
+ optional .android.graphics.RectProto stable_bounds = 1 [deprecated=true];
+ optional .android.graphics.RectProto dock = 2 [deprecated=true];
+ optional .android.graphics.RectProto current = 3 [deprecated=true];
}
message DisplayRotationProto {
@@ -499,19 +499,19 @@
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional .android.graphics.RectProto containing_frame = 1;
- optional .android.graphics.RectProto content_frame = 2;
- optional .android.graphics.RectProto decor_frame = 3;
+ optional .android.graphics.RectProto content_frame = 2 [deprecated=true];
+ optional .android.graphics.RectProto decor_frame = 3 [deprecated=true];
optional .android.graphics.RectProto display_frame = 4;
optional .android.graphics.RectProto frame = 5;
optional .android.graphics.RectProto outset_frame = 6;
optional .android.graphics.RectProto overscan_frame = 7 [deprecated=true];
optional .android.graphics.RectProto parent_frame = 8;
- optional .android.graphics.RectProto visible_frame = 9;
+ optional .android.graphics.RectProto visible_frame = 9 [deprecated=true];
optional .android.view.DisplayCutoutProto cutout = 10;
- optional .android.graphics.RectProto content_insets = 11;
+ optional .android.graphics.RectProto content_insets = 11 [deprecated=true];
optional .android.graphics.RectProto overscan_insets = 12 [deprecated=true];
- optional .android.graphics.RectProto visible_insets = 13;
- optional .android.graphics.RectProto stable_insets = 14;
+ optional .android.graphics.RectProto visible_insets = 13 [deprecated=true];
+ optional .android.graphics.RectProto stable_insets = 14 [deprecated=true];
optional .android.graphics.RectProto outsets = 15;
}
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 081b851..87ca960 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -433,10 +433,10 @@
/**
* Insets the rectangle on all sides specified by the dimensions of {@code insets}.
- * @hide
+ *
* @param insets The insets to inset the rect by.
*/
- public void inset(Insets insets) {
+ public void inset(@NonNull Insets insets) {
left += insets.left;
top += insets.top;
right -= insets.right;
@@ -445,7 +445,7 @@
/**
* Insets the rectangle on all sides specified by the insets.
- * @hide
+ *
* @param left The amount to add from the rectangle's left
* @param top The amount to add from the rectangle's top
* @param right The amount to subtract from the rectangle's right
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 98c38f9..bd8c2ba 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -288,6 +288,7 @@
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
@@ -4228,7 +4229,7 @@
// Force add to mResizingWindows, so that we are guaranteed to get
// another reportDrawn callback.
- w.resetLastContentInsets();
+ w.forceReportingResized();
}
}, true /* traverseTopToBottom */);
}
@@ -6192,9 +6193,17 @@
// destination of the thumbnail header animation. If this is a full screen
// window scenario, we use the whole display as the target.
WindowState win = findMainWindow();
- final Rect appRect = win != null ? win.getContentFrame() :
- new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
- final Rect insets = win != null ? win.getContentInsets() : null;
+ Rect insets;
+ Rect appRect;
+ if (win != null) {
+ insets = win.getInsetsStateWithVisibilityOverride().calculateInsets(
+ win.getFrame(), Type.systemBars(), false /* ignoreVisibility */);
+ appRect = new Rect(win.getFrame());
+ appRect.inset(insets);
+ } else {
+ insets = null;
+ appRect = new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+ }
final Configuration displayConfig = mDisplayContent.getConfiguration();
return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
appRect, insets, thumbnailHeader, task, displayConfig.uiMode,
@@ -7918,8 +7927,8 @@
if (task == null || mainWindow == null) {
return null;
}
- final Rect insets = new Rect();
- mainWindow.getContentInsets(insets);
+ final Rect insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets(
+ task.getBounds(), Type.systemBars(), false /* ignoreVisibility */);
InsetUtils.addInsets(insets, getLetterboxInsets());
return new RemoteAnimationTarget(task.mTaskId, record.getMode(),
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 07c61d3..9118944 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -51,6 +51,9 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -756,7 +759,7 @@
if (!w.getFrame().isEmpty()) {
w.updateLastFrames();
}
- w.updateLastInsetValues();
+ w.onResizeHandled();
w.updateLocationInParentDisplayIfNeeded();
}
@@ -2562,7 +2565,9 @@
}
void getStableRect(Rect out) {
- out.set(mDisplayFrames.mStable);
+ final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState();
+ out.set(state.getDisplayFrame());
+ out.inset(state.calculateInsets(out, systemBars(), true /* ignoreVisibility */));
}
/**
@@ -2690,12 +2695,13 @@
// If the task is freeformed, enlarge the area to account for outside
// touch area for resize.
mTmpRect.inset(-delta, -delta);
- // Intersect with display content rect. If we have system decor (status bar/
+ // Intersect with display content frame. If we have system decor (status bar/
// navigation bar), we want to exclude that from the tap detection.
// Otherwise, if the app is partially placed under some system button (eg.
// Recents, Home), pressing that button would cause a full series of
// unwanted transfer focus/resume/pause, before we could go home.
- mTmpRect.intersect(mDisplayFrames.mContent);
+ mTmpRect.inset(getInsetsStateController().getRawInsetsState().calculateInsets(
+ mTmpRect, systemBars() | ime(), false /* ignoreVisibility */));
}
mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
}
@@ -2783,10 +2789,25 @@
final WindowState imeWin = mInputMethodWindow;
final boolean imeVisible = imeWin != null && imeWin.isVisible()
&& imeWin.isDisplayed();
- final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
+ final int imeHeight = getInputMethodWindowVisibleHeight();
mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
}
+ int getInputMethodWindowVisibleHeight() {
+ final InsetsState state = getInsetsStateController().getRawInsetsState();
+ final InsetsSource imeSource = state.peekSource(ITYPE_IME);
+ if (imeSource == null || !imeSource.isVisible()) {
+ return 0;
+ }
+ final Rect imeFrame = imeSource.getVisibleFrame() != null
+ ? imeSource.getVisibleFrame() : imeSource.getFrame();
+ final Rect dockFrame = mTmpRect;
+ dockFrame.set(state.getDisplayFrame());
+ dockFrame.inset(state.calculateInsets(dockFrame, systemBars() | displayCutout(),
+ false /* ignoreVisibility */));
+ return dockFrame.bottom - imeFrame.top;
+ }
+
void prepareFreezingTaskBounds() {
forAllTaskDisplayAreas(TaskDisplayArea::prepareFreezingTaskBounds);
}
diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java
index d67f3f9..7f3cb49 100644
--- a/services/core/java/com/android/server/wm/DisplayFrames.java
+++ b/services/core/java/com/android/server/wm/DisplayFrames.java
@@ -16,10 +16,6 @@
package com.android.server.wm;
-import static com.android.server.wm.DisplayFramesProto.CURRENT;
-import static com.android.server.wm.DisplayFramesProto.DOCK;
-import static com.android.server.wm.DisplayFramesProto.STABLE_BOUNDS;
-
import android.annotation.NonNull;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
@@ -43,51 +39,6 @@
*/
public final Rect mUnrestricted = new Rect();
- /**
- * The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar
- * can't be hidden; in that case it effectively carves out that area of the display from all
- * other windows.
- */
- public final Rect mRestricted = new Rect();
-
- /**
- * During layout, the current screen borders accounting for any currently visible system UI
- * elements.
- */
- public final Rect mSystem = new Rect();
-
- /** For applications requesting stable content insets, these are them. */
- public final Rect mStable = new Rect();
-
- /**
- * For applications requesting stable content insets but have also set the fullscreen window
- * flag, these are the stable dimensions without the status bar.
- */
- public final Rect mStableFullscreen = new Rect();
-
- /**
- * During layout, the current screen borders with all outer decoration (status bar, input method
- * dock) accounted for.
- */
- public final Rect mCurrent = new Rect();
-
- /**
- * During layout, the frame in which content should be displayed to the user, accounting for all
- * screen decoration except for any space they deem as available for other content. This is
- * usually the same as mCurrent*, but may be larger if the screen decor has supplied content
- * insets.
- */
- public final Rect mContent = new Rect();
-
- /**
- * During layout, the frame in which voice content should be displayed to the user, accounting
- * for all screen decoration except for any space they deem as available for other content.
- */
- public final Rect mVoiceContent = new Rect();
-
- /** During layout, the current screen borders along which input method windows are placed. */
- public final Rect mDock = new Rect();
-
/** The display cutout used for layout (after rotation) */
@NonNull public WmDisplayCutout mDisplayCutout = WmDisplayCutout.NO_CUTOUT;
@@ -118,15 +69,6 @@
public void onBeginLayout() {
mUnrestricted.set(0, 0, mDisplayWidth, mDisplayHeight);
- mRestricted.set(mUnrestricted);
- mSystem.set(mUnrestricted);
- mDock.set(mUnrestricted);
- mContent.set(mUnrestricted);
- mVoiceContent.set(mUnrestricted);
- mStable.set(mUnrestricted);
- mStableFullscreen.set(mUnrestricted);
- mCurrent.set(mUnrestricted);
-
mDisplayCutout = mDisplayInfoCutout;
mDisplayCutoutSafe.set(Integer.MIN_VALUE, Integer.MIN_VALUE,
Integer.MAX_VALUE, Integer.MAX_VALUE);
@@ -147,15 +89,8 @@
}
}
- public int getInputMethodWindowVisibleHeight() {
- return mDock.bottom - mCurrent.bottom;
- }
-
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
- mStable.dumpDebug(proto, STABLE_BOUNDS);
- mDock.dumpDebug(proto, DOCK);
- mCurrent.dumpDebug(proto, CURRENT);
proto.end(token);
}
@@ -163,14 +98,6 @@
pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight
+ " r=" + mRotation);
final String myPrefix = prefix + " ";
- dumpFrame(mStable, "mStable", myPrefix, pw);
- dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw);
- dumpFrame(mDock, "mDock", myPrefix, pw);
- dumpFrame(mCurrent, "mCurrent", myPrefix, pw);
- dumpFrame(mSystem, "mSystem", myPrefix, pw);
- dumpFrame(mContent, "mContent", myPrefix, pw);
- dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw);
- dumpFrame(mRestricted, "mRestricted", myPrefix, pw);
dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw);
pw.println(myPrefix + "mDisplayCutout=" + mDisplayCutout);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index fc3fc47..11a436e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -68,9 +68,6 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
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;
@@ -323,7 +320,6 @@
private boolean mLastImmersiveMode;
- private StatusBarManagerInternal mStatusBarInternal;
private final BarController mStatusBarController;
private final BarController mNavigationBarController;
@@ -333,12 +329,6 @@
private WindowState mSystemUiControllingWindow;
- // The states of decor windows from the last layout. These are used to generate another display
- // layout in different bounds but with the same states.
- private boolean mLastNavVisible;
- private boolean mLastNavTranslucent;
- private boolean mLastNavAllowedHidden;
-
private int mLastDisableFlags;
private int mLastAppearance;
private int mLastFullscreenAppearance;
@@ -1568,18 +1558,14 @@
simulateLayoutDecorWindow(mNavigationBar, displayFrames, insetsState,
simulatedWindowFrames, barContentFrames,
contentFrame -> layoutNavigationBar(displayFrames,
- mDisplayContent.getConfiguration().uiMode, mLastNavVisible,
- mLastNavTranslucent, mLastNavAllowedHidden,
- contentFrame));
+ mDisplayContent.getConfiguration().uiMode, contentFrame));
}
if (mStatusBar != null) {
simulateLayoutDecorWindow(mStatusBar, displayFrames, insetsState,
simulatedWindowFrames, barContentFrames,
- contentFrame -> layoutStatusBar(displayFrames, mLastAppearance,
- contentFrame));
+ contentFrame -> layoutStatusBar(displayFrames, contentFrame));
}
layoutScreenDecorWindows(displayFrames, simulatedWindowFrames);
- postAdjustDisplayFrames(displayFrames);
}
/**
@@ -1596,35 +1582,11 @@
mSystemGestures.screenWidth = displayFrames.mUnrestricted.width();
mSystemGestures.screenHeight = displayFrames.mUnrestricted.height();
- // For purposes of putting out fake window up to steal focus, we will
- // drive nav being hidden only by whether it is requested.
- final int appearance = mLastAppearance;
- final int behavior = mLastBehavior;
- final InsetsSourceProvider provider =
- mDisplayContent.getInsetsStateController().peekSourceProvider(ITYPE_NAVIGATION_BAR);
- boolean navVisible = provider != null ? provider.isClientVisible()
- : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR);
- boolean navTranslucent = (appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) == 0;
- boolean immersive = (behavior & BEHAVIOR_SHOW_BARS_BY_SWIPE) != 0;
- boolean immersiveSticky = (behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0;
- boolean navAllowedHidden = immersive || immersiveSticky;
- navTranslucent &= !immersiveSticky; // transient trumps translucent
-
updateHideNavInputEventReceiver();
- // For purposes of positioning and showing the nav bar, if we have decided that it can't
- // be hidden (because of the screen aspect ratio), then take that into account.
- navVisible |= !canHideNavigationBar();
-
- layoutNavigationBar(displayFrames, uiMode, navVisible,
- navTranslucent, navAllowedHidden, null /* simulatedContentFrame */);
- if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock);
- layoutStatusBar(displayFrames, appearance, null /* simulatedContentFrame */);
+ layoutNavigationBar(displayFrames, uiMode, null /* simulatedContentFrame */);
+ layoutStatusBar(displayFrames, null /* simulatedContentFrame */);
layoutScreenDecorWindows(displayFrames, null /* simulatedFrames */);
- postAdjustDisplayFrames(displayFrames);
- mLastNavVisible = navVisible;
- mLastNavTranslucent = navTranslucent;
- mLastNavAllowedHidden = navAllowedHidden;
}
void updateHideNavInputEventReceiver() {
@@ -1679,26 +1641,6 @@
state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(u.left, s.bottom, u.right, u.bottom);
}
- /** Enforces the last layout policy for display frames. */
- private void postAdjustDisplayFrames(DisplayFrames displayFrames) {
- if (displayFrames.mDisplayCutoutSafe.top > displayFrames.mUnrestricted.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.
- displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top,
- displayFrames.mStable.top);
- }
-
- // In case this is a virtual display, and the host display has insets that overlap this
- // virtual display, apply the insets of the overlapped area onto the current and content
- // frame of this virtual display. This let us layout windows in the virtual display as
- // expected when the window needs to avoid overlap with the system windows.
- // TODO: Generalize the forwarded insets, so that we can handle system windows other than
- // IME.
- displayFrames.mCurrent.inset(mForwardedInsets);
- displayFrames.mContent.inset(mForwardedInsets);
- }
-
/**
* Layout the decor windows with {@link #PRIVATE_FLAG_IS_SCREEN_DECOR}.
*
@@ -1714,9 +1656,6 @@
sTmpRect.setEmpty();
final int displayId = displayFrames.mDisplayId;
- final Rect dockFrame = displayFrames.mDock;
- final int displayHeight = displayFrames.mDisplayHeight;
- final int displayWidth = displayFrames.mDisplayWidth;
for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {
final WindowState w = mScreenDecorWindows.valueAt(i);
@@ -1732,10 +1671,7 @@
getRotatedWindowBounds(displayFrames, w, sTmpScreenDecorFrame);
final WindowFrames windowFrames = w.getLayoutingWindowFrames();
windowFrames.setFrames(sTmpScreenDecorFrame /* parentFrame */,
- sTmpScreenDecorFrame /* displayFrame */,
- sTmpScreenDecorFrame /* contentFrame */,
- sTmpScreenDecorFrame /* visibleFrame */, sTmpRect /* decorFrame */,
- sTmpScreenDecorFrame /* stableFrame */);
+ sTmpScreenDecorFrame /* displayFrame */);
try {
w.computeFrame(displayFrames);
} finally {
@@ -1743,128 +1679,61 @@
w.setSimulatedWindowFrames(null);
}
}
- final Rect frame = windowFrames.mFrame;
-
- if (frame.left <= 0 && frame.top <= 0) {
- // Docked at left or top.
- if (frame.bottom >= displayHeight) {
- // Docked left.
- dockFrame.left = Math.max(frame.right, dockFrame.left);
- } else if (frame.right >= displayWidth) {
- // Docked top.
- dockFrame.top = Math.max(frame.bottom, dockFrame.top);
- } else {
- Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
- + " not docked on left or top of display. frame=" + frame
- + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
- }
- } else if (frame.right >= displayWidth && frame.bottom >= displayHeight) {
- // Docked at right or bottom.
- if (frame.top <= 0) {
- // Docked right.
- dockFrame.right = Math.min(frame.left, dockFrame.right);
- } else if (frame.left <= 0) {
- // Docked bottom.
- dockFrame.bottom = Math.min(frame.top, dockFrame.bottom);
- } else {
- Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
- + " not docked on right or bottom" + " of display. frame=" + frame
- + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
- }
- } else {
- // Screen decor windows are required to be docked on one of the sides of the screen.
- Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w
- + " not docked on one of the sides of the display. frame=" + frame
- + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight);
- }
}
-
- displayFrames.mRestricted.set(dockFrame);
- displayFrames.mCurrent.set(dockFrame);
- displayFrames.mVoiceContent.set(dockFrame);
- displayFrames.mSystem.set(dockFrame);
- displayFrames.mContent.set(dockFrame);
}
- private void layoutStatusBar(DisplayFrames displayFrames, int appearance,
- Rect simulatedContentFrame) {
+ private void layoutStatusBar(DisplayFrames displayFrames, Rect simulatedContentFrame) {
// decide where the status bar goes ahead of time
if (mStatusBar == null) {
return;
}
// apply any status bar insets
getRotatedWindowBounds(displayFrames, mStatusBar, sTmpStatusFrame);
- sTmpRect.setEmpty();
final WindowFrames windowFrames = mStatusBar.getLayoutingWindowFrames();
windowFrames.setFrames(sTmpStatusFrame /* parentFrame */,
- sTmpStatusFrame /* displayFrame */, sTmpStatusFrame /* contentFrame */,
- sTmpStatusFrame /* visibleFrame */, sTmpRect /* decorFrame */,
- sTmpStatusFrame /* stableFrame */);
+ sTmpStatusFrame /* displayFrame */);
// Let the status bar determine its size.
mStatusBar.computeFrame(displayFrames);
// For layout, the status bar is always at the top with our fixed height.
- displayFrames.mStable.top = displayFrames.mUnrestricted.top
+ int statusBarBottom = displayFrames.mUnrestricted.top
+ mStatusBarHeightForRotation[displayFrames.mRotation];
// Make sure the status bar covers the entire cutout height
- displayFrames.mStable.top = Math.max(displayFrames.mStable.top,
- displayFrames.mDisplayCutoutSafe.top);
+ statusBarBottom = Math.max(statusBarBottom, displayFrames.mDisplayCutoutSafe.top);
+
+ if (displayFrames.mDisplayCutoutSafe.top > displayFrames.mUnrestricted.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.
+ displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top,
+ statusBarBottom);
+ }
// Tell the bar controller where the collapsed status bar content is.
- sTmpRect.set(windowFrames.mContentFrame);
+ sTmpRect.set(windowFrames.mFrame);
sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
- sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset
- sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size
+ sTmpRect.top = windowFrames.mFrame.top; // Ignore top display cutout inset
+ sTmpRect.bottom = statusBarBottom; // Use collapsed status bar size
if (simulatedContentFrame != null) {
simulatedContentFrame.set(sTmpRect);
} else {
mStatusBarController.setContentFrame(sTmpRect);
}
-
- boolean statusBarTransient =
- mDisplayContent.getInsetsPolicy().isTransient(ITYPE_STATUS_BAR);
- boolean statusBarTranslucent = (appearance & APPEARANCE_OPAQUE_STATUS_BARS) == 0;
-
- // If the status bar is hidden, we don't want to cause windows behind it to scroll.
- if (mStatusBar.isVisible() && !statusBarTransient) {
- // Status bar may go away, so the screen area it occupies is available to apps but just
- // covering them when the status bar is visible.
- final Rect dockFrame = displayFrames.mDock;
- dockFrame.top = displayFrames.mStable.top;
- displayFrames.mContent.set(dockFrame);
- displayFrames.mVoiceContent.set(dockFrame);
- displayFrames.mCurrent.set(dockFrame);
-
- if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + String.format(
- "dock=%s content=%s cur=%s", dockFrame.toString(),
- displayFrames.mContent.toString(), displayFrames.mCurrent.toString()));
-
- if (!statusBarTranslucent && !mStatusBar.isAnimatingLw()) {
-
- // If the opaque status bar is currently requested to be visible, and not in the
- // process of animating on or off, then we can tell the app that it is covered by
- // it.
- displayFrames.mSystem.top = displayFrames.mStable.top;
- }
- }
}
- private void layoutNavigationBar(DisplayFrames displayFrames, int uiMode, boolean navVisible,
- boolean navTranslucent, boolean navAllowedHidden, Rect simulatedContentFrame) {
+ private void layoutNavigationBar(DisplayFrames displayFrames, int uiMode,
+ Rect simulatedContentFrame) {
if (mNavigationBar == null) {
return;
}
final Rect navigationFrame = sTmpNavFrame;
- boolean navBarTransient =
- mDisplayContent.getInsetsPolicy().isTransient(ITYPE_NAVIGATION_BAR);
// Force the navigation bar to its appropriate place and size. We need to do this directly,
// instead of relying on it to bubble up from the nav bar, because this needs to change
// atomically with screen rotations.
final int rotation = displayFrames.mRotation;
final int displayHeight = displayFrames.mDisplayHeight;
final int displayWidth = displayFrames.mDisplayWidth;
- final Rect dockFrame = displayFrames.mDock;
final int navBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);
getRotatedWindowBounds(displayFrames, mNavigationBar, navigationFrame);
@@ -1875,73 +1744,31 @@
if (navBarPosition == NAV_BAR_BOTTOM) {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
- final int topNavBar = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
+ navigationFrame.top = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
- getNavigationBarFrameHeight(rotation, uiMode);
- final int top = mNavButtonForcedVisible ? topNavBar :
- Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)
- - getNavigationBarHeight(rotation, uiMode);
- navigationFrame.top = topNavBar;
- displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
- if (navVisible && !navBarTransient) {
- dockFrame.bottom = displayFrames.mRestricted.bottom = top;
- }
- if (navVisible && !navTranslucent && !navAllowedHidden
- && !mNavigationBar.isAnimatingLw()) {
- // If the opaque nav bar is currently requested to be visible and not in the process
- // of animating on or off, then we can tell the app that it is covered by it.
- displayFrames.mSystem.bottom = top;
- }
} else if (navBarPosition == NAV_BAR_RIGHT) {
// Landscape screen; nav bar goes to the right.
- final int left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right)
+ navigationFrame.left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right)
- getNavigationBarWidth(rotation, uiMode);
- navigationFrame.left = left;
- displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left;
- if (navVisible && !navBarTransient) {
- dockFrame.right = displayFrames.mRestricted.right = left;
- }
- if (navVisible && !navTranslucent && !navAllowedHidden
- && !mNavigationBar.isAnimatingLw()) {
- // If the nav bar is currently requested to be visible, and not in the process of
- // animating on or off, then we can tell the app that it is covered by it.
- displayFrames.mSystem.right = left;
- }
} else if (navBarPosition == NAV_BAR_LEFT) {
// Seascape screen; nav bar goes to the left.
- final int right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left)
+ navigationFrame.right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left)
+ getNavigationBarWidth(rotation, uiMode);
- navigationFrame.right = right;
- displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
- if (navVisible && !navBarTransient) {
- dockFrame.left = displayFrames.mRestricted.left = right;
- }
- if (navVisible && !navTranslucent && !navAllowedHidden
- && !mNavigationBar.isAnimatingLw()) {
- // If the nav bar is currently requested to be visible, and not in the process of
- // animating on or off, then we can tell the app that it is covered by it.
- displayFrames.mSystem.left = right;
- }
}
- // Make sure the content and current rectangles are updated to account for the restrictions
- // from the navigation bar.
- displayFrames.mCurrent.set(dockFrame);
- displayFrames.mVoiceContent.set(dockFrame);
- displayFrames.mContent.set(dockFrame);
- // And compute the final frame.
- sTmpRect.setEmpty();
+ // Compute the final frame.
final WindowFrames windowFrames = mNavigationBar.getLayoutingWindowFrames();
windowFrames.setFrames(navigationFrame /* parentFrame */,
- navigationFrame /* displayFrame */,
- displayFrames.mDisplayCutoutSafe /* contentFrame */,
- navigationFrame /* visibleFrame */, sTmpRect /* decorFrame */,
- navigationFrame /* stableFrame */);
+ navigationFrame /* displayFrame */);
mNavigationBar.computeFrame(displayFrames);
+ final Rect contentFrame = sTmpRect;
+ contentFrame.set(windowFrames.mFrame);
+ contentFrame.intersect(displayFrames.mDisplayCutoutSafe);
if (simulatedContentFrame != null) {
- simulatedContentFrame.set(windowFrames.mContentFrame);
+ simulatedContentFrame.set(contentFrame);
} else {
mNavigationBarPosition = navBarPosition;
- mNavigationBarController.setContentFrame(windowFrames.mContentFrame);
+ mNavigationBarController.setContentFrame(contentFrame);
}
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + navigationFrame);
@@ -2010,21 +1837,12 @@
sTmpLastParentFrame.set(windowFrames.mParentFrame);
final Rect pf = windowFrames.mParentFrame;
final Rect df = windowFrames.mDisplayFrame;
- final Rect cf = windowFrames.mContentFrame;
- final Rect vf = windowFrames.mVisibleFrame;
- final Rect dcf = windowFrames.mDecorFrame;
- final Rect sf = windowFrames.mStableFrame;
- dcf.setEmpty();
windowFrames.setParentFrameWasClippedByDisplayCutout(false);
- final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
-
final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR;
- sf.set(displayFrames.mStable);
-
- final InsetsState state = mDisplayContent.getInsetsPolicy().getInsetsForWindow(win);
+ final InsetsState state = win.getInsetsState();
computeWindowBounds(attrs, state, df);
if (attached == null) {
pf.set(df);
@@ -2034,15 +1852,9 @@
pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */));
}
}
- vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING
- ? displayFrames.mCurrent : displayFrames.mDock);
} else {
pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrame() : df);
- vf.set(attached.getVisibleFrame());
}
- cf.set(adjust != SOFT_INPUT_ADJUST_RESIZE
- ? displayFrames.mDock : displayFrames.mContent);
- dcf.set(displayFrames.mSystem);
final int cutoutMode = attrs.layoutInDisplayCutoutMode;
// Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
@@ -2114,75 +1926,25 @@
df.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
}
- // Content should never appear in the cutout.
- cf.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
-
// TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
// Also, we don't allow windows in multi-window mode to extend out of the screen.
if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR
&& !win.inMultiWindowMode()) {
df.left = df.top = -10000;
df.right = df.bottom = 10000;
- if (type != TYPE_WALLPAPER) {
- cf.left = cf.top = vf.left = vf.top = -10000;
- cf.right = cf.bottom = vf.right = vf.bottom = 10000;
- }
}
if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
+ ": sim=#" + Integer.toHexString(sim)
+ " attach=" + attached + " type=" + type
+ String.format(" flags=0x%08x", fl)
- + " pf=" + pf.toShortString() + " df=" + df.toShortString()
- + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
- + " dcf=" + dcf.toShortString()
- + " sf=" + sf.toShortString());
+ + " pf=" + pf.toShortString() + " df=" + df.toShortString());
if (!sTmpLastParentFrame.equals(pf)) {
windowFrames.setContentChanged(true);
}
win.computeFrame(displayFrames);
- // Dock windows carve out the bottom of the screen, so normal windows
- // can't appear underneath them.
- if (type == TYPE_INPUT_METHOD && win.isVisible() && !win.mGivenInsetsPending) {
- offsetInputMethodWindowLw(win, displayFrames);
- }
- if (type == TYPE_VOICE_INTERACTION && win.isVisible() && !win.mGivenInsetsPending) {
- offsetVoiceInputWindowLw(win, displayFrames);
- }
- }
-
- private void offsetInputMethodWindowLw(WindowState win, DisplayFrames displayFrames) {
- final int rotation = displayFrames.mRotation;
- final int navBarPosition = navigationBarPosition(displayFrames.mDisplayWidth,
- displayFrames.mDisplayHeight, rotation);
-
- int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top);
- top += win.mGivenContentInsets.top;
- displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, top);
- if (navBarPosition == NAV_BAR_BOTTOM) {
- // Always account for the nav bar frame height on the bottom since in all navigation
- // modes we make room to show the dismiss-ime button, even if the IME does not report
- // insets (ie. when floating)
- final int uimode = mService.mPolicy.getUiMode();
- final int navFrameHeight = getNavigationBarFrameHeight(rotation, uimode);
- displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom,
- displayFrames.mUnrestricted.bottom - navFrameHeight);
- }
- displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
- top = win.getVisibleFrame().top;
- top += win.mGivenVisibleInsets.top;
- displayFrames.mCurrent.bottom = Math.min(displayFrames.mCurrent.bottom, top);
- if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom="
- + displayFrames.mDock.bottom + " mContentBottom="
- + displayFrames.mContent.bottom + " mCurBottom=" + displayFrames.mCurrent.bottom);
- }
-
- private void offsetVoiceInputWindowLw(WindowState win, DisplayFrames displayFrames) {
- int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top);
- top += win.mGivenContentInsets.top;
- displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);
}
WindowState getTopFullscreenOpaqueWindow() {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 73641f4..d308766 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -492,10 +492,10 @@
}
mAnimatingShown = show;
+ final InsetsState state = getInsetsForWindow(mFocusedWin);
mAnimationControl = new InsetsAnimationControlImpl(controls,
- mFocusedWin.getDisplayContent().getBounds(), mFocusedWin.getInsetsState(),
- mListener, typesReady, this, mListener.getDurationMs(),
- InsetsController.SYSTEM_BARS_INTERPOLATOR,
+ state.getDisplayFrame(), state, mListener, typesReady, this,
+ mListener.getDurationMs(), InsetsController.SYSTEM_BARS_INTERPOLATOR,
show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, null /* translator */);
SurfaceAnimationThread.getHandler().post(
() -> mListener.onReady(mAnimationControl, typesReady));
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 2de4a71..0605ed8 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -548,8 +548,7 @@
@Override
public void startAnimation(SurfaceControl animationLeash, Transaction t,
@AnimationType int type, OnAnimationFinishedCallback finishCallback) {
- // TODO(b/118118435): We can remove the type check when implementing the transient bar
- // animation.
+ // TODO(b/166736352): Check if we still need to control the IME visibility here.
if (mSource.getType() == ITYPE_IME) {
// TODO: use 0 alpha and remove t.hide() once b/138459974 is fixed.
t.setAlpha(animationLeash, 1 /* alpha */);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 1736ac9..d3ff031 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -53,6 +53,7 @@
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason;
@@ -534,7 +535,10 @@
: null;
final Rect contentInsets;
if (mTargetActivityRecord != null && mTargetActivityRecord.findMainWindow() != null) {
- contentInsets = mTargetActivityRecord.findMainWindow().getContentInsets();
+ contentInsets = mTargetActivityRecord.findMainWindow()
+ .getInsetsStateWithVisibilityOverride()
+ .calculateInsets(mTargetActivityRecord.getBounds(), Type.systemBars(),
+ false /* ignoreVisibility */);
} else {
// If the window for the activity had not yet been created, use the display insets.
mService.getStableInsets(mDisplayId, mTmpRect);
@@ -969,8 +973,8 @@
if (mainWindow == null) {
return null;
}
- final Rect insets = new Rect();
- mainWindow.getContentInsets(insets);
+ final Rect insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets(
+ mBounds, Type.systemBars(), false /* ignoreVisibility */);
InsetUtils.addInsets(insets, mainWindow.mActivityRecord.getLetterboxInsets());
final int mode = topApp.getActivityType() == mTargetActivityType
? MODE_OPENING
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 90c3f9e..6577cce 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -448,6 +448,7 @@
private final Rect mTmpBounds = new Rect();
private final Rect mTmpInsets = new Rect();
private final Rect mTmpFullBounds = new Rect();
+ private static final Rect sTmpBounds = new Rect();
// Last non-fullscreen bounds the task was launched in or resized to.
// The information is persisted and used to determine the appropriate stack to launch the
@@ -3419,8 +3420,7 @@
* a dialog that's different in size from the activity below, in which case we should
* be dimming the entire task area behind the dialog.
*
- * @param out Rect containing the max visible bounds.
- * @return true if the task has some visible app windows; false otherwise.
+ * @param out the union of visible bounds.
*/
private static void getMaxVisibleBounds(ActivityRecord token, Rect out, boolean[] foundTop) {
// skip hidden (or about to hide) apps
@@ -3436,7 +3436,11 @@
out.setEmpty();
}
- win.getMaxVisibleBounds(out);
+ final Rect visibleFrame = sTmpBounds;
+ visibleFrame.set(win.getFrame());
+ visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
+ visibleFrame, win.mAttrs.softInputMode));
+ out.union(visibleFrame);
}
/** Bounds of the task to be used for dimming, as well as touch related tests. */
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 9a818ce..1c6480c 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -85,6 +85,7 @@
private final ActivityStackSupervisor mSupervisor;
private final Rect mTmpBounds = new Rect();
+ private final Rect mTmpStableBounds = new Rect();
private final int[] mTmpDirections = new int[2];
private StringBuilder mLogBuilder;
@@ -425,7 +426,8 @@
// Use stable frame instead of raw frame to avoid launching freeform windows on top of
// stable insets, which usually are system widgets such as sysbar & navbar.
- final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
+ final Rect displayStableBounds = mTmpStableBounds;
+ display.getStableRect(displayStableBounds);
final int defaultWidth = displayStableBounds.width();
final int defaultHeight = displayStableBounds.height();
@@ -636,7 +638,8 @@
// of default size is calculated to keep the same aspect ratio as the display's. Here we use
// stable bounds of displays because that indicates the area that isn't occupied by system
// widgets (e.g. sysbar and navbar).
- Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
+ final Rect displayStableBounds = mTmpStableBounds;
+ display.getStableRect(displayStableBounds);
final int portraitHeight =
Math.min(displayStableBounds.width(), displayStableBounds.height());
final int otherDimension =
@@ -676,7 +679,7 @@
private void centerBounds(@NonNull DisplayContent display, int width, int height,
@NonNull Rect inOutBounds) {
if (inOutBounds.isEmpty()) {
- inOutBounds.set(display.mDisplayContent.mDisplayFrames.mStable);
+ display.getStableRect(inOutBounds);
}
final int left = inOutBounds.centerX() - width / 2;
final int top = inOutBounds.centerY() - height / 2;
@@ -685,7 +688,8 @@
private void adjustBoundsToFitInDisplay(@NonNull DisplayContent display,
@NonNull Rect inOutBounds) {
- final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
+ final Rect displayStableBounds = mTmpStableBounds;
+ display.getStableRect(displayStableBounds);
if (displayStableBounds.width() < inOutBounds.width()
|| displayStableBounds.height() < inOutBounds.height()) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 3ce04af..3327300 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -16,9 +16,7 @@
package com.android.server.wm;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -39,12 +37,10 @@
import android.os.Handler;
import android.util.ArraySet;
import android.util.Slog;
-import android.view.InsetsSource;
import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
import android.view.SurfaceControl;
import android.view.ThreadedRenderer;
-import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
import android.view.WindowManager.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
@@ -310,9 +306,13 @@
return false;
}
+ final Rect contentInsets = getSystemBarInsets(task.getBounds(),
+ mainWindow.getInsetsStateWithVisibilityOverride());
+ InsetUtils.addInsets(contentInsets, activity.getLetterboxInsets());
+
builder.setIsRealSnapshot(true);
builder.setId(System.currentTimeMillis());
- builder.setContentInsets(getInsets(mainWindow));
+ builder.setContentInsets(contentInsets);
final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0;
@@ -420,21 +420,6 @@
return mIsRunningOnWear || mIsRunningOnTv || mIsRunningOnIoT;
}
- private Rect getInsets(WindowState state) {
- // XXX(b/72757033): These are insets relative to the window frame, but we're really
- // interested in the insets relative to the task bounds.
- final Rect insets = minRect(state.getContentInsets(), state.getStableInsets());
- InsetUtils.addInsets(insets, state.mActivityRecord.getLetterboxInsets());
- return insets;
- }
-
- private Rect minRect(Rect rect1, Rect rect2) {
- return new Rect(Math.min(rect1.left, rect2.left),
- Math.min(rect1.top, rect2.top),
- Math.min(rect1.right, rect2.right),
- Math.min(rect1.bottom, rect2.bottom));
- }
-
/**
* Retrieves all closing tasks based on the list of closing apps during an app transition.
*/
@@ -488,13 +473,14 @@
final int color = ColorUtils.setAlphaComponent(
task.getTaskDescription().getBackgroundColor(), 255);
final LayoutParams attrs = mainWindow.getAttrs();
- final InsetsState insetsState = getInsetsStateWithVisibilityOverride(mainWindow);
- final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState);
+ final Rect taskBounds = task.getBounds();
+ final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride();
+ final Rect systemBarInsets = getSystemBarInsets(taskBounds, insetsState);
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.insetsFlags.appearance, task.getTaskDescription(),
mHighResTaskSnapshotScale, insetsState);
- final int taskWidth = task.getBounds().width();
- final int taskHeight = task.getBounds().height();
+ final int taskWidth = taskBounds.width();
+ final int taskHeight = taskBounds.height();
final int width = (int) (taskWidth * mHighResTaskSnapshotScale);
final int height = (int) (taskHeight * mHighResTaskSnapshotScale);
@@ -510,6 +496,8 @@
if (hwBitmap == null) {
return null;
}
+ final Rect contentInsets = new Rect(systemBarInsets);
+ InsetUtils.addInsets(contentInsets, topChild.getLetterboxInsets());
// Note, the app theme snapshot is never translucent because we enforce a non-translucent
// color above
@@ -518,9 +506,8 @@
topChild.mActivityComponent, hwBitmap.getHardwareBuffer(),
hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,
mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),
- getInsets(mainWindow), false /* isLowResolution */,
- false /* isRealSnapshot */, task.getWindowingMode(),
- getSystemUiVisibility(task), false);
+ contentInsets, false /* isLowResolution */, false /* isRealSnapshot */,
+ task.getWindowingMode(), getSystemUiVisibility(task), false);
}
/**
@@ -611,26 +598,8 @@
return 0;
}
- static InsetsState getInsetsStateWithVisibilityOverride(WindowState win) {
- final InsetsState state = new InsetsState(win.getInsetsState());
- for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
- final boolean requestedVisible = win.getRequestedVisibility(type);
- InsetsSource source = state.peekSource(type);
- if (source != null && source.isVisible() != requestedVisible) {
- source = new InsetsSource(source);
- source.setVisible(requestedVisible);
- state.addSource(source);
- }
- }
- return state;
- }
-
static Rect getSystemBarInsets(Rect frame, InsetsState state) {
- return state.calculateInsets(frame, null /* ignoringVisibilityState */,
- false /* isScreenRound */, false /* alwaysConsumeSystemBars */,
- null /* displayCutout */, 0 /* legacySoftInputMode */, 0 /* legacyWindowFlags */,
- 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
- null /* typeSideMap */).getInsets(WindowInsets.Type.systemBars()).toRect();
+ return state.calculateInsets(frame, Type.systemBars(), false /* ignoreVisibility */);
}
void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 30f09ce..d2cd1a1 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -43,7 +43,6 @@
import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.TaskSnapshotController.getInsetsStateWithVisibilityOverride;
import static com.android.server.wm.TaskSnapshotController.getSystemBarInsets;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -246,7 +245,7 @@
task.getBounds(taskBounds);
currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;
activityType = activity.getActivityType();
- insetsState = getInsetsStateWithVisibilityOverride(topFullscreenOpaqueWindow);
+ insetsState = topFullscreenOpaqueWindow.getInsetsStateWithVisibilityOverride();
}
int displayId = activity.getDisplayContent().getDisplayId();
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index 81122ac..7991ec6 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -17,23 +17,16 @@
package com.android.server.wm;
import static com.android.server.wm.WindowFramesProto.CONTAINING_FRAME;
-import static com.android.server.wm.WindowFramesProto.CONTENT_FRAME;
-import static com.android.server.wm.WindowFramesProto.CONTENT_INSETS;
import static com.android.server.wm.WindowFramesProto.CUTOUT;
-import static com.android.server.wm.WindowFramesProto.DECOR_FRAME;
import static com.android.server.wm.WindowFramesProto.DISPLAY_FRAME;
import static com.android.server.wm.WindowFramesProto.FRAME;
import static com.android.server.wm.WindowFramesProto.PARENT_FRAME;
-import static com.android.server.wm.WindowFramesProto.STABLE_INSETS;
-import static com.android.server.wm.WindowFramesProto.VISIBLE_FRAME;
-import static com.android.server.wm.WindowFramesProto.VISIBLE_INSETS;
import android.annotation.NonNull;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayCutout;
-import com.android.server.wm.utils.InsetUtils;
import com.android.server.wm.utils.WmDisplayCutout;
import java.io.PrintWriter;
@@ -66,30 +59,6 @@
public final Rect mDisplayFrame = new Rect();
/**
- * Legacy stuff. Generally equal to the content frame expect when the IME for older apps
- * displays hint text.
- */
- public final Rect mVisibleFrame = new Rect();
-
- /**
- * The area not occupied by the status and navigation bars. So, if both status and navigation
- * bars are visible, the decor frame is equal to the stable frame.
- */
- public final Rect mDecorFrame = new Rect();
-
- /**
- * Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame
- * minus the area occupied by the IME if the IME is present.
- */
- public final Rect mContentFrame = new Rect();
-
- /**
- * The display frame minus the stable insets. This value is always constant regardless of if
- * the status bar or navigation bar is visible.
- */
- public final Rect mStableFrame = new Rect();
-
- /**
* Similar to {@link #mDisplayFrame}
*
* TODO: Why is this different than mDisplayFrame
@@ -139,52 +108,21 @@
private boolean mDisplayCutoutChanged;
- /**
- * Insets that determine the area covered by the stable system windows. These are in the
- * application's coordinate space (without compatibility scale applied).
- */
- final Rect mStableInsets = new Rect();
- final Rect mLastStableInsets = new Rect();
- private boolean mStableInsetsChanged;
-
- /**
- * Insets that determine the actually visible area. These are in the application's
- * coordinate space (without compatibility scale applied).
- */
- final Rect mVisibleInsets = new Rect();
- final Rect mLastVisibleInsets = new Rect();
- private boolean mVisibleInsetsChanged;
-
- /**
- * Insets that are covered by system windows (such as the status bar) and
- * transient docking windows (such as the IME). These are in the application's
- * coordinate space (without compatibility scale applied).
- */
- final Rect mContentInsets = new Rect();
- final Rect mLastContentInsets = new Rect();
- private boolean mContentInsetsChanged;
-
- private final Rect mTmpRect = new Rect();
+ boolean mLastForceReportingResized = false;
+ boolean mForceReportingResized = false;
private boolean mContentChanged;
public WindowFrames() {
}
- public WindowFrames(Rect parentFrame, Rect displayFrame, Rect contentFrame,
- Rect visibleFrame, Rect decorFrame, Rect stableFrame) {
- setFrames(parentFrame, displayFrame, contentFrame, visibleFrame, decorFrame,
- stableFrame);
+ public WindowFrames(Rect parentFrame, Rect displayFrame) {
+ setFrames(parentFrame, displayFrame);
}
- public void setFrames(Rect parentFrame, Rect displayFrame,
- Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame) {
+ public void setFrames(Rect parentFrame, Rect displayFrame) {
mParentFrame.set(parentFrame);
mDisplayFrame.set(displayFrame);
- mContentFrame.set(contentFrame);
- mVisibleFrame.set(visibleFrame);
- mDecorFrame.set(decorFrame);
- mStableFrame.set(stableFrame);
}
public void setParentFrameWasClippedByDisplayCutout(
@@ -207,49 +145,8 @@
return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height());
}
- /**
- * Calculate the insets for a window.
- *
- * @param windowsAreFloating Whether the window is in a floating task such as pinned or
- * freeform
- * @param inFullscreenContainer Whether the window is in a container that takes up the screen's
- * entire space
- * @param windowBounds The bounds for the window
- */
- void calculateInsets(boolean windowsAreFloating, boolean inFullscreenContainer,
- Rect windowBounds) {
- // Override right and/or bottom insets in case if the frame doesn't fit the screen in
- // non-fullscreen mode.
- boolean overrideRightInset = !windowsAreFloating && !inFullscreenContainer
- && mFrame.right > windowBounds.right;
- boolean overrideBottomInset = !windowsAreFloating && !inFullscreenContainer
- && mFrame.bottom > windowBounds.bottom;
-
- mTmpRect.set(mFrame.left, mFrame.top,
- overrideRightInset ? windowBounds.right : mFrame.right,
- overrideBottomInset ? windowBounds.bottom : mFrame.bottom);
-
- InsetUtils.insetsBetweenFrames(mTmpRect, mContentFrame, mContentInsets);
- InsetUtils.insetsBetweenFrames(mTmpRect, mVisibleFrame, mVisibleInsets);
- InsetUtils.insetsBetweenFrames(mTmpRect, mStableFrame, mStableInsets);
- }
-
- /**
- * Scales all the insets by a specific amount.
- *
- * @param scale The amount to scale the insets by.
- */
- void scaleInsets(float scale) {
- mContentInsets.scale(scale);
- mVisibleInsets.scale(scale);
- mStableInsets.scale(scale);
- }
-
void offsetFrames(int layoutXDiff, int layoutYDiff) {
mFrame.offset(layoutXDiff, layoutYDiff);
- mContentFrame.offset(layoutXDiff, layoutYDiff);
- mVisibleFrame.offset(layoutXDiff, layoutYDiff);
- mStableFrame.offset(layoutXDiff, layoutYDiff);
}
/**
@@ -258,44 +155,35 @@
* @return true if info about size has changed since last reported.
*/
boolean setReportResizeHints() {
- mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
- mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets);
- mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets);
+ mLastForceReportingResized |= mForceReportingResized;
mFrameSizeChanged |= didFrameSizeChange();
mDisplayCutoutChanged |= !mLastDisplayCutout.equals(mDisplayCutout);
- return mContentInsetsChanged || mVisibleInsetsChanged
- || mStableInsetsChanged || mFrameSizeChanged
- || mDisplayCutoutChanged;
+ return mLastForceReportingResized || mFrameSizeChanged || mDisplayCutoutChanged;
}
/**
- * Resets the insets changed flags so they're all set to false again. This should be called
- * after the insets are reported to client.
+ * Resets the size changed flags so they're all set to false again. This should be called
+ * after the frames are reported to client.
*/
- void resetInsetsChanged() {
- mContentInsetsChanged = false;
- mVisibleInsetsChanged = false;
- mStableInsetsChanged = false;
+ void clearReportResizeHints() {
+ mLastForceReportingResized = false;
mFrameSizeChanged = false;
mDisplayCutoutChanged = false;
}
/**
- * Copy over inset values as the last insets that were sent to the client.
+ * Clears factors that would cause report-resize.
*/
- void updateLastInsetValues() {
- mLastContentInsets.set(mContentInsets);
- mLastVisibleInsets.set(mVisibleInsets);
- mLastStableInsets.set(mStableInsets);
+ void onResizeHandled() {
+ mForceReportingResized = false;
mLastDisplayCutout = mDisplayCutout;
}
/**
- * Sets the last content insets as (-1, -1, -1, -1) to force the next layout pass to update
- * the client.
+ * Forces the next layout pass to update the client.
*/
- void resetLastContentInsets() {
- mLastContentInsets.set(-1, -1, -1, -1);
+ void forceReportingResized() {
+ mForceReportingResized = true;
}
/**
@@ -316,16 +204,10 @@
public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
mParentFrame.dumpDebug(proto, PARENT_FRAME);
- mContentFrame.dumpDebug(proto, CONTENT_FRAME);
mDisplayFrame.dumpDebug(proto, DISPLAY_FRAME);
- mVisibleFrame.dumpDebug(proto, VISIBLE_FRAME);
- mDecorFrame.dumpDebug(proto, DECOR_FRAME);
mContainingFrame.dumpDebug(proto, CONTAINING_FRAME);
mFrame.dumpDebug(proto, FRAME);
mDisplayCutout.getDisplayCutout().dumpDebug(proto, CUTOUT);
- mContentInsets.dumpDebug(proto, CONTENT_INSETS);
- mVisibleInsets.dumpDebug(proto, VISIBLE_INSETS);
- mStableInsets.dumpDebug(proto, STABLE_INSETS);
proto.end(token);
}
@@ -333,36 +215,16 @@
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "Frames: containing="
+ mContainingFrame.toShortString(sTmpSB)
- + " parent=" + mParentFrame.toShortString(sTmpSB));
- pw.println(prefix + " display=" + mDisplayFrame.toShortString(sTmpSB));
- pw.println(prefix + " content=" + mContentFrame.toShortString(sTmpSB)
- + " visible=" + mVisibleFrame.toShortString(sTmpSB));
- pw.println(prefix + " decor=" + mDecorFrame.toShortString(sTmpSB));
+ + " parent=" + mParentFrame.toShortString(sTmpSB)
+ + " display=" + mDisplayFrame.toShortString(sTmpSB));
pw.println(prefix + "mFrame=" + mFrame.toShortString(sTmpSB)
+ " last=" + mLastFrame.toShortString(sTmpSB));
pw.println(prefix + " cutout=" + mDisplayCutout.getDisplayCutout()
+ " last=" + mLastDisplayCutout.getDisplayCutout());
- pw.print(prefix + "Cur insets: content=" + mContentInsets.toShortString(sTmpSB)
- + " visible=" + mVisibleInsets.toShortString(sTmpSB)
- + " stable=" + mStableInsets.toShortString(sTmpSB));
- pw.println(prefix + "Lst insets: content=" + mLastContentInsets.toShortString(sTmpSB)
- + " visible=" + mLastVisibleInsets.toShortString(sTmpSB)
- + " stable=" + mLastStableInsets.toShortString(sTmpSB));
- }
-
- String getInsetsInfo() {
- return "ci=" + mContentInsets.toShortString()
- + " vi=" + mVisibleInsets.toShortString()
- + " si=" + mStableInsets.toShortString();
}
String getInsetsChangedInfo() {
- return "contentInsetsChanged=" + mContentInsetsChanged
- + " " + mContentInsets.toShortString()
- + " visibleInsetsChanged=" + mVisibleInsetsChanged
- + " " + mVisibleInsets.toShortString()
- + " stableInsetsChanged=" + mStableInsetsChanged
- + " " + mStableInsets.toShortString()
+ return "forceReportingResized=" + mLastForceReportingResized
+ " displayCutoutChanged=" + mDisplayCutoutChanged;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 782d6e3..fbcbe00 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1916,7 +1916,9 @@
}
// We use the visible frame, because we want the animation to morph the window from what
// was visible to the user to the final destination of the new window.
- Rect frame = replacedWindow.getVisibleFrame();
+ final Rect frame = new Rect(replacedWindow.getFrame());
+ frame.inset(replacedWindow.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
+ frame, replacedWindow.mAttrs.softInputMode));
// We treat this as if this activity was opening, so we can trigger the app transition
// animation and piggy-back on existing transition animation infrastructure.
final DisplayContent dc = activity.getDisplayContent();
@@ -2460,12 +2462,11 @@
win.setLastReportedMergedConfiguration(mergedConfiguration);
- // Update the last inset values here because the values are sent back to the client.
- // The last inset values represent the last client state
- win.updateLastInsetValues();
+ // Set resize-handled here because the values are sent back to the client.
+ win.onResizeHandled();
win.fillClientWindowFrames(outFrames);
- outInsetsState.set(win.getInsetsState(), win.isClientLocal());
+ outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
+ ", requestedWidth=" + requestedWidth
@@ -7564,7 +7565,7 @@
public int getInputMethodWindowVisibleHeight(int displayId) {
synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
- return dc.mDisplayFrames.getInputMethodWindowVisibleHeight();
+ return dc.getInputMethodWindowVisibleHeight();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 04d7772..d972a51 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -30,13 +30,15 @@
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.SurfaceControl.Transaction;
-import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
@@ -798,11 +800,10 @@
}
boolean isImplicitlyExcludingAllSystemGestures() {
- final int immersiveStickyFlags =
- SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
- final boolean immersiveSticky =
- (mSystemUiVisibility & immersiveStickyFlags) == immersiveStickyFlags;
- return immersiveSticky && mWmService.mConstants.mSystemGestureExcludedByPreQStickyImmersive
+ final boolean stickyHideNav =
+ mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+ && !getRequestedVisibility(ITYPE_NAVIGATION_BAR);
+ return stickyHideNav && mWmService.mConstants.mSystemGestureExcludedByPreQStickyImmersive
&& mActivityRecord != null && mActivityRecord.mTargetSdk < Build.VERSION_CODES.Q;
}
@@ -1121,12 +1122,17 @@
if (isImeTarget) {
if (inFreeformWindowingMode()) {
// Push the freeform window up to make room for the IME. However, don't push
- // it up past the top of the screen.
- final int bottomOverlap = windowFrames.mContainingFrame.bottom
- - windowFrames.mVisibleFrame.bottom;
+ // it up past the bottom of the top bar.
+ final InsetsState state = dc.getInsetsStateController().getRawInsetsState();
+ final Rect visibleFrame = mTmpRect;
+ visibleFrame.set(state.getDisplayFrame());
+ visibleFrame.inset(state.calculateInsets(visibleFrame,
+ systemBars() | ime() | displayCutout(), false /* ignoreVisibility */));
+ final int bottomOverlap =
+ windowFrames.mContainingFrame.bottom - visibleFrame.bottom;
if (bottomOverlap > 0) {
final int distanceToTop = Math.max(windowFrames.mContainingFrame.top
- - windowFrames.mContentFrame.top, 0);
+ - visibleFrame.top, 0);
int offs = Math.min(bottomOverlap, distanceToTop);
windowFrames.mContainingFrame.offset(0, -offs);
mInsetFrame.offset(0, -offs);
@@ -1145,7 +1151,7 @@
// if it wasn't set already. No need to intersect it with the (visible)
// "content frame" since it is allowed to be outside the visible desktop.
if (windowFrames.mContainingFrame.isEmpty()) {
- windowFrames.mContainingFrame.set(windowFrames.mContentFrame);
+ windowFrames.mContainingFrame.set(windowFrames.mDisplayFrame);
}
}
@@ -1180,52 +1186,12 @@
applyGravityAndUpdateFrame(windowFrames, layoutContainingFrame, layoutDisplayFrame);
- // Make sure the content and visible frames are inside of the
- // final window frame.
- if (windowsAreFloating && !windowFrames.mFrame.isEmpty()) {
- final int visBottom = windowFrames.mVisibleFrame.bottom;
- final int contentBottom = windowFrames.mContentFrame.bottom;
- windowFrames.mContentFrame.set(windowFrames.mFrame);
- windowFrames.mVisibleFrame.set(windowFrames.mContentFrame);
- windowFrames.mStableFrame.set(windowFrames.mContentFrame);
- if (isImeTarget && inFreeformWindowingMode()) {
- // After displacing a freeform window to make room for the ime, any part of
- // the window still covered by IME should be inset.
- if (contentBottom + layoutYDiff < windowFrames.mContentFrame.bottom) {
- windowFrames.mContentFrame.bottom = contentBottom + layoutYDiff;
- }
- if (visBottom + layoutYDiff < windowFrames.mVisibleFrame.bottom) {
- windowFrames.mVisibleFrame.bottom = visBottom + layoutYDiff;
- }
- }
- } else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
- windowFrames.mContentFrame.set(windowFrames.mFrame);
+ if (mAttrs.type == TYPE_DOCK_DIVIDER) {
if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {
mMovedByResize = true;
}
- } else {
- windowFrames.mContentFrame.set(
- Math.max(windowFrames.mContentFrame.left, windowFrames.mFrame.left),
- Math.max(windowFrames.mContentFrame.top, windowFrames.mFrame.top),
- Math.min(windowFrames.mContentFrame.right, windowFrames.mFrame.right),
- Math.min(windowFrames.mContentFrame.bottom, windowFrames.mFrame.bottom));
-
- windowFrames.mVisibleFrame.set(
- Math.max(windowFrames.mVisibleFrame.left, windowFrames.mFrame.left),
- Math.max(windowFrames.mVisibleFrame.top, windowFrames.mFrame.top),
- Math.min(windowFrames.mVisibleFrame.right, windowFrames.mFrame.right),
- Math.min(windowFrames.mVisibleFrame.bottom, windowFrames.mFrame.bottom));
-
- windowFrames.mStableFrame.set(
- Math.max(windowFrames.mStableFrame.left, windowFrames.mFrame.left),
- Math.max(windowFrames.mStableFrame.top, windowFrames.mFrame.top),
- Math.min(windowFrames.mStableFrame.right, windowFrames.mFrame.right),
- Math.min(windowFrames.mStableFrame.bottom, windowFrames.mFrame.bottom));
}
- windowFrames.calculateInsets(windowsAreFloating, isFullscreenAndFillsDisplay,
- getDisplayFrames(dc.mDisplayFrames).mUnrestricted);
-
windowFrames.setDisplayCutout(
windowFrames.mDisplayCutout.calculateRelativeTo(windowFrames.mFrame));
@@ -1234,11 +1200,6 @@
windowFrames.mCompatFrame.set(windowFrames.mFrame);
if (inSizeCompatMode()) {
- // If there is a size compatibility scale being applied to the
- // window, we need to apply this to its insets so that they are
- // reported to the app in its coordinate space.
- windowFrames.scaleInsets(mInvGlobalScale);
-
// Also the scaled frame that we report to the app needs to be
// adjusted to be in its coordinate space.
windowFrames.mCompatFrame.scale(mInvGlobalScale);
@@ -1270,7 +1231,6 @@
+ mRequestedWidth + ", mRequestedheight="
+ mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+ "): frame=" + windowFrames.mFrame.toShortString()
- + " " + windowFrames.getInsetsInfo()
+ " " + mAttrs.getTitle());
}
}
@@ -1303,33 +1263,6 @@
return mWindowFrames.mDisplayFrame;
}
- /**
- * Retrieves the frame of the content area that this window was last laid out in. This is the
- * area in which the content of the window should be placed. It will be smaller than the display
- * frame to account for screen decorations such as a status bar or soft keyboard.
- */
- Rect getContentFrame() {
- return mWindowFrames.mContentFrame;
- }
-
- /**
- * Retrieves the frame of the visible area that this window was last laid out in. This is the
- * area of the screen in which the window will actually be fully visible. It will be smaller
- * than the content frame to account for transient UI elements blocking it such as an input
- * method's candidates UI.
- */
- Rect getVisibleFrame() {
- return mWindowFrames.mVisibleFrame;
- }
-
- Rect getStableFrame() {
- return mWindowFrames.mStableFrame;
- }
-
- Rect getDecorFrame() {
- return mWindowFrames.mDecorFrame;
- }
-
Rect getParentFrame() {
return mWindowFrames.mParentFrame;
}
@@ -1342,10 +1275,6 @@
return mWindowFrames.mDisplayCutout;
}
- void getCompatFrame(Rect outFrame) {
- outFrame.set(mWindowFrames.mCompatFrame);
- }
-
void getCompatFrameSize(Rect outFrame) {
outFrame.set(0, 0, mWindowFrames.mCompatFrame.width(), mWindowFrames.mCompatFrame.height());
}
@@ -1433,7 +1362,7 @@
return;
}
- updateLastInsetValues();
+ onResizeHandled();
mWmService.makeWindowFreezingScreenIfNeededLocked(this);
// If the orientation is changing, or we're starting or ending a drag resizing action,
@@ -1534,11 +1463,19 @@
}
/**
- * Returns the insets state for the client. Its sources may be the copies with visibility
+ * Returns the insets state for the window. Its sources may be the copies with visibility
* modification according to the state of transient bars.
*/
InsetsState getInsetsState() {
- InsetsState state = getDisplayContent().getInsetsPolicy().getInsetsForWindow(this);
+ return getDisplayContent().getInsetsPolicy().getInsetsForWindow(this);
+ }
+
+ /**
+ * Returns the insets state for the client and scales the frames if the client is in the size
+ * compatible mode.
+ */
+ InsetsState getCompatInsetsState() {
+ InsetsState state = getInsetsState();
if (inSizeCompatMode()) {
state = new InsetsState(state, true);
state.scale(mInvGlobalScale);
@@ -1546,6 +1483,23 @@
return state;
}
+ /**
+ * Returns the insets state for the window and applies the requested visibility.
+ */
+ InsetsState getInsetsStateWithVisibilityOverride() {
+ final InsetsState state = new InsetsState(getInsetsState());
+ for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
+ final boolean requestedVisible = getRequestedVisibility(type);
+ InsetsSource source = state.peekSource(type);
+ if (source != null && source.isVisible() != requestedVisible) {
+ source = new InsetsSource(source);
+ source.setVisible(requestedVisible);
+ state.addSource(source);
+ }
+ }
+ return state;
+ }
+
int getDisplayId() {
final DisplayContent displayContent = getDisplayContent();
if (displayContent == null) {
@@ -1625,18 +1579,12 @@
}
}
- bounds.set(mWindowFrames.mVisibleFrame);
+ bounds.set(mWindowFrames.mFrame);
+ bounds.inset(getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
+ bounds, mAttrs.softInputMode));
if (intersectWithStackBounds) {
bounds.intersect(mTmpRect);
}
-
- if (bounds.isEmpty()) {
- bounds.set(mWindowFrames.mFrame);
- if (intersectWithStackBounds) {
- bounds.intersect(mTmpRect);
- }
- return;
- }
}
public long getInputDispatchingTimeoutMillis() {
@@ -1958,7 +1906,7 @@
mWinAnimator.mDrawState = DRAW_PENDING;
// Force add to {@link WindowManagerService#mResizingWindows}.
- resetLastContentInsets();
+ forceReportingResized();
outWaitingForDrawn.add(this);
}
@@ -3423,8 +3371,8 @@
// bottom right.
if (win.getFrame().left <= win.getDisplayFrame().left
&& win.getFrame().top <= win.getDisplayFrame().top
- && win.getFrame().right >= win.getStableFrame().right
- && win.getFrame().bottom >= win.getStableFrame().bottom) {
+ && win.getFrame().right >= win.getDisplayFrame().right
+ && win.getFrame().bottom >= win.getDisplayFrame().bottom) {
// Is a fullscreen window, like the clock alarm. Show to everyone.
return true;
}
@@ -3623,7 +3571,7 @@
// that may cause WINDOW_FREEZE_TIMEOUT because resizing the client keeps failing.
mReportOrientationChanged = false;
mDragResizingChangeReported = true;
- mWindowFrames.resetInsetsChanged();
+ mWindowFrames.clearReportResizeHints();
final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;
final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported;
@@ -3692,7 +3640,7 @@
void notifyInsetsChanged() {
ProtoLog.d(WM_DEBUG_IME, "notifyInsetsChanged for %s ", this);
try {
- mClient.insetsChanged(getInsetsState());
+ mClient.insetsChanged(getCompatInsetsState());
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver inset state change w=" + this, e);
}
@@ -3707,7 +3655,7 @@
final InsetsStateController stateController =
getDisplayContent().getInsetsStateController();
try {
- mClient.insetsControlChanged(getInsetsState(),
+ mClient.insetsControlChanged(getCompatInsetsState(),
stateController.getControlsForDispatch(this));
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver inset state change to w=" + this, e);
@@ -4917,24 +4865,6 @@
}
}
- private boolean skipDecorCrop() {
- // The decor frame is used to specify the region not covered by the system
- // decorations (nav bar, status bar). In case this is empty, for example with
- // FLAG_TRANSLUCENT_NAVIGATION, we don't need to do any cropping.
- if (mWindowFrames.mDecorFrame.isEmpty()) {
- return true;
- }
-
- // But if we have a frame, and are an application window, then we must be cropped.
- if (mActivityRecord != null) {
- return false;
- }
-
- // For non application windows, we may be allowed to extend over the decor bars
- // depending on our type and permissions assosciated with our token.
- return mToken.canLayerAboveSystemBars();
- }
-
/**
* Expand the given rectangle by this windows surface insets. This
* takes you from the 'window size' to the 'surface size'.
@@ -5062,10 +4992,10 @@
}
/**
- * Updates the last inset values to the current ones.
+ * Clears factors that would cause report-resize.
*/
- void updateLastInsetValues() {
- mWindowFrames.updateLastInsetValues();
+ void onResizeHandled() {
+ mWindowFrames.onResizeHandled();
}
@Override
@@ -5550,48 +5480,8 @@
mFrameNumber = frameNumber;
}
- public void getMaxVisibleBounds(Rect out) {
- if (out.isEmpty()) {
- out.set(mWindowFrames.mVisibleFrame);
- return;
- }
-
- if (mWindowFrames.mVisibleFrame.left < out.left) {
- out.left = mWindowFrames.mVisibleFrame.left;
- }
- if (mWindowFrames.mVisibleFrame.top < out.top) {
- out.top = mWindowFrames.mVisibleFrame.top;
- }
- if (mWindowFrames.mVisibleFrame.right > out.right) {
- out.right = mWindowFrames.mVisibleFrame.right;
- }
- if (mWindowFrames.mVisibleFrame.bottom > out.bottom) {
- out.bottom = mWindowFrames.mVisibleFrame.bottom;
- }
- }
-
- void getContentInsets(Rect outContentInsets) {
- outContentInsets.set(mWindowFrames.mContentInsets);
- }
-
- Rect getContentInsets() {
- return mWindowFrames.mContentInsets;
- }
-
- void getStableInsets(Rect outStableInsets) {
- outStableInsets.set(mWindowFrames.mStableInsets);
- }
-
- Rect getStableInsets() {
- return mWindowFrames.mStableInsets;
- }
-
- void resetLastContentInsets() {
- mWindowFrames.resetLastContentInsets();
- }
-
- Rect getVisibleInsets() {
- return mWindowFrames.mVisibleInsets;
+ void forceReportingResized() {
+ mWindowFrames.forceReportingResized();
}
/** Returns the {@link WindowFrames} associated with this {@link WindowState}. */
@@ -5719,10 +5609,11 @@
outFrame.set(getContainingFrame());
}
outSurfaceInsets.set(getAttrs().surfaceInsets);
- // TODO(b/72757033): These are insets relative to the window frame, but we're really
- // interested in the insets relative to the frame we chose in the if-blocks above.
- getContentInsets(outInsets);
- getStableInsets(outStableInsets);
+ final InsetsState state = getInsetsStateWithVisibilityOverride();
+ outInsets.set(state.calculateInsets(outFrame, systemBars(),
+ false /* ignoreVisibility */));
+ outStableInsets.set(state.calculateInsets(outFrame, systemBars(),
+ true /* ignoreVisibility */));
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index dc33b75..ec30dc5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -30,11 +30,11 @@
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
-import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
-import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
@@ -101,6 +101,7 @@
import android.view.IDisplayWindowRotationController;
import android.view.ISystemGestureExclusionListener;
import android.view.IWindowManager;
+import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl.Transaction;
@@ -1092,9 +1093,11 @@
win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
- win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
- SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ win.getAttrs().insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+ final InsetsState requestedState = new InsetsState();
+ requestedState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
+ requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+ win.updateRequestedVisibility(requestedState);
win.mActivityRecord.mTargetSdk = P;
performLayout(dc);
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 3598cd8..378a0a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -16,10 +16,6 @@
package com.android.server.wm;
-import static android.view.Gravity.BOTTOM;
-import static android.view.Gravity.LEFT;
-import static android.view.Gravity.RIGHT;
-import static android.view.Gravity.TOP;
import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
@@ -32,12 +28,10 @@
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
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_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_INSET_PARENT_FRAME_BY_IME;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -58,7 +52,6 @@
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.testng.Assert.expectThrows;
@@ -106,7 +99,6 @@
private int mRotation = ROTATION_0;
private boolean mHasDisplayCutout;
private boolean mIsLongEdgeDisplayCutout;
- private static final int DECOR_WINDOW_INSET = 50;
private final Rect mDisplayBounds = new Rect();
@@ -282,12 +274,8 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
@@ -298,12 +286,8 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
@@ -314,12 +298,8 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
@@ -330,18 +310,13 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
public void layoutWindowLw_fitInsetsIgnoringVisibility() {
- final InsetsState state =
- mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow);
+ final InsetsState state = mWindow.getInsetsState();
state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);
mWindow.mAttrs.setFitInsetsIgnoringVisibility(true);
@@ -350,18 +325,13 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
public void layoutWindowLw_fitInsetsNotIgnoringVisibility() {
- final InsetsState state =
- mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow);
+ final InsetsState state = mWindow.getInsetsState();
state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);
mWindow.mAttrs.setFitInsetsIgnoringVisibility(false);
@@ -370,12 +340,8 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
@@ -407,12 +373,8 @@
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0);
assertInsetByTopBottom(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
}
@Test
@@ -428,9 +390,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@@ -448,9 +407,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
}
@@ -468,9 +424,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@@ -488,9 +441,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@@ -509,9 +459,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@@ -522,8 +469,7 @@
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow)
- .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
+ mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
final InsetsState requestedState = new InsetsState();
requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
mWindow.updateRequestedVisibility(requestedState);
@@ -533,9 +479,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);
}
@@ -546,8 +489,7 @@
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow)
- .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
+ mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
final InsetsState requestedState = new InsetsState();
requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
mWindow.updateRequestedVisibility(requestedState);
@@ -558,9 +500,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);
}
@@ -578,10 +517,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrame(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@@ -599,10 +534,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getStableFrame(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
- assertInsetBy(mWindow.getContentFrame(),
- NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
}
@@ -622,10 +553,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrame(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@Test
@@ -663,10 +590,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrame(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@Test
@@ -682,10 +605,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@@ -703,11 +622,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@@ -725,10 +639,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@@ -746,10 +656,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@@ -767,10 +673,6 @@
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);
}
@@ -832,10 +734,16 @@
// Initialize DisplayFrames
mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ final InsetsState state =
+ mDisplayContent.getInsetsStateController().getRawInsetsState();
+ final Rect contentFrame = new Rect(state.getDisplayFrame());
+ contentFrame.inset(state.calculateInsets(contentFrame, Type.systemBars(),
+ false /* ignoreVisibility */));
+
// Task is in the nav bar area (usually does not happen, but this is similar enough to
// the possible overlap with the IME)
- final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
- 200, mFrames.mContent.bottom + 10);
+ final Rect taskBounds = new Rect(100, contentFrame.bottom + 1,
+ 200, contentFrame.bottom + 10);
final Task task = mWindow.getTask();
// Make the task floating.
@@ -915,59 +823,6 @@
assertEquals(DISPLAY_HEIGHT, rotatedFrame.width());
}
- @Test
- public void testScreenDecorWindows() {
- final WindowState decorWindow = spy(
- createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow"));
- mWindow.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR
- | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
- addWindow(decorWindow);
- addWindow(mWindow);
- doReturn(new Rect(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight))
- .when(decorWindow).getBounds();
-
- // Decor on top
- updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrame(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
-
- // Decor on bottom
- updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT,
- DECOR_WINDOW_INSET);
-
- // Decor on the left
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrame(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
-
- // Decor on the right
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
- NAV_BAR_HEIGHT);
-
- // Decor not allowed as inset
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- }
-
- private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) {
- decorWindow.mAttrs.width = width;
- decorWindow.mAttrs.height = height;
- decorWindow.mAttrs.gravity = gravity;
- decorWindow.setRequestedSize(width, height);
- }
-
/**
* Asserts that {@code actual} is inset by the given amounts from the full display rect.
*
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index bbe811d..e0fd379 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -356,7 +356,7 @@
assertNull(controls[i].getLeash());
}
- final InsetsState state = policy.getInsetsForWindow(mAppWindow);
+ final InsetsState state = mAppWindow.getInsetsState();
state.setSourceVisible(ITYPE_STATUS_BAR, true);
state.setSourceVisible(ITYPE_NAVIGATION_BAR, true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index a1097d2..98520bb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -28,6 +28,10 @@
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
+import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -36,6 +40,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
@@ -45,6 +51,7 @@
import android.os.Build;
import android.platform.test.annotations.Presubmit;
import android.view.Gravity;
+import android.view.InsetsState;
import androidx.test.filters.SmallTest;
@@ -1114,8 +1121,9 @@
// This test case requires a relatively big app bounds to ensure the default size calculated
// by letterbox won't be too small to hold the minimum width/height.
- freeformDisplay.mDisplayContent.mDisplayFrames.mStable.set(/* left */ 10, /* top */ 10,
- /* right */ 1910, /* top */ 1070);
+ configInsetsState(
+ freeformDisplay.getInsetsStateController().getRawInsetsState(),
+ DISPLAY_BOUNDS, new Rect(10, 10, 1910, 1070));
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
@@ -1339,15 +1347,45 @@
display.setBounds(DISPLAY_BOUNDS);
display.getConfiguration().densityDpi = DENSITY_DEFAULT;
display.getConfiguration().orientation = ORIENTATION_LANDSCAPE;
- display.mDisplayContent.mDisplayFrames.mStable.set(DISPLAY_STABLE_BOUNDS);
- spyOn(display.mDisplayContent.mDisplayFrames);
+ configInsetsState(display.getInsetsStateController().getRawInsetsState(),
+ DISPLAY_BOUNDS, DISPLAY_STABLE_BOUNDS);
// We didn't set up the overall environment for this test, so we need to mute the side
// effect of layout passes that loosen the stable frame.
- doNothing().when(display.mDisplayContent.mDisplayFrames).onBeginLayout();
+ final DisplayPolicy policy = display.getDisplayPolicy();
+ spyOn(policy);
+ doNothing().when(policy).beginLayoutLw(any(), anyInt());
return display;
}
+ /**
+ * Creates insets sources so that we can get the expected stable frame.
+ */
+ private static void configInsetsState(InsetsState state, Rect displayFrame, Rect stableFrame) {
+ final int dl = displayFrame.left;
+ final int dt = displayFrame.top;
+ final int dr = displayFrame.right;
+ final int db = displayFrame.bottom;
+ final int sl = stableFrame.left;
+ final int st = stableFrame.top;
+ final int sr = stableFrame.right;
+ final int sb = stableFrame.bottom;
+
+ state.setDisplayFrame(displayFrame);
+ if (sl > dl) {
+ state.getSource(ITYPE_CLIMATE_BAR).setFrame(dl, dt, sl, db);
+ }
+ if (st > dt) {
+ state.getSource(ITYPE_STATUS_BAR).setFrame(dl, dt, dr, st);
+ }
+ if (sr < dr) {
+ state.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(sr, dt, dr, db);
+ }
+ if (sb < db) {
+ state.getSource(ITYPE_NAVIGATION_BAR).setFrame(dl, sb, dr, db);
+ }
+ }
+
private ActivityRecord createSourceActivity(TestDisplayContent display) {
final Task stack = display.getDefaultTaskDisplayArea()
.createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 0cf63f4..d2be50d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -21,9 +21,10 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -34,6 +35,8 @@
import android.platform.test.annotations.Presubmit;
import android.view.DisplayInfo;
import android.view.Gravity;
+import android.view.InsetsSource;
+import android.view.InsetsState;
import android.view.WindowManager;
import androidx.test.filters.FlakyTest;
@@ -57,7 +60,6 @@
@RunWith(WindowTestRunner.class)
public class WindowFrameTests extends WindowTestsBase {
- private final Rect mEmptyRect = new Rect();
private DisplayContent mTestDisplayContent;
@Before
@@ -76,18 +78,6 @@
assertEquals(bottom, rect.bottom);
}
- private void assertContentInset(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getContentInsets(), left, top, right, bottom);
- }
-
- private void assertVisibleInset(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getVisibleInsets(), left, top, right, bottom);
- }
-
- private void assertStableInset(WindowState w, int left, int top, int right, int bottom) {
- assertRect(w.getStableInsets(), left, top, right, bottom);
- }
-
private void assertFrame(WindowState w, Rect frame) {
assertEquals(w.getFrame(), frame);
}
@@ -100,82 +90,8 @@
assertRect(w.getRelativeFrame(), left, top, right, bottom);
}
- private void assertContentFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getContentFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
- expectedRect.bottom);
- }
-
- private void assertVisibleFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getVisibleFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
- expectedRect.bottom);
- }
-
- private void assertStableFrame(WindowState w, Rect expectedRect) {
- assertRect(w.getStableFrame(), expectedRect.left, expectedRect.top, expectedRect.right,
- expectedRect.bottom);
- }
-
@Test
- public void testLayoutInFullscreenTaskInsets() {
- // fullscreen task doesn't use bounds for computeFrame
- WindowState w = createWindow();
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
-
- final int bottomContentInset = 100;
- final int topContentInset = 50;
- final int bottomVisibleInset = 30;
- final int topVisibleInset = 70;
- final int leftStableInset = 20;
- final int rightStableInset = 90;
-
- // With no insets or system decor all the frames incoming from PhoneWindowManager
- // are identical.
- final Rect pf = new Rect(0, 0, 1000, 1000);
- final Rect df = pf;
- final Rect of = df;
- final Rect cf = new Rect(pf);
- // Produce some insets
- cf.top += 50;
- cf.bottom -= 100;
- final Rect vf = new Rect(pf);
- vf.top += topVisibleInset;
- vf.bottom -= bottomVisibleInset;
- final Rect sf = new Rect(pf);
- sf.left += leftStableInset;
- sf.right -= rightStableInset;
-
- final Rect dcf = pf;
- // When mFrame extends past cf, the content insets are
- // the difference between mFrame and ContentFrame. Visible
- // and stable frames work the same way.
- w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrame();
- assertFrame(w, 0, 0, 1000, 1000);
- assertRelFrame(w, 0, 0, 1000, 1000);
- assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
- assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset);
- assertStableInset(w, leftStableInset, 0, rightStableInset, 0);
- assertContentFrame(w, cf);
- assertVisibleFrame(w, vf);
- assertStableFrame(w, sf);
- // On the other hand getFrame() doesn't extend past cf we won't get any insets
- w.mAttrs.x = 100;
- w.mAttrs.y = 100;
- w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
- w.mRequestedWidth = 100;
- w.mRequestedHeight = 100;
- w.computeFrame();
- assertFrame(w, 100, 100, 200, 200);
- assertRelFrame(w, 100, 100, 200, 200);
- assertContentInset(w, 0, 0, 0, 0);
- // In this case the frames are shrunk to the window frame.
- assertContentFrame(w, w.getFrame());
- assertVisibleFrame(w, w.getFrame());
- assertStableFrame(w, w.getFrame());
- }
-
- @Test
- public void testLayoutInFullscreenTaskNoInsets() {
+ public void testLayoutInFullscreenTask() {
// fullscreen task doesn't use bounds for computeFrame
WindowState w = createWindow();
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
@@ -186,7 +102,7 @@
// Here the window has FILL_PARENT, FILL_PARENT
// so we expect it to fill the entire available frame.
- w.getWindowFrames().setFrames(pf, pf, pf, pf, pf, pf);
+ w.getWindowFrames().setFrames(pf, pf);
w.computeFrame();
assertFrame(w, 0, 0, 1000, 1000);
assertRelFrame(w, 0, 0, 1000, 1000);
@@ -278,76 +194,24 @@
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
+ windowFrames.setFrames(pf, pf);
w.computeFrame();
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
assertEquals(resolvedTaskBounds, w.getFrame());
assertEquals(0, w.getRelativeFrame().left);
assertEquals(0, w.getRelativeFrame().top);
- assertContentFrame(w, resolvedTaskBounds);
- assertContentInset(w, 0, 0, 0, 0);
pf.set(0, 0, logicalWidth, logicalHeight);
// We still produce insets against the containing frame the same way.
final int cfRight = logicalWidth / 2;
final int cfBottom = logicalHeight / 2;
final Rect cf = new Rect(0, 0, cfRight, cfBottom);
- windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
+ windowFrames.setFrames(pf, pf);
w.computeFrame();
assertEquals(resolvedTaskBounds, w.getFrame());
assertEquals(0, w.getRelativeFrame().left);
assertEquals(0, w.getRelativeFrame().top);
- int contentInsetRight = resolvedTaskBounds.right - cfRight;
- int contentInsetBottom = resolvedTaskBounds.bottom - cfBottom;
- assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
- assertContentFrame(w, new Rect(resolvedTaskBounds.left, resolvedTaskBounds.top,
- resolvedTaskBounds.right - contentInsetRight,
- resolvedTaskBounds.bottom - contentInsetBottom));
- }
-
- @Test
- @FlakyTest(bugId = 130388666)
- public void testCalculatePolicyCrop() {
- final WindowState w = createWindow();
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
-
- final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
- final int logicalWidth = displayInfo.logicalWidth;
- final int logicalHeight = displayInfo.logicalHeight;
- final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
- final Rect df = pf;
- final Rect cf = new Rect(pf);
- // Produce some insets
- cf.top += displayInfo.logicalWidth / 10;
- cf.bottom -= displayInfo.logicalWidth / 5;
- final Rect vf = cf;
- final Rect sf = vf;
- // We use a decor content frame with insets to produce cropping.
- Rect dcf = new Rect(cf);
-
- final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, df, cf, vf, dcf, sf);
- w.computeFrame();
-
- windowFrames.mDecorFrame.setEmpty();
- // Likewise with no decor frame we would get no crop
- w.computeFrame();
-
- // Now we set up a window which doesn't fill the entire decor frame.
- // Normally it would be cropped to it's frame but in the case of docked resizing
- // we need to account for the fact the windows surface will be made
- // fullscreen and thus also make the crop fullscreen.
-
- windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
- w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
- w.mAttrs.width = logicalWidth / 2;
- w.mAttrs.height = logicalHeight / 2;
- w.mRequestedWidth = logicalWidth / 2;
- w.mRequestedHeight = logicalHeight / 2;
- w.computeFrame();
-
- doReturn(true).when(w).isDockedResizing();
}
@Test
@@ -372,13 +236,11 @@
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
+ windowFrames.setFrames(pf, pf);
w.computeFrame();
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
- assertContentFrame(w, taskBounds);
- assertContentInset(w, 0, 0, 0, 0);
// Now simulate switch to fullscreen for letterboxed app.
final int xInset = logicalWidth / 10;
@@ -390,11 +252,9 @@
pf.set(0, 0, logicalWidth, logicalHeight);
task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
task.setBounds(null);
- windowFrames.setFrames(pf, pf, cf, cf, pf, cf);
+ windowFrames.setFrames(pf, pf);
w.computeFrame();
assertFrame(w, cf);
- assertContentFrame(w, cf);
- assertContentInset(w, 0, 0, 0, 0);
}
@Test
@@ -411,7 +271,7 @@
pf.width(), pf.height());
final WindowFrames windowFrames = w.getWindowFrames();
- windowFrames.setFrames(pf, pf, pf, pf, pf, pf);
+ windowFrames.setFrames(pf, pf);
windowFrames.setDisplayCutout(cutout);
w.computeFrame();
@@ -430,51 +290,52 @@
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
task.setWindowingMode(WINDOWING_MODE_FREEFORM);
- DisplayContent dc = mTestDisplayContent;
+ // Make IME attach to the window and can produce insets.
+ final DisplayContent dc = mTestDisplayContent;
dc.mInputMethodTarget = w;
WindowState mockIme = mock(WindowState.class);
Mockito.doReturn(true).when(mockIme).isVisibleNow();
dc.mInputMethodWindow = mockIme;
+ final InsetsState state = dc.getInsetsStateController().getRawInsetsState();
+ final InsetsSource imeSource = state.getSource(ITYPE_IME);
+ final Rect imeFrame = new Rect(state.getDisplayFrame());
+ imeFrame.top = 400;
+ imeSource.setFrame(imeFrame);
+ imeSource.setVisible(true);
+ w.updateRequestedVisibility(state);
+ w.mBehindIme = true;
// With no insets or system decor all the frames incoming from PhoneWindowManager
// are identical.
final Rect pf = new Rect(0, 0, 1000, 800);
- final Rect df = pf;
- final Rect of = df;
- final Rect cf = new Rect(pf);
- cf.bottom -= 400;
- final Rect vf = new Rect(cf);
- final Rect sf = new Rect(pf);
- final Rect dcf = pf;
// First check that it only gets moved up enough to show window.
final Rect winRect = new Rect(200, 200, 300, 500);
-
task.setBounds(winRect);
- w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
+ w.getWindowFrames().setFrames(pf, pf);
w.computeFrame();
+ assertFrame(w, winRect.left, imeFrame.top - winRect.height(), winRect.right, imeFrame.top);
- final Rect expected = new Rect(winRect.left, cf.bottom - winRect.height(),
- winRect.right, cf.bottom);
- assertEquals(expected, w.getFrame());
- assertEquals(expected, w.getContentFrame());
- assertEquals(expected, w.getVisibleFrame());
-
- // Now check that it won't get moved beyond the top and then has appropriate insets
- winRect.bottom = 600;
+ // Now check that it won't get moved beyond the top
+ winRect.bottom = 650;
task.setBounds(winRect);
w.setBounds(winRect);
- w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf);
+ w.getWindowFrames().setFrames(pf, pf);
w.computeFrame();
-
assertFrame(w, winRect.left, 0, winRect.right, winRect.height());
- expected.top = 0;
- expected.bottom = cf.bottom;
- assertContentFrame(w, expected);
- assertVisibleFrame(w, expected);
+
+ // Now we have status bar. Check that it won't go into the status bar area.
+ final Rect statusBarFrame = new Rect(state.getDisplayFrame());
+ statusBarFrame.bottom = 60;
+ state.getSource(ITYPE_STATUS_BAR).setFrame(statusBarFrame);
+ w.getWindowFrames().setFrames(pf, pf);
+ w.computeFrame();
+ assertFrame(w, winRect.left, statusBarFrame.bottom, winRect.right,
+ statusBarFrame.bottom + winRect.height());
// Check that it's moved back without ime insets
- w.getWindowFrames().setFrames(pf, df, pf, pf, dcf, sf);
+ state.removeSource(ITYPE_IME);
+ w.getWindowFrames().setFrames(pf, pf);
w.computeFrame();
assertEquals(winRect, w.getFrame());
}