Loading services/core/java/com/android/server/wm/Task.java +1 −1 Original line number Diff line number Diff line Loading @@ -1523,7 +1523,7 @@ class Task extends TaskFragment { mTaskSupervisor.removeTask(this, false /* killProcess */, !REMOVE_FROM_RECENTS, reason); } } else if (!mReuseTask && !mCreatedByOrganizer) { } else if (!mReuseTask && shouldRemoveSelfOnLastChildRemoval()) { // Remove entire task if it doesn't have any activity left and it isn't marked for reuse // or created by task organizer. if (!isRootTask()) { Loading services/core/java/com/android/server/wm/TaskFragment.java +13 −4 Original line number Diff line number Diff line Loading @@ -2304,6 +2304,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mMinHeight = minHeight; } boolean shouldRemoveSelfOnLastChildRemoval() { return !mCreatedByOrganizer || mIsRemovalRequested; } @Override void removeChild(WindowContainer child) { removeChild(child, true /* removeSelfIfPossible */); Loading @@ -2319,7 +2323,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { mBackScreenshots.remove(r.mActivityComponent.flattenToString()); } } if (removeSelfIfPossible && (!mCreatedByOrganizer || mIsRemovalRequested) && !hasChild()) { if (removeSelfIfPossible && shouldRemoveSelfOnLastChildRemoval() && !hasChild()) { removeImmediately("removeLastChild " + child); } } Loading @@ -2337,13 +2341,18 @@ class TaskFragment extends WindowContainer<WindowContainer> { return; } mIsRemovalRequested = true; forAllActivities(r -> { if (withTransition) { // The task order may be changed by finishIfPossible() for adjusting focus if there are // nested tasks, so add all activities into a list to avoid missed removals. final ArrayList<ActivityRecord> removingActivities = new ArrayList<>(); forAllActivities((Consumer<ActivityRecord>) removingActivities::add); for (int i = removingActivities.size() - 1; i >= 0; --i) { final ActivityRecord r = removingActivities.get(i); if (withTransition && r.isVisible()) { r.finishIfPossible(reason, false /* oomAdj */); } else { r.destroyIfPossible(reason); } }); } } void setDelayLastActivityRemoval(boolean delay) { Loading services/tests/wmtests/src/com/android/server/wm/TaskTests.java +21 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,27 @@ public class TaskTests extends WindowTestsBase { verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask); } @Test public void testRemoveContainer_multipleNestedTasks() { final Task rootTask = createTask(mDisplayContent); rootTask.mCreatedByOrganizer = true; final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build(); final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build(); final ActivityRecord activity1 = createActivityRecord(task1); final ActivityRecord activity2 = createActivityRecord(task2); activity1.setVisible(false); // All activities under the root task should be finishing. rootTask.remove(true /* withTransition */, "test"); assertTrue(activity1.finishing); assertTrue(activity2.finishing); // After all activities activities are destroyed, the root task should also be removed. activity1.removeImmediately(); activity2.removeImmediately(); assertFalse(rootTask.isAttached()); } @Test public void testRemoveContainer_deferRemoval() { final Task rootTask = createTask(mDisplayContent); Loading Loading
services/core/java/com/android/server/wm/Task.java +1 −1 Original line number Diff line number Diff line Loading @@ -1523,7 +1523,7 @@ class Task extends TaskFragment { mTaskSupervisor.removeTask(this, false /* killProcess */, !REMOVE_FROM_RECENTS, reason); } } else if (!mReuseTask && !mCreatedByOrganizer) { } else if (!mReuseTask && shouldRemoveSelfOnLastChildRemoval()) { // Remove entire task if it doesn't have any activity left and it isn't marked for reuse // or created by task organizer. if (!isRootTask()) { Loading
services/core/java/com/android/server/wm/TaskFragment.java +13 −4 Original line number Diff line number Diff line Loading @@ -2304,6 +2304,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mMinHeight = minHeight; } boolean shouldRemoveSelfOnLastChildRemoval() { return !mCreatedByOrganizer || mIsRemovalRequested; } @Override void removeChild(WindowContainer child) { removeChild(child, true /* removeSelfIfPossible */); Loading @@ -2319,7 +2323,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { mBackScreenshots.remove(r.mActivityComponent.flattenToString()); } } if (removeSelfIfPossible && (!mCreatedByOrganizer || mIsRemovalRequested) && !hasChild()) { if (removeSelfIfPossible && shouldRemoveSelfOnLastChildRemoval() && !hasChild()) { removeImmediately("removeLastChild " + child); } } Loading @@ -2337,13 +2341,18 @@ class TaskFragment extends WindowContainer<WindowContainer> { return; } mIsRemovalRequested = true; forAllActivities(r -> { if (withTransition) { // The task order may be changed by finishIfPossible() for adjusting focus if there are // nested tasks, so add all activities into a list to avoid missed removals. final ArrayList<ActivityRecord> removingActivities = new ArrayList<>(); forAllActivities((Consumer<ActivityRecord>) removingActivities::add); for (int i = removingActivities.size() - 1; i >= 0; --i) { final ActivityRecord r = removingActivities.get(i); if (withTransition && r.isVisible()) { r.finishIfPossible(reason, false /* oomAdj */); } else { r.destroyIfPossible(reason); } }); } } void setDelayLastActivityRemoval(boolean delay) { Loading
services/tests/wmtests/src/com/android/server/wm/TaskTests.java +21 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,27 @@ public class TaskTests extends WindowTestsBase { verify(mAtm.getLockTaskController(), atLeast(1)).clearLockedTask(rootTask); } @Test public void testRemoveContainer_multipleNestedTasks() { final Task rootTask = createTask(mDisplayContent); rootTask.mCreatedByOrganizer = true; final Task task1 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build(); final Task task2 = new TaskBuilder(mSupervisor).setParentTaskFragment(rootTask).build(); final ActivityRecord activity1 = createActivityRecord(task1); final ActivityRecord activity2 = createActivityRecord(task2); activity1.setVisible(false); // All activities under the root task should be finishing. rootTask.remove(true /* withTransition */, "test"); assertTrue(activity1.finishing); assertTrue(activity2.finishing); // After all activities activities are destroyed, the root task should also be removed. activity1.removeImmediately(); activity2.removeImmediately(); assertFalse(rootTask.isAttached()); } @Test public void testRemoveContainer_deferRemoval() { final Task rootTask = createTask(mDisplayContent); Loading