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

Commit 7a572dc3 authored by Orhan Uysal's avatar Orhan Uysal
Browse files

Handle mid recents transition in desktop

When a freeform launch happens during the middle of the recents
transition, we should handle it so that the task gets launched in
fullscreen instead of in desktop.

Fix: 327447672
Fix: 354171747
Flag: EXEMPT Bugfix
Test: atest DesktopTasksControllerTest
Change-Id: If6192975e1d25fbdac774e9bbf71f6828e194e44
parent 1ef1c0b8
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -819,8 +819,12 @@ class DesktopTasksController(
        // Check if we should skip handling this transition
        var reason = ""
        val triggerTask = request.triggerTask
        var shouldHandleMidRecentsFreeformLaunch =
            recentsAnimationRunning && isFreeformRelaunch(triggerTask, request)
        val shouldHandleRequest =
            when {
                // Handle freeform relaunch during recents animation
                shouldHandleMidRecentsFreeformLaunch -> true
                recentsAnimationRunning -> {
                    reason = "recents animation is running"
                    false
@@ -860,6 +864,8 @@ class DesktopTasksController(
        val result =
            triggerTask?.let { task ->
                when {
                    // Check if freeform task launch during recents should be handled
                    shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task)
                    // Check if the closing task needs to be handled
                    TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
                    // Check if the top task shouldn't be allowed to enter desktop mode
@@ -893,6 +899,12 @@ class DesktopTasksController(
            .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
    }

    /** Returns whether an existing desktop task is being relaunched in freeform or not. */
    private fun isFreeformRelaunch(triggerTask: RunningTaskInfo?, request: TransitionRequestInfo) =
        (triggerTask != null && triggerTask.windowingMode == WINDOWING_MODE_FREEFORM
                && TransitionUtil.isOpeningType(request.type)
                && taskRepository.isActiveTask(triggerTask.taskId))

    private fun isIncompatibleTask(task: TaskInfo) =
        DesktopModeFlags.MODALS_POLICY.isEnabled(context)
                && isTopActivityExemptFromDesktopWindowing(context, task)
@@ -957,6 +969,21 @@ class DesktopTasksController(
        }
    }

    /**
     * Handles the case where a freeform task is launched from recents.
     *
     * This is a special case where we want to launch the task in fullscreen instead of freeform.
     */
    private fun handleMidRecentsFreeformTaskLaunch(
        task: RunningTaskInfo
    ): WindowContainerTransaction? {
        logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch")
        val wct = WindowContainerTransaction()
        addMoveToFullscreenChanges(wct, task)
        wct.reorder(task.token, true)
        return wct
    }

    private fun handleFreeformTaskLaunch(
        task: RunningTaskInfo,
        transition: IBinder
+16 −0
Original line number Diff line number Diff line
@@ -19,12 +19,14 @@ package com.android.wm.shell.recents;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
import static android.view.WindowManager.TRANSIT_PIP;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;

import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_CAN_HAND_OFF_ANIMATION;
@@ -775,6 +777,20 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
                    // Don't consider order-only & non-leaf changes as changing apps.
                    if (!TransitionUtil.isOrderOnly(change) && isLeafTask) {
                        hasChangingApp = true;
                        // Check if the changing app is moving to top and fullscreen. This handles
                        // the case where we moved from desktop to recents and launching a desktop
                        // task in fullscreen.
                        if ((change.getFlags() & FLAG_MOVED_TO_TOP) != 0
                                && taskInfo != null
                                && taskInfo.getWindowingMode()
                                == WINDOWING_MODE_FULLSCREEN) {
                            if (openingTasks == null) {
                                openingTasks = new ArrayList<>();
                                openingTaskIsLeafs = new IntArray();
                            }
                            openingTasks.add(change);
                            openingTaskIsLeafs.add(1);
                        }
                    } else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME
                            && !isRecentsTask ) {
                        // Unless it is a 3p launcher. This means that the 3p launcher was already
+15 −0
Original line number Diff line number Diff line
@@ -1565,6 +1565,21 @@ class DesktopTasksControllerTest : ShellTestCase() {
    assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
  }

  @Test
  fun handleRequest_recentsAnimationRunning_relaunchActiveTask_taskBecomesUndefined() {
    // Set up a visible freeform task
    val freeformTask = setUpFreeformTask()
    markTaskVisible(freeformTask)

    // Mark recents animation running
    recentsTransitionStateListener.onAnimationStateChanged(true)

    // Should become undefined as the TDA is set to fullscreen. It will inherit from the TDA.
    val result = controller.handleRequest(Binder(), createTransition(freeformTask))
    assertThat(result?.changes?.get(freeformTask.token.asBinder())?.windowingMode)
      .isEqualTo(WINDOWING_MODE_UNDEFINED)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
  fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() {