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

Commit 4b141c61 authored by Merissa Mitchell's avatar Merissa Mitchell
Browse files

[PiP on CD] Activate desk if expanding PiP at Home on Desktop-first

displays in multi-desks case.

When expanding to PiP at Home on Desktop-first displays, we would expect
PiP to expand to freeform windowing mode, just like launching any other
task. However, at the time of expanding PiP, if it is the only task
running, there is actually no Desks active yet. In this case, we also
need to add desk activation changes, in addition to reparenting the PiP
task to the root desk.

Note that this change also relies on the
enable_overview_on_connected_displays flag to update the Taskbar with
the task icon.

Bug: 417522949
Test: atest WMShellUnitTests:com.android.wm.shell.pip2
Test: atest DesktopPipTransitionControllerTest
Test: Manual - expand PiP at Home on Desktop-first display, verify PiP
icon is added to Taskbar and reparented to root desk
Flag: com.android.window.flags.enable_connected_displays_pip

Change-Id: Ibb025c17e1a787171800295a188db9ba6c1a80b3
parent c58f3cdc
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -115,6 +115,10 @@ class PipDesktopState(
                rootTaskDisplayAreaOrganizer.isDisplayDesktopFirst(displayId)
    }

    /** Returns whether the display with the given id is a Desktop-first display. */
    fun isDisplayDesktopFirst(displayId: Int) =
        rootTaskDisplayAreaOrganizer.isDisplayDesktopFirst(displayId)

    /** Returns the windowing mode to restore to when resizing out of PIP direction. */
    fun getOutPipWindowingMode(): Int {
        val isInDesktop = isPipInDesktopMode()
+30 −6
Original line number Diff line number Diff line
@@ -81,9 +81,11 @@ class DesktopPipTransitionController(
    }

    /**
     * This is called by [PipScheduler#getExitPipViaExpandTransaction] before starting a PiP
     * This is called by [PipScheduler#getExitPipViaExpandTransaction] before starting an EXIT_PiP
     * transition. If the ENABLE_MULTIPLE_DESKTOPS_BACKEND flag is enabled and the PiP task is going
     * to freeform windowing mode, we need to reparent the task to the root desk.
     * to freeform windowing mode, we need to reparent the task to the root desk. In addition, if we
     * are expanding PiP at Home (as in with a Desktop-first display), we also need to activate the
     * default desk.
     *
     * @param wct WindowContainerTransaction that will apply these changes
     * @param taskId of the task that is exiting PiP
@@ -104,20 +106,39 @@ class DesktopPipTransitionController(

        val desktopRepository = desktopUserRepositories.getProfile(runningTaskInfo.userId)
        val displayId = runningTaskInfo.displayId
        if (!desktopRepository.isAnyDeskActive(displayId)) {
        if (!pipDesktopState.isPipInDesktopMode()) {
            logD("maybeReparentTaskToDesk: PiP transition is not in Desktop session")
            return
        }

        val deskId = getDeskId(desktopRepository, displayId)
        if (deskId == INVALID_DESK_ID) return
        if (!desktopRepository.isDeskActive(deskId)) {
            logD(
                "maybeReparentTaskToDesk: addDeskActivationChanges, taskId=%d deskId=%d, " +
                    "displayId=%d",
                runningTaskInfo.taskId,
                deskId,
                displayId,
            )
            desktopTasksController.addDeskActivationChanges(
                deskId = deskId,
                wct = wct,
                newTask = runningTaskInfo,
                displayId = displayId,
            )
        }

        logD(
            "maybeReparentTaskToDesk: addMoveToDeskTaskChanges, taskId=%d deskId=%d",
            runningTaskInfo.taskId,
            deskId,
        )
        desktopTasksController.addMoveToDeskTaskChanges(wct, runningTaskInfo, deskId)
        desktopTasksController.addMoveToDeskTaskChanges(
            wct = wct,
            task = runningTaskInfo,
            deskId = deskId,
        )
    }

    /**
@@ -146,7 +167,7 @@ class DesktopPipTransitionController(
        val taskId = taskInfo.taskId
        val displayId = taskInfo.displayId
        val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
        if (!desktopRepository.isAnyDeskActive(displayId)) {
        if (!pipDesktopState.isPipInDesktopMode()) {
            logD("handlePipTransition: PiP transition is not in Desktop session")
            return
        }
@@ -183,7 +204,10 @@ class DesktopPipTransitionController(

    private fun getDeskId(repository: DesktopRepository, displayId: Int): Int =
        repository.getActiveDeskId(displayId)
            ?: if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
            ?: if (
                DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue &&
                    !pipDesktopState.isDisplayDesktopFirst(displayId)
            ) {
                logW("getDeskId: Active desk not found for display id %d", displayId)
                INVALID_DESK_ID
            } else {
+1 −1
Original line number Diff line number Diff line
@@ -3641,7 +3641,7 @@ class DesktopTasksController(
     * null and may be used to run other desktop policies, such as minimizing another task if the
     * task limit has been exceeded.
     */
    private fun addDeskActivationChanges(
    fun addDeskActivationChanges(
        deskId: Int,
        wct: WindowContainerTransaction,
        newTask: TaskInfo? = null,
+25 −3
Original line number Diff line number Diff line
@@ -82,6 +82,8 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
    @Before
    fun setUp() {
        whenever(mockPipDesktopState.isDesktopWindowingPipEnabled()).thenReturn(true)
        whenever(mockPipDesktopState.isDisplayDesktopFirst(any())).thenReturn(false)
        whenever(mockPipDesktopState.isPipInDesktopMode()).thenReturn(true)
        whenever(mockDesktopUserRepositories.getProfile(any())).thenReturn(mockDesktopRepository)
        whenever(mockDesktopRepository.isAnyDeskActive(any())).thenReturn(true)
        whenever(mockDesktopRepository.getActiveDeskId(any())).thenReturn(DESK_ID)
@@ -122,7 +124,6 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
    @Test
    fun maybeUpdateParentInWct_inDesktop_addFreeformChangesToWct() {
        val wct = WindowContainerTransaction()
        whenever(mockPipDesktopState.isPipInDesktopMode()).thenReturn(true)

        controller.maybeUpdateParentInWct(wct, fullscreenParentTask.taskId)

@@ -146,7 +147,6 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
    @Test
    fun maybeUpdateParentInWct_inDesktop_parentWindowingModeMatches_noWctChanges() {
        val wct = WindowContainerTransaction()
        whenever(mockPipDesktopState.isPipInDesktopMode()).thenReturn(true)

        controller.maybeUpdateParentInWct(wct, freeformParentTask.taskId)

@@ -165,7 +165,7 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_noDeskActive_noWctChanges() {
    fun maybeReparentTaskToDesk_noDeskActive_notDesktopFirstDisplay_noWctChanges() {
        val wct = WindowContainerTransaction()
        whenever(mockDesktopRepository.isAnyDeskActive(eq(taskInfo.displayId))).thenReturn(false)

@@ -186,6 +186,28 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
            .addMoveToDeskTaskChanges(wct = wct, task = taskInfo, deskId = DESK_ID)
    }

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_noDeskActive_desktopFirstDisplay_addDeskActivationChanges() {
        val wct = WindowContainerTransaction()
        whenever(mockDesktopRepository.getActiveDeskId(any())).thenReturn(null)
        whenever(mockDesktopRepository.isAnyDeskActive(eq(taskInfo.displayId))).thenReturn(false)
        whenever(mockPipDesktopState.isDisplayDesktopFirst(any())).thenReturn(true)
        whenever(mockDesktopRepository.getDefaultDeskId(any())).thenReturn(DESK_ID)

        controller.maybeReparentTaskToDesk(wct, taskInfo.taskId)

        verify(mockDesktopTasksController)
            .addDeskActivationChanges(
                deskId = DESK_ID,
                wct = wct,
                newTask = taskInfo,
                displayId = taskInfo.displayId,
            )
        verify(mockDesktopTasksController)
            .addMoveToDeskTaskChanges(wct = wct, task = taskInfo, deskId = DESK_ID)
    }

    @Test
    fun handlePipTransition_noDeskActive_doesntPerformDesktopExitCleanup() {
        whenever(mockDesktopRepository.isAnyDeskActive(eq(taskInfo.displayId))).thenReturn(false)