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

Commit 7b588fe2 authored by Pragya Bajoria's avatar Pragya Bajoria
Browse files

Refactor DesktopTasksController to update logic for moving task to desktop mode.

- Move allFocusedTasks to a private function
- Move splitFocusedTask to a private function
- Move moveToDesktopFromNonRunningTask to moveBackgroundTaskToDesktop
- Move addMoveToDesktopChangesNonRunningTask to updateDesktopTasksToFront
- Move moveToDesktop to moveRunningTaskToDesktop

Change-Id: I20f50bdcfbed68ab522ec6f10d5554a36716ef20
Bug: 332682201
Flag: EXEMPT (no-op for functionality)
Test: atest DesktopTasksControllerTest
parent 86be86aa
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -63,8 +63,7 @@ class DesktopModeShellCommandHandler(private val controller: DesktopTasksControl
                pw.println("Error: task id should be an integer")
                return false
            }

        return controller.moveToDesktop(taskId, transitionSource = UNKNOWN)
        return controller.moveTaskToDesktop(taskId, transitionSource = UNKNOWN)
    }

    private fun runMoveToNextDisplay(args: Array<String>, pw: PrintWriter): Boolean {
+63 −62
Original line number Diff line number Diff line
@@ -255,81 +255,82 @@ class DesktopTasksController(
    /** Returns true if any tasks are visible in Desktop Mode. */
    fun isDesktopModeShowing(displayId: Int): Boolean = visibleTaskCount(displayId) > 0

    /** Enter desktop by using the focused task in given `displayId` */
    /** Moves focused task to desktop mode for given [displayId]. */
    fun moveFocusedTaskToDesktop(displayId: Int, transitionSource: DesktopModeTransitionSource) {
        val allFocusedTasks =
            shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo ->
                taskInfo.isFocused &&
                    (taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
                        taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
                    taskInfo.activityType != ACTIVITY_TYPE_HOME
            }
        if (allFocusedTasks.isNotEmpty()) {
        val allFocusedTasks = getAllFocusedTasks(displayId)
        when (allFocusedTasks.size) {
                2 -> {
            0 -> return
            // Full screen case
            1 -> moveRunningTaskToDesktop(
                allFocusedTasks.single(), transitionSource = transitionSource)
            // Split-screen case where there are two focused tasks, then we find the child
            // task to move to desktop.
                    val splitFocusedTask =
                        if (allFocusedTasks[0].taskId == allFocusedTasks[1].parentTaskId) {
                            allFocusedTasks[1]
                        } else {
                            allFocusedTasks[0]
                        }
                    moveToDesktop(splitFocusedTask, transitionSource = transitionSource)
                }
                1 -> {
                    // Fullscreen case where we move the current focused task.
                    moveToDesktop(allFocusedTasks[0].taskId, transitionSource = transitionSource)
                }
                else -> logW("Cannot enter desktop, expected < 3 focused tasks, found %d",
                    allFocusedTasks.size)
            2 -> moveRunningTaskToDesktop(
                getSplitFocusedTask(allFocusedTasks[0], allFocusedTasks[1]),
                    transitionSource = transitionSource)
            else -> logW(
                "DesktopTasksController: Cannot enter desktop, expected less " +
                "than 3 focused tasks but found %d", allFocusedTasks.size)
        }
    }

    /**
     * Returns all focused tasks in full screen or split screen mode in [displayId] when
     * it is not the home activity.
     */
    private fun getAllFocusedTasks(displayId: Int): List<RunningTaskInfo> =
        shellTaskOrganizer.getRunningTasks(displayId).filter {
            it.isFocused &&
            (it.windowingMode == WINDOWING_MODE_FULLSCREEN ||
                it.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
            it.activityType != ACTIVITY_TYPE_HOME
        }

    /** Move a task with given `taskId` to desktop */
    fun moveToDesktop(
    /** Returns child task from two focused tasks in split screen mode. */
    private fun getSplitFocusedTask(task1: RunningTaskInfo, task2: RunningTaskInfo) =
        if (task1.taskId == task2.parentTaskId) task2 else task1

    /** Moves task to desktop mode if task is running, else launches it in desktop mode. */
    fun moveTaskToDesktop(
        taskId: Int,
        wct: WindowContainerTransaction = WindowContainerTransaction(),
        transitionSource: DesktopModeTransitionSource,
    ): Boolean {
        shellTaskOrganizer.getRunningTaskInfo(taskId)?.let {
            moveToDesktop(it, wct, transitionSource)
        val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId)
        if (runningTask == null) {
            return moveBackgroundTaskToDesktop(taskId, wct, transitionSource)
        }
            ?: moveToDesktopFromNonRunningTask(taskId, wct, transitionSource)
        moveRunningTaskToDesktop(runningTask, wct, transitionSource)
        return true
    }

    private fun moveToDesktopFromNonRunningTask(
    private fun moveBackgroundTaskToDesktop(
            taskId: Int,
            wct: WindowContainerTransaction,
            transitionSource: DesktopModeTransitionSource,
    ): Boolean {
        recentTasksController?.findTaskInBackground(taskId)?.let {
            logV("moveToDesktopFromNonRunningTask with taskId=%d, displayId=%d", taskId)
        if (recentTasksController?.findTaskInBackground(taskId) == null) {
            logW("moveBackgroundTaskToDesktop taskId=%d not found", taskId)
            return false
        }
        logV("moveBackgroundTaskToDesktop with taskId=%d, displayId=%d", taskId)
        // TODO(342378842): Instead of using default display, support multiple displays
            val taskToMinimize =
                bringDesktopAppsToFrontBeforeShowingNewTask(DEFAULT_DISPLAY, wct, taskId)
            addMoveToDesktopChangesNonRunningTask(wct, taskId)
        val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(
            DEFAULT_DISPLAY, wct, taskId)
        wct.startTask(
            taskId,
            ActivityOptions.makeBasic().apply {
                launchWindowingMode = WINDOWING_MODE_FREEFORM
            }.toBundle(),
        )
        // TODO(343149901): Add DPI changes for task launch
        val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
        addPendingMinimizeTransition(transition, taskToMinimize)
        return true
    }
            ?: return false
    }

    private fun addMoveToDesktopChangesNonRunningTask(
        wct: WindowContainerTransaction,
        taskId: Int
    ) {
        val options = ActivityOptions.makeBasic()
        options.launchWindowingMode = WINDOWING_MODE_FREEFORM
        wct.startTask(taskId, options.toBundle())
    }

    /** Move a task to desktop */
    fun moveToDesktop(
   /** Moves a running task to desktop. */
    fun moveRunningTaskToDesktop(
        task: RunningTaskInfo,
        wct: WindowContainerTransaction = WindowContainerTransaction(),
        transitionSource: DesktopModeTransitionSource,
@@ -339,7 +340,7 @@ class DesktopTasksController(
            logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId)
            return
        }
        logV("moveToDesktop taskId=%d", task.taskId)
        logV("moveRunningTaskToDesktop taskId=%d", task.taskId)
        exitSplitIfApplicable(wct, task)
        // Bring other apps to front first
        val taskToMinimize =
@@ -1519,8 +1520,8 @@ class DesktopTasksController(
        }

        override fun moveToDesktop(taskId: Int, transitionSource: DesktopModeTransitionSource) {
            executeRemoteCallWithTaskPermission(controller, "moveToDesktop") { c ->
                c.moveToDesktop(taskId, transitionSource = transitionSource)
            executeRemoteCallWithTaskPermission(controller, "moveTaskToDesktop") { c ->
                c.moveTaskToDesktop(taskId, transitionSource = transitionSource)
            }
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -512,7 +512,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                mInteractionJankMonitor.begin(decoration.mTaskSurface, mContext,
                        CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU);
                mWindowDecorByTaskId.get(mTaskId).addCaptionInset(wct);
                mDesktopTasksController.moveToDesktop(mTaskId, wct,
                mDesktopTasksController.moveTaskToDesktop(mTaskId, wct,
                        DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON);
                decoration.closeHandleMenu();
            } else if (id == R.id.fullscreen_button) {
+32 −32
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
  }

  @Test
  fun instantiate_canNotEnterDesktopMode_doNotAddInitCallback() {
  fun instantiate_cannotEnterDesktopMode_doNotAddInitCallback() {
    whenever(DesktopModeStatus.canEnterDesktopMode(context)).thenReturn(false)
    clearInvocations(shellInit)

@@ -752,36 +752,36 @@ class DesktopTasksControllerTest : ShellTestCase() {
    val task = setUpFullscreenTask()
    val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
    tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
  }

  @Test
  fun moveToDesktop_tdaFreeform_windowingModeSetToUndefined() {
  fun moveRunningTaskToDesktop_tdaFreeform_windowingModeSetToUndefined() {
    val task = setUpFullscreenTask()
    val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
    tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
        .isEqualTo(WINDOWING_MODE_UNDEFINED)
  }

  @Test
  fun moveToDesktop_nonExistentTask_doesNothing() {
    controller.moveToDesktop(999, transitionSource = UNKNOWN)
  fun moveTaskToDesktop_nonExistentTask_doesNothing() {
    controller.moveTaskToDesktop(999, transitionSource = UNKNOWN)
    verifyEnterDesktopWCTNotExecuted()
  }

  @Test
  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_desktopWallpaperDisabled_nonRunningTask_launchesInFreeform() {
  fun moveTaskToDesktop_desktopWallpaperDisabled_nonRunningTask_launchesInFreeform() {
    val task = createTaskInfo(1)
    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
    whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)

    controller.moveToDesktop(task.taskId, transitionSource = UNKNOWN)
    controller.moveTaskToDesktop(task.taskId, transitionSource = UNKNOWN)

    with(getLatestEnterDesktopWct()) {
      assertLaunchTaskAt(0, task.taskId, WINDOWING_MODE_FREEFORM)
@@ -790,12 +790,12 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_desktopWallpaperEnabled_nonRunningTask_launchesInFreeform() {
  fun moveTaskToDesktop_desktopWallpaperEnabled_nonRunningTask_launchesInFreeform() {
    val task = createTaskInfo(1)
    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
    whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)

    controller.moveToDesktop(task.taskId, transitionSource = UNKNOWN)
    controller.moveTaskToDesktop(task.taskId, transitionSource = UNKNOWN)

    with(getLatestEnterDesktopWct()) {
      // Add desktop wallpaper activity
@@ -807,7 +807,7 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
  fun moveToDesktop_topActivityTranslucentWithStyleFloating_taskIsMovedToDesktop() {
  fun moveRunningTaskToDesktop_topActivityTranslucentWithStyleFloating_taskIsMovedToDesktop() {
    val task =
      setUpFullscreenTask().apply {
        isTopActivityTransparent = true
@@ -815,7 +815,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
        numActivities = 1
      }

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)

    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
@@ -823,7 +823,7 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
  fun moveToDesktop_topActivityTranslucentWithoutStyleFloating_doesNothing() {
  fun moveRunningTaskToDesktop_topActivityTranslucentWithoutStyleFloating_doesNothing() {
    val task =
      setUpFullscreenTask().apply {
        isTopActivityTransparent = true
@@ -831,13 +831,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
        numActivities = 1
      }

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    verifyEnterDesktopWCTNotExecuted()
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
  fun moveToDesktop_systemUIActivity_doesNothing() {
  fun moveRunningTaskToDesktop_systemUIActivity_doesNothing() {
    val task = setUpFullscreenTask()

    // Set task as systemUI package
@@ -846,15 +846,15 @@ class DesktopTasksControllerTest : ShellTestCase() {
    val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
    task.baseActivity = baseComponent

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    verifyEnterDesktopWCTNotExecuted()
  }

  @Test
  fun moveToDesktop_deviceSupported_taskIsMovedToDesktop() {
  fun moveRunningTaskToDesktop_deviceSupported_taskIsMovedToDesktop() {
    val task = setUpFullscreenTask()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)

    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
@@ -862,13 +862,13 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperDisabled() {
  fun moveRunningTaskToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperDisabled() {
    val homeTask = setUpHomeTask()
    val freeformTask = setUpFreeformTask()
    val fullscreenTask = setUpFullscreenTask()
    markTaskHidden(freeformTask)

    controller.moveToDesktop(fullscreenTask, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(fullscreenTask, transitionSource = UNKNOWN)

    with(getLatestEnterDesktopWct()) {
      // Operations should include home task, freeform task
@@ -881,12 +881,12 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperEnabled() {
  fun moveRunningTaskToDesktop_otherFreeformTasksBroughtToFront_desktopWallpaperEnabled() {
    val freeformTask = setUpFreeformTask()
    val fullscreenTask = setUpFullscreenTask()
    markTaskHidden(freeformTask)

    controller.moveToDesktop(fullscreenTask, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(fullscreenTask, transitionSource = UNKNOWN)

    with(getLatestEnterDesktopWct()) {
      // Operations should include wallpaper intent, freeform task, fullscreen task
@@ -900,7 +900,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
  }

  @Test
  fun moveToDesktop_onlyFreeformTasksFromCurrentDisplayBroughtToFront() {
  fun moveRunningTaskToDesktop_onlyFreeformTasksFromCurrentDisplayBroughtToFront() {
    setUpHomeTask(displayId = DEFAULT_DISPLAY)
    val freeformTaskDefault = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
    val fullscreenTaskDefault = setUpFullscreenTask(displayId = DEFAULT_DISPLAY)
@@ -910,7 +910,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
    val freeformTaskSecond = setUpFreeformTask(displayId = SECOND_DISPLAY)
    markTaskHidden(freeformTaskSecond)

    controller.moveToDesktop(fullscreenTaskDefault, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(fullscreenTaskDefault, transitionSource = UNKNOWN)

    with(getLatestEnterDesktopWct()) {
      // Check that hierarchy operations do not include tasks from second display
@@ -921,9 +921,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
  }

  @Test
  fun moveToDesktop_splitTaskExitsSplit() {
  fun moveRunningTaskToDesktop_splitTaskExitsSplit() {
    val task = setUpSplitScreenTask()
    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
    verify(splitScreenController)
@@ -931,9 +931,9 @@ class DesktopTasksControllerTest : ShellTestCase() {
  }

  @Test
  fun moveToDesktop_fullscreenTaskDoesNotExitSplit() {
  fun moveRunningTaskToDesktop_fullscreenTaskDoesNotExitSplit() {
    val task = setUpFullscreenTask()
    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
    verify(splitScreenController, never())
@@ -942,12 +942,12 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_desktopWallpaperDisabled_bringsTasksOver_dontShowBackTask() {
  fun moveRunningTaskToDesktop_desktopWallpaperDisabled_bringsTasksOver_dontShowBackTask() {
    val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
    val newTask = setUpFullscreenTask()
    val homeTask = setUpHomeTask()

    controller.moveToDesktop(newTask, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(newTask, transitionSource = UNKNOWN)

    val wct = getLatestEnterDesktopWct()
    assertThat(wct.hierarchyOps.size).isEqualTo(MAX_TASK_LIMIT + 1) // visible tasks + home
@@ -960,12 +960,12 @@ class DesktopTasksControllerTest : ShellTestCase() {

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
  fun moveToDesktop_desktopWallpaperEnabled_bringsTasksOverLimit_dontShowBackTask() {
  fun moveRunningTaskToDesktop_desktopWallpaperEnabled_bringsTasksOverLimit_dontShowBackTask() {
    val freeformTasks = (1..MAX_TASK_LIMIT).map { _ -> setUpFreeformTask() }
    val newTask = setUpFullscreenTask()
    val homeTask = setUpHomeTask()

    controller.moveToDesktop(newTask, transitionSource = UNKNOWN)
    controller.moveRunningTaskToDesktop(newTask, transitionSource = UNKNOWN)

    val wct = getLatestEnterDesktopWct()
    assertThat(wct.hierarchyOps.size).isEqualTo(MAX_TASK_LIMIT + 2) // tasks + home + wallpaper