Loading services/core/java/com/android/server/wm/ActivityRecord.java +3 −0 Original line number Diff line number Diff line Loading @@ -4214,6 +4214,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this); } } if (task != null && task.mKillProcessesOnDestroyed) { mTaskSupervisor.removeTimeoutOfKillProcessesOnProcessDied(this, task); } // upgrade transition trigger to task if this is the last activity since it means we are // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +20 −2 Original line number Diff line number Diff line Loading @@ -1891,7 +1891,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // DestroyActivityItem may be called first. final ActivityRecord top = task.getTopMostActivity(); if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0 && !task.mKillProcessesOnDestroyed) { && !task.mKillProcessesOnDestroyed && top.hasProcess()) { task.mKillProcessesOnDestroyed = true; mHandler.sendMessageDelayed( mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task), Loading @@ -1901,8 +1901,26 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { killTaskProcessesIfPossible(task); } void removeTimeoutOfKillProcessesOnProcessDied(@NonNull ActivityRecord r, @NonNull Task task) { if (r.packageName.equals(task.getBasePackageName())) { task.mKillProcessesOnDestroyed = false; mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); } } void killTaskProcessesOnDestroyedIfNeeded(Task task) { if (task == null || !task.mKillProcessesOnDestroyed) return; final int[] numDestroyingActivities = new int[1]; task.forAllActivities(r -> { if (r.finishing && r.lastVisibleTime > 0 && r.attachedToProcess()) { numDestroyingActivities[0]++; } }); if (numDestroyingActivities[0] > 1) { // Skip if there are still destroying activities. When the last activity reports // destroyed, the number will be 1 to proceed the kill. return; } mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); killTaskProcessesIfPossible(task); } Loading Loading @@ -2763,7 +2781,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } break; case KILL_TASK_PROCESSES_TIMEOUT_MSG: { final Task task = (Task) msg.obj; if (task.mKillProcessesOnDestroyed) { if (task.mKillProcessesOnDestroyed && task.hasActivity()) { Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task); killTaskProcessesIfPossible(task); } Loading services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +13 −2 Original line number Diff line number Diff line Loading @@ -1040,14 +1040,25 @@ public class RecentTasksTest extends WindowTestsBase { // If the task has a non-stopped activity, the removal will wait for its onDestroy. final Task task = tasks.get(0); final ActivityRecord bottom = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).build(); top.lastVisibleTime = 123; bottom.lastVisibleTime = top.lastVisibleTime = 123; top.setState(ActivityRecord.State.RESUMED, "test"); mRecentTasks.removeTasksByPackageName(task.getBasePackageName(), TEST_USER_0_ID); assertTrue(task.mKillProcessesOnDestroyed); top.setState(ActivityRecord.State.DESTROYING, "test"); bottom.destroyed("test"); assertTrue("Wait for all destroyed", task.mKillProcessesOnDestroyed); top.destroyed("test"); assertFalse(task.mKillProcessesOnDestroyed); assertFalse("Consume kill", task.mKillProcessesOnDestroyed); // If the process is died, the state should be cleared. final Task lastTask = tasks.get(0); lastTask.intent.setComponent(top.mActivityComponent); lastTask.addChild(top); lastTask.mKillProcessesOnDestroyed = true; top.handleAppDied(); assertFalse(lastTask.mKillProcessesOnDestroyed); } @Test Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +3 −0 Original line number Diff line number Diff line Loading @@ -4214,6 +4214,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this); } } if (task != null && task.mKillProcessesOnDestroyed) { mTaskSupervisor.removeTimeoutOfKillProcessesOnProcessDied(this, task); } // upgrade transition trigger to task if this is the last activity since it means we are // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +20 −2 Original line number Diff line number Diff line Loading @@ -1891,7 +1891,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // DestroyActivityItem may be called first. final ActivityRecord top = task.getTopMostActivity(); if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0 && !task.mKillProcessesOnDestroyed) { && !task.mKillProcessesOnDestroyed && top.hasProcess()) { task.mKillProcessesOnDestroyed = true; mHandler.sendMessageDelayed( mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task), Loading @@ -1901,8 +1901,26 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { killTaskProcessesIfPossible(task); } void removeTimeoutOfKillProcessesOnProcessDied(@NonNull ActivityRecord r, @NonNull Task task) { if (r.packageName.equals(task.getBasePackageName())) { task.mKillProcessesOnDestroyed = false; mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); } } void killTaskProcessesOnDestroyedIfNeeded(Task task) { if (task == null || !task.mKillProcessesOnDestroyed) return; final int[] numDestroyingActivities = new int[1]; task.forAllActivities(r -> { if (r.finishing && r.lastVisibleTime > 0 && r.attachedToProcess()) { numDestroyingActivities[0]++; } }); if (numDestroyingActivities[0] > 1) { // Skip if there are still destroying activities. When the last activity reports // destroyed, the number will be 1 to proceed the kill. return; } mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); killTaskProcessesIfPossible(task); } Loading Loading @@ -2763,7 +2781,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } break; case KILL_TASK_PROCESSES_TIMEOUT_MSG: { final Task task = (Task) msg.obj; if (task.mKillProcessesOnDestroyed) { if (task.mKillProcessesOnDestroyed && task.hasActivity()) { Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task); killTaskProcessesIfPossible(task); } Loading
services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +13 −2 Original line number Diff line number Diff line Loading @@ -1040,14 +1040,25 @@ public class RecentTasksTest extends WindowTestsBase { // If the task has a non-stopped activity, the removal will wait for its onDestroy. final Task task = tasks.get(0); final ActivityRecord bottom = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).build(); top.lastVisibleTime = 123; bottom.lastVisibleTime = top.lastVisibleTime = 123; top.setState(ActivityRecord.State.RESUMED, "test"); mRecentTasks.removeTasksByPackageName(task.getBasePackageName(), TEST_USER_0_ID); assertTrue(task.mKillProcessesOnDestroyed); top.setState(ActivityRecord.State.DESTROYING, "test"); bottom.destroyed("test"); assertTrue("Wait for all destroyed", task.mKillProcessesOnDestroyed); top.destroyed("test"); assertFalse(task.mKillProcessesOnDestroyed); assertFalse("Consume kill", task.mKillProcessesOnDestroyed); // If the process is died, the state should be cleared. final Task lastTask = tasks.get(0); lastTask.intent.setComponent(top.mActivityComponent); lastTask.addChild(top); lastTask.mKillProcessesOnDestroyed = true; top.handleAppDied(); assertFalse(lastTask.mKillProcessesOnDestroyed); } @Test Loading