Merge "Remove legacy frames from WindowFrames and DisplayFrames"
diff --git a/core/api/current.txt b/core/api/current.txt
index 419ae51..f665512 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 33a1f22..2bea0d6 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 22ebf30..d8b750e 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;
@@ -4232,7 +4233,7 @@
 
                                 // Force add to mResizingWindows, so that we are guaranteed to get
                                 // another reportDrawn callback.
-                                w.resetLastContentInsets();
+                                w.forceReportingResized();
                             }
                         }, true /* traverseTopToBottom */);
                     }
@@ -6195,9 +6196,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,
@@ -7932,8 +7941,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 c2f43fe..388422e 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 5f8b12e..6d29a1d 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 0e2c2f9..99e1791 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
@@ -3418,8 +3419,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
@@ -3435,7 +3435,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 1809cdd..6dc957c 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 ActivityTaskSupervisor 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 5b126b8..2e95fca 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 c81f271..0f7a254 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;
@@ -1107,9 +1108,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());
     }