Evict all main stage tasks only for non-drag split starts

* See bug for root cause info.
* Technically we'd want to expand the scope of this
to not only drag n drop but all explicit split starts, but
for QPR2 we'll keep it contained.
* The reason we evict has to do w/ launch-adjacent split
scenarios (highlighted in original bug b/279720005)

Test: Original bug doesn't repro nor does the current one with
drag and drop. Tested Chrome w/ some multi-instance drags and
that also seems to work fine
Fixes: 309905087
Flag: None

Change-Id: I3b4238141d8fadf0cde2ea7fe9fe1161496ce888
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 37b24e5..b7e98da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -838,9 +838,12 @@
                 .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1))
                 .orElse(null);
         if (taskInfo != null) {
-            startTask(taskInfo.taskId, position, options);
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
-                    "Start task in background");
+            if (ENABLE_SHELL_TRANSITIONS) {
+                mStageCoordinator.startTask(taskInfo.taskId, position, options);
+            } else {
+                startTask(taskInfo.taskId, position, options);
+            }
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
             return;
         }
         if (samePackage(packageName1, packageName2, userId1, userId2)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index be685b5..449bef5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -263,6 +263,10 @@
             mStartIntent2 = startIntent2;
             mActivatePosition = position;
         }
+        SplitRequest(int taskId1, int position) {
+            mActivateTaskId = taskId1;
+            mActivatePosition = position;
+        }
         SplitRequest(int taskId1, int taskId2, int position) {
             mActivateTaskId = taskId1;
             mActivateTaskId2 = taskId2;
@@ -556,6 +560,27 @@
         }
     }
 
+    /** Use this method to launch an existing Task via a taskId */
+    void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+        mSplitRequest = new SplitRequest(taskId, position);
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+        wct.startTask(taskId, options);
+        // If this should be mixed, send the task to avoid split handle transition directly.
+        if (mMixedHandler != null && mMixedHandler.shouldSplitEnterMixed(taskId, mTaskOrganizer)) {
+            mTaskOrganizer.applyTransaction(wct);
+            return;
+        }
+
+        // If split screen is not activated, we're expecting to open a pair of apps to split.
+        final int extraTransitType = mMainStage.isActive()
+                ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
+        prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering);
+
+        mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
+                extraTransitType, !mIsDropEntering);
+    }
+
     /** Launches an activity into split. */
     void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
             @Nullable Bundle options) {
@@ -1593,7 +1618,9 @@
             // Ensure to evict old splitting tasks because the new split pair might be composed by
             // one of the splitting tasks, evicting the task when finishing entering transition
             // won't guarantee to put the task to the indicated new position.
-            mMainStage.evictAllChildren(wct);
+            if (!mIsDropEntering) {
+                mMainStage.evictAllChildren(wct);
+            }
             mMainStage.reparentTopTask(wct);
             prepareSplitLayout(wct, resizeAnim);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index ce7fef2..d73dc18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -48,6 +48,7 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.desktopmode.DesktopModeStatus;
@@ -902,6 +903,18 @@
         return false;
     }
 
+    /** Use to when split use taskId to enter, check if this enter transition should be mixed or
+     * not.*/
+    public boolean shouldSplitEnterMixed(int taskId, ShellTaskOrganizer shellTaskOrganizer) {
+        // Check if this intent package is same as pip one or not, if true we want let the pip
+        // task enter split.
+        if (mPipHandler != null) {
+            return mPipHandler.isInPipPackage(
+                    SplitScreenUtils.getPackageName(taskId, shellTaskOrganizer));
+        }
+        return false;
+    }
+
     /** @return whether the transition-request represents a pip-entry. */
     public boolean requestHasPipEnter(TransitionRequestInfo request) {
         return mPipHandler.requestHasPipEnter(request);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index 99cd4f3..855b7ee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -235,7 +235,7 @@
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
                 SPLIT_POSITION_TOP_OR_LEFT, null);
 
-        verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
+        verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
                 isNull());
         verify(mSplitScreenController, never()).supportMultiInstancesSplit(any());
         verify(mStageCoordinator, never()).switchSplitPosition(any());
@@ -243,7 +243,6 @@
 
     @Test
     public void startIntent_multiInstancesSupported_startTaskInBackgroundAfterSplitActivated() {
-        doReturn(true).when(mSplitScreenController).supportMultiInstancesSplit(any());
         doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
@@ -260,8 +259,8 @@
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
                 SPLIT_POSITION_TOP_OR_LEFT, null);
-
-        verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
+        verify(mSplitScreenController, never()).supportMultiInstancesSplit(any());
+        verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
                 isNull());
     }