Merge "Allow split with an existing split task" into tm-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 435eae4..6a2f622 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -469,13 +469,19 @@
             }
         });
         mReturnAnimator.addListener(new AnimatorListenerAdapter() {
+            private boolean mCanceled = false;
+
             @Override
             public void onAnimationCancel(Animator animation) {
                 cleanUpSurface();
+                mCanceled = true;
             }
 
             @Override
             public void onAnimationEnd(Animator animation) {
+                if (mCanceled) {
+                    return;
+                }
                 cleanUpSurface();
             }
 
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 307c51f..f2f1c3f 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -48,8 +48,6 @@
 
     private SplitPlaceholderView mSplitPlaceholderView;
     private RectF mStartingPosition;
-    @Nullable
-    private Consumer<RectF> mAdditionalOffsetter;
     private final StatefulActivity mActivity;
     private final boolean mIsRtl;
     private final Rect mOutline = new Rect();
@@ -81,9 +79,8 @@
     }
 
     private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
-            Drawable icon, RectF positionOut, Consumer<RectF> additionalOffsetter) {
+            Drawable icon, RectF positionOut) {
         mStartingPosition = positionOut;
-        mAdditionalOffsetter = additionalOffsetter;
         updateInitialPositionForView(originalView);
         final InsettableFrameLayout.LayoutParams lp =
                 (InsettableFrameLayout.LayoutParams) getLayoutParams();
@@ -113,15 +110,13 @@
      *                               translation values from originalView will be used
      */
     public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
-            View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut,
-            @Nullable Consumer<RectF> additionalOffsetter) {
+            View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
         final BaseDragLayer dragLayer = launcher.getDragLayer();
         ViewGroup parent = (ViewGroup) dragLayer.getParent();
         final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
                 .inflate(R.layout.floating_split_select_view, parent, false);
 
-        floatingView.init(launcher, originalView, thumbnail, icon, positionOut,
-                additionalOffsetter);
+        floatingView.init(launcher, originalView, thumbnail, icon, positionOut);
         parent.addView(floatingView);
         return floatingView;
     }
@@ -129,14 +124,8 @@
     public void updateInitialPositionForView(View originalView) {
         Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
         Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView, viewBounds,
-                true /* ignoreTransform */, null /* recycle */,
+                false /* ignoreTransform */, null /* recycle */,
                 mStartingPosition);
-        if (mAdditionalOffsetter != null) {
-            mAdditionalOffsetter.accept(mStartingPosition);
-        } else {
-            mStartingPosition.offset(originalView.getTranslationX(),
-                    originalView.getTranslationY());
-        }
         final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
                 Math.round(mStartingPosition.width()),
                 Math.round(mStartingPosition.height()));
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index af9f818..04af3c1 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -5,14 +5,17 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
 
 import android.content.Context;
+import android.graphics.PointF;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
 import com.android.launcher3.util.TransformingTouchDelegate;
@@ -52,7 +55,6 @@
     @Nullable private StagedSplitBounds mSplitBoundsConfig;
     private final DigitalWellBeingToast mDigitalWellBeingToast2;
 
-
     public GroupedTaskView(Context context) {
         this(context, null);
     }
@@ -205,6 +207,20 @@
     }
 
     @Override
+    protected int getChildTaskIndexAtPosition(PointF position) {
+        if (isCoordInView(mIconView2, position) || isCoordInView(mSnapshotView2, position)) {
+            return 1;
+        }
+        return super.getChildTaskIndexAtPosition(position);
+    }
+
+    private boolean isCoordInView(View v, PointF position) {
+        float[] localPos = new float[]{position.x, position.y};
+        Utilities.mapCoordInSelfToDescendant(v, this, localPos);
+        return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
+    }
+
+    @Override
     public void onRecycle() {
         super.onRecycle();
         mSnapshotView2.setThumbnail(mSecondaryTask, null);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a042bff..cb7e08a 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -619,7 +619,7 @@
     @Nullable
     private TaskView mSplitHiddenTaskView;
     @Nullable
-    private TaskView mSecondSplitHiddenTaskView;
+    private View mSecondSplitHiddenView;
     @Nullable
     private StagedSplitBounds mSplitBoundsConfig;
     private final Toast mSplitToast = Toast.makeText(getContext(),
@@ -2729,11 +2729,7 @@
             mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                     mSplitHiddenTaskView.getThumbnail(),
                     mSplitHiddenTaskView.getThumbnail().getThumbnail(),
-                    mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect,
-                    floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
-                            mSplitHiddenTaskView.getTranslationX(),
-                            mSplitHiddenTaskView.getTranslationY()
-                    ));
+                    mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
             mFirstFloatingTaskView.setAlpha(1);
             mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
                     mTempRect, true /*fadeWithThumbnail*/);
@@ -2741,7 +2737,7 @@
             mSplitSelectSource.view.setVisibility(INVISIBLE);
             mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                     mSplitSelectSource.view, null,
-                    mSplitSelectSource.drawable, startingTaskRect, null /*additionalOffsetter*/);
+                    mSplitSelectSource.drawable, startingTaskRect);
             mFirstFloatingTaskView.setAlpha(1);
             mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
                     mTempRect, true /*fadeWithThumbnail*/);
@@ -4004,9 +4000,14 @@
         }
     }
 
-    public void confirmSplitSelect(TaskView taskView) {
+    /**
+     * Confirms the selection of the next split task. The extra data is passed through because the
+     * user may be selecting a subtask in a group.
+     */
+    public void confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
+            TaskThumbnailView thumbnailView) {
         mSplitToast.cancel();
-        if (!taskView.getTask().isDockable) {
+        if (!task.isDockable) {
             // Task not split screen supported
             mSplitUnsupportedToast.show();
             return;
@@ -4032,20 +4033,21 @@
                 false /*fadeWithThumbnail*/);
 
         mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
-                taskView.getThumbnail(), taskView.getThumbnail().getThumbnail(),
-                taskView.getIconView().getDrawable(), secondTaskStartingBounds,
-                floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
-                        taskView.getTranslationX(),
-                        taskView.getTranslationY()
-                ));
+                thumbnailView, thumbnailView.getThumbnail(),
+                iconView.getDrawable(), secondTaskStartingBounds);
         mSecondFloatingTaskView.setAlpha(1);
         mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
-                secondTaskEndingBounds, true /*fadeWithThumbnail*/);
+                secondTaskEndingBounds, true /* fadeWithThumbnail */);
         pendingAnimation.addEndListener(aBoolean ->
-                mSplitSelectStateController.setSecondTaskId(taskView.getTask().key.id,
+                mSplitSelectStateController.setSecondTaskId(task.key.id,
                 aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
-        mSecondSplitHiddenTaskView = taskView;
-        taskView.setVisibility(INVISIBLE);
+        if (containerTaskView.containsMultipleTasks()) {
+            // If we are launching from a child task, then only hide the thumbnail itself
+            mSecondSplitHiddenView = thumbnailView;
+        } else {
+            mSecondSplitHiddenView = containerTaskView;
+        }
+        mSecondSplitHiddenView.setVisibility(INVISIBLE);
         pendingAnimation.buildAnim().start();
     }
 
@@ -4059,8 +4061,8 @@
             if (mSecondFloatingTaskView != null) {
                 mActivity.getRootView().removeView(mSecondFloatingTaskView);
                 mSecondFloatingTaskView = null;
-                mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
-                mSecondSplitHiddenTaskView = null;
+                mSecondSplitHiddenView.setVisibility(VISIBLE);
+                mSecondSplitHiddenView = null;
             }
             mSplitSelectSource = null;
         }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 488789b..f716965 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -45,6 +45,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Outline;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
@@ -426,8 +427,11 @@
 
     private final float[] mIconCenterCoords = new float[2];
 
+    private final PointF mLastTouchDownPosition = new PointF();
+
     private boolean mIsClickableAsLiveTile = true;
 
+
     public TaskView(Context context) {
         this(context, null);
     }
@@ -600,6 +604,14 @@
         return mIconView;
     }
 
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mLastTouchDownPosition.set(ev.getX(), ev.getY());
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
     private void onClick(View view) {
         if (getTask() == null) {
             return;
@@ -688,12 +700,22 @@
     private boolean confirmSecondSplitSelectApp() {
         boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
         if (isSelectingSecondSplitApp) {
-            getRecentsView().confirmSplitSelect(this);
+            int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
+            TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
+            getRecentsView().confirmSplitSelect(this, container.getTask(), container.getIconView(),
+                    container.getThumbnailView());
         }
         return isSelectingSecondSplitApp;
     }
 
     /**
+     * Returns the task under the given position in the local coordinates of this task view.
+     */
+    protected int getChildTaskIndexAtPosition(PointF position) {
+        return 0;
+    }
+
+    /**
      * Starts the task associated with this view and animates the startup.
      * @return CompletionStage to indicate the animation completion or null if the launch failed.
      */