Clean-up some out-dated layout shenanigans

Task.isFullscreen was checking for empty bounds, this wasn't
accounting for the (new) difference between being FULLSCREEN
(by policy) and actually filling the screen. This resulted in
certain checks not working properly (eg. letterbox surface
layout). isFullscreen has been removed and the callers now
check for what they care about.

useCurrentBounds is effectively dead-code now. It was
originally to deal with multi-user cases to prevent docked
stack of one user influencing the size of another user's
stacks. Nowadays, mode changes through the configuration
hierarchy handles these adjustments and falling-back on
displayBounds won't be appropriate in nested situations.

getAnimationBounds was basically trying to duplicate the
logic already performed by the hierarchy configuration
update. Specifically, looking at the mode and picking
which bounds to use. This is redundant and was actually
causing problems because new policies handled in the
hierarchy weren't being reproduced faithfully here. However,
due to letterbox, we can't use AppWindowToken bounds
directly. So for now we just use task (instead of stack)
for a representation of "the window" that also works
for freeform.

Letterbox layout was only being calculated relative to the
task. For fixed-orientation letterbox, this doesn't work
because the task itself needs to be letterboxed. For now,
this CL hard-codes an additional level (stack) and unions
that for the "letterbox fill region". We should probably
replace this with a recursive solution, but there's
currently still some issues that might require moving this
stuff around anyways.

Bug: 124626708
Test: launch a portrait-only app into fullscreen on a
      landscape-only display.
      atest AppWindowTokenTests WindowFrameTests
Change-Id: I1375c1988fbc8460802f30acee2207289fdb18e7
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index d58707c..2af2342 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -443,7 +443,7 @@
          * Returns true if the window is current in multi-windowing mode. i.e. it shares the
          * screen with other application windows.
          */
-        public boolean isInMultiWindowMode();
+        boolean inMultiWindowMode();
 
         public int getRotationAnimationHint();
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 5ba6c76..ea3a7d5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1979,7 +1979,14 @@
                 mLetterbox.attachInput(w);
             }
             getPosition(mTmpPoint);
-            mLetterbox.layout(getParent().getBounds(), w.getFrameLw(), mTmpPoint);
+            // Get the bounds of the "space-to-fill". We union the Task and the Stack bounds here
+            // to handle both split window (where task-bounds can be larger) and orientation
+            // letterbox (where the task is letterboxed within stack).
+            Rect spaceToFill = getTask().getBounds();
+            if (getStack() != null) {
+                spaceToFill.union(getStack().getBounds());
+            }
+            mLetterbox.layout(spaceToFill, w.getFrameLw(), mTmpPoint);
         } else if (mLetterbox != null) {
             mLetterbox.hide();
         }
@@ -2448,28 +2455,6 @@
         return boundsLayer;
     }
 
-    /** Get position and crop region of animation. */
-    @VisibleForTesting
-    void getAnimationBounds(Point outPosition, Rect outBounds) {
-        outPosition.set(0, 0);
-        outBounds.setEmpty();
-
-        final TaskStack stack = getStack();
-        final Task task = getTask();
-        if (task != null && task.inFreeformWindowingMode()) {
-            task.getRelativeDisplayedPosition(outPosition);
-            task.getBounds(outBounds);
-        } else if (stack != null) {
-            stack.getRelativeDisplayedPosition(outPosition);
-            // Use stack bounds in order to have the ability to animate outside the task region.
-            // Needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
-            // according to the bounds.
-            stack.getBounds(outBounds);
-        }
-        // We have the relative position so the local position can be removed from bounds.
-        outBounds.offsetTo(0, 0);
-    }
-
     @Override
     Rect getDisplayedBounds() {
         final Task task = getTask();
@@ -2501,7 +2486,12 @@
         if (okToAnimate()) {
             final AnimationAdapter adapter;
             AnimationAdapter thumbnailAdapter = null;
-            getAnimationBounds(mTmpPoint, mTmpRect);
+
+            // Separate position and size for use in animators. Use task-bounds for now so
+            // that activity-level letterbox (maxAspectRatio) is included in the animation.
+            mTmpRect.set(getTask() != null ? getTask().getBounds() : getBounds());
+            mTmpPoint.set(mTmpRect.left, mTmpRect.top);
+            mTmpRect.offsetTo(0, 0);
 
             final boolean isChanging = AppTransition.isChangeTransit(transit) && enter
                     && getDisplayContent().mChangingApps.contains(this);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5862d43..ef0ffec 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2151,7 +2151,7 @@
         // 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.isInMultiWindowMode()) {
+                && !win.inMultiWindowMode()) {
             df.left = df.top = -10000;
             df.right = df.bottom = 10000;
             if (type != TYPE_WALLPAPER) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 499cbaf..bb7867c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -433,29 +433,6 @@
         }
     }
 
-    /** Return true if the current bound can get outputted to the rest of the system as-is. */
-    private boolean useCurrentBounds() {
-        final DisplayContent displayContent = getDisplayContent();
-        return matchParentBounds()
-                || !inSplitScreenSecondaryWindowingMode()
-                || displayContent == null
-                || displayContent.getSplitScreenPrimaryStackIgnoringVisibility() != null;
-    }
-
-    @Override
-    public void getBounds(Rect out) {
-        if (useCurrentBounds()) {
-            // No need to adjust the output bounds if fullscreen or the docked stack is visible
-            // since it is already what we want to represent to the rest of the system.
-            super.getBounds(out);
-            return;
-        }
-
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack is
-        // not currently visible. Go ahead a represent it as fullscreen to the rest of the system.
-        mStack.getDisplayContent().getBounds(out);
-    }
-
     @Override
     public Rect getDisplayedBounds() {
         if (mOverrideDisplayedBounds.isEmpty()) {
@@ -506,36 +483,28 @@
         // a DimLayer anyway if we weren't visible.
         final boolean dockedResizing = displayContent != null
                 && displayContent.mDividerControllerLocked.isResizing();
-        if (useCurrentBounds()) {
-            if (inFreeformWindowingMode() && getMaxVisibleBounds(out)) {
-                return;
-            }
-
-            if (!matchParentBounds()) {
-                // When minimizing the docked stack when going home, we don't adjust the task bounds
-                // so we need to intersect the task bounds with the stack bounds here.
-                //
-                // If we are Docked Resizing with snap points, the task bounds could be smaller than the stack
-                // bounds and so we don't even want to use them. Even if the app should not be resized the Dim
-                // should keep up with the divider.
-                if (dockedResizing) {
-                    mStack.getBounds(out);
-                } else {
-                    mStack.getBounds(mTmpRect);
-                    mTmpRect.intersect(getBounds());
-                    out.set(mTmpRect);
-                }
-            } else {
-                out.set(getBounds());
-            }
+        if (inFreeformWindowingMode() && getMaxVisibleBounds(out)) {
             return;
         }
 
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack is
-        // not currently visible. Go ahead a represent it as fullscreen to the rest of the system.
-        if (displayContent != null) {
-            displayContent.getBounds(out);
+        if (!matchParentBounds()) {
+            // When minimizing the docked stack when going home, we don't adjust the task bounds
+            // so we need to intersect the task bounds with the stack bounds here.
+            //
+            // If we are Docked Resizing with snap points, the task bounds could be smaller than the
+            // stack bounds and so we don't even want to use them. Even if the app should not be
+            // resized the Dim should keep up with the divider.
+            if (dockedResizing) {
+                mStack.getBounds(out);
+            } else {
+                mStack.getBounds(mTmpRect);
+                mTmpRect.intersect(getBounds());
+                out.set(mTmpRect);
+            }
+        } else {
+            out.set(getBounds());
         }
+        return;
     }
 
     void setDragResizing(boolean dragResizing, int dragResizeMode) {
@@ -702,16 +671,6 @@
         positionChildAt(position, aToken, false /* includeParents */);
     }
 
-    boolean isFullscreen() {
-        if (useCurrentBounds()) {
-            return matchParentBounds();
-        }
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
-        // system.
-        return true;
-    }
-
     void forceWindowsScaleable(boolean force) {
         mWmService.openSurfaceTransaction();
         try {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 241f14e..e6b8112 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -303,17 +303,6 @@
         return super.getBounds();
     }
 
-    /** Return true if the current bound can get outputted to the rest of the system as-is. */
-    private boolean useCurrentBounds() {
-        if (matchParentBounds()
-                || !inSplitScreenSecondaryWindowingMode()
-                || mDisplayContent == null
-                || mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility() != null) {
-            return true;
-        }
-        return false;
-    }
-
     @Override
     public void getBounds(Rect bounds) {
         bounds.set(getBounds());
@@ -321,22 +310,15 @@
 
     @Override
     public Rect getBounds() {
-        if (useCurrentBounds()) {
-            // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
-            // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
-            // stack is visible since it is already what we want to represent to the rest of the
-            // system.
-            if (!mAdjustedBounds.isEmpty()) {
-                return mAdjustedBounds;
-            } else {
-                return super.getBounds();
-            }
-        }
-
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
+        // If we're currently adjusting for IME or minimized docked stack, we use the adjusted
+        // bounds; otherwise, no need to adjust the output bounds if fullscreen or the docked
+        // stack is visible since it is already what we want to represent to the rest of the
         // system.
-        return mDisplayContent.getBounds();
+        if (!mAdjustedBounds.isEmpty()) {
+            return mAdjustedBounds;
+        } else {
+            return super.getBounds();
+        }
     }
 
     /**
@@ -1425,13 +1407,7 @@
 
     @Override
     boolean fillsParent() {
-        if (useCurrentBounds()) {
-            return matchParentBounds();
-        }
-        // The bounds has been adjusted to accommodate for a docked stack, but the docked stack
-        // is not currently visible. Go ahead a represent it as fullscreen to the rest of the
-        // system.
-        return true;
+        return matchParentBounds();
     }
 
     @Override
@@ -1516,7 +1492,7 @@
 
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final Task task = mChildren.get(i);
-            if (task.isFullscreen()) {
+            if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                 results.searchDone = true;
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d5a6f00..174be2a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -826,7 +826,7 @@
         mHaveFrame = true;
 
         final Task task = getTask();
-        final boolean inFullscreenContainer = inFullscreenContainer();
+        final boolean isFullscreenAndFillsDisplay = !inMultiWindowMode() && matchesDisplayBounds();
         final boolean windowsAreFloating = task != null && task.isFloating();
         final DisplayContent dc = getDisplayContent();
 
@@ -845,7 +845,7 @@
         final WindowState imeWin = mWmService.mRoot.getCurrentInputMethodWindow();
         final boolean isImeTarget =
                 imeWin != null && imeWin.isVisibleNow() && isInputMethodTarget();
-        if (inFullscreenContainer || layoutInParentFrame()) {
+        if (isFullscreenAndFillsDisplay || layoutInParentFrame()) {
             // We use the parent frame as the containing frame for fullscreen and child windows
             mWindowFrames.mContainingFrame.set(mWindowFrames.mParentFrame);
             layoutDisplayFrame = mWindowFrames.mDisplayFrame;
@@ -1003,7 +1003,7 @@
                     Math.min(mWindowFrames.mStableFrame.bottom, mWindowFrames.mFrame.bottom));
         }
 
-        if (inFullscreenContainer && !windowsAreFloating) {
+        if (isFullscreenAndFillsDisplay && !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.
             InsetUtils.insetsBetweenFrames(layoutContainingFrame, mWindowFrames.mOverscanFrame,
@@ -1016,7 +1016,8 @@
             mWindowFrames.calculateDockedDividerInsets(c.getDisplayCutout().getSafeInsets());
         } else {
             getDisplayContent().getBounds(mTmpRect);
-            mWindowFrames.calculateInsets(windowsAreFloating, inFullscreenContainer, mTmpRect);
+            mWindowFrames.calculateInsets(
+                    windowsAreFloating, isFullscreenAndFillsDisplay, mTmpRect);
         }
 
         mWindowFrames.setDisplayCutout(
@@ -1058,9 +1059,7 @@
     // TODO: Look into whether this override is still necessary.
     @Override
     public Rect getBounds() {
-        if (isInMultiWindowMode()) {
-            return getTask().getBounds();
-        } else if (mAppToken != null){
+        if (mAppToken != null) {
             return mAppToken.getBounds();
         } else {
             return super.getBounds();
@@ -1771,6 +1770,10 @@
                 && mWindowFrames.mFrame.bottom >= displayInfo.appHeight;
     }
 
+    private boolean matchesDisplayBounds() {
+        return getDisplayContent().getBounds().equals(getBounds());
+    }
+
     /** Returns true if last applied config was not yet requested by client. */
     boolean isConfigChanged() {
         return !getLastReportedConfiguration().equals(getConfiguration());
@@ -3134,20 +3137,16 @@
         return getDisplayContent().mCurrentFocus == this;
     }
 
-    @Override
-    public boolean isInMultiWindowMode() {
-        final Task task = getTask();
-        return task != null && !task.isFullscreen();
-    }
 
     /** Is this window in a container that takes up the entire screen space? */
-    private boolean inFullscreenContainer() {
-        return mAppToken == null || (mAppToken.matchParentBounds() && !isInMultiWindowMode());
+    private boolean inAppWindowThatMatchesParentBounds() {
+        return mAppToken == null || (mAppToken.matchParentBounds() && !inMultiWindowMode());
     }
 
-    /** @return true when the window is in fullscreen task, but has non-fullscreen bounds set. */
+    /** @return true when the window is in fullscreen mode, but has non-fullscreen bounds set, or
+     *          is transitioning into/out-of fullscreen. */
     boolean isLetterboxedAppWindow() {
-        return !isInMultiWindowMode() && mAppToken != null && !mAppToken.matchParentBounds()
+        return !inMultiWindowMode() && !matchesDisplayBounds()
                 || isLetterboxedForDisplayCutoutLw();
     }
 
@@ -3514,7 +3513,7 @@
         final int pw = containingFrame.width();
         final int ph = containingFrame.height();
         final Task task = getTask();
-        final boolean inNonFullscreenContainer = !inFullscreenContainer();
+        final boolean inNonFullscreenContainer = !inAppWindowThatMatchesParentBounds();
         final boolean noLimits = (mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
 
         // We need to fit it to the display if either
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 969ced4..817c48d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -26,7 +26,6 @@
 
 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;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -790,16 +789,10 @@
         if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                 + w.getDecorFrame() + " mSystemDecorRect=" + mSystemDecorRect);
 
-        final Task task = w.getTask();
-        final boolean fullscreen = w.fillsDisplay() || (task != null && task.isFullscreen());
-        final boolean isFreeformResizing =
-                w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
-
         // We use the clip rect as provided by the tranformation for non-fullscreen windows to
         // avoid premature clipping with the system decor rect.
         clipRect.set(mSystemDecorRect);
-        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect
-                + " fullscreen=" + fullscreen);
+        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "win=" + w + " Initial clip rect: " + clipRect);
 
         w.expandForSurfaceInsets(clipRect);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 468728f..84320fe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
@@ -48,7 +46,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
@@ -479,34 +476,6 @@
         assertHasStartingWindow(tokenBottom);
     }
 
-    @Test
-    public void testTransitionAnimationPositionAndBounds() {
-        final Rect stackBounds = new Rect(
-                0/* left */, 0 /* top */, 1000 /* right */, 1000 /* bottom */);
-        final Rect taskBounds = new Rect(
-                100/* left */, 200 /* top */, 600 /* right */, 600 /* bottom */);
-        mStack.setBounds(stackBounds);
-        mTask.setBounds(taskBounds);
-
-        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        final Rect taskBoundsSize = new Rect(taskBounds);
-        taskBoundsSize.offsetTo(0, 0);
-        assertTransitionAnimationPositionAndBounds(taskBounds.left, taskBounds.top, taskBoundsSize);
-
-        mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-        assertTransitionAnimationPositionAndBounds(stackBounds.left, stackBounds.top, stackBounds);
-    }
-
-    private void assertTransitionAnimationPositionAndBounds(int expectedX, int expectedY,
-            Rect expectedBounds) {
-        final Point outPosition = new Point();
-        final Rect outBounds = new Rect();
-        mToken.getAnimationBounds(outPosition, outBounds);
-        assertEquals(expectedX, outPosition.x);
-        assertEquals(expectedY, outPosition.y);
-        assertEquals(expectedBounds, outBounds);
-    }
-
     private void assertHasStartingWindow(AppWindowToken atoken) {
         assertNotNull(atoken.startingSurface);
         assertNotNull(atoken.startingData);
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 2ccdb9e..78fca0f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+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.WindowManager.LayoutParams.MATCH_PARENT;
@@ -27,7 +28,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 
-import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
@@ -54,23 +54,15 @@
 @Presubmit
 public class WindowFrameTests extends WindowTestsBase {
 
-    private WindowToken mWindowToken;
     private final IWindow mIWindow = new TestIWindow();
     private final Rect mEmptyRect = new Rect();
 
-    static class WindowStateWithTask extends WindowState {
-        final Task mTask;
+    static class FrameTestWindowState extends WindowState {
         boolean mDockedResizingForTest = false;
-        WindowStateWithTask(WindowManagerService wm, IWindow iWindow, WindowToken windowToken,
-                WindowManager.LayoutParams attrs, Task t) {
+        FrameTestWindowState(WindowManagerService wm, IWindow iWindow, WindowToken windowToken,
+                WindowManager.LayoutParams attrs) {
             super(wm, mock(Session.class), iWindow, windowToken, null, 0, 0, attrs, 0, 0,
                     false /* ownerCanAddInternalSystemWindow */);
-            mTask = t;
-        }
-
-        @Override
-        Task getTask() {
-            return mTask;
         }
 
         @Override
@@ -79,52 +71,10 @@
         }
     }
 
-    private static class TaskWithBounds extends Task {
-        Rect mBounds;
-        final Rect mOverrideDisplayedBounds = new Rect();
-        boolean mFullscreenForTest = true;
-
-        TaskWithBounds(TaskStack stack, WindowManagerService wm, Rect bounds) {
-            super(0, stack, 0, wm, 0, false, new TaskDescription(), null);
-            setBounds(bounds);
-        }
-
-        @Override
-        public int setBounds(Rect bounds) {
-            mBounds = bounds;
-            return super.setBounds(bounds);
-        }
-
-        @Override
-        public Rect getBounds() {
-            return mBounds;
-        }
-
-        @Override
-        public void getBounds(Rect out) {
-            out.set(mBounds);
-        }
-
-        @Override
-        public void getRequestedOverrideBounds(Rect outBounds) {
-            outBounds.set(mBounds);
-        }
-        @Override
-        Rect getOverrideDisplayedBounds() {
-            return mOverrideDisplayedBounds;
-        }
-        @Override
-        boolean isFullscreen() {
-            return mFullscreenForTest;
-        }
-    }
-
     TaskStack mStubStack;
 
     @Before
     public void setUp() throws Exception {
-        mWindowToken = createAppWindowToken(mWm.getDefaultDisplayContentLocked(),
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         mStubStack = mock(TaskStack.class);
     }
 
@@ -168,7 +118,8 @@
                 expectedRect.bottom);
     }
 
-    private void assertPolicyCrop(WindowStateWithTask w, int left, int top, int right, int bottom) {
+    private void assertPolicyCrop(
+            FrameTestWindowState w, int left, int top, int right, int bottom) {
         Rect policyCrop = new Rect();
         w.calculatePolicyCrop(policyCrop);
         assertRect(policyCrop, left, top, right, bottom);
@@ -177,8 +128,7 @@
     @Test
     public void testLayoutInFullscreenTaskInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final int bottomContentInset = 100;
@@ -235,8 +185,7 @@
     @Test
     public void testLayoutInFullscreenTaskNoInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         // With no insets or system decor all the frames incoming from PhoneWindowManager
@@ -323,9 +272,11 @@
         final int taskRight = logicalWidth / 4 * 3;
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mFullscreenForTest = false;
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        // Use split-screen because it is non-fullscreen, but also not floating
+        task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        task.setBounds(taskBounds);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -359,8 +310,8 @@
         final int insetTop = logicalHeight / 5;
         final int insetRight = insetLeft + (taskRight - taskLeft);
         final int insetBottom = insetTop + (taskBottom - taskTop);
-        task.mOverrideDisplayedBounds.set(taskBounds);
-        task.mBounds.set(insetLeft, insetTop, insetRight, insetBottom);
+        task.setOverrideDisplayedBounds(taskBounds);
+        task.setBounds(insetLeft, insetTop, insetRight, insetBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -373,8 +324,7 @@
 
     @Test
     public void testCalculatePolicyCrop() {
-        final WindowStateWithTask w = createWindow(
-                new TaskWithBounds(mStubStack, mWm, null), MATCH_PARENT, MATCH_PARENT);
+        final FrameTestWindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
@@ -439,9 +389,11 @@
         final int taskRight = logicalWidth / 4 * 3;
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mFullscreenForTest = false;
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        // Use split-screen because it is non-fullscreen, but also not floating
+        task.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        task.setBounds(taskBounds);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -461,7 +413,8 @@
         config.windowConfiguration.setBounds(cf);
         w.mAppToken.onRequestedOverrideConfigurationChanged(config);
         pf.set(0, 0, logicalWidth, logicalHeight);
-        task.mFullscreenForTest = true;
+        task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        task.setBounds(null);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, cf.left, cf.top, cf.right, cf.bottom);
@@ -472,8 +425,7 @@
     @Test
     public void testDisplayCutout() {
         // Regular fullscreen task and window
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, 0, 1000, 2000);
@@ -496,11 +448,10 @@
     @Test
     public void testDisplayCutout_tempDisplayedBounds() {
         // Regular fullscreen task and window
-        final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm,
-                new Rect(0, 0, 1000, 2000));
-        task.mFullscreenForTest = false;
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
+        task.setBounds(new Rect(0, 0, 1000, 2000));
         task.setOverrideDisplayedBounds(new Rect(0, -500, 1000, 1500));
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
         final Rect pf = new Rect(0, -500, 1000, 1500);
@@ -523,12 +474,10 @@
     @Test
     public void testFreeformContentInsets() {
         // fullscreen task doesn't use bounds for computeFrame
-        final Task task = new TaskWithBounds(mStubStack, mWm, null);
-        WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
+        WindowState w = createWindow(MATCH_PARENT, MATCH_PARENT);
+        final Task task = w.getTask();
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
         task.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        ((TaskWithBounds) task).mFullscreenForTest = false;
-        w.setWindowingMode(WINDOWING_MODE_FREEFORM);
 
         DisplayContent dc = mWm.getDefaultDisplayContentLocked();
         dc.mInputMethodTarget = w;
@@ -551,7 +500,6 @@
         final Rect winRect = new Rect(200, 200, 300, 500);
 
         task.setBounds(winRect);
-        w.setBounds(winRect);
         w.getWindowFrames().setFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
         w.computeFrameLw();
 
@@ -580,11 +528,16 @@
         assertEquals(winRect, w.getFrameLw());
     }
 
-    private WindowStateWithTask createWindow(Task task, int width, int height) {
+    private FrameTestWindowState createWindow(int width, int height) {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.width = width;
         attrs.height = height;
 
-        return new WindowStateWithTask(mWm, mIWindow, mWindowToken, attrs, task);
+        AppWindowToken token = createAppWindowToken(mWm.getDefaultDisplayContentLocked(),
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+
+        FrameTestWindowState ws = new FrameTestWindowState(mWm, mIWindow, token, attrs);
+        token.addWindow(ws);
+        return ws;
     }
 }