Do not use top running activities in other tasks when reset tasks

There were no running activities left in the resetting task, because
all activities in the task were set as finishing. The next top running
activity from other tasks was selected and returning it as the new
taskTop. However, we shouldn’t return the activity that was not
belonging to the resetting task because other tasks below would be
reused for the newly starting activity.

Bug: 135033489
Test: atest ActivityStackTests

Change-Id: Ia3793cd3d65837fdbc4cd43c2639e86184f6fb15
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 12eab50..3875ee4 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -3579,6 +3579,16 @@
         return taskInsertionPoint;
     }
 
+    /**
+     * Reset the task by reparenting the activities that have same affinity to the task or
+     * reparenting the activities that have different affinityies out of the task, while these
+     * activities allow task reparenting.
+     *
+     * @param taskTop     Top activity of the task might be reset.
+     * @param newActivity The activity that going to be started.
+     * @return The non-finishing top activity of the task after reset or the original task top
+     *         activity if all activities within the task are finishing.
+     */
     final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
             ActivityRecord newActivity) {
         final boolean forceReset =
@@ -3609,9 +3619,10 @@
 
         int taskNdx = mTaskHistory.indexOf(task);
         if (taskNdx >= 0) {
-            do {
-                taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
-            } while (taskTop == null && taskNdx >= 0);
+            ActivityRecord newTop = mTaskHistory.get(taskNdx).getTopActivity();
+            if (newTop != null) {
+                taskTop = newTop;
+            }
         }
 
         if (topOptions != null) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index e5278d8..a97217c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1079,6 +1079,19 @@
         assertTrue(listener.mChanged);
     }
 
+    @Test
+    public void testResetTaskWithFinishingActivities() {
+        final ActivityRecord taskTop =
+                new ActivityBuilder(mService).setStack(mStack).setCreateTask(true).build();
+        // Make all activities in the task are finishing to simulate TaskRecord#getTopActivity
+        // returns null.
+        taskTop.finishing = true;
+
+        final ActivityRecord newR = new ActivityBuilder(mService).build();
+        final ActivityRecord result = mStack.resetTaskIfNeededLocked(taskTop, newR);
+        assertThat(result).isEqualTo(taskTop);
+    }
+
     private void verifyShouldSleepActivities(boolean focusedStack,
             boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
         final ActivityDisplay display = mock(ActivityDisplay.class);