diff options
3 files changed, 34 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 6abd4887645b..76fd57b6ed37 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2158,6 +2158,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Use Task#setBoundsUnchecked to skip checking windowing mode as the windowing mode // will be updated later after this is collected in transition. rootTask.setBoundsUnchecked(taskFragment.getBounds()); + // The exit-PIP activity resumes early for seamless transition. In certain + // scenarios, this introduces unintended addition to recents. To address this, + // we mark the root task for automatic removal from recents. This ensures that + // after the pinned activity reparents to its original task, the root task is + // automatically removed from the recents list. + rootTask.autoRemoveRecents = true; // Move the last recents animation transaction from original task to the new one. if (task.mLastRecentsAnimationTransaction != null) { diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index eb79118fe1c7..3078df026d8a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -392,6 +392,8 @@ public class RootWindowContainerTests extends WindowTestsBase { assertEquals(newPipTask, mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask()); assertNotEquals(newPipTask, activity1.getTask()); assertFalse("Created PiP task must not be in recents", newPipTask.inRecents); + assertThat(newPipTask.autoRemoveRecents).isTrue(); + assertThat(activity1.getTask().autoRemoveRecents).isFalse(); } /** @@ -427,6 +429,7 @@ public class RootWindowContainerTests extends WindowTestsBase { bounds.scale(0.5f); task.setBounds(bounds); assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertThat(task.autoRemoveRecents).isFalse(); } /** @@ -451,6 +454,7 @@ public class RootWindowContainerTests extends WindowTestsBase { // Ensure a task has moved over. ensureTaskPlacement(task, activity); assertTrue(task.inPinnedWindowingMode()); + assertThat(task.autoRemoveRecents).isFalse(); } /** @@ -480,6 +484,8 @@ public class RootWindowContainerTests extends WindowTestsBase { ensureTaskPlacement(fullscreenTask, secondActivity); assertTrue(pinnedRootTask.inPinnedWindowingMode()); assertEquals(WINDOWING_MODE_FULLSCREEN, fullscreenTask.getWindowingMode()); + assertThat(pinnedRootTask.autoRemoveRecents).isTrue(); + assertThat(secondActivity.getTask().autoRemoveRecents).isFalse(); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index e01cea3d62f8..ef0aa9ef7666 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -42,6 +42,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE; +import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK; import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT; @@ -222,6 +223,27 @@ public class TaskTests extends WindowTestsBase { } @Test + public void testReparentPinnedActivityBackToOriginalTask() { + final ActivityRecord activityMain = new ActivityBuilder(mAtm).setCreateTask(true).build(); + final Task originalTask = activityMain.getTask(); + final ActivityRecord activityPip = new ActivityBuilder(mAtm).setTask(originalTask).build(); + activityPip.setState(RESUMED, "test"); + mAtm.mRootWindowContainer.moveActivityToPinnedRootTask(activityPip, + null /* launchIntoPipHostActivity */, "test"); + final Task pinnedActivityTask = activityPip.getTask(); + + // Simulate pinnedActivityTask unintentionally added to recent during top activity resume. + mAtm.getRecentTasks().getRawTasks().add(pinnedActivityTask); + + // Reparent the activity back to its original task when exiting PIP mode. + pinnedActivityTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + + assertThat(activityPip.getTask()).isEqualTo(originalTask); + assertThat(originalTask.autoRemoveRecents).isFalse(); + assertThat(mAtm.getRecentTasks().getRawTasks()).containsExactly(originalTask); + } + + @Test public void testReparent_BetweenDisplays() { // Create first task on primary display. final Task rootTask1 = createTask(mDisplayContent); |