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

Commit 12d4a095 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[PiP on Desktop] Fix multi-activity PiP switching in and out of Desktop" into main

parents 4833ca66 8854b91f
Loading
Loading
Loading
Loading
+87 −24
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.wm.shell.desktopmode

import android.app.ActivityManager
import android.app.ActivityManager.RunningTaskInfo
import android.app.ActivityTaskManager
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
@@ -71,6 +71,12 @@ class DesktopPipTransitionController(
            if (pipDesktopState.isPipInDesktopMode()) WINDOWING_MODE_FREEFORM
            else WINDOWING_MODE_FULLSCREEN

        logD(
            "maybeUpdateParentInWct: parentTaskId=%d parentWinMode=%d resolvedWinMode=%d",
            parentTask.taskId,
            parentTask.windowingMode,
            resolvedWinMode,
        )
        if (resolvedWinMode != parentTask.windowingMode) {
            wct.setWindowingMode(parentTask.token, resolvedWinMode)
            wct.setBounds(
@@ -78,6 +84,42 @@ class DesktopPipTransitionController(
                if (resolvedWinMode == WINDOWING_MODE_FREEFORM) defaultFreeformBounds else Rect(),
            )
        }
        if (resolvedWinMode == WINDOWING_MODE_FULLSCREEN) {
            maybeAddMoveToFullscreenChanges(wct, parentTask)
        }
    }

    /**
     * In multi-activity PiP case, if the task entering PiP was previously active in a Desk and is
     * now expanding to fullscreen, call [DesktopTasksController#addMoveToFullscreenChanges] for the
     * parent task to properly move the task to fullscreen.
     *
     * @param wct WindowContainerTransaction that will apply these changes
     * @param parentTask the multi-activity PiP parent
     */
    private fun maybeAddMoveToFullscreenChanges(
        wct: WindowContainerTransaction,
        parentTask: RunningTaskInfo,
    ) {
        val desktopRepository = desktopUserRepositories.getProfile(parentTask.userId)
        if (!desktopRepository.isActiveTask(parentTask.taskId)) {
            logW(
                "maybeAddMoveToFullscreenChanges: parentTask with id=%d is not active in any desk",
                parentTask.taskId,
            )
            return
        }

        logD(
            "maybeAddMoveToFullscreenChanges: addMoveToFullscreenChanges, taskId=%d displayId=%d",
            parentTask.taskId,
            parentTask.displayId,
        )
        desktopTasksController.addMoveToFullscreenChanges(
            wct = wct,
            taskInfo = parentTask,
            willExitDesktop = true,
        )
    }

    /**
@@ -118,58 +160,79 @@ class DesktopPipTransitionController(
        if (deskId == INVALID_DESK_ID) return

        val parentTaskId = runningTaskInfo.lastParentTaskIdBeforePip
        var parentTask: RunningTaskInfo? = null
        var shouldAddParentToDesk = false

        // If PiP is multi-activity, we should use the parent task for the rest of this method
        if (parentTaskId != ActivityTaskManager.INVALID_TASK_ID) {
            parentTask = shellTaskOrganizer.getRunningTaskInfo(parentTaskId)
            if (parentTask == null) {
                logW(
                    "maybeReparentTaskToDesk: Failed to find RunningTaskInfo for parentTaskId %d",
                    parentTaskId,
                )
                return
            }
            if (desktopRepository.isActiveTask(parentTaskId)) {
                logD(
                "maybeReparentTaskToDesk: Multi-activity PiP, unminimize parent task in Desk" +
                    " instead of moving PiP task to Desk"
                    "maybeReparentTaskToDesk: Multi-activity PiP with parent taskId=%d already " +
                        "in the Desk, move parent task to front",
                    parentTaskId,
                )
            unminimizeParentInDesk(wct, parentTaskId, deskId)
                moveParentTaskToFront(wct, parentTask, deskId)
                return
            } else {
                logD(
                    "maybeReparentTaskToDesk: Multi-activity PiP with parent taskId=%d not " +
                        "already in the Desk, should add parent to the desk",
                    parentTaskId,
                )
                shouldAddParentToDesk = true
            }
        }

        if (!desktopRepository.isDeskActive(deskId)) {
            logD(
                "maybeReparentTaskToDesk: addDeskActivationChanges, taskId=%d deskId=%d, " +
                    "displayId=%d",
                runningTaskInfo.taskId,
                if (shouldAddParentToDesk) parentTaskId else runningTaskInfo.taskId,
                deskId,
                displayId,
            )
            desktopTasksController.addDeskActivationChanges(
                deskId = deskId,
                wct = wct,
                newTask = runningTaskInfo,
                newTask = if (shouldAddParentToDesk) parentTask!! else runningTaskInfo,
                displayId = displayId,
            )
        }

        logD(
            "maybeReparentTaskToDesk: addMoveToDeskTaskChanges, taskId=%d deskId=%d",
            runningTaskInfo.taskId,
            if (shouldAddParentToDesk) parentTaskId else runningTaskInfo.taskId,
            deskId,
        )
        desktopTasksController.addMoveToDeskTaskChanges(
            wct = wct,
            task = runningTaskInfo,
            task = if (shouldAddParentToDesk) parentTask!! else runningTaskInfo,
            deskId = deskId,
        )
    }

    private fun unminimizeParentInDesk(
    /**
     * In multi-activity PiP case, call [DesktopTasksController#addMoveTaskToFrontChanges] to move
     * the parent task to front within the desk.
     *
     * @param wct WindowContainerTransaction that will apply these changes
     * @param parentTask the parent task
     * @param deskId desk id that the multi-activity PiP parent is in
     */
    private fun moveParentTaskToFront(
        wct: WindowContainerTransaction,
        parentTaskId: Int,
        parentTask: RunningTaskInfo,
        deskId: Int,
    ) {
        val parentTask = shellTaskOrganizer.getRunningTaskInfo(parentTaskId)
        if (parentTask == null) {
            logW(
                "unminimizeParentInDesk: Failed to find RunningTaskInfo for parentTaskId %d",
                parentTaskId,
            )
            return
        }

        logD("unminimizeParentInDesk: parentTaskId=%d deskId=%d", parentTask.taskId, deskId)
        logD("moveParentTaskToFront: parentTaskId=%d deskId=%d", parentTask.taskId, deskId)
        desktopTasksController.addMoveTaskToFrontChanges(
            wct = wct,
            deskId = deskId,
@@ -187,7 +250,7 @@ class DesktopPipTransitionController(
    fun handlePipTransition(
        wct: WindowContainerTransaction,
        transition: IBinder,
        taskInfo: ActivityManager.RunningTaskInfo,
        taskInfo: RunningTaskInfo,
    ) {
        if (!pipDesktopState.isDesktopWindowingPipEnabled()) {
            return
+1 −1
Original line number Diff line number Diff line
@@ -3575,7 +3575,7 @@ class DesktopTasksController(
    }

    /** Applies the changes needed to enter fullscreen and clean up the desktop if needed. */
    private fun addMoveToFullscreenChanges(
    fun addMoveToFullscreenChanges(
        wct: WindowContainerTransaction,
        taskInfo: TaskInfo,
        willExitDesktop: Boolean,
+21 −5
Original line number Diff line number Diff line
@@ -174,14 +174,16 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
        controller.maybeReparentTaskToDesk(wct, taskInfo.taskId)

        verify(mockDesktopTasksController, never())
            .addMoveToDeskTaskChanges(wct = wct, task = taskInfo, deskId = DESK_ID)
            .addMoveToDeskTaskChanges(wct = any(), task = any(), deskId = any())
    }

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_multiActivity_addMoveTaskToFrontChanges() {
    fun maybeReparentTaskToDesk_multiActivity_parentInDesk_addMoveTaskToFrontChanges() {
        val wct = WindowContainerTransaction()
        taskInfo.lastParentTaskIdBeforePip = freeformParentTask.taskId
        val parentTaskId = freeformParentTask.taskId
        taskInfo.lastParentTaskIdBeforePip = parentTaskId
        whenever(mockDesktopRepository.isActiveTask(parentTaskId)).thenReturn(true)

        controller.maybeReparentTaskToDesk(wct, taskInfo.taskId)

@@ -189,6 +191,20 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
            .addMoveTaskToFrontChanges(wct = wct, deskId = DESK_ID, taskInfo = freeformParentTask)
    }

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_multiActivity_parentNotInDesk_addMoveToDeskTaskChanges() {
        val wct = WindowContainerTransaction()
        val parentTaskId = freeformParentTask.taskId
        taskInfo.lastParentTaskIdBeforePip = parentTaskId
        whenever(mockDesktopRepository.isActiveTask(parentTaskId)).thenReturn(false)

        controller.maybeReparentTaskToDesk(wct, taskInfo.taskId)

        verify(mockDesktopTasksController)
            .addMoveToDeskTaskChanges(wct = wct, task = freeformParentTask, deskId = DESK_ID)
    }

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_noDeskActive_noAddMoveToDeskTaskChanges() {
@@ -198,7 +214,7 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe
        controller.maybeReparentTaskToDesk(wct, taskInfo.taskId)

        verify(mockDesktopTasksController, never())
            .addMoveToDeskTaskChanges(wct = wct, task = taskInfo, deskId = DESK_ID)
            .addMoveToDeskTaskChanges(wct = any(), task = any(), deskId = any())
    }

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
@@ -214,7 +230,7 @@ class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTe

    @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
    @Test
    fun maybeReparentTaskToDesk_desktopFirstDisplay_addDeskActivationChanges() {
    fun maybeReparentTaskToDesk_noDeskActive_desktopFirstDisplay_addDeskActivationChanges() {
        val wct = WindowContainerTransaction()
        whenever(mockDesktopRepository.getActiveDeskId(any())).thenReturn(null)
        whenever(mockPipDesktopState.isDisplayDesktopFirst(any())).thenReturn(true)