Implement stashing in PiP2

Implement stashing fling gesture and animation in PiP2
via transitions as per go/pip2-transitions.

Bug: 352119868
Flag: com.android.wm.shell.enable_pip2_implementation
Test: fling to stash PiP and tap to unstash
Change-Id: I4ed0882de013301322ff9f57bb7943a89c2dbbfc
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index e277a8d..ea02de9d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -816,6 +816,26 @@
         mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded();
         mSpringingToTouch = false;
         mDismissalPending = false;
+
+        // Check whether new bounds after fling imply we need to update stash state too.
+        stashEndActionIfNeeded();
+    }
+
+    private void stashEndActionIfNeeded() {
+        boolean isStashing = mPipBoundsState.getBounds().right > mPipBoundsState
+                .getDisplayBounds().width() || mPipBoundsState.getBounds().left < 0;
+        if (!isStashing) {
+            return;
+        }
+
+        if (mPipBoundsState.getBounds().left < 0
+                && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT) {
+            mPipBoundsState.setStashed(STASH_TYPE_LEFT);
+        } else if (mPipBoundsState.getBounds().left >= 0
+                && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT) {
+            mPipBoundsState.setStashed(STASH_TYPE_RIGHT);
+        }
+        mMenuController.hideMenu();
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 0c4ed26..53b80e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -106,9 +106,6 @@
 
     private float mStashVelocityThreshold;
 
-    // The reference inset bounds, used to determine the dismiss fraction
-    private final Rect mInsetBounds = new Rect();
-
     // Used to workaround an issue where the WM rotation happens before we are notified, allowing
     // us to send stale bounds
     private int mDeferResizeToNormalBoundsUntilRotation = -1;
@@ -206,17 +203,10 @@
                 mMotionHelper, mainExecutor);
         mTouchState = new PipTouchState(ViewConfiguration.get(context),
                 () -> {
-                    if (mPipBoundsState.isStashed()) {
-                        animateToUnStashedState();
-                        mPipUiEventLogger.log(
-                                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_UNSTASHED);
-                        mPipBoundsState.setStashed(STASH_TYPE_NONE);
-                    } else {
-                        mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL,
-                                mPipBoundsState.getBounds(), true /* allowMenuTimeout */,
-                                willResizeMenu(),
-                                shouldShowResizeHandle());
-                    }
+                    mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL,
+                            mPipBoundsState.getBounds(), true /* allowMenuTimeout */,
+                            willResizeMenu(),
+                            shouldShowResizeHandle());
                 },
                 menuController::hideMenu,
                 mainExecutor);
@@ -438,7 +428,6 @@
         mPipBoundsState.setNormalMovementBounds(normalMovementBounds);
         mPipBoundsState.setExpandedMovementBounds(expandedMovementBounds);
         mDisplayRotation = displayRotation;
-        mInsetBounds.set(insetBounds);
         updateMovementBounds();
         mMovementBoundsExtraOffsets = extraOffset;
 
@@ -748,10 +737,13 @@
         final Rect pipBounds = mPipBoundsState.getBounds();
         final boolean onLeftEdge = pipBounds.left < mPipBoundsState.getDisplayBounds().left;
         final Rect unStashedBounds = new Rect(0, pipBounds.top, 0, pipBounds.bottom);
-        unStashedBounds.left = onLeftEdge ? mInsetBounds.left
-                : mInsetBounds.right - pipBounds.width();
-        unStashedBounds.right = onLeftEdge ? mInsetBounds.left + pipBounds.width()
-                : mInsetBounds.right;
+
+        Rect insetBounds = new Rect();
+        mPipBoundsAlgorithm.getInsetBounds(insetBounds);
+        unStashedBounds.left = onLeftEdge ? insetBounds.left
+                : insetBounds.right - pipBounds.width();
+        unStashedBounds.right = onLeftEdge ? insetBounds.left + pipBounds.width()
+                : insetBounds.right;
         mMotionHelper.animateToUnStashedBounds(unStashedBounds);
     }
 
@@ -899,8 +891,7 @@
                 // Reset the touch state on up before the fling settles
                 mTouchState.reset();
                 if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds())) {
-                    // mMotionHelper.stashToEdge(vel.x, vel.y,
-                    //      this::stashEndAction /* endAction */);
+                    mMotionHelper.stashToEdge(vel.x, vel.y, null /* endAction */);
                 } else {
                     if (mPipBoundsState.isStashed()) {
                         // Reset stashed state if previously stashed
@@ -1030,8 +1021,10 @@
      * resized.
      */
     private void updateMovementBounds() {
+        Rect insetBounds = new Rect();
+        mPipBoundsAlgorithm.getInsetBounds(insetBounds);
         mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds(),
-                mInsetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
+                insetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
         mMotionHelper.onMovementBoundsChanged();
     }