diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index ef0ee1206208a..47bec3081dc34 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2196,8 +2196,9 @@ class ActivityStarter { // removed from calling performClearTaskLocked (For example, if it is being brought out // of history or if it is finished immediately), thus disassociating the task. Also note // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked} - // launching another activity. - targetTask.performClearTaskLocked(); + // launching another activity. Keep the task-overlay activity because the targetTask + // will be reused to launch new activity. + targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/); targetTask.setIntent(mStartActivity); mAddingToTask = true; } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0 @@ -2207,8 +2208,7 @@ class ActivityStarter { // In this situation we want to remove all activities from the task up to the one // being started. In most cases this means we are resetting the task to its initial // state. - final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity, - mLaunchFlags); + final ActivityRecord top = targetTask.performClearTop(mStartActivity, mLaunchFlags); if (top != null) { if (top.isRootOfTask()) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 3d7dead7d4c03..5573f161d1c1e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1605,7 +1605,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { task.mTransitionController.requestCloseTransitionIfNeeded(task); task.mInRemoveTask = true; try { - task.performClearTask(reason); + task.removeActivities(reason, false /* excludingTaskOverlay */); cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents); mService.getLockTaskController().clearLockedTask(task); mService.getTaskChangeNotificationController().notifyTaskStackChanged(); diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 8a2d11636fe37..160fc95f3f7c8 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -542,7 +542,7 @@ public class LockTaskController { if (mLockTaskModeTasks.isEmpty()) { return; } - task.performClearTaskLocked(); + task.performClearTaskForReuse(false /* excludingTaskOverlay*/); mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); } @@ -740,7 +740,7 @@ public class LockTaskController { ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: removing %s" + " mLockTaskAuth()=%s", lockedTask, lockedTask.lockTaskAuthToString()); removeLockedTask(lockedTask); - lockedTask.performClearTaskLocked(); + lockedTask.performClearTaskForReuse(false /* excludingTaskOverlay*/); taskChanged = true; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 98c74f8ad81dc..8d6df6b3427d1 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1583,19 +1583,23 @@ class Task extends TaskFragment { } /** Completely remove all activities associated with an existing task. */ - void performClearTask(String reason) { + void removeActivities(String reason, boolean excludingTaskOverlay) { clearPinnedTaskIfNeed(); // Broken down into to cases to avoid object create due to capturing mStack. if (getRootTask() == null) { forAllActivities((r) -> { - if (r.finishing) return; + if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) { + return; + } // Task was restored from persistent storage. r.takeFromHistory(); removeChild(r, reason); }); } else { forAllActivities((r) -> { - if (r.finishing) return; + if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) { + return; + } // Prevent the transition from being executed too early if the top activity is // resumed but the mVisibleRequested of any other activity is true, the transition // should wait until next activity resumed. @@ -1612,26 +1616,24 @@ class Task extends TaskFragment { /** * Completely remove all activities associated with an existing task. */ - void performClearTaskLocked() { + void performClearTaskForReuse(boolean excludingTaskOverlay) { mReuseTask = true; mTaskSupervisor.beginDeferResume(); try { - performClearTask("clear-task-all"); + removeActivities("clear-task-all", excludingTaskOverlay); } finally { mTaskSupervisor.endDeferResume(); mReuseTask = false; } } - ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) { - mReuseTask = true; + ActivityRecord performClearTop(ActivityRecord newR, int launchFlags) { mTaskSupervisor.beginDeferResume(); final ActivityRecord result; try { - result = performClearTaskLocked(newR, launchFlags); + result = clearTopActivities(newR, launchFlags); } finally { mTaskSupervisor.endDeferResume(); - mReuseTask = false; } return result; } @@ -1647,7 +1649,7 @@ class Task extends TaskFragment { * @return Returns the old activity that should be continued to be used, * or {@code null} if none was found. */ - private ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) { + private ActivityRecord clearTopActivities(ActivityRecord newR, int launchFlags) { final ActivityRecord r = findActivityInHistory(newR.mActivityComponent); if (r == null) return null; @@ -1674,7 +1676,7 @@ class Task extends TaskFragment { // Stop operation once we reach the boundary activity. if (r == boundaryActivity) return true; - if (!r.finishing) { + if (!r.finishing && !r.isTaskOverlay()) { final ActivityOptions opts = r.getOptions(); if (opts != null) { r.clearOptionsAnimation(); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 0d6794685f09b..72521fd06245a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -120,7 +120,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { behind.setState(ActivityRecord.State.STARTED, "test"); behind.mVisibleRequested = true; - task.performClearTask("test"); + task.removeActivities("test", false /* excludingTaskOverlay */); assertFalse(mDisplayContent.mAppTransition.isReady()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java index cc1869e72b341..9fc9489e3c2e7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java @@ -557,7 +557,7 @@ public class LockTaskControllerTest { mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); // THEN the task running that package should be stopped - verify(tr2).performClearTaskLocked(); + verify(tr2).performClearTaskForReuse(false /* excludingTaskOverlay*/); assertFalse(mLockTaskController.isTaskLocked(tr2)); // THEN the other task should remain locked assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState()); @@ -569,7 +569,7 @@ public class LockTaskControllerTest { mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist); // THEN the last task should be cleared, and the system should quit LockTask mode - verify(tr1).performClearTaskLocked(); + verify(tr1).performClearTaskForReuse(false /* excludingTaskOverlay*/); assertFalse(mLockTaskController.isTaskLocked(tr1)); assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState()); verifyLockTaskStopped(times(1));