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

Commit 874cbb14 authored by Jorge Gil's avatar Jorge Gil
Browse files

Add mixed transition for to-front with immersive exit

When a task is brought to front over a desktop-immersive task, the
immersive task exits (resizes back to its original bounds) in that same
transition. To animate that change using the DesktopImmersiveController
animations, the transition is moved to the mixed handler to delegate
that change and keep any other changes animated by the default handler.

Flag: com.android.window.flags.enable_fully_immersive_in_desktop
Bug: 372319492
Video: http://recall/-/MhxArsavh2DYsjdkHA7z7/Zma0YC46L9Tw1f0jEBYTz
Test: open Freefire and the Play Store in desktop, put Freefire into
immersive, then bring the store to the front from the taskbar. Verify
the Freefire exits immersive with a veiled bounds animation.

Change-Id: I348ccfbb5129344725e3ad738d9e86d03c6fbb5f
parent c624da5f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ public abstract class WMShellModule {
            Transitions transitions,
            KeyguardManager keyguardManager,
            ReturnToDragStartAnimator returnToDragStartAnimator,
            Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
            EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
            ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
            DesktopModeDragAndDropTransitionHandler desktopModeDragAndDropTransitionHandler,
@@ -736,6 +737,7 @@ public abstract class WMShellModule {
                transitions,
                keyguardManager,
                returnToDragStartAnimator,
                desktopMixedTransitionHandler.get(),
                enterDesktopTransitionHandler,
                exitDesktopTransitionHandler,
                desktopModeDragAndDropTransitionHandler,
@@ -960,6 +962,7 @@ public abstract class WMShellModule {
            @DynamicOverride DesktopRepository desktopRepository,
            FreeformTaskTransitionHandler freeformTaskTransitionHandler,
            CloseDesktopTaskTransitionHandler closeDesktopTaskTransitionHandler,
            Optional<DesktopImmersiveController> desktopImmersiveController,
            InteractionJankMonitor interactionJankMonitor,
            @ShellMainThread Handler handler) {
        if (!DesktopModeStatus.canEnterDesktopMode(context)) {
@@ -972,6 +975,7 @@ public abstract class WMShellModule {
                        desktopRepository,
                        freeformTaskTransitionHandler,
                        closeDesktopTaskTransitionHandler,
                        desktopImmersiveController.get(),
                        interactionJankMonitor,
                        handler));
    }
+42 −17
Original line number Diff line number Diff line
@@ -130,7 +130,8 @@ class DesktopImmersiveController(
        displayId: Int
    ) {
        if (!Flags.enableFullyImmersiveInDesktop()) return
        exitImmersiveIfApplicable(wct, displayId)?.invoke(transition)
        val result = exitImmersiveIfApplicable(wct, displayId)
        result.asExit()?.runOnTransitionStart?.invoke(transition)
    }

    /**
@@ -145,16 +146,23 @@ class DesktopImmersiveController(
        wct: WindowContainerTransaction,
        displayId: Int,
        excludeTaskId: Int? = null,
    ): ((IBinder) -> Unit)? {
        if (!Flags.enableFullyImmersiveInDesktop()) return null
        val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId) ?: return null
    ): ExitResult {
        if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
        val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId)
            ?: return ExitResult.NoExit
        if (immersiveTask == excludeTaskId) {
            return null
            return ExitResult.NoExit
        }
        val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask) ?: return null
        val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask)
            ?: return ExitResult.NoExit
        logV("Appending immersive exit for task: $immersiveTask in display: $displayId")
        wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
        return { transition -> addPendingImmersiveExit(immersiveTask, displayId, transition) }
        return ExitResult.Exit(
            exitingTask = immersiveTask,
            runOnTransitionStart = { transition ->
                addPendingImmersiveExit(immersiveTask, displayId, transition)
            }
        )
    }

    /**
@@ -167,22 +175,25 @@ class DesktopImmersiveController(
    fun exitImmersiveIfApplicable(
        wct: WindowContainerTransaction,
        taskInfo: RunningTaskInfo
    ): ((IBinder) -> Unit)? {
        if (!Flags.enableFullyImmersiveInDesktop()) return null
    ): ExitResult {
        if (!Flags.enableFullyImmersiveInDesktop()) return ExitResult.NoExit
        if (desktopRepository.isTaskInFullImmersiveState(taskInfo.taskId)) {
            // A full immersive task is being minimized, make sure the immersive state is broken
            // (i.e. resize back to max bounds).
            wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo))
            logV("Appending immersive exit for task: ${taskInfo.taskId}")
            return { transition ->
            return ExitResult.Exit(
                exitingTask = taskInfo.taskId,
                runOnTransitionStart = { transition ->
                    addPendingImmersiveExit(
                        taskId = taskInfo.taskId,
                        displayId = taskInfo.displayId,
                        transition = transition
                    )
                }
            )
        }
        return null
        return ExitResult.NoExit
    }


@@ -461,6 +472,20 @@ class DesktopImmersiveController(
        var transition: IBinder,
    )

    /** The result of an external exit request. */
    sealed class ExitResult {
        /** An immersive task exit (meaning, resize) was appended to the request. */
        data class Exit(
            val exitingTask: Int,
            val runOnTransitionStart: ((IBinder) -> Unit)
        ) : ExitResult()
        /** There was no exit appended to the request. */
        data object NoExit : ExitResult()

        /** Returns the result as an [Exit] or null if it isn't of that type. */
        fun asExit(): Exit? = if (this is Exit) this else null
    }

    private enum class Direction {
        ENTER, EXIT
    }
+202 −4
Original line number Diff line number Diff line
@@ -27,15 +27,18 @@ import android.window.DesktopModeFlags
import android.window.TransitionInfo
import android.window.TransitionRequestInfo
import android.window.WindowContainerTransaction
import androidx.annotation.VisibleForTesting
import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags
import com.android.wm.shell.freeform.FreeformTaskTransitionHandler
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.transition.MixedTransitionHandler
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TransitionFinishCallback

/** The [Transitions.TransitionHandler] coordinates transition handlers in desktop windowing. */
class DesktopMixedTransitionHandler(
@@ -44,10 +47,14 @@ class DesktopMixedTransitionHandler(
    private val desktopRepository: DesktopRepository,
    private val freeformTaskTransitionHandler: FreeformTaskTransitionHandler,
    private val closeDesktopTaskTransitionHandler: CloseDesktopTaskTransitionHandler,
    private val desktopImmersiveController: DesktopImmersiveController,
    private val interactionJankMonitor: InteractionJankMonitor,
    @ShellMainThread private val handler: Handler,
) : MixedTransitionHandler, FreeformTaskTransitionStarter {

    @VisibleForTesting
    val pendingMixedTransitions = mutableListOf<PendingMixedTransition>()

    /** Delegates starting transition to [FreeformTaskTransitionHandler]. */
    override fun startWindowingModeTransition(
        targetWindowingMode: Int,
@@ -65,6 +72,40 @@ class DesktopMixedTransitionHandler(
        }
        requireNotNull(wct)
        return transitions.startTransition(WindowManager.TRANSIT_CLOSE, wct, /* handler= */ this)
            .also { transition ->
                pendingMixedTransitions.add(PendingMixedTransition.Close(transition))
            }
    }

    /**
     * Starts a launch transition for [taskId], with an optional [exitingImmersiveTask] if it was
     * included in the [wct] and is expected to be animated by this handler.
     */
    fun startLaunchTransition(
        @WindowManager.TransitionType transitionType: Int,
        wct: WindowContainerTransaction,
        taskId: Int,
        exitingImmersiveTask: Int? = null,
    ): IBinder {
        if (!Flags.enableFullyImmersiveInDesktop()) {
            return transitions.startTransition(transitionType, wct, /* handler= */ null)
        }
        if (exitingImmersiveTask == null) {
            logV("Starting mixed launch transition for task#%d", taskId)
        } else {
            logV(
                "Starting mixed launch transition for task#%d with immersive exit of task#%d",
                taskId, exitingImmersiveTask
            )
        }
        return transitions.startTransition(transitionType, wct, /* handler= */ this)
            .also { transition ->
                pendingMixedTransitions.add(PendingMixedTransition.Launch(
                    transition = transition,
                    launchingTask = taskId,
                    exitingImmersiveTask = exitingImmersiveTask
                ))
            }
    }

    /** Returns null, as it only handles transitions started from Shell. */
@@ -78,11 +119,43 @@ class DesktopMixedTransitionHandler(
        info: TransitionInfo,
        startTransaction: SurfaceControl.Transaction,
        finishTransaction: SurfaceControl.Transaction,
        finishCallback: Transitions.TransitionFinishCallback,
        finishCallback: TransitionFinishCallback,
    ): Boolean {
        val pending = pendingMixedTransitions.find { pending -> pending.transition == transition }
            ?: return false.also {
                logW("Should have pending desktop transition")
            }
        pendingMixedTransitions.remove(pending)
        logV("Animating pending mixed transition: %s", pending)
        return when (pending) {
            is PendingMixedTransition.Close -> animateCloseTransition(
                transition,
                info,
                startTransaction,
                finishTransaction,
                finishCallback
            )
            is PendingMixedTransition.Launch -> animateLaunchTransition(
                pending,
                transition,
                info,
                startTransaction,
                finishTransaction,
                finishCallback
            )
        }
    }

    private fun animateCloseTransition(
        transition: IBinder,
        info: TransitionInfo,
        startTransaction: SurfaceControl.Transaction,
        finishTransaction: SurfaceControl.Transaction,
        finishCallback: TransitionFinishCallback,
    ): Boolean {
        val closeChange = findCloseDesktopTaskChange(info)
        if (closeChange == null) {
            ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: Should have closing desktop task", TAG)
            logW("Should have closing desktop task")
            return false
        }
        if (isLastDesktopTask(closeChange)) {
@@ -106,6 +179,74 @@ class DesktopMixedTransitionHandler(
        )
    }

    private fun animateLaunchTransition(
        pending: PendingMixedTransition.Launch,
        transition: IBinder,
        info: TransitionInfo,
        startTransaction: SurfaceControl.Transaction,
        finishTransaction: SurfaceControl.Transaction,
        finishCallback: TransitionFinishCallback,
    ): Boolean {
        // Check if there's also an immersive change during this launch.
        val immersiveExitChange = pending.exitingImmersiveTask?.let { exitingTask ->
            findDesktopTaskChange(info, exitingTask)
        }
        val launchChange = findDesktopTaskChange(info, pending.launchingTask)
            ?: error("Should have pending launching task change")

        var subAnimationCount = -1
        var combinedWct: WindowContainerTransaction? = null
        val finishCb = TransitionFinishCallback { wct ->
            --subAnimationCount
            combinedWct = combinedWct.merge(wct)
            if (subAnimationCount > 0) return@TransitionFinishCallback
            finishCallback.onTransitionFinished(combinedWct)
        }

        logV(
            "Animating pending mixed launch transition task#%d immersiveExitTask#%s",
            launchChange.taskInfo!!.taskId, immersiveExitChange?.taskInfo?.taskId
        )
        if (immersiveExitChange != null) {
            subAnimationCount = 2
            // Animate the immersive exit change separately.
            info.changes.remove(immersiveExitChange)
            desktopImmersiveController.animateResizeChange(
                immersiveExitChange,
                startTransaction,
                finishTransaction,
                finishCb
            )
            // Let the leftover/default handler animate the remaining changes.
            return dispatchToLeftoverHandler(
                transition,
                info,
                startTransaction,
                finishTransaction,
                finishCb
            )
        }
        // There's nothing to animate separately, so let the left over handler animate
        // the entire transition.
        subAnimationCount = 1
        return dispatchToLeftoverHandler(
            transition,
            info,
            startTransaction,
            finishTransaction,
            finishCb
        )
    }

    override fun onTransitionConsumed(
        transition: IBinder,
        aborted: Boolean,
        finishTransaction: SurfaceControl.Transaction?
    ) {
        pendingMixedTransitions.removeAll { pending -> pending.transition == transition }
        super.onTransitionConsumed(transition, aborted, finishTransaction)
    }

    /**
     * Dispatch close desktop task animation to the default transition handlers. Allows delegating
     * it to Launcher to animate in sync with show Home transition.
@@ -126,14 +267,34 @@ class DesktopMixedTransitionHandler(
            CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE,
        )
        // Dispatch the last desktop task closing animation.
        return dispatchToLeftoverHandler(
            transition = transition,
            info = info,
            startTransaction = startTransaction,
            finishTransaction = finishTransaction,
            finishCallback = finishCallback,
            doOnFinishCallback = {
                // Finish the jank trace when closing the last window in desktop mode.
                interactionJankMonitor.end(CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE)
            }
        )
    }

    private fun dispatchToLeftoverHandler(
        transition: IBinder,
        info: TransitionInfo,
        startTransaction: SurfaceControl.Transaction,
        finishTransaction: SurfaceControl.Transaction,
        finishCallback: TransitionFinishCallback,
        doOnFinishCallback: (() -> Unit)? = null,
    ): Boolean {
        return transitions.dispatchTransition(
            transition,
            info,
            startTransaction,
            finishTransaction,
            { wct ->
                // Finish the jank trace when closing the last window in desktop mode.
                interactionJankMonitor.end(CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE)
                doOnFinishCallback?.invoke()
                finishCallback.onTransitionFinished(wct)
            },
            /* skip= */ this
@@ -155,6 +316,43 @@ class DesktopMixedTransitionHandler(
        }
    }

    private fun findDesktopTaskChange(info: TransitionInfo, taskId: Int): TransitionInfo.Change? {
        return info.changes.firstOrNull { change -> change.taskInfo?.taskId == taskId }
    }

    private fun WindowContainerTransaction?.merge(
        wct: WindowContainerTransaction?
    ): WindowContainerTransaction? {
        if (wct == null) return this
        if (this == null) return wct
        return this.merge(wct)
    }

    /** A scheduled transition that will potentially be animated by more than one handler */
    sealed class PendingMixedTransition {
        abstract val transition: IBinder

        /** A task is closing. */
        data class Close(
            override val transition: IBinder,
        ) : PendingMixedTransition()

        /** A task is opening or moving to front. */
        data class Launch(
            override val transition: IBinder,
            val launchingTask: Int,
            val exitingImmersiveTask: Int?,
        ) : PendingMixedTransition()
    }

    private fun logV(msg: String, vararg arguments: Any?) {
        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
    }

    private fun logW(msg: String, vararg arguments: Any?) {
        ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
    }

    companion object {
        private const val TAG = "DesktopMixedTransitionHandler"
    }
+46 −30
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SingleInstanceRemoteListener
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitResult
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.DragStartState
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType
import com.android.wm.shell.desktopmode.DesktopRepository.VisibleTasksListener
@@ -146,6 +147,7 @@ class DesktopTasksController(
    private val transitions: Transitions,
    private val keyguardManager: KeyguardManager,
    private val returnToDragStartAnimator: ReturnToDragStartAnimator,
    private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
    private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
    private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
    private val desktopModeDragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler,
@@ -379,7 +381,7 @@ class DesktopTasksController(
        // TODO(342378842): Instead of using default display, support multiple displays
        val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(
            DEFAULT_DISPLAY, wct, taskId)
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
            wct = wct,
            displayId = DEFAULT_DISPLAY,
            excludeTaskId = taskId,
@@ -393,7 +395,7 @@ class DesktopTasksController(
        // TODO(343149901): Add DPI changes for task launch
        val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
        taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
        runOnTransit?.invoke(transition)
        exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
        return true
    }

@@ -410,7 +412,7 @@ class DesktopTasksController(
        }
        logV("moveRunningTaskToDesktop taskId=%d", task.taskId)
        exitSplitIfApplicable(wct, task)
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
            wct = wct,
            displayId = task.displayId,
            excludeTaskId = task.taskId,
@@ -422,7 +424,7 @@ class DesktopTasksController(

        val transition = enterDesktopTaskTransitionHandler.moveToDesktop(wct, transitionSource)
        taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
        runOnTransit?.invoke(transition)
        exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
    }

    /**
@@ -459,12 +461,12 @@ class DesktopTasksController(
        val taskIdToMinimize =
            bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
        addMoveToDesktopChanges(wct, taskInfo)
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
            wct, taskInfo.displayId)
        val transition = dragToDesktopTransitionHandler.finishDragToDesktopTransition(wct)
        transition?.let {
            taskIdToMinimize?.let { taskId -> addPendingMinimizeTransition(it, taskId) }
            runOnTransit?.invoke(transition)
            exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
        }
    }

@@ -507,7 +509,8 @@ class DesktopTasksController(
                taskId
            )
        )
        return desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
        return desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo).asExit()
            ?.runOnTransitionStart
    }

    fun minimizeTask(taskInfo: RunningTaskInfo) {
@@ -520,7 +523,7 @@ class DesktopTasksController(
            removeWallpaperActivity(wct)
        }
        // Notify immersive handler as it might need to exit immersive state.
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)
        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(wct, taskInfo)

        wct.reorder(taskInfo.token, false)
        val transition = freeformTaskTransitionStarter.startMinimizedModeTransition(wct)
@@ -531,7 +534,7 @@ class DesktopTasksController(
                taskId = taskId
            )
        }
        runOnTransit?.invoke(transition)
        exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
    }

    /** Move a task with given `taskId` to fullscreen */
@@ -627,7 +630,7 @@ class DesktopTasksController(
        logV("moveBackgroundTaskToFront taskId=%s", taskId)
        val wct = WindowContainerTransaction()
        // TODO: b/342378842 - Instead of using default display, support multiple displays
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
        val exitResult = desktopImmersiveController.exitImmersiveIfApplicable(
            wct = wct,
            displayId = DEFAULT_DISPLAY,
            excludeTaskId = taskId,
@@ -638,8 +641,13 @@ class DesktopTasksController(
                launchWindowingMode = WINDOWING_MODE_FREEFORM
            }.toBundle(),
        )
        val transition = startLaunchTransition(TRANSIT_OPEN, wct, taskId, remoteTransition)
        runOnTransit?.invoke(transition)
        val transition = startLaunchTransition(
            TRANSIT_OPEN,
            wct,
            taskId,
            remoteTransition = remoteTransition
        )
        exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
    }

    /**
@@ -658,32 +666,39 @@ class DesktopTasksController(
        }
        val wct = WindowContainerTransaction()
        wct.reorder(taskInfo.token, true /* onTop */, true /* includingParents */)
        val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
        val result = desktopImmersiveController.exitImmersiveIfApplicable(
            wct = wct,
            displayId = taskInfo.displayId,
            excludeTaskId = taskInfo.taskId,
        )
        val transition =
            startLaunchTransition(
                TRANSIT_TO_FRONT,
                wct,
                taskInfo.taskId,
                remoteTransition,
                taskInfo.displayId
        val exitResult = if (result is ExitResult.Exit) { result } else { null }
        val transition = startLaunchTransition(
            transitionType = TRANSIT_TO_FRONT,
            wct = wct,
            taskId = taskInfo.taskId,
            exitingImmersiveTask = exitResult?.exitingTask,
            remoteTransition = remoteTransition,
            displayId = taskInfo.displayId,
        )
        runOnTransit?.invoke(transition)
        exitResult?.runOnTransitionStart?.invoke(transition)
    }

    private fun startLaunchTransition(
        transitionType: Int,
        wct: WindowContainerTransaction,
        taskId: Int,
        remoteTransition: RemoteTransition?,
        exitingImmersiveTask: Int? = null,
        remoteTransition: RemoteTransition? = null,
        displayId: Int = DEFAULT_DISPLAY,
    ): IBinder {
        val taskIdToMinimize = addAndGetMinimizeChanges(displayId, wct, taskId)
        if (remoteTransition == null) {
            val t = transitions.startTransition(transitionType, wct, null /* handler */)
            val t = desktopMixedTransitionHandler.startLaunchTransition(
                transitionType = transitionType,
                wct = wct,
                taskId = taskId,
                exitingImmersiveTask = exitingImmersiveTask,
            )
            taskIdToMinimize?.let { addPendingMinimizeTransition(t, it) }
            return t
        }
@@ -1373,14 +1388,15 @@ class DesktopTasksController(
            wct.startTask(requestedTaskId, options.toBundle())
            val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(
                callingTask.displayId, wct, requestedTaskId)
            val runOnTransit = desktopImmersiveController.exitImmersiveIfApplicable(
            val exitResult = desktopImmersiveController
                .exitImmersiveIfApplicable(
                    wct = wct,
                    displayId = callingTask.displayId,
                    excludeTaskId = requestedTaskId,
                )
            val transition = transitions.startTransition(TRANSIT_OPEN, wct, null)
            taskIdToMinimize?.let { addPendingMinimizeTransition(transition, it) }
            runOnTransit?.invoke(transition)
            exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
        } else {
            val splitPosition = splitScreenController.determineNewInstancePosition(callingTask)
            splitScreenController.startTask(requestedTaskId, splitPosition,
+26 −11

File changed.

Preview size limit exceeded, changes collapsed.

Loading