Consolidate entering split screen behavior

Add a fallback logic for entering split screen by verifying it contances
opening task to the indicated side to prevent leaving one side of the
split empty. Fix checking the wrong running task when entering split
screen by checking the top running task instead of checking reported
focusing task since the focusing task is not matching with the leaf task
running on top always.

Fix: 246689775
Fix: 260389099
Test: atest WMShellUnitTests
Test: drag and drop Calender to enter split while Calender on top won't
      leave empty side split.
Test: drag and drop Chrome to enter split while Chrome on top won't pup
      up not supported toast.
Change-Id: Ic7ea239b10ce41d956a85dbd6d04e007babd0743
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index f9172ba..7908f35 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -342,6 +342,16 @@
     }
 
     /**
+     * Returns the top running leaf task.
+     */
+    @Nullable
+    public ActivityManager.RunningTaskInfo getTopRunningTask() {
+        List<ActivityManager.RunningTaskInfo> tasks = mActivityTaskManager.getTasks(1,
+                false /* filterOnlyVisibleRecents */);
+        return tasks.isEmpty() ? null : tasks.get(0);
+    }
+
+    /**
      * Find the background task that match the given component.
      */
     @Nullable
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 a79ac45..b20125d 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
@@ -315,10 +315,6 @@
         return mStageCoordinator;
     }
 
-    public ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
-        return mStageCoordinator.getFocusingTaskInfo();
-    }
-
     public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
         return mStageCoordinator.isValidToEnterSplitScreen(taskInfo);
     }
@@ -628,9 +624,10 @@
         if (!isSplitScreenVisible()) {
             // Split screen is not yet activated, check if the current top running task is valid to
             // split together.
-            final ActivityManager.RunningTaskInfo taskInfo = getFocusingTaskInfo();
-            if (taskInfo != null && isValidToEnterSplitScreen(taskInfo)) {
-                return Objects.equals(taskInfo.baseIntent.getComponent(), launchingActivity);
+            final ActivityManager.RunningTaskInfo topRunningTask = mRecentTasksOptional
+                    .map(recentTasks -> recentTasks.getTopRunningTask()).orElse(null);
+            if (topRunningTask != null && isValidToEnterSplitScreen(topRunningTask)) {
+                return Objects.equals(topRunningTask.baseIntent.getComponent(), launchingActivity);
             }
             return false;
         }
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 acb71a8..db1062a 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
@@ -150,7 +150,7 @@
  */
 public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
-        ShellTaskOrganizer.TaskListener, ShellTaskOrganizer.FocusListener {
+        ShellTaskOrganizer.TaskListener {
 
     private static final String TAG = StageCoordinator.class.getSimpleName();
 
@@ -186,8 +186,6 @@
     private final Rect mTempRect1 = new Rect();
     private final Rect mTempRect2 = new Rect();
 
-    private ActivityManager.RunningTaskInfo mFocusingTaskInfo;
-
     /**
      * A single-top root task which the split divider attached to.
      */
@@ -304,7 +302,6 @@
         mDisplayController.addDisplayWindowListener(this);
         mDisplayLayout = new DisplayLayout(displayController.getDisplayLayout(displayId));
         transitions.addHandler(this);
-        mTaskOrganizer.addFocusListener(this);
         mSplitUnsupportedToast = Toast.makeText(mContext,
                 R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
     }
@@ -455,8 +452,9 @@
     }
 
     /** Launches an activity into split by legacy transition. */
-    void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
-            @SplitPosition int position, @Nullable Bundle options) {
+    void startIntentLegacy(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
+            @Nullable Bundle options) {
+        final boolean isEnteringSplit = !isSplitActive();
         final WindowContainerTransaction evictWct = new WindowContainerTransaction();
         prepareEvictChildTasks(position, evictWct);
 
@@ -466,22 +464,29 @@
                     RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                     IRemoteAnimationFinishedCallback finishedCallback,
                     SurfaceControl.Transaction t) {
-                if (apps == null || apps.length == 0) {
-                    if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
-                        mMainExecutor.execute(() ->
-                                exitSplitScreen(mMainStage.getChildCount() == 0
-                                        ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
-                        mSplitUnsupportedToast.show();
+                if (isEnteringSplit) {
+                    boolean openingToSide = false;
+                    if (apps != null) {
+                        for (int i = 0; i < apps.length; ++i) {
+                            if (apps[i].mode == MODE_OPENING
+                                    && mSideStage.containsTask(apps[i].taskId)) {
+                                openingToSide = true;
+                                break;
+                            }
+                        }
                     }
-
-                    // Do nothing when the animation was cancelled.
-                    t.apply();
-                    return;
+                    if (!openingToSide) {
+                        mMainExecutor.execute(() -> exitSplitScreen(
+                                mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
+                                EXIT_REASON_UNKNOWN));
+                    }
                 }
 
-                for (int i = 0; i < apps.length; ++i) {
-                    if (apps[i].mode == MODE_OPENING) {
-                        t.show(apps[i].leash);
+                if (apps != null) {
+                    for (int i = 0; i < apps.length; ++i) {
+                        if (apps[i].mode == MODE_OPENING) {
+                            t.show(apps[i].leash);
+                        }
                     }
                 }
                 t.apply();
@@ -503,7 +508,7 @@
 
         // If split still not active, apply windows bounds first to avoid surface reset to
         // wrong pos by SurfaceAnimator from wms.
-        if (!mMainStage.isActive() && mLogger.isEnterRequestedByDrag()) {
+        if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) {
             updateWindowBounds(mSplitLayout, wct);
         }
 
@@ -1617,15 +1622,6 @@
                 && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
     }
 
-    ActivityManager.RunningTaskInfo getFocusingTaskInfo() {
-        return mFocusingTaskInfo;
-    }
-
-    @Override
-    public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        mFocusingTaskInfo = taskInfo;
-    }
-
     @Override
     public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
         final boolean mainStageToTop =
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 38b75f8..f8ded77 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
@@ -178,10 +178,10 @@
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
-        // Put the same component into focus task
-        ActivityManager.RunningTaskInfo focusTaskInfo =
+        // Put the same component to the top running task
+        ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
-        doReturn(focusTaskInfo).when(mStageCoordinator).getFocusingTaskInfo();
+        doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
         doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any());
 
         mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
@@ -199,10 +199,10 @@
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
-        // Put the same component into focus task
-        ActivityManager.RunningTaskInfo focusTaskInfo =
+        // Put the same component to the top running task
+        ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
-        doReturn(focusTaskInfo).when(mStageCoordinator).getFocusingTaskInfo();
+        doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
         doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any());
         // Put the same component into a task in the background
         ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();