Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +92 −19 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.desktopmode import android.annotation.UserIdInt import android.app.ActivityManager import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.KeyguardManager Loading Loading @@ -920,11 +921,28 @@ class DesktopTasksController( ) } /** Move a task with given `taskId` to fullscreen */ fun moveToFullscreen(taskId: Int, transitionSource: DesktopModeTransitionSource) { shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> /** Move or launch a task with given [taskId] to fullscreen */ @JvmOverloads fun moveToFullscreen( taskId: Int, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, ) { val taskInfo: TaskInfo? = shellTaskOrganizer.getRunningTaskInfo(taskId) ?: if (com.android.launcher3.Flags.enableAltTabKqsFlatenning()) { recentTasksController?.findTaskInBackground(taskId) } else { null } taskInfo?.let { task -> snapEventHandler.removeTaskIfTiled(task.displayId, taskId) moveToFullscreenWithAnimation(task, task.positionInParent, transitionSource) moveToFullscreenWithAnimation( task, task.positionInParent, transitionSource, remoteTransition, ) } } Loading Loading @@ -959,28 +977,64 @@ class DesktopTasksController( } private fun moveToFullscreenWithAnimation( task: RunningTaskInfo, task: TaskInfo, position: Point, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, ) { logV("moveToFullscreenWithAnimation taskId=%d", task.taskId) val displayId = when { task.displayId != INVALID_DISPLAY -> task.displayId focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY -> focusTransitionObserver.globallyFocusedDisplayId else -> DEFAULT_DISPLAY } val wct = WindowContainerTransaction() val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceExitDesktop = true) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop) // When a task is background, update wct to start task. if ( com.android.launcher3.Flags.enableAltTabKqsFlatenning() && shellTaskOrganizer.getRunningTaskInfo(task.taskId) == null && task is RecentTaskInfo ) { wct.startTask( task.taskId, // TODO(b/400817258): Use ActivityOptions Utils when available. ActivityOptions.makeBasic() .apply { launchWindowingMode = WINDOWING_MODE_FULLSCREEN launchDisplayId = displayId pendingIntentBackgroundActivityStartMode = ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS } .toBundle(), ) } val willExitDesktop = willExitDesktop(task.taskId, displayId, forceExitDesktop = true) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop, displayId) // We are moving a freeform task to fullscreen, put the home task under the fullscreen task. if (!forceEnterDesktop(task.displayId)) { moveHomeTask(task.displayId, wct) if (!forceEnterDesktop(displayId)) { moveHomeTask(displayId, wct) wct.reorder(task.token, /* onTop= */ true) } val transition = if (remoteTransition != null) { val transitionType = transitionType(remoteTransition) val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition) transitions.startTransition(transitionType, wct, remoteTransitionHandler).also { remoteTransitionHandler.setTransition(it) } } else { exitDesktopTaskTransitionHandler.startTransition( transitionSource, wct, position, mOnAnimationFinishedCallback, ) } deactivationRunnable?.invoke(transition) // handles case where we are moving to full screen without closing all DW tasks. Loading Loading @@ -2756,10 +2810,11 @@ class DesktopTasksController( /** Applies the changes needed to enter fullscreen and clean up the desktop if needed. */ private fun addMoveToFullscreenChanges( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo, taskInfo: TaskInfo, willExitDesktop: Boolean, displayId: Int = taskInfo.displayId, ): RunOnTransitStart? { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) { Loading @@ -2776,11 +2831,19 @@ class DesktopTasksController( if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true) } val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) ?: if (com.android.launcher3.Flags.enableAltTabKqsFlatenning()) { taskRepository.getActiveDeskId(displayId) } else { null } return performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = taskInfo.displayId, displayId = displayId, willExitDesktop = willExitDesktop, shouldEndUpAtHome = false, ) Loading Loading @@ -3944,6 +4007,16 @@ class DesktopTasksController( } } override fun moveToFullscreen( taskId: Int, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition?, ) { executeRemoteCallWithTaskPermission(controller, "moveToFullscreen") { c -> c.moveToFullscreen(taskId, transitionSource, remoteTransition) } } override fun stashDesktopApps(displayId: Int) { ProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated") } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,18 @@ interface IDesktopMode { oneway void showDesktopApp(int taskId, in @nullable RemoteTransition remoteTransition, in DesktopTaskToFrontReason toFrontReason); /** * Move or launch a given task {@code taskId} to fullscreen. * * <p> Note: In non-desktop by default environment this will mean to exit desktop mode. This API * is also used to move to existing (or launch a background) fullscreen task while on desktop as * startActivity will open the fullscreen task in freeform in current desktop. This is because * in tablet desktop mode, system intercepts the transition and converts fullscreen to freeform * task when the display has a desktop active. */ oneway void moveToFullscreen(int taskId, in DesktopModeTransitionSource transitionSource, in @nullable RemoteTransition remoteTransition); /** Perform cleanup transactions after the animation to split select is complete */ oneway void onDesktopSplitSelectAnimComplete(in RunningTaskInfo taskInfo); Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +2 −1 Original line number Diff line number Diff line Loading @@ -827,7 +827,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, SplitScreenController.EXIT_REASON_DESKTOP_MODE); } else { mDesktopTasksController.moveToFullscreen(taskId, DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON); DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON, /* remoteTransition= */ null); } mDesktopModeUiEventLogger.log(decoration.mTaskInfo, DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN); Loading libs/WindowManager/Shell/tests/unittest/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ android_test { "testables", "platform-test-annotations", "servicestests-utils", "com_android_launcher3_flags_lib", "com_android_wm_shell_flags_lib", "guava-android-testlib", "com.android.window.flags.window-aconfig-java", Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +78 −64 Original line number Diff line number Diff line Loading @@ -300,6 +300,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 75, 1730, 1275) private val wallpaperToken = MockToken().token() private val homeComponentName = ComponentName(HOME_LAUNCHER_PACKAGE_NAME, /* class */ "") private val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, /* featureId= */ 0) init { mSetFlagsRule.setFlagsParameterization(flags) Loading Loading @@ -375,6 +377,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECONDARY_DISPLAY_ID)) .thenReturn(tda) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever( mMockDesktopImmersiveController.exitImmersiveIfApplicable( any(), Loading Loading @@ -2483,6 +2487,79 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) } @Test @EnableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_fullscreenTaskWithRemoteTransition_transitToFrontUsesRemoteTransition() { val transitionHandlerArgCaptor = argumentCaptor<TransitionHandler>() whenever(transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())) .thenReturn(Binder()) val task = setUpFullscreenTask() assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)) .configuration .windowConfiguration .windowingMode = WINDOWING_MODE_FREEFORM controller.moveToFullscreen( task.taskId, transitionSource = UNKNOWN, remoteTransition = RemoteTransition(spy(TestRemoteTransition())), ) val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.firstValue) } @Test @EnableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_backgroundFullscreenTask_launchesFullscreenTask() { val task = createRecentTaskInfo(1, INVALID_DISPLAY) whenever(recentTasksController.findTaskInBackground(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) val transitionHandlerArgCaptor = argumentCaptor<TransitionHandler>() whenever(transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())) .thenReturn(Binder()) controller.moveToFullscreen( task.taskId, transitionSource = UNKNOWN, remoteTransition = RemoteTransition(spy(TestRemoteTransition())), ) val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) wct.assertLaunchTask(task.taskId, WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.firstValue) } @Test @DisableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_backgroundFullscreenTask_ignoredWhenFlagOff() { val task = createRecentTaskInfo(1, INVALID_DISPLAY) whenever(recentTasksController.findTaskInBackground(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null) controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN) verify(snapEventHandler, never()).removeTaskIfTiled(anyInt(), anyInt()) verify(transitions, never()).startTransition(anyInt(), any(), any()) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) } @Test @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveTaskToFront_postsWctWithReorderOp() { Loading Loading @@ -2739,10 +2816,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading @@ -2767,10 +2840,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = targetDeskId) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading Loading @@ -2834,10 +2903,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Add a task and a wallpaper val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) Loading @@ -2864,10 +2929,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Add a task and a wallpaper val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) Loading @@ -2891,10 +2952,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -2933,10 +2990,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -2973,10 +3026,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(1280) Loading Loading @@ -3011,10 +3060,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -3058,10 +3103,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading Loading @@ -3091,10 +3132,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading @@ -3118,10 +3155,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3150,10 +3183,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3183,10 +3212,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3214,10 +3239,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -3254,10 +3275,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -3287,10 +3304,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -8554,4 +8567,5 @@ private fun createRecentTaskInfo(taskId: Int, displayId: Int = DEFAULT_DISPLAY) this.taskId = taskId this.displayId = displayId token = WindowContainerToken(mock(IWindowContainerToken::class.java)) positionInParent = Point() } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +92 −19 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.wm.shell.desktopmode import android.annotation.UserIdInt import android.app.ActivityManager import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.KeyguardManager Loading Loading @@ -920,11 +921,28 @@ class DesktopTasksController( ) } /** Move a task with given `taskId` to fullscreen */ fun moveToFullscreen(taskId: Int, transitionSource: DesktopModeTransitionSource) { shellTaskOrganizer.getRunningTaskInfo(taskId)?.let { task -> /** Move or launch a task with given [taskId] to fullscreen */ @JvmOverloads fun moveToFullscreen( taskId: Int, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, ) { val taskInfo: TaskInfo? = shellTaskOrganizer.getRunningTaskInfo(taskId) ?: if (com.android.launcher3.Flags.enableAltTabKqsFlatenning()) { recentTasksController?.findTaskInBackground(taskId) } else { null } taskInfo?.let { task -> snapEventHandler.removeTaskIfTiled(task.displayId, taskId) moveToFullscreenWithAnimation(task, task.positionInParent, transitionSource) moveToFullscreenWithAnimation( task, task.positionInParent, transitionSource, remoteTransition, ) } } Loading Loading @@ -959,28 +977,64 @@ class DesktopTasksController( } private fun moveToFullscreenWithAnimation( task: RunningTaskInfo, task: TaskInfo, position: Point, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, ) { logV("moveToFullscreenWithAnimation taskId=%d", task.taskId) val displayId = when { task.displayId != INVALID_DISPLAY -> task.displayId focusTransitionObserver.globallyFocusedDisplayId != INVALID_DISPLAY -> focusTransitionObserver.globallyFocusedDisplayId else -> DEFAULT_DISPLAY } val wct = WindowContainerTransaction() val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceExitDesktop = true) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop) // When a task is background, update wct to start task. if ( com.android.launcher3.Flags.enableAltTabKqsFlatenning() && shellTaskOrganizer.getRunningTaskInfo(task.taskId) == null && task is RecentTaskInfo ) { wct.startTask( task.taskId, // TODO(b/400817258): Use ActivityOptions Utils when available. ActivityOptions.makeBasic() .apply { launchWindowingMode = WINDOWING_MODE_FULLSCREEN launchDisplayId = displayId pendingIntentBackgroundActivityStartMode = ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS } .toBundle(), ) } val willExitDesktop = willExitDesktop(task.taskId, displayId, forceExitDesktop = true) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop, displayId) // We are moving a freeform task to fullscreen, put the home task under the fullscreen task. if (!forceEnterDesktop(task.displayId)) { moveHomeTask(task.displayId, wct) if (!forceEnterDesktop(displayId)) { moveHomeTask(displayId, wct) wct.reorder(task.token, /* onTop= */ true) } val transition = if (remoteTransition != null) { val transitionType = transitionType(remoteTransition) val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition) transitions.startTransition(transitionType, wct, remoteTransitionHandler).also { remoteTransitionHandler.setTransition(it) } } else { exitDesktopTaskTransitionHandler.startTransition( transitionSource, wct, position, mOnAnimationFinishedCallback, ) } deactivationRunnable?.invoke(transition) // handles case where we are moving to full screen without closing all DW tasks. Loading Loading @@ -2756,10 +2810,11 @@ class DesktopTasksController( /** Applies the changes needed to enter fullscreen and clean up the desktop if needed. */ private fun addMoveToFullscreenChanges( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo, taskInfo: TaskInfo, willExitDesktop: Boolean, displayId: Int = taskInfo.displayId, ): RunOnTransitStart? { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = if (tdaWindowingMode == WINDOWING_MODE_FULLSCREEN) { Loading @@ -2776,11 +2831,19 @@ class DesktopTasksController( if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true) } val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) ?: if (com.android.launcher3.Flags.enableAltTabKqsFlatenning()) { taskRepository.getActiveDeskId(displayId) } else { null } return performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = taskInfo.displayId, displayId = displayId, willExitDesktop = willExitDesktop, shouldEndUpAtHome = false, ) Loading Loading @@ -3944,6 +4007,16 @@ class DesktopTasksController( } } override fun moveToFullscreen( taskId: Int, transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition?, ) { executeRemoteCallWithTaskPermission(controller, "moveToFullscreen") { c -> c.moveToFullscreen(taskId, transitionSource, remoteTransition) } } override fun stashDesktopApps(displayId: Int) { ProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated") } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,18 @@ interface IDesktopMode { oneway void showDesktopApp(int taskId, in @nullable RemoteTransition remoteTransition, in DesktopTaskToFrontReason toFrontReason); /** * Move or launch a given task {@code taskId} to fullscreen. * * <p> Note: In non-desktop by default environment this will mean to exit desktop mode. This API * is also used to move to existing (or launch a background) fullscreen task while on desktop as * startActivity will open the fullscreen task in freeform in current desktop. This is because * in tablet desktop mode, system intercepts the transition and converts fullscreen to freeform * task when the display has a desktop active. */ oneway void moveToFullscreen(int taskId, in DesktopModeTransitionSource transitionSource, in @nullable RemoteTransition remoteTransition); /** Perform cleanup transactions after the animation to split select is complete */ oneway void onDesktopSplitSelectAnimComplete(in RunningTaskInfo taskInfo); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +2 −1 Original line number Diff line number Diff line Loading @@ -827,7 +827,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, SplitScreenController.EXIT_REASON_DESKTOP_MODE); } else { mDesktopTasksController.moveToFullscreen(taskId, DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON); DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON, /* remoteTransition= */ null); } mDesktopModeUiEventLogger.log(decoration.mTaskInfo, DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN); Loading
libs/WindowManager/Shell/tests/unittest/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ android_test { "testables", "platform-test-annotations", "servicestests-utils", "com_android_launcher3_flags_lib", "com_android_wm_shell_flags_lib", "guava-android-testlib", "com.android.window.flags.window-aconfig-java", Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +78 −64 Original line number Diff line number Diff line Loading @@ -300,6 +300,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() private val UNRESIZABLE_PORTRAIT_BOUNDS = Rect(830, 75, 1730, 1275) private val wallpaperToken = MockToken().token() private val homeComponentName = ComponentName(HOME_LAUNCHER_PACKAGE_NAME, /* class */ "") private val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, /* featureId= */ 0) init { mSetFlagsRule.setFlagsParameterization(flags) Loading Loading @@ -375,6 +377,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECONDARY_DISPLAY_ID)) .thenReturn(tda) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever( mMockDesktopImmersiveController.exitImmersiveIfApplicable( any(), Loading Loading @@ -2483,6 +2487,79 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) } @Test @EnableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_fullscreenTaskWithRemoteTransition_transitToFrontUsesRemoteTransition() { val transitionHandlerArgCaptor = argumentCaptor<TransitionHandler>() whenever(transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())) .thenReturn(Binder()) val task = setUpFullscreenTask() assertNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)) .configuration .windowConfiguration .windowingMode = WINDOWING_MODE_FREEFORM controller.moveToFullscreen( task.taskId, transitionSource = UNKNOWN, remoteTransition = RemoteTransition(spy(TestRemoteTransition())), ) val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.firstValue) } @Test @EnableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_backgroundFullscreenTask_launchesFullscreenTask() { val task = createRecentTaskInfo(1, INVALID_DISPLAY) whenever(recentTasksController.findTaskInBackground(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null) whenever(focusTransitionObserver.globallyFocusedDisplayId).thenReturn(SECOND_DISPLAY) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) val transitionHandlerArgCaptor = argumentCaptor<TransitionHandler>() whenever(transitions.startTransition(anyInt(), any(), transitionHandlerArgCaptor.capture())) .thenReturn(Binder()) controller.moveToFullscreen( task.taskId, transitionSource = UNKNOWN, remoteTransition = RemoteTransition(spy(TestRemoteTransition())), ) val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) wct.assertLaunchTask(task.taskId, WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) assertIs<OneShotRemoteHandler>(transitionHandlerArgCaptor.firstValue) } @Test @DisableFlags(com.android.launcher3.Flags.FLAG_ENABLE_ALT_TAB_KQS_FLATENNING) fun moveToFullscreen_backgroundFullscreenTask_ignoredWhenFlagOff() { val task = createRecentTaskInfo(1, INVALID_DISPLAY) whenever(recentTasksController.findTaskInBackground(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null) controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN) verify(snapEventHandler, never()).removeTaskIfTiled(anyInt(), anyInt()) verify(transitions, never()).startTransition(anyInt(), any(), any()) verify(desktopModeEnterExitTransitionListener, never()) .onEnterDesktopModeTransitionStarted(anyInt()) } @Test @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveTaskToFront_postsWctWithReorderOp() { Loading Loading @@ -2739,10 +2816,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading @@ -2767,10 +2840,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = targetDeskId) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading Loading @@ -2834,10 +2903,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Add a task and a wallpaper val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) Loading @@ -2864,10 +2929,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Add a task and a wallpaper val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) Loading @@ -2891,10 +2952,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -2933,10 +2990,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -2973,10 +3026,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = 2) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(1280) Loading Loading @@ -3011,10 +3060,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) // Two displays have different density whenever(displayLayout.densityDpi()).thenReturn(320) whenever(displayLayout.width()).thenReturn(2400) Loading Loading @@ -3058,10 +3103,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) Loading Loading @@ -3091,10 +3132,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading @@ -3118,10 +3155,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3150,10 +3183,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3183,10 +3212,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) Loading Loading @@ -3214,10 +3239,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -3254,10 +3275,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -3287,10 +3304,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) // Create a mock for the target display area: second display val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) .thenReturn(secondDisplayArea) whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) .thenReturn(transition) Loading Loading @@ -8554,4 +8567,5 @@ private fun createRecentTaskInfo(taskId: Int, displayId: Int = DEFAULT_DISPLAY) this.taskId = taskId this.displayId = displayId token = WindowContainerToken(mock(IWindowContainerToken::class.java)) positionInParent = Point() }