Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 090ac6f9 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

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
parent 906f76ae
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -1811,7 +1811,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    }

    @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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        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;
+34 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
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.RemoteException;
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;
@@ -664,6 +664,39 @@ public class RecentTasksTest extends ActivityTestsBase {
        assertTrimmed(t1, t2, t3, t4, t5, t6, t7);
    }

    @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)