Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -1404,6 +1404,7 @@ public abstract class WMShellModule { Optional<DesktopImmersiveController> desktopImmersiveController, DesktopMinimizationTransitionHandler desktopMinimizationTransitionHandler, DesktopModeDragAndDropTransitionHandler desktopModeDragAndDropTransitionHandler, Optional<SystemModalsTransitionHandler> systemModalsTransitionHandler, InteractionJankMonitor interactionJankMonitor, @ShellMainThread Handler handler, ShellInit shellInit, Loading @@ -1424,6 +1425,7 @@ public abstract class WMShellModule { desktopImmersiveController.get(), desktopMinimizationTransitionHandler, desktopModeDragAndDropTransitionHandler, systemModalsTransitionHandler, interactionJankMonitor, handler, shellInit, Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt +34 −3 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.internal.jank.InteractionJankMonitor import com.android.internal.protolog.ProtoLog import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_TASK_LIMIT_MINIMIZE import com.android.wm.shell.desktopmode.compatui.SystemModalsTransitionHandler 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 Loading @@ -45,6 +46,7 @@ import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.MixedTransitionHandler import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.TransitionFinishCallback import java.util.Optional /** The [Transitions.TransitionHandler] coordinates transition handlers in desktop windowing. */ class DesktopMixedTransitionHandler( Loading @@ -56,6 +58,7 @@ class DesktopMixedTransitionHandler( private val desktopImmersiveController: DesktopImmersiveController, private val desktopMinimizationTransitionHandler: DesktopMinimizationTransitionHandler, private val desktopModeDragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler, private val systemModalsTransitionHandler: Optional<SystemModalsTransitionHandler>, private val interactionJankMonitor: InteractionJankMonitor, @ShellMainThread private val handler: Handler, shellInit: ShellInit, Loading Loading @@ -137,6 +140,7 @@ class DesktopMixedTransitionHandler( wct: WindowContainerTransaction, taskId: Int?, minimizingTaskId: Int? = null, closingTopTransparentTaskId: Int? = null, exitingImmersiveTask: Int? = null, dragEvent: DragEvent? = null, ): IBinder { Loading @@ -163,6 +167,7 @@ class DesktopMixedTransitionHandler( transition = transition, launchingTask = taskId, minimizingTask = minimizingTaskId, closingTopTransparentTask = closingTopTransparentTaskId, exitingImmersiveTask = exitingImmersiveTask, dragEvent = dragEvent, ) Loading Loading @@ -274,6 +279,10 @@ class DesktopMixedTransitionHandler( pending.exitingImmersiveTask?.let { exitingTask -> findTaskChange(info, exitingTask) } val minimizeChange = pending.minimizingTask?.let { minimizingTask -> findTaskChange(info, minimizingTask) } val closeTopTransparentFullscreenTaskChange = pending.closingTopTransparentTask?.let { closingTopTransparentTask -> findTaskChange(info, closingTopTransparentTask) } val launchChange = findDesktopTaskLaunchChange(info, pending.launchingTask) if (launchChange == null) { check(immersiveExitChange == null) Loading @@ -281,6 +290,7 @@ class DesktopMixedTransitionHandler( return false } var topTransparentAnimationCount = 0 var subAnimationCount = -1 var combinedWct: WindowContainerTransaction? = null val finishCb = TransitionFinishCallback { wct -> Loading @@ -291,9 +301,11 @@ class DesktopMixedTransitionHandler( } logV( "Animating mixed launch transition task#%d, minimizingTask#%s immersiveExitTask#%s", "Animating mixed launch transition task#%d, minimizingTask#%s " + "closingTopTransparentTask#%s immersiveExitTask#%s", launchChange.taskInfo!!.taskId, minimizeChange?.taskInfo?.taskId, closeTopTransparentFullscreenTaskChange?.taskInfo?.taskId, immersiveExitChange?.taskInfo?.taskId, ) if (DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue) { Loading @@ -314,8 +326,26 @@ class DesktopMixedTransitionHandler( finishCallback, ) } if (closeTopTransparentFullscreenTaskChange != null) { systemModalsTransitionHandler.ifPresent { handler -> logV( "Animating system modal close: taskId=%d", closeTopTransparentFullscreenTaskChange.taskInfo?.taskId, ) topTransparentAnimationCount = 1 // Animate the modal closure separately. info.changes.remove(closeTopTransparentFullscreenTaskChange) handler.animateSystemModal( closeTopTransparentFullscreenTaskChange.leash, startTransaction, finishTransaction, finishCb, /* toShow= */ false, ) } } if (immersiveExitChange != null) { subAnimationCount = 2 subAnimationCount = 2 + topTransparentAnimationCount // Animate the immersive exit change separately. info.changes.remove(immersiveExitChange) desktopImmersiveController.animateResizeChange( Loading @@ -335,7 +365,7 @@ class DesktopMixedTransitionHandler( } // There's nothing to animate separately, so let the left over handler animate // the entire transition. subAnimationCount = 1 subAnimationCount = 1 + topTransparentAnimationCount return dispatchToLeftoverHandler( transition, info, Loading Loading @@ -536,6 +566,7 @@ class DesktopMixedTransitionHandler( override val transition: IBinder, val launchingTask: Int?, val minimizingTask: Int?, val closingTopTransparentTask: Int?, val exitingImmersiveTask: Int?, val dragEvent: DragEvent? = null, ) : PendingMixedTransition() Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +28 −30 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.graphics.Rect import android.graphics.Region import android.util.ArrayMap Loading @@ -25,6 +26,7 @@ import android.util.SparseArray import android.view.Display.INVALID_DISPLAY import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags import android.window.WindowContainerToken import androidx.core.util.forEach import androidx.core.util.valueIterator import com.android.internal.annotations.VisibleForTesting Loading Loading @@ -56,6 +58,9 @@ class DesktopRepository( var activeDeskId: Int? = null } /** Specific [TaskInfo] data related to top transparent fullscreen task handling. */ data class TopTransparentFullscreenTaskData(val taskId: Int, val token: WindowContainerToken) /** * Task data tracked per desk. * Loading Loading @@ -83,7 +88,7 @@ class DesktopRepository( val closingTasks: ArraySet<Int> = ArraySet(), val freeformTasksInZOrder: ArrayList<Int> = ArrayList(), var fullImmersiveTaskId: Int? = null, var topTransparentFullscreenTaskId: Int? = null, var topTransparentFullscreenTaskData: TopTransparentFullscreenTaskData? = null, var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, ) { Loading @@ -97,7 +102,7 @@ class DesktopRepository( closingTasks = ArraySet(closingTasks), freeformTasksInZOrder = ArrayList(freeformTasksInZOrder), fullImmersiveTaskId = fullImmersiveTaskId, topTransparentFullscreenTaskId = topTransparentFullscreenTaskId, topTransparentFullscreenTaskData = topTransparentFullscreenTaskData, leftTiledTaskId = leftTiledTaskId, rightTiledTaskId = rightTiledTaskId, ) Loading @@ -111,7 +116,7 @@ class DesktopRepository( closingTasks.clear() freeformTasksInZOrder.clear() fullImmersiveTaskId = null topTransparentFullscreenTaskId = null topTransparentFullscreenTaskData = null leftTiledTaskId = null rightTiledTaskId = null } Loading Loading @@ -793,36 +798,29 @@ class DesktopRepository( fun getTaskInFullImmersiveState(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.fullImmersiveTaskId /** Sets the top transparent fullscreen task id for a given display's active desk. */ @Deprecated("Deprecated with multiple desks") fun setTopTransparentFullscreenTaskId(displayId: Int, taskId: Int) { if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return /** Sets the top transparent fullscreen task data for a given desk. */ fun setTopTransparentFullscreenTaskData(deskId: Int, task: ActivityManager.RunningTaskInfo) { logD( "Top transparent fullscreen task set for display: taskId=%d, displayId=%d", taskId, displayId, "Top transparent fullscreen task set for desk: taskId=%d, deskId=%d", task.taskId, deskId, ) desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId = taskId desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData = TopTransparentFullscreenTaskData(task.taskId, task.token) } /** Returns the top transparent fullscreen task id for a given display, or null. */ @Deprecated("Deprecated with multiple desks") fun getTopTransparentFullscreenTaskId(displayId: Int): Int? = desktopData .desksSequence(displayId) .mapNotNull { it.topTransparentFullscreenTaskId } .firstOrNull() /** Clears the top transparent fullscreen task id info for a given display's active desk. */ @Deprecated("Deprecated with multiple desks") fun clearTopTransparentFullscreenTaskId(displayId: Int) { if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return /** Returns the top transparent fullscreen task data for a given desk, or null. */ fun getTopTransparentFullscreenTaskData(deskId: Int): TopTransparentFullscreenTaskData? = desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData /** Clears the top transparent fullscreen task data for a given desk. */ fun clearTopTransparentFullscreenTaskData(deskId: Int) { logD( "Top transparent fullscreen task cleared for display: taskId=%d, displayId=%d", desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId, displayId, "Top transparent fullscreen task cleared for desk: taskId=%d, deskId=%d", desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData?.taskId, deskId, ) desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId = null desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData = null } @VisibleForTesting Loading @@ -842,7 +840,7 @@ class DesktopRepository( } val hasVisibleTasks = desk.visibleTasks.isNotEmpty() val hasTopTransparentFullscreenTask = getTopTransparentFullscreenTaskId(displayId) != null getTopTransparentFullscreenTaskData(desk.deskId) != null if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue Loading Loading @@ -1188,8 +1186,8 @@ class DesktopRepository( pw.println(desk.minimizedTasks.toDumpString()) pw.print("$desksPrefix fullImmersiveTaskId=") pw.println(desk.fullImmersiveTaskId) pw.print("$desksPrefix topTransparentFullscreenTaskId=") pw.println(desk.topTransparentFullscreenTaskId) pw.print("$desksPrefix topTransparentFullscreenTaskData=") pw.println(desk.topTransparentFullscreenTaskData) } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +65 −6 Original line number Diff line number Diff line Loading @@ -1506,6 +1506,8 @@ class DesktopTasksController( launchingNewIntent = launchingTaskId == null, ) } val closingTopTransparentTaskId = deskId?.let { taskRepository.getTopTransparentFullscreenTaskData(it)?.taskId } val exitImmersiveResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = launchTransaction, Loading Loading @@ -1543,6 +1545,8 @@ class DesktopTasksController( ) } } // Remove top transparent fullscreen task if needed. deskId?.let { closeTopTransparentFullscreenTask(launchTransaction, it) } val t = if (remoteTransition == null) { logV("startLaunchTransition -- no remoteTransition -- wct = $launchTransaction") Loading @@ -1551,10 +1555,13 @@ class DesktopTasksController( wct = launchTransaction, taskId = launchingTaskId, minimizingTaskId = taskIdToMinimize, closingTopTransparentTaskId = closingTopTransparentTaskId, exitingImmersiveTask = exitImmersiveResult.asExit()?.exitingTask, dragEvent = dragEvent, ) } else if (taskIdToMinimize == null) { // TODO(b/412761429): Move OneShotRemoteHandler call to within // DesktopMixedTransitionHandler. val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition) transitions .startTransition(transitionType, launchTransaction, remoteTransitionHandler) Loading Loading @@ -2938,7 +2945,16 @@ class DesktopTasksController( // 2) minimize a Task if needed. // TODO: b/32994943 - remove dead code when cleaning up task_limit_separate_transition flag val taskIdToMinimize = addAndGetMinimizeChanges(deskId, wct, task.taskId) addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) // 3) Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) addPendingAppLaunchTransition( transition, task.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) if (taskIdToMinimize != null) { addPendingMinimizeTransition(transition, taskIdToMinimize, MinimizeReason.TASK_LIMIT) return wct Loading Loading @@ -2995,8 +3011,17 @@ class DesktopTasksController( ) } addPendingTaskLimitTransition(transition, deskId, task.taskId) // Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) // Also track the pending launching task. addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) addPendingAppLaunchTransition( transition, task.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) } } runOnTransitStart?.invoke(transition) Loading Loading @@ -3060,11 +3085,15 @@ class DesktopTasksController( if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { if (!inDesktop && !forceEnterDesktop(displayId)) return null if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue && isTransparentTask isTransparentTask && (DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue || DesktopModeFlags .INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue) ) { // Only update task repository for transparent task. taskRepository.setTopTransparentFullscreenTaskId(displayId, taskId) val deskId = taskRepository.getActiveDeskId(displayId) deskId?.let { taskRepository.setTopTransparentFullscreenTaskData(it, task) } } // Already fullscreen, no-op. if (task.isFullscreen) return null Loading @@ -3087,6 +3116,16 @@ class DesktopTasksController( logD("handleIncompatibleTaskLaunch not in desktop, not a freeform task, nothing to do") return null } if ( isTransparentTask && (DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue || DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue) ) { // Only update task repository for transparent task. val deskId = taskRepository.getActiveDeskId(displayId) deskId?.let { taskRepository.setTopTransparentFullscreenTaskData(it, task) } } // Both opaque and transparent incompatible tasks need to be forced to fullscreen, but // opaque ones force-exit the desktop while transparent ones are just shown on top of the // desktop while keeping it active. Loading Loading @@ -3448,6 +3487,7 @@ class DesktopTasksController( transition: IBinder, launchTaskId: Int, minimizeTaskId: Int?, closingTopTransparentTaskId: Int?, ) { if (!DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue) { return Loading @@ -3458,6 +3498,7 @@ class DesktopTasksController( transition, launchTaskId, minimizeTaskId, closingTopTransparentTaskId, /* exitingImmersiveTask= */ null, ) ) Loading Loading @@ -3512,7 +3553,16 @@ class DesktopTasksController( launchTaskId = newTask?.taskId, ) if (newTask != null && addPendingLaunchTransition) { addPendingAppLaunchTransition(transition, newTask.taskId, taskIdToMinimize) // Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) addPendingAppLaunchTransition( transition, newTask.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) } } } Loading Loading @@ -3574,6 +3624,15 @@ class DesktopTasksController( } } private fun closeTopTransparentFullscreenTask(wct: WindowContainerTransaction, deskId: Int) { if (!DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue) return val data = taskRepository.getTopTransparentFullscreenTaskData(deskId) if (data != null) { logD("closeTopTransparentFullscreenTask: taskId=%d, deskId=%d", data.taskId, deskId) wct.removeTask(data.token) } } /** Activates the desk at the given index if it exists. */ fun activatePreviousDesk(displayId: Int) { if ( Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt +6 −5 Original line number Diff line number Diff line Loading @@ -79,9 +79,9 @@ class DesktopTasksTransitionObserver( ) { // TODO: b/332682201 Update repository state if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC.isTrue && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue (DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue || DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue) ) { updateTopTransparentFullscreenTaskId(info) } Loading Loading @@ -213,8 +213,9 @@ class DesktopTasksTransitionObserver( change.taskInfo?.let { task -> val desktopRepository = desktopUserRepositories.getProfile(task.userId) val displayId = task.displayId val deskId = desktopRepository.getActiveDeskId(displayId) ?: return@forEachLoop val transparentTaskId = desktopRepository.getTopTransparentFullscreenTaskId(displayId) desktopRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId if (transparentTaskId == null) return@forEachLoop val changeMode = change.mode val taskId = task.taskId Loading @@ -228,7 +229,7 @@ class DesktopTasksTransitionObserver( isTopTransparentFullscreenTaskClosing || isNonTopTransparentFullscreenTaskOpening ) { desktopRepository.clearTopTransparentFullscreenTaskId(displayId) desktopRepository.clearTopTransparentFullscreenTaskData(deskId) return@forEachLoop } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -1404,6 +1404,7 @@ public abstract class WMShellModule { Optional<DesktopImmersiveController> desktopImmersiveController, DesktopMinimizationTransitionHandler desktopMinimizationTransitionHandler, DesktopModeDragAndDropTransitionHandler desktopModeDragAndDropTransitionHandler, Optional<SystemModalsTransitionHandler> systemModalsTransitionHandler, InteractionJankMonitor interactionJankMonitor, @ShellMainThread Handler handler, ShellInit shellInit, Loading @@ -1424,6 +1425,7 @@ public abstract class WMShellModule { desktopImmersiveController.get(), desktopMinimizationTransitionHandler, desktopModeDragAndDropTransitionHandler, systemModalsTransitionHandler, interactionJankMonitor, handler, shellInit, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopMixedTransitionHandler.kt +34 −3 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.internal.jank.InteractionJankMonitor import com.android.internal.protolog.ProtoLog import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_TASK_LIMIT_MINIMIZE import com.android.wm.shell.desktopmode.compatui.SystemModalsTransitionHandler 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 Loading @@ -45,6 +46,7 @@ import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.MixedTransitionHandler import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.TransitionFinishCallback import java.util.Optional /** The [Transitions.TransitionHandler] coordinates transition handlers in desktop windowing. */ class DesktopMixedTransitionHandler( Loading @@ -56,6 +58,7 @@ class DesktopMixedTransitionHandler( private val desktopImmersiveController: DesktopImmersiveController, private val desktopMinimizationTransitionHandler: DesktopMinimizationTransitionHandler, private val desktopModeDragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler, private val systemModalsTransitionHandler: Optional<SystemModalsTransitionHandler>, private val interactionJankMonitor: InteractionJankMonitor, @ShellMainThread private val handler: Handler, shellInit: ShellInit, Loading Loading @@ -137,6 +140,7 @@ class DesktopMixedTransitionHandler( wct: WindowContainerTransaction, taskId: Int?, minimizingTaskId: Int? = null, closingTopTransparentTaskId: Int? = null, exitingImmersiveTask: Int? = null, dragEvent: DragEvent? = null, ): IBinder { Loading @@ -163,6 +167,7 @@ class DesktopMixedTransitionHandler( transition = transition, launchingTask = taskId, minimizingTask = minimizingTaskId, closingTopTransparentTask = closingTopTransparentTaskId, exitingImmersiveTask = exitingImmersiveTask, dragEvent = dragEvent, ) Loading Loading @@ -274,6 +279,10 @@ class DesktopMixedTransitionHandler( pending.exitingImmersiveTask?.let { exitingTask -> findTaskChange(info, exitingTask) } val minimizeChange = pending.minimizingTask?.let { minimizingTask -> findTaskChange(info, minimizingTask) } val closeTopTransparentFullscreenTaskChange = pending.closingTopTransparentTask?.let { closingTopTransparentTask -> findTaskChange(info, closingTopTransparentTask) } val launchChange = findDesktopTaskLaunchChange(info, pending.launchingTask) if (launchChange == null) { check(immersiveExitChange == null) Loading @@ -281,6 +290,7 @@ class DesktopMixedTransitionHandler( return false } var topTransparentAnimationCount = 0 var subAnimationCount = -1 var combinedWct: WindowContainerTransaction? = null val finishCb = TransitionFinishCallback { wct -> Loading @@ -291,9 +301,11 @@ class DesktopMixedTransitionHandler( } logV( "Animating mixed launch transition task#%d, minimizingTask#%s immersiveExitTask#%s", "Animating mixed launch transition task#%d, minimizingTask#%s " + "closingTopTransparentTask#%s immersiveExitTask#%s", launchChange.taskInfo!!.taskId, minimizeChange?.taskInfo?.taskId, closeTopTransparentFullscreenTaskChange?.taskInfo?.taskId, immersiveExitChange?.taskInfo?.taskId, ) if (DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue) { Loading @@ -314,8 +326,26 @@ class DesktopMixedTransitionHandler( finishCallback, ) } if (closeTopTransparentFullscreenTaskChange != null) { systemModalsTransitionHandler.ifPresent { handler -> logV( "Animating system modal close: taskId=%d", closeTopTransparentFullscreenTaskChange.taskInfo?.taskId, ) topTransparentAnimationCount = 1 // Animate the modal closure separately. info.changes.remove(closeTopTransparentFullscreenTaskChange) handler.animateSystemModal( closeTopTransparentFullscreenTaskChange.leash, startTransaction, finishTransaction, finishCb, /* toShow= */ false, ) } } if (immersiveExitChange != null) { subAnimationCount = 2 subAnimationCount = 2 + topTransparentAnimationCount // Animate the immersive exit change separately. info.changes.remove(immersiveExitChange) desktopImmersiveController.animateResizeChange( Loading @@ -335,7 +365,7 @@ class DesktopMixedTransitionHandler( } // There's nothing to animate separately, so let the left over handler animate // the entire transition. subAnimationCount = 1 subAnimationCount = 1 + topTransparentAnimationCount return dispatchToLeftoverHandler( transition, info, Loading Loading @@ -536,6 +566,7 @@ class DesktopMixedTransitionHandler( override val transition: IBinder, val launchingTask: Int?, val minimizingTask: Int?, val closingTopTransparentTask: Int?, val exitingImmersiveTask: Int?, val dragEvent: DragEvent? = null, ) : PendingMixedTransition() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +28 −30 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.graphics.Rect import android.graphics.Region import android.util.ArrayMap Loading @@ -25,6 +26,7 @@ import android.util.SparseArray import android.view.Display.INVALID_DISPLAY import android.window.DesktopExperienceFlags import android.window.DesktopModeFlags import android.window.WindowContainerToken import androidx.core.util.forEach import androidx.core.util.valueIterator import com.android.internal.annotations.VisibleForTesting Loading Loading @@ -56,6 +58,9 @@ class DesktopRepository( var activeDeskId: Int? = null } /** Specific [TaskInfo] data related to top transparent fullscreen task handling. */ data class TopTransparentFullscreenTaskData(val taskId: Int, val token: WindowContainerToken) /** * Task data tracked per desk. * Loading Loading @@ -83,7 +88,7 @@ class DesktopRepository( val closingTasks: ArraySet<Int> = ArraySet(), val freeformTasksInZOrder: ArrayList<Int> = ArrayList(), var fullImmersiveTaskId: Int? = null, var topTransparentFullscreenTaskId: Int? = null, var topTransparentFullscreenTaskData: TopTransparentFullscreenTaskData? = null, var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, ) { Loading @@ -97,7 +102,7 @@ class DesktopRepository( closingTasks = ArraySet(closingTasks), freeformTasksInZOrder = ArrayList(freeformTasksInZOrder), fullImmersiveTaskId = fullImmersiveTaskId, topTransparentFullscreenTaskId = topTransparentFullscreenTaskId, topTransparentFullscreenTaskData = topTransparentFullscreenTaskData, leftTiledTaskId = leftTiledTaskId, rightTiledTaskId = rightTiledTaskId, ) Loading @@ -111,7 +116,7 @@ class DesktopRepository( closingTasks.clear() freeformTasksInZOrder.clear() fullImmersiveTaskId = null topTransparentFullscreenTaskId = null topTransparentFullscreenTaskData = null leftTiledTaskId = null rightTiledTaskId = null } Loading Loading @@ -793,36 +798,29 @@ class DesktopRepository( fun getTaskInFullImmersiveState(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.fullImmersiveTaskId /** Sets the top transparent fullscreen task id for a given display's active desk. */ @Deprecated("Deprecated with multiple desks") fun setTopTransparentFullscreenTaskId(displayId: Int, taskId: Int) { if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return /** Sets the top transparent fullscreen task data for a given desk. */ fun setTopTransparentFullscreenTaskData(deskId: Int, task: ActivityManager.RunningTaskInfo) { logD( "Top transparent fullscreen task set for display: taskId=%d, displayId=%d", taskId, displayId, "Top transparent fullscreen task set for desk: taskId=%d, deskId=%d", task.taskId, deskId, ) desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId = taskId desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData = TopTransparentFullscreenTaskData(task.taskId, task.token) } /** Returns the top transparent fullscreen task id for a given display, or null. */ @Deprecated("Deprecated with multiple desks") fun getTopTransparentFullscreenTaskId(displayId: Int): Int? = desktopData .desksSequence(displayId) .mapNotNull { it.topTransparentFullscreenTaskId } .firstOrNull() /** Clears the top transparent fullscreen task id info for a given display's active desk. */ @Deprecated("Deprecated with multiple desks") fun clearTopTransparentFullscreenTaskId(displayId: Int) { if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return /** Returns the top transparent fullscreen task data for a given desk, or null. */ fun getTopTransparentFullscreenTaskData(deskId: Int): TopTransparentFullscreenTaskData? = desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData /** Clears the top transparent fullscreen task data for a given desk. */ fun clearTopTransparentFullscreenTaskData(deskId: Int) { logD( "Top transparent fullscreen task cleared for display: taskId=%d, displayId=%d", desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId, displayId, "Top transparent fullscreen task cleared for desk: taskId=%d, deskId=%d", desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData?.taskId, deskId, ) desktopData.getActiveDesk(displayId)?.topTransparentFullscreenTaskId = null desktopData.getDesk(deskId)?.topTransparentFullscreenTaskData = null } @VisibleForTesting Loading @@ -842,7 +840,7 @@ class DesktopRepository( } val hasVisibleTasks = desk.visibleTasks.isNotEmpty() val hasTopTransparentFullscreenTask = getTopTransparentFullscreenTaskId(displayId) != null getTopTransparentFullscreenTaskData(desk.deskId) != null if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue Loading Loading @@ -1188,8 +1186,8 @@ class DesktopRepository( pw.println(desk.minimizedTasks.toDumpString()) pw.print("$desksPrefix fullImmersiveTaskId=") pw.println(desk.fullImmersiveTaskId) pw.print("$desksPrefix topTransparentFullscreenTaskId=") pw.println(desk.topTransparentFullscreenTaskId) pw.print("$desksPrefix topTransparentFullscreenTaskData=") pw.println(desk.topTransparentFullscreenTaskData) } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +65 −6 Original line number Diff line number Diff line Loading @@ -1506,6 +1506,8 @@ class DesktopTasksController( launchingNewIntent = launchingTaskId == null, ) } val closingTopTransparentTaskId = deskId?.let { taskRepository.getTopTransparentFullscreenTaskData(it)?.taskId } val exitImmersiveResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = launchTransaction, Loading Loading @@ -1543,6 +1545,8 @@ class DesktopTasksController( ) } } // Remove top transparent fullscreen task if needed. deskId?.let { closeTopTransparentFullscreenTask(launchTransaction, it) } val t = if (remoteTransition == null) { logV("startLaunchTransition -- no remoteTransition -- wct = $launchTransaction") Loading @@ -1551,10 +1555,13 @@ class DesktopTasksController( wct = launchTransaction, taskId = launchingTaskId, minimizingTaskId = taskIdToMinimize, closingTopTransparentTaskId = closingTopTransparentTaskId, exitingImmersiveTask = exitImmersiveResult.asExit()?.exitingTask, dragEvent = dragEvent, ) } else if (taskIdToMinimize == null) { // TODO(b/412761429): Move OneShotRemoteHandler call to within // DesktopMixedTransitionHandler. val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition) transitions .startTransition(transitionType, launchTransaction, remoteTransitionHandler) Loading Loading @@ -2938,7 +2945,16 @@ class DesktopTasksController( // 2) minimize a Task if needed. // TODO: b/32994943 - remove dead code when cleaning up task_limit_separate_transition flag val taskIdToMinimize = addAndGetMinimizeChanges(deskId, wct, task.taskId) addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) // 3) Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) addPendingAppLaunchTransition( transition, task.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) if (taskIdToMinimize != null) { addPendingMinimizeTransition(transition, taskIdToMinimize, MinimizeReason.TASK_LIMIT) return wct Loading Loading @@ -2995,8 +3011,17 @@ class DesktopTasksController( ) } addPendingTaskLimitTransition(transition, deskId, task.taskId) // Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) // Also track the pending launching task. addPendingAppLaunchTransition(transition, task.taskId, taskIdToMinimize) addPendingAppLaunchTransition( transition, task.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) } } runOnTransitStart?.invoke(transition) Loading Loading @@ -3060,11 +3085,15 @@ class DesktopTasksController( if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { if (!inDesktop && !forceEnterDesktop(displayId)) return null if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue && isTransparentTask isTransparentTask && (DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue || DesktopModeFlags .INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue) ) { // Only update task repository for transparent task. taskRepository.setTopTransparentFullscreenTaskId(displayId, taskId) val deskId = taskRepository.getActiveDeskId(displayId) deskId?.let { taskRepository.setTopTransparentFullscreenTaskData(it, task) } } // Already fullscreen, no-op. if (task.isFullscreen) return null Loading @@ -3087,6 +3116,16 @@ class DesktopTasksController( logD("handleIncompatibleTaskLaunch not in desktop, not a freeform task, nothing to do") return null } if ( isTransparentTask && (DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue || DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue) ) { // Only update task repository for transparent task. val deskId = taskRepository.getActiveDeskId(displayId) deskId?.let { taskRepository.setTopTransparentFullscreenTaskData(it, task) } } // Both opaque and transparent incompatible tasks need to be forced to fullscreen, but // opaque ones force-exit the desktop while transparent ones are just shown on top of the // desktop while keeping it active. Loading Loading @@ -3448,6 +3487,7 @@ class DesktopTasksController( transition: IBinder, launchTaskId: Int, minimizeTaskId: Int?, closingTopTransparentTaskId: Int?, ) { if (!DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS_BUGFIX.isTrue) { return Loading @@ -3458,6 +3498,7 @@ class DesktopTasksController( transition, launchTaskId, minimizeTaskId, closingTopTransparentTaskId, /* exitingImmersiveTask= */ null, ) ) Loading Loading @@ -3512,7 +3553,16 @@ class DesktopTasksController( launchTaskId = newTask?.taskId, ) if (newTask != null && addPendingLaunchTransition) { addPendingAppLaunchTransition(transition, newTask.taskId, taskIdToMinimize) // Remove top transparent fullscreen task if needed. val closingTopTransparentTaskId = taskRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId closeTopTransparentFullscreenTask(wct, deskId) addPendingAppLaunchTransition( transition, newTask.taskId, taskIdToMinimize, closingTopTransparentTaskId, ) } } } Loading Loading @@ -3574,6 +3624,15 @@ class DesktopTasksController( } } private fun closeTopTransparentFullscreenTask(wct: WindowContainerTransaction, deskId: Int) { if (!DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue) return val data = taskRepository.getTopTransparentFullscreenTaskData(deskId) if (data != null) { logD("closeTopTransparentFullscreenTask: taskId=%d, deskId=%d", data.taskId, deskId) wct.removeTask(data.token) } } /** Activates the desk at the given index if it exists. */ fun activatePreviousDesk(displayId: Int) { if ( Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt +6 −5 Original line number Diff line number Diff line Loading @@ -79,9 +79,9 @@ class DesktopTasksTransitionObserver( ) { // TODO: b/332682201 Update repository state if ( DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC.isTrue && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue (DesktopModeFlags.INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC .isTrue || DesktopModeFlags.FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK.isTrue) ) { updateTopTransparentFullscreenTaskId(info) } Loading Loading @@ -213,8 +213,9 @@ class DesktopTasksTransitionObserver( change.taskInfo?.let { task -> val desktopRepository = desktopUserRepositories.getProfile(task.userId) val displayId = task.displayId val deskId = desktopRepository.getActiveDeskId(displayId) ?: return@forEachLoop val transparentTaskId = desktopRepository.getTopTransparentFullscreenTaskId(displayId) desktopRepository.getTopTransparentFullscreenTaskData(deskId)?.taskId if (transparentTaskId == null) return@forEachLoop val changeMode = change.mode val taskId = task.taskId Loading @@ -228,7 +229,7 @@ class DesktopTasksTransitionObserver( isTopTransparentFullscreenTaskClosing || isNonTopTransparentFullscreenTaskOpening ) { desktopRepository.clearTopTransparentFullscreenTaskId(displayId) desktopRepository.clearTopTransparentFullscreenTaskData(deskId) return@forEachLoop } } Loading