Splitscreen for minimized state that works with resizable launchers

If a launcher is resizable, going to minimized mode (dock task and then
press home) would show a cropped height of the task at the top in a
minimized state and the fullscreen stack would show the home launcher
which takes the rest of the remaining height. If the launcher is not
resizable, it will default the original behavior.

To enable this in a launcher, add android:resizeableActivity="true" in
the AndroidManifest.xml in the <application/> tag.

Test: manual - rotating while minimized, minimizing using dragging task
or holding overview nav button, installing resizable launcher with a
non-resizable launcher
Fixes: 32504542
Change-Id: Idf4015b40f9bec81b70f146f0f2d7df8ccfb4cf0
diff --git a/core/java/android/view/IDockedStackListener.aidl b/core/java/android/view/IDockedStackListener.aidl
index 36a81db..4cf7cf3e 100644
--- a/core/java/android/view/IDockedStackListener.aidl
+++ b/core/java/android/view/IDockedStackListener.aidl
@@ -40,8 +40,11 @@
      *
      * @param minimized Whether the docked stack is currently minimized.
      * @param animDuration The duration of the animation for changing the minimized state.
+     * @param isHomeStackResizable If the home stack is resizable, a portion of the docked stack
+     *        will be shown with the divider
      */
-    void onDockedStackMinimizedChanged(boolean minimized, long animDuration);
+    void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
+            boolean isHomeStackResizable);
 
     /**
      * Called when window manager decides to adjust the divider for IME. Like the minimized state,
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index cf14471..11e7102 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -53,6 +53,11 @@
      */
     private static final int SNAP_ONLY_1_1 = 2;
 
+    /**
+     * 1 snap target: minimized height, (1 - minimized height)
+     */
+    private static final int SNAP_MODE_MINIMIZED = 3;
+
     private final float mMinFlingVelocityPxPerSecond;
     private final float mMinDismissVelocityPxPerSecond;
     private final int mDisplayWidth;
@@ -62,6 +67,7 @@
     private final Rect mInsets = new Rect();
     private final int mSnapMode;
     private final int mMinimalSizeResizableTask;
+    private final int mTaskHeightInMinimizedMode;
     private final float mFixedRatio;
     private boolean mIsHorizontalDivision;
 
@@ -93,6 +99,11 @@
 
     public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
             boolean isHorizontalDivision, Rect insets) {
+        this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets, false);
+    }
+
+    public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
+            boolean isHorizontalDivision, Rect insets, boolean isMinimizedMode) {
         mMinFlingVelocityPxPerSecond =
                 MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
         mMinDismissVelocityPxPerSecond =
@@ -102,12 +113,14 @@
         mDisplayHeight = displayHeight;
         mIsHorizontalDivision = isHorizontalDivision;
         mInsets.set(insets);
-        mSnapMode = res.getInteger(
-                com.android.internal.R.integer.config_dockedStackDividerSnapMode);
+        mSnapMode = isMinimizedMode ? SNAP_MODE_MINIMIZED :
+                res.getInteger(com.android.internal.R.integer.config_dockedStackDividerSnapMode);
         mFixedRatio = res.getFraction(
                 com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
         mMinimalSizeResizableTask = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.default_minimal_size_resizable_task);
+        mTaskHeightInMinimizedMode = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.task_height_of_minimized_mode);
         calculateTargets(isHorizontalDivision);
         mFirstSplitTarget = mTargets.get(1);
         mLastSplitTarget = mTargets.get(mTargets.size() - 2);
@@ -246,6 +259,7 @@
         int dividerMax = isHorizontalDivision
                 ? mDisplayHeight
                 : mDisplayWidth;
+        int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
         mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START,
                 0.35f));
         switch (mSnapMode) {
@@ -258,8 +272,10 @@
             case SNAP_ONLY_1_1:
                 addMiddleTarget(isHorizontalDivision);
                 break;
+            case SNAP_MODE_MINIMIZED:
+                addMinimizedTarget(isHorizontalDivision);
+                break;
         }
-        int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
         mTargets.add(new SnapTarget(dividerMax - navBarSize, dividerMax,
                 SnapTarget.FLAG_DISMISS_END, 0.35f));
     }
@@ -315,6 +331,12 @@
         mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
     }
 
+    private void addMinimizedTarget(boolean isHorizontalDivision) {
+        int position = mTaskHeightInMinimizedMode;
+        position += isHorizontalDivision ? mInsets.top : mInsets.left;
+        mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
+    }
+
     public SnapTarget getMiddleTarget() {
         return mMiddleTarget;
     }
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index e6358a3..4266f88 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -488,6 +488,9 @@
     <!-- The default minimal size of a resizable task, in both dimensions. -->
     <dimen name="default_minimal_size_resizable_task">220dp</dimen>
 
+    <!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
+    <dimen name="task_height_of_minimized_mode">80dp</dimen>
+
     <!-- Minimum "smallest width" of the display for cascading menus to be enabled. -->
     <dimen name="cascading_menus_min_smallest_width">720dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 78f6b49..169930e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1772,6 +1772,7 @@
   <java-symbol type="id" name="replace_message" />
   <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
   <java-symbol type="dimen" name="default_minimal_size_resizable_task" />
+  <java-symbol type="dimen" name="task_height_of_minimized_mode" />
   <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
   <java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
   <java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 3cd2a7a..b9a0f74 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -44,6 +44,7 @@
     private boolean mVisible = false;
     private boolean mMinimized = false;
     private boolean mAdjustedForIme = false;
+    private boolean mHomeStackResizable = false;
     private ForcedResizableInfoActivityController mForcedResizableController;
 
     @Override
@@ -75,6 +76,7 @@
         mView = (DividerView)
                 LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
         mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
+        mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
         final int size = mContext.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
         final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
@@ -92,7 +94,7 @@
         removeDivider();
         addDivider(configuration);
         if (mMinimized) {
-            mView.setMinimizedDockStack(true);
+            mView.setMinimizedDockStack(true, mHomeStackResizable);
             updateTouchable();
         }
     }
@@ -106,13 +108,14 @@
                     mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
 
                     // Update state because animations won't finish.
-                    mView.setMinimizedDockStack(mMinimized);
+                    mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
                 }
             }
         });
     }
 
-    private void updateMinimizedDockedStack(final boolean minimized, final long animDuration) {
+    private void updateMinimizedDockedStack(final boolean minimized, final long animDuration,
+            final boolean isHomeStackResizable) {
         mView.post(new Runnable() {
             @Override
             public void run() {
@@ -120,9 +123,9 @@
                     mMinimized = minimized;
                     updateTouchable();
                     if (animDuration > 0) {
-                        mView.setMinimizedDockStack(minimized, animDuration);
+                        mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
                     } else {
-                        mView.setMinimizedDockStack(minimized);
+                        mView.setMinimizedDockStack(minimized, isHomeStackResizable);
                     }
                 }
             }
@@ -139,7 +142,7 @@
     }
 
     private void updateTouchable() {
-        mWindowManager.setTouchable(!mMinimized && !mAdjustedForIme);
+        mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
     }
 
     @Override
@@ -162,9 +165,10 @@
         }
 
         @Override
-        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
-                throws RemoteException {
-            updateMinimizedDockedStack(minimized, animDuration);
+        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
+                boolean isHomeStackResizable) throws RemoteException {
+            mHomeStackResizable = isHomeStackResizable;
+            updateMinimizedDockedStack(minimized, animDuration, isHomeStackResizable);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 47d2def..49035ba 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -64,6 +64,7 @@
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
 import com.android.systemui.recents.events.activity.UndockingTaskEvent;
 import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
 import com.android.systemui.recents.events.ui.RecentsGrowingEvent;
@@ -123,6 +124,8 @@
     private boolean mMoving;
     private int mTouchSlop;
     private boolean mBackgroundLifted;
+    private boolean mIsInMinimizeInteraction;
+    private int mDividerPositionBeforeMinimized;
 
     private int mDividerInsets;
     private int mDisplayWidth;
@@ -145,6 +148,7 @@
     private VelocityTracker mVelocityTracker;
     private FlingAnimationUtils mFlingAnimationUtils;
     private DividerSnapAlgorithm mSnapAlgorithm;
+    private DividerSnapAlgorithm mMinimizedSnapAlgorithm;
     private final Rect mStableInsets = new Rect();
 
     private boolean mGrowRecents;
@@ -154,6 +158,7 @@
     private int mExitStartPosition;
     private GestureDetector mGestureDetector;
     private boolean mDockedStackMinimized;
+    private boolean mHomeStackResizable;
     private boolean mAdjustedForIme;
     private DividerState mState;
 
@@ -350,8 +355,9 @@
                 || mStableInsets.bottom != insets.getStableInsetBottom()) {
             mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(),
                     insets.getStableInsetRight(), insets.getStableInsetBottom());
-            if (mSnapAlgorithm != null) {
+            if (mSnapAlgorithm != null || mMinimizedSnapAlgorithm != null) {
                 mSnapAlgorithm = null;
+                mMinimizedSnapAlgorithm = null;
                 initializeSnapAlgorithm();
             }
         }
@@ -446,11 +452,17 @@
             mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth,
                     mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets);
         }
+        if (mMinimizedSnapAlgorithm == null) {
+            mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(),
+                    mDisplayWidth, mDisplayHeight, mDividerSize, isHorizontalDivision(),
+                    mStableInsets, mDockedStackMinimized && mHomeStackResizable);
+        }
     }
 
     public DividerSnapAlgorithm getSnapAlgorithm() {
         initializeSnapAlgorithm();
-        return mSnapAlgorithm;
+        return mDockedStackMinimized && mHomeStackResizable ? mMinimizedSnapAlgorithm :
+                mSnapAlgorithm;
     }
 
     public int getCurrentPosition() {
@@ -495,7 +507,7 @@
                     mMoving = true;
                 }
                 if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
-                    SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(
+                    SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget(
                             mStartPosition, 0 /* velocity */, false /* hardDismiss */);
                     resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget);
                 }
@@ -551,9 +563,10 @@
 
     private void fling(int position, float velocity, boolean avoidDismissStart,
             boolean logMetrics) {
-        SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(position, velocity);
-        if (avoidDismissStart && snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
-            snapTarget = mSnapAlgorithm.getFirstSplitTarget();
+        DividerSnapAlgorithm currentSnapAlgorithm = getSnapAlgorithm();
+        SnapTarget snapTarget = currentSnapAlgorithm.calculateSnapTarget(position, velocity);
+        if (avoidDismissStart && snapTarget == currentSnapAlgorithm.getDismissStartTarget()) {
+            snapTarget = currentSnapAlgorithm.getFirstSplitTarget();
         }
         if (logMetrics) {
             logResizeEvent(snapTarget);
@@ -574,6 +587,10 @@
 
     private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget,
             final long endDelay) {
+        if (mCurrentAnimator != null) {
+            cancelFlingAnimation();
+            updateDockSide();
+        }
         final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE;
         ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
         anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(),
@@ -590,6 +607,12 @@
             mExitAnimationRunning = false;
             EventBus.getDefault().send(new StoppedDragingEvent());
         };
+        Runnable notCancelledEndAction = () -> {
+            // Reset minimized divider position after unminimized state animation finishes
+            if (!mDockedStackMinimized && mIsInMinimizeInteraction) {
+                mIsInMinimizeInteraction = false;
+            }
+        };
         anim.addListener(new AnimatorListenerAdapter() {
 
             private boolean mCancelled;
@@ -612,8 +635,14 @@
                 }
                 if (delay == 0) {
                     endAction.run();
+                    if (!mCancelled) {
+                        notCancelledEndAction.run();
+                    }
                 } else {
                     mHandler.postDelayed(endAction, delay);
+                    if (!mCancelled) {
+                        mHandler.postDelayed(notCancelledEndAction, delay);
+                    }
                 }
             }
         });
@@ -692,57 +721,92 @@
     }
 
 
-    public void setMinimizedDockStack(boolean minimized) {
+    public void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable) {
+        mHomeStackResizable = isHomeStackResizable;
         updateDockSide();
-        mHandle.setAlpha(minimized ? 0f : 1f);
         if (!minimized) {
             resetBackground();
-        } else if (mDockSide == WindowManager.DOCKED_TOP) {
-            mBackground.setPivotY(0);
-            mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
-        } else if (mDockSide == WindowManager.DOCKED_LEFT
-                || mDockSide == WindowManager.DOCKED_RIGHT) {
-            mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
-                    ? 0
-                    : mBackground.getWidth());
-            mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
+        } else if (!isHomeStackResizable) {
+            if (mDockSide == WindowManager.DOCKED_TOP) {
+                mBackground.setPivotY(0);
+                mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
+            } else if (mDockSide == WindowManager.DOCKED_LEFT
+                    || mDockSide == WindowManager.DOCKED_RIGHT) {
+                mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
+                        ? 0
+                        : mBackground.getWidth());
+                mBackground.setScaleX(MINIMIZE_DOCK_SCALE);
+            }
         }
         mMinimizedShadow.setAlpha(minimized ? 1f : 0f);
-        mDockedStackMinimized = minimized;
+        if (!isHomeStackResizable) {
+            mHandle.setAlpha(minimized ? 0f : 1f);
+            mDockedStackMinimized = minimized;
+        } else if (mDockedStackMinimized != minimized) {
+            if (mStableInsets.isEmpty()) {
+                SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+            }
+            if (!mIsInMinimizeInteraction && minimized) {
+                mIsInMinimizeInteraction = true;
+                mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
+                        isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
+                        mDividerSize);
+            }
+            mMinimizedSnapAlgorithm = null;
+            mDockedStackMinimized = minimized;
+            initializeSnapAlgorithm();
+        }
     }
 
-    public void setMinimizedDockStack(boolean minimized, long animDuration) {
+    public void setMinimizedDockStack(boolean minimized, long animDuration,
+            boolean isHomeStackResizable) {
+        mHomeStackResizable = isHomeStackResizable;
         updateDockSide();
-        mHandle.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setDuration(animDuration)
-                .alpha(minimized ? 0f : 1f)
-                .start();
-        if (mDockSide == WindowManager.DOCKED_TOP) {
-            mBackground.setPivotY(0);
-            mBackground.animate()
-                    .scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
-        } else if (mDockSide == WindowManager.DOCKED_LEFT
-                || mDockSide == WindowManager.DOCKED_RIGHT) {
-            mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
-                    ? 0
-                    : mBackground.getWidth());
-            mBackground.animate()
-                    .scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+        if (!isHomeStackResizable) {
+            mMinimizedShadow.animate()
+                    .alpha(minimized ? 1f : 0f)
+                    .setInterpolator(Interpolators.ALPHA_IN)
+                    .setDuration(animDuration)
+                    .start();
+            mHandle.animate()
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .setDuration(animDuration)
+                    .alpha(minimized ? 0f : 1f)
+                    .start();
+            if (mDockSide == WindowManager.DOCKED_TOP) {
+                mBackground.setPivotY(0);
+                mBackground.animate()
+                        .scaleY(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+            } else if (mDockSide == WindowManager.DOCKED_LEFT
+                    || mDockSide == WindowManager.DOCKED_RIGHT) {
+                mBackground.setPivotX(mDockSide == WindowManager.DOCKED_LEFT
+                        ? 0
+                        : mBackground.getWidth());
+                mBackground.animate()
+                        .scaleX(minimized ? MINIMIZE_DOCK_SCALE : 1f);
+            }
+            mDockedStackMinimized = minimized;
+        } else if (mDockedStackMinimized != minimized) {
+            mIsInMinimizeInteraction = true;
+            if (minimized) {
+                mDividerPositionBeforeMinimized = getCurrentPosition();
+            }
+            mMinimizedSnapAlgorithm = null;
+            mDockedStackMinimized = minimized;
+            initializeSnapAlgorithm();
+            stopDragging(getCurrentPosition(), minimized ?
+                            mMinimizedSnapAlgorithm.getMiddleTarget() :
+                            mSnapAlgorithm.calculateNonDismissingSnapTarget(
+                                    mDividerPositionBeforeMinimized),
+                    animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
         }
         if (!minimized) {
             mBackground.animate().withEndAction(mResetBackgroundRunnable);
         }
-        mMinimizedShadow.animate()
-                .alpha(minimized ? 1f : 0f)
-                .setInterpolator(Interpolators.ALPHA_IN)
-                .setDuration(animDuration)
-                .start();
         mBackground.animate()
                 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setDuration(animDuration)
                 .start();
-        mDockedStackMinimized = minimized;
     }
 
     public void setAdjustedForIme(boolean adjustedForIme) {
@@ -809,6 +873,7 @@
         mDisplayWidth = info.logicalWidth;
         mDisplayHeight = info.logicalHeight;
         mSnapAlgorithm = null;
+        mMinimizedSnapAlgorithm = null;
         initializeSnapAlgorithm();
     }
 
@@ -871,6 +936,15 @@
         }
 
         mLastResizeRect.set(mDockedRect);
+        if (mHomeStackResizable && mIsInMinimizeInteraction) {
+            calculateBoundsForPosition(mDividerPositionBeforeMinimized, mDockSide, mDockedTaskRect);
+            calculateBoundsForPosition(mDividerPositionBeforeMinimized,
+                    DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
+            mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
+                    mOtherTaskRect, null);
+            return;
+        }
+
         if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) {
             if (mCurrentAnimator != null) {
                 calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
@@ -922,7 +996,7 @@
         } else {
             mWindowManagerProxy.resizeDockedStack(mDockedRect, null, null, null, null);
         }
-        SnapTarget closestDismissTarget = mSnapAlgorithm.getClosestDismissTarget(position);
+        SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
         float dimFraction = getDimFraction(position, closestDismissTarget);
         mWindowManagerProxy.setResizeDimLayer(dimFraction != 0f,
                 getStackIdForDismissTarget(closestDismissTarget),
@@ -943,7 +1017,7 @@
         if (mEntranceAnimationRunning) {
             return 0f;
         }
-        float fraction = mSnapAlgorithm.calculateDismissingFraction(position);
+        float fraction = getSnapAlgorithm().calculateDismissingFraction(position);
         fraction = Math.max(0, Math.min(fraction, 1f));
         fraction = DIM_INTERPOLATOR.getInterpolation(fraction);
         if (hasInsetsAtDismissTarget(dismissTarget)) {
@@ -959,13 +1033,13 @@
      */
     private boolean hasInsetsAtDismissTarget(SnapTarget dismissTarget) {
         if (isHorizontalDivision()) {
-            if (dismissTarget == mSnapAlgorithm.getDismissStartTarget()) {
+            if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) {
                 return mStableInsets.top != 0;
             } else {
                 return mStableInsets.bottom != 0;
             }
         } else {
-            if (dismissTarget == mSnapAlgorithm.getDismissStartTarget()) {
+            if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) {
                 return mStableInsets.left != 0;
             } else {
                 return mStableInsets.right != 0;
@@ -1135,6 +1209,7 @@
         if (mStableInsets.isEmpty()) {
             SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
             mSnapAlgorithm = null;
+            mMinimizedSnapAlgorithm = null;
             initializeSnapAlgorithm();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 319f124..2f4f30e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -553,8 +553,8 @@
                 }
 
                 @Override
-                public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
-                        throws RemoteException {
+                public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
+                        boolean isHomeStackResizable) throws RemoteException {
                 }
 
                 @Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 43afbd1..ec0b926 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -19598,10 +19598,15 @@
 
     /** Helper method that requests bounds from WM and applies them to stack. */
     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
-        final Rect newBounds = mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration();
+        final Rect newStackBounds = new Rect();
+        final Rect newTempTaskBounds = new Rect();
+        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds,
+                newTempTaskBounds);
         mStackSupervisor.resizeStackLocked(
-                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
-                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
+                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
+                !newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */,
+                null /* tempTaskInsetBounds */, false /* preserveWindows */,
+                false /* allowResizeInDockedMode */, deferResume);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 98b5835c..163e2b6 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -542,8 +542,10 @@
         mWindowContainerController.setPictureInPictureAspectRatio(aspectRatio);
     }
 
-    void getStackDockedModeBounds(Rect outBounds, boolean ignoreVisibility) {
-        mWindowContainerController.getStackDockedModeBounds(outBounds, ignoreVisibility);
+    void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds, Rect outTempInsetBounds,
+            boolean ignoreVisibility) {
+        mWindowContainerController.getStackDockedModeBounds(outBounds, outTempBounds,
+                outTempInsetBounds, ignoreVisibility);
     }
 
     void prepareFreezingTaskBounds() {
@@ -562,8 +564,8 @@
         outBounds.setEmpty();
     }
 
-    Rect getBoundsForNewConfiguration() {
-        return mWindowContainerController.getBoundsForNewConfiguration();
+    void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
+        mWindowContainerController.getBoundsForNewConfiguration(outBounds, outTempBounds);
     }
 
     void positionChildWindowContainerAtTop(TaskRecord child) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 29032f8..57df2dd 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -418,8 +418,6 @@
 
     final ActivityMetricsLogger mActivityMetricsLogger;
 
-    private final ResizeDockedStackTimeout mResizeDockedStackTimeout;
-
     @Override
     protected int getChildCount() {
         return mActivityDisplays.size();
@@ -529,7 +527,6 @@
         mService = service;
         mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
         mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
-        mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
         mKeyguardController = new KeyguardController(service, this);
     }
 
@@ -2346,13 +2343,19 @@
                 // static stacks need to be adjusted so they don't overlap with the docked stack.
                 // We get the bounds to use from window manager which has been adjusted for any
                 // screen controls and is also the same for all stacks.
+                final Rect tempOtherTaskRect = new Rect();
+                final Rect tempOtherTaskInsetRect = new Rect();
                 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
                     final ActivityStack current = getStack(i);
                     if (current != null && StackId.isResizeableByDockedStack(i)) {
-                        current.getStackDockedModeBounds(tempRect, true /* ignoreVisibility */);
-                        resizeStackLocked(i, tempRect, tempOtherTaskBounds,
-                                tempOtherTaskInsetBounds, preserveWindows,
-                                true /* allowResizeInDockedMode */, deferResume);
+                        current.getStackDockedModeBounds(tempRect, tempOtherTaskRect,
+                                tempOtherTaskInsetRect, true /* ignoreVisibility */);
+                        resizeStackLocked(i, tempRect,
+                                !tempOtherTaskRect.isEmpty() ? tempOtherTaskRect :
+                                        tempOtherTaskBounds,
+                                !tempOtherTaskInsetRect.isEmpty() ? tempOtherTaskInsetRect :
+                                        tempOtherTaskInsetBounds,
+                                preserveWindows, true /* allowResizeInDockedMode */, deferResume);
                     }
                 }
             }
@@ -2364,12 +2367,6 @@
             mWindowManager.continueSurfaceLayout();
             Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
         }
-
-        mResizeDockedStackTimeout.notifyResizing(dockedBounds,
-                tempDockedTaskBounds != null
-                || tempDockedTaskInsetBounds != null
-                || tempOtherTaskBounds != null
-                || tempOtherTaskInsetBounds != null);
     }
 
     void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
diff --git a/services/core/java/com/android/server/am/ResizeDockedStackTimeout.java b/services/core/java/com/android/server/am/ResizeDockedStackTimeout.java
deleted file mode 100644
index ff39589..0000000
--- a/services/core/java/com/android/server/am/ResizeDockedStackTimeout.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import android.graphics.Rect;
-import android.os.Handler;
-
-import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
-
-/**
- * When resizing the docked stack, a caller can temporarily supply task bounds that are different
- * from the stack bounds. In order to return to a sane state if the caller crashes or has a bug,
- * this class manages this cycle.
- */
-class ResizeDockedStackTimeout {
-
-    private static final long TIMEOUT_MS = 10 * 1000;
-    private final ActivityManagerService mService;
-    private final ActivityStackSupervisor mSupervisor;
-    private final Handler mHandler;
-    private final Rect mCurrentDockedBounds = new Rect();
-
-    private final Runnable mTimeoutRunnable = new Runnable() {
-        @Override
-        public void run() {
-            synchronized (mService) {
-                mSupervisor.resizeDockedStackLocked(mCurrentDockedBounds, null, null, null, null,
-                        PRESERVE_WINDOWS);
-            }
-        }
-    };
-
-    ResizeDockedStackTimeout(ActivityManagerService service, ActivityStackSupervisor supervisor,
-            Handler handler) {
-        mService = service;
-        mSupervisor = supervisor;
-        mHandler = handler;
-    }
-
-    void notifyResizing(Rect dockedBounds, boolean hasTempBounds) {
-        mHandler.removeCallbacks(mTimeoutRunnable);
-        if (!hasTempBounds) {
-            return;
-        }
-        mCurrentDockedBounds.set(dockedBounds);
-        mHandler.postDelayed(mTimeoutRunnable, TIMEOUT_MS);
-    }
-
-}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index aaf724e..5a2ee9a 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -102,12 +102,14 @@
     private int mDividerWindowWidth;
     private int mDividerWindowWidthInactive;
     private int mDividerInsets;
+    private int mTaskHeightInMinimizedMode;
     private boolean mResizing;
     private WindowState mWindow;
     private final Rect mTmpRect = new Rect();
     private final Rect mTmpRect2 = new Rect();
     private final Rect mTmpRect3 = new Rect();
     private final Rect mLastRect = new Rect();
+    private final Rect mMiddlePositionDockedStackRect = new Rect();
     private boolean mLastVisibility = false;
     private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
             = new RemoteCallbackList<>();
@@ -189,6 +191,40 @@
         return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
     }
 
+    /**
+     * The middlePositionDockedStackRect is half the screen area that sits at the top (portrait) or
+     * left (landscape).
+     *
+     * @return fixed rect for temp stack
+     */
+    Rect getMiddlePositionDockedStackRect() {
+        return mMinimizedDock && isHomeStackResizable() ? mMiddlePositionDockedStackRect : null;
+    }
+
+    void getHomeStackBoundsInDockedMode(Rect outBounds) {
+        final DisplayInfo di = mDisplayContent.getDisplayInfo();
+        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                mTmpRect);
+        int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
+        Configuration configuration = mDisplayContent.getConfiguration();
+        if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
+            outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
+                    di.logicalWidth, di.logicalHeight);
+        } else {
+            outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left, 0,
+                    di.logicalWidth, di.logicalHeight);
+        }
+    }
+
+    boolean isHomeStackResizable() {
+        final TaskStack homeStack = mDisplayContent.getHomeStack();
+        if (homeStack == null) {
+            return false;
+        }
+        final Task homeTask = homeStack.findHomeTask();
+        return homeTask != null && homeTask.isResizeable();
+    }
+
     private void initSnapAlgorithmForRotations() {
         final Configuration baseConfig = mDisplayContent.getConfiguration();
 
@@ -228,11 +264,34 @@
                 com.android.internal.R.dimen.docked_stack_divider_insets);
         mDividerWindowWidthInactive = WindowManagerService.dipToPixel(
                 DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics());
+        mTaskHeightInMinimizedMode = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.task_height_of_minimized_mode);
         initSnapAlgorithmForRotations();
     }
 
+    /**
+     * Calculates the constant rects {@link mMiddlePositionDockedStackRect} based on orientation,
+     * stable insets and display size.
+     */
+    private void updateConstantRects() {
+        final DisplayInfo di = mDisplayContent.getDisplayInfo();
+        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
+                mTmpRect);
+        int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
+        Configuration configuration = mDisplayContent.getConfiguration();
+        boolean isHorizontal = configuration.orientation == Configuration.ORIENTATION_PORTRAIT;
+        int middlePosition = DockedDividerUtils.calculateMiddlePosition(isHorizontal, mTmpRect,
+                di.logicalWidth, di.logicalHeight, dividerSize);
+        if (isHorizontal) {
+            mMiddlePositionDockedStackRect.set(0, 0, di.logicalWidth, middlePosition);
+        } else {
+            mMiddlePositionDockedStackRect.set(0, 0, middlePosition, di.logicalHeight);
+        }
+    }
+
     void onConfigurationChanged() {
         loadDimens();
+        updateConstantRects();
     }
 
     boolean isResizing() {
@@ -412,7 +471,19 @@
         return mImeHideRequested;
     }
 
-    private void notifyDockedStackMinimizedChanged(boolean minimizedDock, long animDuration) {
+    private void notifyDockedStackMinimizedChanged(boolean minimizedDock, boolean animate,
+            boolean isHomeStackResizable) {
+        long animDuration = 0;
+        if (animate) {
+            final TaskStack stack = mDisplayContent.getStackById(DOCKED_STACK_ID);
+            final long transitionDuration = isAnimationMaximizing()
+                    ? mService.mAppTransition.getLastClipRevealTransitionDuration()
+                    : DEFAULT_APP_TRANSITION_DURATION;
+            mAnimationDuration = (long)
+                    (transitionDuration * mService.getTransitionAnimationScaleLocked());
+            mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
+            animDuration = (long) (mAnimationDuration * mMaximizeMeetFraction);
+        }
         mService.mH.removeMessages(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED);
         mService.mH.obtainMessage(NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED,
                 minimizedDock ? 1 : 0, 0).sendToTarget();
@@ -420,7 +491,8 @@
         for (int i = 0; i < size; ++i) {
             final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
             try {
-                listener.onDockedStackMinimizedChanged(minimizedDock, animDuration);
+                listener.onDockedStackMinimizedChanged(minimizedDock, animDuration,
+                        isHomeStackResizable);
             } catch (RemoteException e) {
                 Slog.e(TAG_WM, "Error delivering minimized dock changed event.", e);
             }
@@ -458,7 +530,8 @@
         mDockedStackListeners.register(listener);
         notifyDockedDividerVisibilityChanged(wasVisible());
         notifyDockedStackExistsChanged(mDisplayContent.getDockedStackIgnoringVisibility() != null);
-        notifyDockedStackMinimizedChanged(mMinimizedDock, 0 /* animDuration */);
+        notifyDockedStackMinimizedChanged(mMinimizedDock, false /* animate */,
+                isHomeStackResizable());
         notifyAdjustedForImeChanged(mAdjustedForIme, 0 /* animDuration */);
 
     }
@@ -577,17 +650,23 @@
 
         final boolean imeChanged = clearImeAdjustAnimation();
         boolean minimizedChange = false;
-        if (minimizedDock) {
-            if (animate) {
-                startAdjustAnimation(0f, 1f);
-            } else {
-                minimizedChange |= setMinimizedDockedStack(true);
-            }
+        if (isHomeStackResizable()) {
+            notifyDockedStackMinimizedChanged(minimizedDock, true /* animate */,
+                    true /* isHomeStackResizable */);
+            minimizedChange = true;
         } else {
-            if (animate) {
-                startAdjustAnimation(1f, 0f);
+            if (minimizedDock) {
+                if (animate) {
+                    startAdjustAnimation(0f, 1f);
+                } else {
+                    minimizedChange |= setMinimizedDockedStack(true);
+                }
             } else {
-                minimizedChange |= setMinimizedDockedStack(false);
+                if (animate) {
+                    startAdjustAnimation(1f, 0f);
+                } else {
+                    minimizedChange |= setMinimizedDockedStack(false);
+                }
             }
         }
         if (imeChanged || minimizedChange) {
@@ -688,7 +767,7 @@
 
     private boolean setMinimizedDockedStack(boolean minimized) {
         final TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
-        notifyDockedStackMinimizedChanged(minimized, 0);
+        notifyDockedStackMinimizedChanged(minimized, false /* animate */, isHomeStackResizable());
         return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
     }
 
@@ -742,14 +821,8 @@
         if (!mAnimationStarted) {
             mAnimationStarted = true;
             mAnimationStartTime = now;
-            final long transitionDuration = isAnimationMaximizing()
-                    ? mService.mAppTransition.getLastClipRevealTransitionDuration()
-                    : DEFAULT_APP_TRANSITION_DURATION;
-            mAnimationDuration = (long)
-                    (transitionDuration * mService.getTransitionAnimationScaleLocked());
-            mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
-            notifyDockedStackMinimizedChanged(mMinimizedDock,
-                    (long) (mAnimationDuration * mMaximizeMeetFraction));
+            notifyDockedStackMinimizedChanged(mMinimizedDock, true /* animate */,
+                    isHomeStackResizable() /* isHomeStackResizable */);
         }
         float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration);
         t = (isAnimationMaximizing() ? TOUCH_RESPONSE_INTERPOLATOR : mMinimizedDockInterpolator)
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index f754775..f2b6447 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -619,7 +619,7 @@
             final InputChannel inputChannel = w.mInputChannel;
             final InputWindowHandle inputWindowHandle = w.mInputWindowHandle;
             if (inputChannel == null || inputWindowHandle == null || w.mRemoved
-                    || w.isAdjustedForMinimizedDock()) {
+                    || w.canReceiveTouchInput()) {
                 // Skip this window because it cannot possibly receive input.
                 return;
             }
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 9a6f3eb5..e2ea2c5 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -220,13 +220,17 @@
         }
     }
 
-    public void getStackDockedModeBounds(Rect outBounds, boolean ignoreVisibility) {
+    public void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds,
+            Rect outTempInsetBounds, boolean ignoreVisibility) {
         synchronized (mWindowMap) {
             if (mContainer != null) {
-                mContainer.getStackDockedModeBoundsLocked(outBounds, ignoreVisibility);
+                mContainer.getStackDockedModeBoundsLocked(outBounds, outTempBounds,
+                        outTempInsetBounds, ignoreVisibility);
                 return;
             }
             outBounds.setEmpty();
+            outTempBounds.setEmpty();
+            outTempInsetBounds.setEmpty();
         }
     }
 
@@ -269,11 +273,9 @@
         }
     }
 
-    public Rect getBoundsForNewConfiguration() {
+    public void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
         synchronized(mWindowMap) {
-            final Rect outBounds = new Rect();
-            mContainer.getBoundsForNewConfiguration(outBounds);
-            return outBounds;
+            mContainer.getBoundsForNewConfiguration(outBounds, outTempBounds);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d3eae8c..0ff1f0c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -213,7 +213,7 @@
         mAdjustedBounds.set(bounds);
         final boolean adjusted = !mAdjustedBounds.isEmpty();
         Rect insetBounds = null;
-        if (adjusted && isAdjustedForMinimizedDock()) {
+        if (adjusted && isAdjustedForMinimizedDockedStack()) {
             insetBounds = mBounds;
         } else if (adjusted && mAdjustedForIme) {
             if (mImeGoingAway) {
@@ -420,9 +420,14 @@
         return true;
     }
 
-    void getBoundsForNewConfiguration(Rect outBounds) {
+    void getBoundsForNewConfiguration(Rect outBounds, Rect outTempBounds) {
         outBounds.set(mBoundsAfterRotation);
         mBoundsAfterRotation.setEmpty();
+        final DockedStackDividerController controller = getDisplayContent()
+                .mDividerControllerLocked;
+        if (controller.isMinimizedDock() && mStackId == DOCKED_STACK_ID) {
+            outTempBounds.set(controller.getMiddlePositionDockedStackRect());
+        }
     }
 
     /**
@@ -482,7 +487,8 @@
         mService.mPolicy.getStableInsetsLw(rotation, displayWidth, displayHeight, outBounds);
         final DividerSnapAlgorithm algorithm = new DividerSnapAlgorithm(
                 mService.mContext.getResources(), displayWidth, displayHeight,
-                dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds);
+                dividerSize, orientation == Configuration.ORIENTATION_PORTRAIT, outBounds,
+                isMinimizedDockAndHomeStackResizable());
         final SnapTarget target = algorithm.calculateNonDismissingSnapTarget(dividerPosition);
 
         // Recalculate the bounds based on the position of the target.
@@ -675,7 +681,18 @@
         super.onDisplayChanged(dc);
     }
 
-    void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) {
+    void getStackDockedModeBoundsLocked(Rect outBounds, Rect outTempBounds,
+            Rect outTempInsetBounds, boolean ignoreVisibility) {
+        if (mStackId == HOME_STACK_ID && findHomeTask().isResizeable()) {
+            // Calculate the home stack bounds when in docked mode
+            getDisplayContent().mDividerControllerLocked
+                    .getHomeStackBoundsInDockedMode(outTempBounds);
+            outTempInsetBounds.set(outTempBounds);
+        } else {
+            outTempBounds.setEmpty();
+            outTempInsetBounds.setEmpty();
+        }
+
         if ((mStackId != DOCKED_STACK_ID && !StackId.isResizeableByDockedStack(mStackId))
                 || mDisplayContent == null) {
             outBounds.set(mBounds);
@@ -789,7 +806,9 @@
         mService.mDockedStackCreateBounds = null;
 
         final Rect bounds = new Rect();
-        getStackDockedModeBoundsLocked(bounds, true /*ignoreVisibility*/);
+        final Rect tempBounds = new Rect();
+        final Rect tempInsetBounds = new Rect();
+        getStackDockedModeBoundsLocked(bounds, tempBounds, tempInsetBounds, true /*ignoreVisibility*/);
         getController().requestResize(bounds);
     }
 
@@ -946,8 +965,9 @@
         }
     }
 
-    boolean isAdjustedForMinimizedDock() {
-        return mMinimizeAmount != 0f;
+    boolean shouldIgnoreInput() {
+        return isAdjustedForMinimizedDockedStack() || mStackId == DOCKED_STACK_ID &&
+                isMinimizedDockAndHomeStackResizable();
     }
 
     /**
@@ -1075,6 +1095,11 @@
         return true;
     }
 
+    private boolean isMinimizedDockAndHomeStackResizable() {
+        return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
+                && mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
+    }
+
     /**
      * @return the distance in pixels how much the stack gets minimized from it's original size
      */
@@ -1344,9 +1369,17 @@
              * tasks (including the focused).
              *
              * We save the focused task region once we find it, and add it back at the end.
+             *
+             * If the task is home stack and it is resizable in the minimized state, we want to
+             * exclude the docked stack from touch so we need the entire screen area and not just a
+             * small portion which the home stack currently is resized to.
              */
 
-            task.getDimBounds(mTmpRect);
+            if (task.isHomeTask() && isMinimizedDockAndHomeStackResizable()) {
+                mDisplayContent.getLogicalDisplayRect(mTmpRect);
+            } else {
+                task.getDimBounds(mTmpRect);
+            }
 
             if (task == focusedTask) {
                 // Add the focused task rect back into the exclude region once we are done
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5e458d4..1dcdffb 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1671,11 +1671,6 @@
         return !mLastReportedConfiguration.equals(getConfiguration());
     }
 
-    boolean isAdjustedForMinimizedDock() {
-        return mAppToken != null && mAppToken.mTask != null
-                && mAppToken.mTask.mStack.isAdjustedForMinimizedDock();
-    }
-
     void onWindowReplacementTimeout() {
         if (mWillReplaceWindow) {
             // Since the window already timed out, remove it immediately now.
@@ -2364,7 +2359,13 @@
                 && (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
                 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
                 && (mAppToken == null || mAppToken.windowsAreFocusable())
-                && !isAdjustedForMinimizedDock();
+                && !canReceiveTouchInput();
+    }
+
+    /** @return true if this window desires touch events. */
+    boolean canReceiveTouchInput() {
+        return mAppToken != null && mAppToken.mTask != null
+                && mAppToken.mTask.mStack.shouldIgnoreInput();
     }
 
     @Override