diff options
11 files changed, 370 insertions, 277 deletions
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index f1bd63b3bb6e..125733665a18 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -271,7 +271,7 @@ message WindowStateProto { optional .android.graphics.RectProto containing_frame = 8 [deprecated=true]; optional .android.graphics.RectProto parent_frame = 9 [deprecated=true]; optional .android.graphics.RectProto content_frame = 10 [deprecated=true]; - optional .android.graphics.RectProto content_insets = 11; + optional .android.graphics.RectProto content_insets = 11 [deprecated=true]; optional .android.graphics.RectProto surface_insets = 12; optional WindowStateAnimatorProto animator = 13; optional bool animating_exit = 14; @@ -288,10 +288,10 @@ message WindowStateProto { optional .android.graphics.RectProto visible_frame = 26 [deprecated=true]; optional .android.graphics.RectProto decor_frame = 27 [deprecated=true]; optional .android.graphics.RectProto outset_frame = 28 [deprecated=true]; - optional .android.graphics.RectProto overscan_insets = 29; - optional .android.graphics.RectProto visible_insets = 30; - optional .android.graphics.RectProto stable_insets = 31; - optional .android.graphics.RectProto outsets = 32; + optional .android.graphics.RectProto overscan_insets = 29 [deprecated=true]; + optional .android.graphics.RectProto visible_insets = 30 [deprecated=true]; + optional .android.graphics.RectProto stable_insets = 31 [deprecated=true]; + optional .android.graphics.RectProto outsets = 32 [deprecated=true]; optional .android.view.DisplayCutoutProto cutout = 33 [deprecated=true]; optional bool remove_on_exit = 34; optional bool destroying = 35; @@ -380,4 +380,9 @@ message WindowFramesProto { optional .android.graphics.RectProto parent_frame = 8; optional .android.graphics.RectProto visible_frame = 9; optional .android.view.DisplayCutoutProto cutout = 10; + optional .android.graphics.RectProto content_insets = 11; + optional .android.graphics.RectProto overscan_insets = 12; + optional .android.graphics.RectProto visible_insets = 13; + optional .android.graphics.RectProto stable_insets = 14; + optional .android.graphics.RectProto outsets = 15; } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index b7759182fb01..6da9f104a212 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -32,29 +32,11 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; - +import static android.view.WindowManager.TRANSIT_UNSET; import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN; + import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; -import static android.view.WindowManager.TRANSIT_UNSET; - -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN; -import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; -import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; -import static com.android.server.wm.WindowManagerService.logWithStack; import static com.android.server.wm.AppWindowTokenProto.ALL_DRAWN; import static com.android.server.wm.AppWindowTokenProto.APP_STOPPED; import static com.android.server.wm.AppWindowTokenProto.CLIENT_HIDDEN; @@ -78,6 +60,23 @@ import static com.android.server.wm.AppWindowTokenProto.STARTING_MOVED; import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW; import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL; import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN; +import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; +import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; +import static com.android.server.wm.WindowManagerService.logWithStack; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM; import android.annotation.CallSuper; @@ -1845,8 +1844,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree surfaceInsets = win.getAttrs().surfaceInsets; // XXX(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. - insets.set(win.mContentInsets); - stableInsets.set(win.mStableInsets); + win.getContentInsets(insets); + win.getStableInsets(stableInsets); } if (mLaunchTaskBehind) { @@ -2099,7 +2098,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree WindowState win = findMainWindow(); Rect appRect = win != null ? win.getContentFrameLw() : new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight); - Rect insets = win != null ? win.mContentInsets : null; + final Rect insets = win != null ? win.getContentInsets() : null; final Configuration displayConfig = mDisplayContent.getConfiguration(); return mService.mAppTransition.createThumbnailAspectScaleAnimationLocked( appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode, diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 32fa9bf97930..1536d1833dd9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3009,7 +3009,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) { w.mWinAnimator.mDrawState = DRAW_PENDING; // Force add to mResizingWindows. - w.mLastContentInsets.set(-1, -1, -1, -1); + w.resetLastContentInsets(); mService.mWaitingForDrawn.add(w); } }, true /* traverseTopToBottom */); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 4dbd858ec45b..1eae56745a75 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -373,7 +373,7 @@ public class RecentsAnimationController implements DeathRecipient { : null; final Rect contentInsets; if (mTargetAppToken != null && mTargetAppToken.findMainWindow() != null) { - contentInsets = mTargetAppToken.findMainWindow().mContentInsets; + contentInsets = mTargetAppToken.findMainWindow().getContentInsets(); } else { // If the window for the activity had not yet been created, use the display insets. mService.getStableInsets(mDisplayId, mTmpRect); @@ -583,7 +583,8 @@ public class RecentsAnimationController implements DeathRecipient { if (mainWindow == null) { return null; } - final Rect insets = new Rect(mainWindow.mContentInsets); + final Rect insets = new Rect(); + mainWindow.getContentInsets(insets); InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets()); mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash, !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect, diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 67ef47103103..00422e3497be 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -305,7 +305,8 @@ class RemoteAnimationController implements DeathRecipient { || mCapturedLeash == null) { return null; } - final Rect insets = new Rect(mainWindow.mContentInsets); + final Rect insets = new Rect(); + mainWindow.getContentInsets(insets); InsetUtils.addInsets(insets, mAppWindowToken.getLetterboxInsets()); mTarget = new RemoteAnimationTarget(task.mTaskId, getMode(), mCapturedLeash, !mAppWindowToken.fillsParent(), diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 6c8572a864c6..b7507a42485c 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -303,7 +303,7 @@ class TaskSnapshotController { 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.mContentInsets, state.mStableInsets); + final Rect insets = minRect(state.getContentInsets(), state.getStableInsets()); InsetUtils.addInsets(insets, state.mAppToken.getLetterboxInsets()); return insets; } @@ -373,7 +373,7 @@ class TaskSnapshotController { node.setClipToBounds(false); final DisplayListCanvas c = node.start(width, height); c.drawColor(color); - decorPainter.setInsets(mainWindow.mContentInsets, mainWindow.mStableInsets); + decorPainter.setInsets(mainWindow.getContentInsets(), mainWindow.getStableInsets()); decorPainter.drawDecors(c, null /* statusBarExcludeFrame */); node.end(c); final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height); @@ -383,7 +383,7 @@ class TaskSnapshotController { // Note, the app theme snapshot is never translucent because we enforce a non-translucent // color above return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(), - topChild.getConfiguration().orientation, mainWindow.mStableInsets, + topChild.getConfiguration().orientation, mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task), false); diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index 228bfade25d5..9381fc61821e 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -18,20 +18,27 @@ 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.OUTSETS; import static com.android.server.wm.WindowFramesProto.OUTSET_FRAME; import static com.android.server.wm.WindowFramesProto.OVERSCAN_FRAME; +import static com.android.server.wm.WindowFramesProto.OVERSCAN_INSETS; 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 android.view.WindowManager; +import com.android.server.wm.utils.InsetUtils; import com.android.server.wm.utils.WmDisplayCutout; import java.io.PrintWriter; @@ -60,7 +67,7 @@ public class WindowFrames { * * TODO(b/111611553): The name is unclear and most likely should be swapped with * {@link #mParentFrame} - */ + */ public final Rect mDisplayFrame = new Rect(); /** @@ -118,6 +125,12 @@ public class WindowFrames { */ final Rect mLastFrame = new Rect(); + private boolean mFrameSizeChanged = false; + + // Frame that is scaled to the application's coordinate space when in + // screen size compatibility mode. + final Rect mCompatFrame = new Rect(); + /** * Whether the parent frame would have been different if there was no display cutout. */ @@ -131,7 +144,52 @@ public class WindowFrames { /** * The last cutout that has been reported to the client. */ - WmDisplayCutout mLastDisplayCutout = WmDisplayCutout.NO_CUTOUT; + private WmDisplayCutout mLastDisplayCutout = WmDisplayCutout.NO_CUTOUT; + + private boolean mDisplayCutoutChanged; + + /** + * Insets that determine the area covered by the display overscan region. These are in the + * application's coordinate space (without compatibility scale applied). + */ + final Rect mOverscanInsets = new Rect(); + final Rect mLastOverscanInsets = new Rect(); + private boolean mOverscanInsetsChanged; + + /** + * 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; + + /** + * Outsets determine the area outside of the surface where we want to pretend that it's possible + * to draw anyway. + */ + final Rect mOutsets = new Rect(); + final Rect mLastOutsets = new Rect(); + private boolean mOutsetsChanged = false; + + /** + * 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(); public WindowFrames() { } @@ -171,15 +229,141 @@ public class WindowFrames { /** * @return true if the width or height has changed since last reported to the client. */ - boolean didFrameSizeChange() { + private boolean didFrameSizeChange() { return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height()); } /** - * @return true if the display cutout has changed since last reported to the client. + * Calculates the outsets for this windowFrame. The outsets are calculated by the area between + * the {@link #mOutsetFrame} and the {@link #mContentFrame}. If there are no outsets, then + * {@link #mOutsets} is set to empty. + * + * @param hasOutsets Whether this frame has outsets. + */ + void calculateOutsets(boolean hasOutsets) { + if (hasOutsets) { + InsetUtils.insetsBetweenFrames(mOutsetFrame, mContentFrame, mOutsets); + } else { + mOutsets.setEmpty(); + } + } + + /** + * Calculate the insets for the type {@link WindowManager.LayoutParams#TYPE_DOCK_DIVIDER} + * + * @param cutoutInsets The insets for the cutout. */ - boolean didDisplayCutoutChange() { - return !mLastDisplayCutout.equals(mDisplayCutout); + void calculateDockedDividerInsets(Rect cutoutInsets) { + // For the docked divider, we calculate the stable insets like a full-screen window + // so it can use it to calculate the snap positions. + mTmpRect.set(mDisplayFrame); + mTmpRect.inset(cutoutInsets); + mTmpRect.intersectUnchecked(mStableFrame); + InsetUtils.insetsBetweenFrames(mDisplayFrame, mTmpRect, mStableInsets); + + // The divider doesn't care about insets in any case, so set it to empty so we don't + // trigger a relayout when moving it. + mContentInsets.setEmpty(); + mVisibleInsets.setEmpty(); + mDisplayCutout = WmDisplayCutout.NO_CUTOUT; + } + + /** + * 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 ? mTmpRect.right : mFrame.right, + overrideBottomInset ? mTmpRect.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) { + mOverscanInsets.scale(scale); + mContentInsets.scale(scale); + mVisibleInsets.scale(scale); + mStableInsets.scale(scale); + mOutsets.scale(scale); + } + + void offsetFrames(int layoutXDiff, int layoutYDiff) { + mFrame.offset(layoutXDiff, layoutYDiff); + mContentFrame.offset(layoutXDiff, layoutYDiff); + mVisibleFrame.offset(layoutXDiff, layoutYDiff); + mStableFrame.offset(layoutXDiff, layoutYDiff); + } + + /** + * Updates info about whether the size of the window has changed since last reported. + * + * @return true if info about size has changed since last reported. + */ + boolean setReportResizeHints() { + mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); + mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); + mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); + mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); + mOutsetsChanged |= !mLastOutsets.equals(mOutsets); + mFrameSizeChanged |= didFrameSizeChange(); + mDisplayCutoutChanged |= !mLastDisplayCutout.equals(mDisplayCutout); + return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged + || mStableInsetsChanged || mOutsetsChanged || 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. + */ + void resetInsetsChanged() { + mOverscanInsetsChanged = false; + mContentInsetsChanged = false; + mVisibleInsetsChanged = false; + mStableInsetsChanged = false; + mOutsetsChanged = false; + mFrameSizeChanged = false; + mDisplayCutoutChanged = false; + } + + /** + * Copy over inset values as the last insets that were sent to the client. + */ + void updateLastInsetValues() { + mLastOverscanInsets.set(mOverscanInsets); + mLastContentInsets.set(mContentInsets); + mLastVisibleInsets.set(mVisibleInsets); + mLastStableInsets.set(mStableInsets); + mLastOutsets.set(mOutsets); + mLastDisplayCutout = mDisplayCutout; + } + + /** + * Sets the last content insets as (-1, -1, -1, -1) to force the next layout pass to update + * the client. + */ + void resetLastContentInsets() { + mLastContentInsets.set(-1, -1, -1, -1); } public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) { @@ -194,6 +378,12 @@ public class WindowFrames { mContainingFrame.writeToProto(proto, CONTAINING_FRAME); mFrame.writeToProto(proto, FRAME); mDisplayCutout.getDisplayCutout().writeToProto(proto, CUTOUT); + mContentInsets.writeToProto(proto, CONTENT_INSETS); + mOverscanInsets.writeToProto(proto, OVERSCAN_INSETS); + mVisibleInsets.writeToProto(proto, VISIBLE_INSETS); + mStableInsets.writeToProto(proto, STABLE_INSETS); + mOutsets.writeToProto(proto, OUTSETS); + proto.end(token); } @@ -211,5 +401,34 @@ public class WindowFrames { + " last=" + mLastFrame.toShortString(sTmpSB)); pw.println(prefix + " cutout=" + mDisplayCutout.getDisplayCutout() + " last=" + mLastDisplayCutout.getDisplayCutout()); + pw.print(prefix + "Cur insets: overscan=" + mOverscanInsets.toShortString(sTmpSB) + + " content=" + mContentInsets.toShortString(sTmpSB) + + " visible=" + mVisibleInsets.toShortString(sTmpSB) + + " stable=" + mStableInsets.toShortString(sTmpSB) + + " outsets=" + mOutsets.toShortString(sTmpSB)); + pw.println(prefix + "Lst insets: overscan=" + mLastOverscanInsets.toShortString(sTmpSB) + + " content=" + mLastContentInsets.toShortString(sTmpSB) + + " visible=" + mLastVisibleInsets.toShortString(sTmpSB) + + " stable=" + mLastStableInsets.toShortString(sTmpSB) + + " outset=" + mLastOutsets.toShortString(sTmpSB)); + } + + String getInsetsInfo() { + return "ci=" + mContentInsets.toShortString() + + " vi=" + mVisibleInsets.toShortString() + + " si=" + mStableInsets.toShortString() + + " of=" + mOutsets.toShortString(); + } + + String getInsetsChangedInfo() { + return "contentInsetsChanged=" + mContentInsetsChanged + + " " + mContentInsets.toShortString() + + " visibleInsetsChanged=" + mVisibleInsetsChanged + + " " + mVisibleInsets.toShortString() + + " stableInsetsChanged=" + mStableInsetsChanged + + " " + mStableInsets.toShortString() + + " outsetsChanged=" + mOutsetsChanged + + " " + mOutsets.toShortString() + + " 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 e80a47eef2d5..b1358364a8d5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2167,14 +2167,10 @@ public class WindowManagerService extends IWindowManager.Stub // The last inset values represent the last client state. win.updateLastInsetValues(); - outFrame.set(win.mCompatFrame); - outOverscanInsets.set(win.mOverscanInsets); - outContentInsets.set(win.mContentInsets); - win.mLastRelayoutContentInsets.set(win.mContentInsets); - outVisibleInsets.set(win.mVisibleInsets); - outStableInsets.set(win.mStableInsets); + win.getCompatFrame(outFrame); + win.getInsetsForRelayout(outOverscanInsets, outContentInsets, outVisibleInsets, + outStableInsets, outOutsets); outCutout.set(win.getWmDisplayCutout().getDisplayCutout()); - outOutsets.set(win.mOutsets); outBackdropFrame.set(win.getBackdropFrame(win.getFrameLw())); if (localLOGV) Slog.v( TAG_WM, "Relayout given client " + client.asBinder() diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 466e298974d0..637c0eabdac4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -120,7 +120,6 @@ import static com.android.server.wm.WindowStateProto.ANIMATING_EXIT; import static com.android.server.wm.WindowStateProto.ANIMATOR; import static com.android.server.wm.WindowStateProto.ATTRIBUTES; import static com.android.server.wm.WindowStateProto.CHILD_WINDOWS; -import static com.android.server.wm.WindowStateProto.CONTENT_INSETS; import static com.android.server.wm.WindowStateProto.DESTROYING; import static com.android.server.wm.WindowStateProto.DISPLAY_ID; import static com.android.server.wm.WindowStateProto.FINISHED_SEAMLESS_ROTATION_FRAME; @@ -131,20 +130,16 @@ import static com.android.server.wm.WindowStateProto.IDENTIFIER; import static com.android.server.wm.WindowStateProto.IS_ON_SCREEN; import static com.android.server.wm.WindowStateProto.IS_READY_FOR_DISPLAY; import static com.android.server.wm.WindowStateProto.IS_VISIBLE; -import static com.android.server.wm.WindowStateProto.OUTSETS; -import static com.android.server.wm.WindowStateProto.OVERSCAN_INSETS; import static com.android.server.wm.WindowStateProto.PENDING_SEAMLESS_ROTATION; import static com.android.server.wm.WindowStateProto.REMOVED; import static com.android.server.wm.WindowStateProto.REMOVE_ON_EXIT; import static com.android.server.wm.WindowStateProto.REQUESTED_HEIGHT; import static com.android.server.wm.WindowStateProto.REQUESTED_WIDTH; -import static com.android.server.wm.WindowStateProto.STABLE_INSETS; import static com.android.server.wm.WindowStateProto.STACK_ID; import static com.android.server.wm.WindowStateProto.SURFACE_INSETS; import static com.android.server.wm.WindowStateProto.SURFACE_POSITION; import static com.android.server.wm.WindowStateProto.SYSTEM_UI_VISIBILITY; import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY; -import static com.android.server.wm.WindowStateProto.VISIBLE_INSETS; import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES; @@ -200,6 +195,7 @@ import com.android.internal.util.ToBooleanFunction; import com.android.server.input.InputWindowHandle; import com.android.server.policy.WindowManagerPolicy; import com.android.server.wm.LocalAnimationAdapter.AnimationSpec; +import com.android.server.wm.utils.InsetUtils; import com.android.server.wm.utils.WmDisplayCutout; import java.io.PrintWriter; @@ -309,22 +305,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration(); /** - * Insets that determine the actually visible area. These are in the application's - * coordinate space (without compatibility scale applied). - */ - final Rect mVisibleInsets = new Rect(); - private 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(); - - /** * The last content insets returned to the client in relayout. We use * these in the bounds animation to ensure we only observe inset changes * at the same time that a client resizes it's surface so that we may use @@ -333,34 +313,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ final Rect mLastRelayoutContentInsets = new Rect(); - private boolean mContentInsetsChanged; - - /** - * Insets that determine the area covered by the display overscan region. These are in the - * application's coordinate space (without compatibility scale applied). - */ - final Rect mOverscanInsets = new Rect(); - private final Rect mLastOverscanInsets = new Rect(); - private boolean mOverscanInsetsChanged; - - /** - * 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(); - private final Rect mLastStableInsets = new Rect(); - private boolean mStableInsetsChanged; - - /** - * Outsets determine the area outside of the surface where we want to pretend that it's possible - * to draw anyway. - */ - final Rect mOutsets = new Rect(); - private final Rect mLastOutsets = new Rect(); - private boolean mOutsetsChanged = false; - - private boolean mDisplayCutoutChanged; - /** * Set to true if we are waiting for this window to receive its * given internal insets before laying out other windows based on it. @@ -399,11 +351,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP float mLastHScale=1, mLastVScale=1; final Matrix mTmpMatrix = new Matrix(); - private boolean mFrameSizeChanged = false; - // Frame that is scaled to the application's coordinate space when in - // screen size compatibility mode. - final Rect mCompatFrame = new Rect(); - private final WindowFrames mWindowFrames = new WindowFrames(); /** @@ -988,17 +935,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame); // Calculate the outsets before the content frame gets shrinked to the window frame. - if (hasOutsets) { - mOutsets.set( - Math.max(mWindowFrames.mContentFrame.left - mWindowFrames.mOutsetFrame.left, 0), - Math.max(mWindowFrames.mContentFrame.top - mWindowFrames.mOutsetFrame.top, 0), - Math.max(mWindowFrames.mOutsetFrame.right - mWindowFrames.mContentFrame.right, - 0), - Math.max(mWindowFrames.mOutsetFrame.bottom - mWindowFrames.mContentFrame.bottom, - 0)); - } else { - mOutsets.set(0, 0, 0, 0); - } + mWindowFrames.calculateOutsets(hasOutsets); // Make sure the content and visible frames are inside of the // final window frame. @@ -1055,90 +992,35 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (inFullscreenContainer && !windowsAreFloating) { // Windows that are not fullscreen can be positioned outside of the display frame, // but that is not a reason to provide them with overscan insets. - mOverscanInsets.set( - Math.max(mWindowFrames.mOverscanFrame.left - layoutContainingFrame.left, 0), - Math.max(mWindowFrames.mOverscanFrame.top - layoutContainingFrame.top, 0), - Math.max(layoutContainingFrame.right - mWindowFrames.mOverscanFrame.right, 0), - Math.max(layoutContainingFrame.bottom - mWindowFrames.mOverscanFrame.bottom, - 0)); + InsetUtils.insetsBetweenFrames(layoutContainingFrame, mWindowFrames.mOverscanFrame, + mWindowFrames.mOverscanInsets); } if (mAttrs.type == TYPE_DOCK_DIVIDER) { - // For the docked divider, we calculate the stable insets like a full-screen window - // so it can use it to calculate the snap positions. final WmDisplayCutout c = windowFrames.mDisplayCutout.calculateRelativeTo( mWindowFrames.mDisplayFrame); - mTmpRect.set(mWindowFrames.mDisplayFrame); - mTmpRect.inset(c.getDisplayCutout().getSafeInsets()); - mTmpRect.intersectUnchecked(mWindowFrames.mStableFrame); - - mStableInsets.set(Math.max(mTmpRect.left - mWindowFrames.mDisplayFrame.left, 0), - Math.max(mTmpRect.top - mWindowFrames.mDisplayFrame.top, 0), - Math.max(mWindowFrames.mDisplayFrame.right - mTmpRect.right, 0), - Math.max(mWindowFrames.mDisplayFrame.bottom - mTmpRect.bottom, 0)); - - // The divider doesn't care about insets in any case, so set it to empty so we don't - // trigger a relayout when moving it. - mContentInsets.setEmpty(); - mVisibleInsets.setEmpty(); - windowFrames.setDisplayCutout(WmDisplayCutout.NO_CUTOUT); + mWindowFrames.calculateDockedDividerInsets(c.getDisplayCutout().getSafeInsets()); } else { getDisplayContent().getBounds(mTmpRect); - // Override right and/or bottom insets in case if the frame doesn't fit the screen in - // non-fullscreen mode. - boolean overrideRightInset = !windowsAreFloating && !inFullscreenContainer - && mWindowFrames.mFrame.right > mTmpRect.right; - boolean overrideBottomInset = !windowsAreFloating && !inFullscreenContainer - && mWindowFrames.mFrame.bottom > mTmpRect.bottom; - mContentInsets.set(mWindowFrames.mContentFrame.left - mWindowFrames.mFrame.left, - mWindowFrames.mContentFrame.top - mWindowFrames.mFrame.top, - overrideRightInset ? mTmpRect.right - mWindowFrames.mContentFrame.right - : mWindowFrames.mFrame.right - mWindowFrames.mContentFrame.right, - overrideBottomInset ? mTmpRect.bottom - mWindowFrames.mContentFrame.bottom - : mWindowFrames.mFrame.bottom - mWindowFrames.mContentFrame.bottom); - - mVisibleInsets.set(mWindowFrames.mVisibleFrame.left - mWindowFrames.mFrame.left, - mWindowFrames.mVisibleFrame.top - mWindowFrames.mFrame.top, - overrideRightInset ? mTmpRect.right - mWindowFrames.mVisibleFrame.right - : mWindowFrames.mFrame.right - mWindowFrames.mVisibleFrame.right, - overrideBottomInset ? mTmpRect.bottom - mWindowFrames.mVisibleFrame.bottom - : mWindowFrames.mFrame.bottom - mWindowFrames.mVisibleFrame.bottom); - - mStableInsets.set( - Math.max(mWindowFrames.mStableFrame.left - mWindowFrames.mFrame.left, 0), - Math.max(mWindowFrames.mStableFrame.top - mWindowFrames.mFrame.top, 0), - overrideRightInset ? Math.max(mTmpRect.right - mWindowFrames.mStableFrame.right, - 0) : Math.max( - mWindowFrames.mFrame.right - mWindowFrames.mStableFrame.right, 0), - overrideBottomInset ? Math.max( - mTmpRect.bottom - mWindowFrames.mStableFrame.bottom, 0) : Math.max( - mWindowFrames.mFrame.bottom - mWindowFrames.mStableFrame.bottom, 0)); + mWindowFrames.calculateInsets(windowsAreFloating, inFullscreenContainer, mTmpRect); } mWindowFrames.setDisplayCutout( windowFrames.mDisplayCutout.calculateRelativeTo(mWindowFrames.mFrame)); // Offset the actual frame by the amount layout frame is off. - mWindowFrames.mFrame.offset(-layoutXDiff, -layoutYDiff); - mCompatFrame.offset(-layoutXDiff, -layoutYDiff); - mWindowFrames.mContentFrame.offset(-layoutXDiff, -layoutYDiff); - mWindowFrames.mVisibleFrame.offset(-layoutXDiff, -layoutYDiff); - mWindowFrames.mStableFrame.offset(-layoutXDiff, -layoutYDiff); + mWindowFrames.offsetFrames(-layoutXDiff, -layoutYDiff); - mCompatFrame.set(mWindowFrames.mFrame); + mWindowFrames.mCompatFrame.set(mWindowFrames.mFrame); if (mEnforceSizeCompat) { // 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. - mOverscanInsets.scale(mInvGlobalScale); - mContentInsets.scale(mInvGlobalScale); - mVisibleInsets.scale(mInvGlobalScale); - mStableInsets.scale(mInvGlobalScale); - mOutsets.scale(mInvGlobalScale); + mWindowFrames.scaleInsets(mInvGlobalScale); // Also the scaled frame that we report to the app needs to be // adjusted to be in its coordinate space. - mCompatFrame.scale(mInvGlobalScale); + mWindowFrames.mCompatFrame.scale(mInvGlobalScale); } if (mIsWallpaper && (fw != mWindowFrames.mFrame.width() @@ -1156,10 +1038,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP + mRequestedWidth + ", mRequestedheight=" + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph + "): frame=" + mWindowFrames.mFrame.toShortString() - + " ci=" + mContentInsets.toShortString() - + " vi=" + mVisibleInsets.toShortString() - + " si=" + mStableInsets.toShortString() - + " of=" + mOutsets.toShortString()); + + " " + mWindowFrames.getInsetsInfo()); } // TODO: Look into whether this override is still necessary. @@ -1219,6 +1098,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP 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()); + } + @Override public boolean getGivenInsetsPendingLw() { return mGivenInsetsPending; @@ -1270,15 +1157,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean setReportResizeHints() { - mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); - mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); - mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); - mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); - mOutsetsChanged |= !mLastOutsets.equals(mOutsets); - mFrameSizeChanged |= mWindowFrames.didFrameSizeChange(); - mDisplayCutoutChanged |= mWindowFrames.didDisplayCutoutChange(); - return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged - || mOutsetsChanged || mFrameSizeChanged || mDisplayCutoutChanged; + return mWindowFrames.setReportResizeHints(); } /** @@ -1301,7 +1180,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return; } - setReportResizeHints(); + boolean didFrameInsetsChange = setReportResizeHints(); boolean configChanged = isConfigChanged(); if (DEBUG_CONFIGURATION && configChanged) { Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration()); @@ -1318,31 +1197,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // variables, because mFrameSizeChanged only tracks the width and height changing. mWindowFrames.mLastFrame.set(mWindowFrames.mFrame); - if (mContentInsetsChanged - || mVisibleInsetsChanged - || mStableInsetsChanged + if (didFrameInsetsChange || winAnimator.mSurfaceResized - || mOutsetsChanged - || mFrameSizeChanged - || mDisplayCutoutChanged || configChanged || dragResizingChanged || mReportOrientationChanged) { if (DEBUG_RESIZE || DEBUG_ORIENTATION) { Slog.v(TAG_WM, "Resize reasons for w=" + this + ": " - + " contentInsetsChanged=" + mContentInsetsChanged - + " " + mContentInsets.toShortString() - + " visibleInsetsChanged=" + mVisibleInsetsChanged - + " " + mVisibleInsets.toShortString() - + " stableInsetsChanged=" + mStableInsetsChanged - + " " + mStableInsets.toShortString() - + " outsetsChanged=" + mOutsetsChanged - + " " + mOutsets.toShortString() + + " " + mWindowFrames.getInsetsChangedInfo() + " surfaceResized=" + winAnimator.mSurfaceResized + " configChanged=" + configChanged + " dragResizingChanged=" + dragResizingChanged - + " reportOrientationChanged=" + mReportOrientationChanged - + " displayCutoutChanged=" + mDisplayCutoutChanged); + + " reportOrientationChanged=" + mReportOrientationChanged); } // If it's a dead window left on screen, and the configuration changed, there is nothing @@ -3015,7 +2881,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag()); try { if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this - + ": " + mCompatFrame); + + ": " + mWindowFrames.mCompatFrame); final MergedConfiguration mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(), getMergedOverrideConfiguration()); @@ -3026,11 +2892,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); final Rect frame = mWindowFrames.mFrame; - final Rect overscanInsets = mLastOverscanInsets; - final Rect contentInsets = mLastContentInsets; - final Rect visibleInsets = mLastVisibleInsets; - final Rect stableInsets = mLastStableInsets; - final Rect outsets = mLastOutsets; + final Rect overscanInsets = mWindowFrames.mLastOverscanInsets; + final Rect contentInsets = mWindowFrames.mLastContentInsets; + final Rect visibleInsets = mWindowFrames.mLastVisibleInsets; + final Rect stableInsets = mWindowFrames.mLastStableInsets; + final Rect outsets = mWindowFrames.mLastOutsets; final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING; final boolean reportOrientation = mReportOrientationChanged; final int displayId = getDisplayId(); @@ -3061,13 +2927,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); } - mOverscanInsetsChanged = false; - mContentInsetsChanged = false; - mVisibleInsetsChanged = false; - mStableInsetsChanged = false; - mOutsetsChanged = false; - mFrameSizeChanged = false; - mDisplayCutoutChanged = false; + mWindowFrames.resetInsetsChanged(); mWinAnimator.mSurfaceResized = false; mReportOrientationChanged = false; } catch (RemoteException e) { @@ -3293,7 +3153,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mAttrs.writeToProto(proto, ATTRIBUTES); mGivenContentInsets.writeToProto(proto, GIVEN_CONTENT_INSETS); mWindowFrames.writeToProto(proto, WINDOW_FRAMES); - mContentInsets.writeToProto(proto, CONTENT_INSETS); mAttrs.surfaceInsets.writeToProto(proto, SURFACE_INSETS); mSurfacePosition.writeToProto(proto, SURFACE_POSITION); mWinAnimator.writeToProto(proto, ANIMATOR); @@ -3307,10 +3166,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP proto.write(SYSTEM_UI_VISIBILITY, mSystemUiVisibility); proto.write(HAS_SURFACE, mHasSurface); proto.write(IS_READY_FOR_DISPLAY, isReadyForDisplay()); - mOverscanInsets.writeToProto(proto, OVERSCAN_INSETS); - mVisibleInsets.writeToProto(proto, VISIBLE_INSETS); - mStableInsets.writeToProto(proto, STABLE_INSETS); - mOutsets.writeToProto(proto, OUTSETS); proto.write(REMOVE_ON_EXIT, mRemoveOnExit); proto.write(DESTROYING, mDestroying); proto.write(REMOVED, mRemoved); @@ -3417,21 +3272,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP + " isReadyForDisplay()=" + isReadyForDisplay() + " mWindowRemovalAllowed=" + mWindowRemovalAllowed); if (mEnforceSizeCompat) { - pw.println(prefix + "mCompatFrame=" + mCompatFrame.toShortString(sTmpSB)); + pw.println(prefix + "mCompatFrame=" + mWindowFrames.mCompatFrame.toShortString(sTmpSB)); } if (dumpAll) { mWindowFrames.dump(pw, prefix); - pw.print(prefix + "Cur insets: overscan=" + mOverscanInsets.toShortString(sTmpSB) - + " content=" + mContentInsets.toShortString(sTmpSB) - + " visible=" + mVisibleInsets.toShortString(sTmpSB) - + " stable=" + mStableInsets.toShortString(sTmpSB) - + " surface=" + mAttrs.surfaceInsets.toShortString(sTmpSB) - + " outsets=" + mOutsets.toShortString(sTmpSB)); - pw.println(prefix + "Lst insets: overscan=" + mLastOverscanInsets.toShortString(sTmpSB) - + " content=" + mLastContentInsets.toShortString(sTmpSB) - + " visible=" + mLastVisibleInsets.toShortString(sTmpSB) - + " stable=" + mLastStableInsets.toShortString(sTmpSB) - + " outset=" + mLastOutsets.toShortString(sTmpSB)); + pw.println(prefix + " surface=" + mAttrs.surfaceInsets.toShortString(sTmpSB)); } super.dump(pw, prefix, dumpAll); pw.println(prefix + mWinAnimator + ":"); @@ -3531,7 +3376,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - void applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame) { + private void applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame) { final int pw = containingFrame.width(); final int ph = containingFrame.height(); final Task task = getTask(); @@ -3609,10 +3454,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // We need to make sure we update the CompatFrame as it is used for // cropping decisions, etc, on systems where we lack a decor layer. - mCompatFrame.set(mWindowFrames.mFrame); + mWindowFrames.mCompatFrame.set(mWindowFrames.mFrame); if (mEnforceSizeCompat) { // See comparable block in computeFrameLw. - mCompatFrame.scale(mInvGlobalScale); + mWindowFrames.mCompatFrame.scale(mInvGlobalScale); } } @@ -4322,13 +4167,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // On a different display there is no system decor. Crop the window // by the screen boundaries. // TODO(multi-display) - policyCrop.set(0, 0, mCompatFrame.width(), mCompatFrame.height()); - policyCrop.intersect(-mCompatFrame.left, -mCompatFrame.top, - displayInfo.logicalWidth - mCompatFrame.left, - displayInfo.logicalHeight - mCompatFrame.top); + policyCrop.set(0, 0, mWindowFrames.mCompatFrame.width(), + mWindowFrames.mCompatFrame.height()); + policyCrop.intersect(-mWindowFrames.mCompatFrame.left, -mWindowFrames.mCompatFrame.top, + displayInfo.logicalWidth - mWindowFrames.mCompatFrame.left, + displayInfo.logicalHeight - mWindowFrames.mCompatFrame.top); } else if (skipDecorCrop()) { // Windows without policy decor aren't cropped. - policyCrop.set(0, 0, mCompatFrame.width(), mCompatFrame.height()); + policyCrop.set(0, 0, mWindowFrames.mCompatFrame.width(), + mWindowFrames.mCompatFrame.height()); } else { // Crop to the system decor specified by policy. calculateSystemDecorRect(policyCrop); @@ -4486,12 +4333,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * Updates the last inset values to the current ones. */ void updateLastInsetValues() { - mLastOverscanInsets.set(mOverscanInsets); - mLastContentInsets.set(mContentInsets); - mLastVisibleInsets.set(mVisibleInsets); - mLastStableInsets.set(mStableInsets); - mLastOutsets.set(mOutsets); - mWindowFrames.mLastDisplayCutout = mWindowFrames.mDisplayCutout; + mWindowFrames.updateLastInsetValues(); } void startAnimation(Animation anim) { @@ -4880,6 +4722,44 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } + /** + * Copy the inset values over so they can be sent back to the client when a relayout occurs. + */ + void getInsetsForRelayout(Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, + Rect outStableInsets, Rect outOutsets) { + outOverscanInsets.set(mWindowFrames.mOverscanInsets); + outContentInsets.set(mWindowFrames.mContentInsets); + outVisibleInsets.set(mWindowFrames.mVisibleInsets); + outStableInsets.set(mWindowFrames.mStableInsets); + outOutsets.set(mWindowFrames.mOutsets); + + mLastRelayoutContentInsets.set(mWindowFrames.mContentInsets); + } + + 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; + } + private final class MoveAnimationSpec implements AnimationSpec { private final long mDuration; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index b158ae2840dc..c80eb868a732 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_NONE; + import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM; @@ -46,7 +47,6 @@ import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT; import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; -import static com.android.server.wm.utils.CoordinateTransforms.transformToRotation; import android.content.Context; import android.graphics.Matrix; @@ -476,8 +476,7 @@ class WindowStateAnimator { flags |= SurfaceControl.SECURE; } - mTmpSize.set(0, 0, 0, 0); - calculateSurfaceBounds(w, attrs); + calculateSurfaceBounds(w, attrs, mTmpSize); final int width = mTmpSize.width(); final int height = mTmpSize.height(); @@ -556,44 +555,38 @@ class WindowStateAnimator { return mSurfaceController; } - private void calculateSurfaceBounds(WindowState w, LayoutParams attrs) { + private void calculateSurfaceBounds(WindowState w, LayoutParams attrs, Rect outSize) { + outSize.setEmpty(); if ((attrs.flags & FLAG_SCALED) != 0) { // For a scaled surface, we always want the requested size. - mTmpSize.right = mTmpSize.left + w.mRequestedWidth; - mTmpSize.bottom = mTmpSize.top + w.mRequestedHeight; + outSize.right = w.mRequestedWidth; + outSize.bottom = w.mRequestedHeight; } else { // When we're doing a drag-resizing, request a surface that's fullscreen size, // so that we don't need to reallocate during the process. This also prevents // buffer drops due to size mismatch. if (w.isDragResizing()) { - if (w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM) { - mTmpSize.left = 0; - mTmpSize.top = 0; - } final DisplayInfo displayInfo = w.getDisplayInfo(); - mTmpSize.right = mTmpSize.left + displayInfo.logicalWidth; - mTmpSize.bottom = mTmpSize.top + displayInfo.logicalHeight; + outSize.right = displayInfo.logicalWidth; + outSize.bottom = displayInfo.logicalHeight; } else { - mTmpSize.right = mTmpSize.left + w.mCompatFrame.width(); - mTmpSize.bottom = mTmpSize.top + w.mCompatFrame.height(); + w.getCompatFrameSize(outSize); } } // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values. // This doesn't necessarily mean that there is an error in the system. The sizes might be // incorrect, because it is before the first layout or draw. - if (mTmpSize.width() < 1) { - mTmpSize.right = mTmpSize.left + 1; + if (outSize.width() < 1) { + outSize.right = 1; } - if (mTmpSize.height() < 1) { - mTmpSize.bottom = mTmpSize.top + 1; + if (outSize.height() < 1) { + outSize.bottom = 1; } // Adjust for surface insets. - mTmpSize.left -= attrs.surfaceInsets.left; - mTmpSize.top -= attrs.surfaceInsets.top; - mTmpSize.right += attrs.surfaceInsets.right; - mTmpSize.bottom += attrs.surfaceInsets.bottom; + outSize.inset(-attrs.surfaceInsets.left, -attrs.surfaceInsets.top, + -attrs.surfaceInsets.right, -attrs.surfaceInsets.bottom); } boolean hasSurface() { @@ -870,8 +863,7 @@ class WindowStateAnimator { final LayoutParams attrs = mWin.getAttrs(); final Task task = w.getTask(); - mTmpSize.set(0, 0, 0, 0); - calculateSurfaceBounds(w, attrs); + calculateSurfaceBounds(w, attrs, mTmpSize); mExtraHScale = (float) 1.0; mExtraVScale = (float) 1.0; diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java index ea3a3d097dae..e64823085d35 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java @@ -133,15 +133,15 @@ public class WindowFrameTests extends WindowTestsBase { } private void assertContentInset(WindowState w, int left, int top, int right, int bottom) { - assertRect(w.mContentInsets, left, top, right, bottom); + assertRect(w.getContentInsets(), left, top, right, bottom); } private void assertVisibleInset(WindowState w, int left, int top, int right, int bottom) { - assertRect(w.mVisibleInsets, left, top, right, bottom); + assertRect(w.getVisibleInsets(), left, top, right, bottom); } private void assertStableInset(WindowState w, int left, int top, int right, int bottom) { - assertRect(w.mStableInsets, left, top, right, bottom); + assertRect(w.getStableInsets(), left, top, right, bottom); } private void assertFrame(WindowState w, int left, int top, int right, int bottom) { |