Don't restore from recent task if not launching

The restored task may not contain activities. If the operation
is not to launch an activity (e.g. start activity from recents),
it just produces an unused empty task into stack. That may also
cause an unexpected state than originally intended (e.g. resize
a finished task).

Bug: 113363177
Test: RecentTasksTest#testNotRestoreRecentTaskApis

Change-Id: Ibb8384c0364c421a5d8169f118ea521e7b5f33ae
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 5b0a4a9..ba8662a 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -1811,7 +1811,8 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     return;
                 }
@@ -1971,7 +1972,8 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
                     return;
@@ -2302,7 +2304,8 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
                     return false;
@@ -2437,13 +2440,17 @@
     }
 
     @Override
-    public void startSystemLockTaskMode(int taskId) throws RemoteException {
+    public void startSystemLockTaskMode(int taskId) {
         mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
         // This makes inner call to look as if it was initiated by system.
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY);
+                if (task == null) {
+                    return;
+                }
 
                 // When starting lock task mode the stack must be in front and focused
                 task.getStack().moveToFront("startSystemLockTaskMode");
@@ -2801,7 +2808,8 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
-                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+                        MATCH_TASK_IN_STACKS_ONLY);
                 if (task == null) {
                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
                     return;
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 129b835..04fe787 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -30,6 +30,7 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -55,7 +56,6 @@
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.util.MutableLong;
-import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
 import androidx.test.InstrumentationRegistry;
@@ -665,6 +665,39 @@
     }
 
     @Test
+    public void testNotRestoreRecentTaskApis() {
+        final TaskRecord task = createTaskBuilder(".Task").build();
+        final int taskId = task.taskId;
+        mRecentTasks.add(task);
+        // Only keep the task in RecentTasks.
+        task.removeWindowContainer();
+        mStack.remove();
+
+        // The following APIs should not restore task from recents to the active list.
+        assertNotRestoreTask(() -> mService.setFocusedTask(taskId));
+        assertNotRestoreTask(() -> mService.startSystemLockTaskMode(taskId));
+        assertNotRestoreTask(() -> mService.cancelTaskWindowTransition(taskId));
+        assertNotRestoreTask(
+                () -> mService.resizeTask(taskId, null /* bounds */, 0 /* resizeMode */));
+        assertNotRestoreTask(
+                () -> mService.setTaskWindowingMode(taskId, WINDOWING_MODE_FULLSCREEN,
+                        false/* toTop */));
+        assertNotRestoreTask(
+                () -> mService.setTaskWindowingModeSplitScreenPrimary(taskId,
+                        SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
+                        false /* toTop */, false /* animate */, null /* initialBounds */,
+                        true /* showRecents */));
+    }
+
+    private void assertNotRestoreTask(Runnable action) {
+        // Verify stack count doesn't change because task with fullscreen mode and standard type
+        // would have its own stack.
+        final int orignalStackCount = mDisplay.getChildCount();
+        action.run();
+        assertEquals(orignalStackCount, mDisplay.getChildCount());
+    }
+
+    @Test
     public void testNotRecentsComponent_denyApiAccess() throws Exception {
         doReturn(PackageManager.PERMISSION_DENIED).when(mService)
                 .checkGetTasksPermission(anyString(), anyInt(), anyInt());