Loading core/java/com/android/internal/util/LatencyTracker.java +14 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK; Loading Loading @@ -301,6 +302,14 @@ public class LatencyTracker { */ public static final int ACTION_DESKTOP_MODE_EXIT_MODE = 32; /** * Time it takes for the "exit desktop" mode animation to begin after closing the last window. * <p> * Starts when the user provides input to either close or minimize the last window in desktop * mode. Ends when the animation to exit desktop mode is about to draw its first frame. */ public static final int ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE = 33; private static final int[] ACTIONS_ALL = { ACTION_EXPAND_PANEL, ACTION_TOGGLE_RECENTS, Loading Loading @@ -335,6 +344,7 @@ public class LatencyTracker { ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, ACTION_DESKTOP_MODE_EXIT_MODE, ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }; /** @hide */ Loading Loading @@ -372,6 +382,7 @@ public class LatencyTracker { ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, ACTION_DESKTOP_MODE_EXIT_MODE, ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }) @Retention(RetentionPolicy.SOURCE) public @interface Action {} Loading Loading @@ -411,6 +422,7 @@ public class LatencyTracker { UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }; private final Object mLock = new Object(); Loading Loading @@ -617,6 +629,8 @@ public class LatencyTracker { return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE: return "ACTION_DESKTOP_MODE_EXIT_MODE"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE: return "ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE"; default: throw new IllegalArgumentException("Invalid action"); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +18 −10 Original line number Diff line number Diff line Loading @@ -235,6 +235,7 @@ class DesktopTasksController( private var userId: Int private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = DesktopModeShellCommandHandler(this, focusTransitionObserver) private val latencyTracker: LatencyTracker private val mOnAnimationFinishedCallback = { releaseVisualIndicator() } private lateinit var snapEventHandler: SnapEventHandler Loading Loading @@ -284,6 +285,7 @@ class DesktopTasksController( } userId = ActivityManager.getCurrentUser() taskRepository = userRepositories.getProfile(userId) latencyTracker = LatencyTracker.getInstance(context) if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { desktopRepositoryInitializer.deskRecreationFactory = Loading Loading @@ -750,8 +752,7 @@ class DesktopTasksController( taskRepository.setActiveDesk(displayId = taskInfo.displayId, deskId = deskId) } } else { LatencyTracker.getInstance(context) .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) latencyTracker.onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) } } Loading Loading @@ -1045,7 +1046,8 @@ class DesktopTasksController( && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ) { desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } } Loading Loading @@ -2006,7 +2008,8 @@ class DesktopTasksController( ): RunOnTransitStart? { if (!willExitDesktop) return null desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome, ) // No need to clean up the wallpaper / reorder home when coming from a recents transition. if ( Loading Loading @@ -3562,8 +3565,9 @@ class DesktopTasksController( val indicatorType = indicator.updateIndicatorType(inputCoordinates) when (indicatorType) { IndicatorType.TO_DESKTOP_INDICATOR -> { LatencyTracker.getInstance(context) .onActionStart(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) latencyTracker.onActionStart( LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG ) // Start a new jank interaction for the drag release to desktop window animation. interactionJankMonitor.begin( taskSurface, Loading Loading @@ -3942,14 +3946,18 @@ class DesktopTasksController( } } override fun onExitDesktopModeTransitionStarted(transitionDuration: Int) { override fun onExitDesktopModeTransitionStarted( transitionDuration: Int, shouldEndUpAtHome: Boolean, ) { ProtoLog.v( WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: onExitDesktopModeTransitionStarted transitionTime=%s", "IDesktopModeImpl: onExitDesktopModeTransitionStarted transitionTime=%s shouldEndUpAtHome=%b", transitionDuration, shouldEndUpAtHome, ) remoteListener.call { l -> l.onExitDesktopModeTransitionStarted(transitionDuration) l.onExitDesktopModeTransitionStarted(transitionDuration, shouldEndUpAtHome) } } } Loading Loading @@ -4164,7 +4172,7 @@ class DesktopTasksController( fun onEnterDesktopModeTransitionStarted(transitionDuration: Int) /** [transitionDuration] time it takes to run exit desktop mode transition */ fun onExitDesktopModeTransitionStarted(transitionDuration: Int) fun onExitDesktopModeTransitionStarted(transitionDuration: Int, shouldEndUpAtHome: Boolean) } /** The positions on a screen that a task can snap to. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopTaskListener.aidl +5 −2 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ oneway interface IDesktopTaskListener { /** Entering desktop mode transition is started, send the signal with transition duration. */ void onEnterDesktopModeTransitionStarted(int transitionDuration); /** Exiting desktop mode transition is started, send the signal with transition duration. */ void onExitDesktopModeTransitionStarted(int transitionDuration); /** Exiting desktop mode transition is started, send the signal with transition duration * and whether the display will end up at the home activity (as opposed to an app's full screen * mode). */ void onExitDesktopModeTransitionStarted(int transitionDuration, boolean shouldEndUpAtHome); /** * Called when the conditions that allow the creation of a new desk changes. This is a global Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +46 −47 Original line number Diff line number Diff line Loading @@ -2234,7 +2234,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN) val wct = getLatestExitDesktopWct() verify(desktopModeEnterExitTransitionListener, times(1)) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) } Loading @@ -2256,7 +2259,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) assertThat(wct.hierarchyOps).hasSize(3) // Removes wallpaper activity when leaving desktop Loading Loading @@ -2285,7 +2291,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // Removes wallpaper activity when leaving desktop wct.assertReorder(wallpaperToken, toTop = false) Loading @@ -2310,7 +2319,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // Moves home task behind the fullscreen task val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true) Loading @@ -2335,7 +2347,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Removes wallpaper activity when leaving desktop but doesn't reorder home or the task wct.assertReorder(wallpaperToken, toTop = false) wct.assertWithoutHop(ReorderPredicate(homeTask.token, toTop = null)) Loading @@ -2351,7 +2366,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } @Test Loading @@ -2373,7 +2391,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(wct.hierarchyOps).hasSize(3) // Removes wallpaper activity when leaving desktop wct.assertReorderAt(index = 0, wallpaperToken, toTop = false) Loading Loading @@ -2402,7 +2423,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Removes wallpaper activity when leaving desktop wct.assertReorder(wallpaperToken, toTop = false) } Loading @@ -2428,7 +2452,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Moves home task behind the fullscreen task val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true) val fullscreenReorderIndex = wct.indexOfReorder(task, toTop = true) Loading Loading @@ -2459,7 +2486,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task1Change = assertNotNull(wct.changes[task1.token.asBinder()]) assertThat(task1Change.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Does not remove wallpaper activity, as desktop still has a visible desktop task assertThat(wct.hierarchyOps).hasSize(2) // Moves home task behind the fullscreen task Loading @@ -2485,7 +2515,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(changes.keys).doesNotContain(taskSecondDisplay.token.asBinder()) } verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } @Test Loading Loading @@ -6214,41 +6247,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() ) } @Test @EnableFlags( Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG, Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, ) fun onDesktopDragEnd_noIndicatorAndMoveToNewDisplay_reparentToDesk() { val deskId = 5 val task = setUpFreeformTask() val spyController = spy(controller) val mockSurface = mock(SurfaceControl::class.java) val mockDisplayLayout = mock(DisplayLayout::class.java) taskRepository.addDesk(displayId = SECONDARY_DISPLAY_ID, deskId = deskId) whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000)) spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000)) val currentDragBounds = Rect(100, 200, 500, 1000) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) whenever(motionEvent.displayId).thenReturn(SECONDARY_DISPLAY_ID) spyController.onDragPositioningEnd( task, mockSurface, inputCoordinate = PointF(200f, 300f), currentDragBounds, validDragArea = Rect(0, 50, 2000, 2000), dragStartBounds = Rect(), motionEvent, ) verify(desksOrganizer).moveTaskToDesk(any(), eq(deskId), eq(task)) } @Test fun onDesktopDragEnd_fullscreenIndicator_dragToExitDesktop() { val task = setUpFreeformTask(bounds = Rect(0, 0, 100, 100)) Loading Loading @@ -7947,7 +7945,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() returnToApp = false, ) verify(desktopModeEnterExitTransitionListener).onExitDesktopModeTransitionStarted(any()) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(any(), any()) } @Test Loading Loading
core/java/com/android/internal/util/LatencyTracker.java +14 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK; import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK; Loading Loading @@ -301,6 +302,14 @@ public class LatencyTracker { */ public static final int ACTION_DESKTOP_MODE_EXIT_MODE = 32; /** * Time it takes for the "exit desktop" mode animation to begin after closing the last window. * <p> * Starts when the user provides input to either close or minimize the last window in desktop * mode. Ends when the animation to exit desktop mode is about to draw its first frame. */ public static final int ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE = 33; private static final int[] ACTIONS_ALL = { ACTION_EXPAND_PANEL, ACTION_TOGGLE_RECENTS, Loading Loading @@ -335,6 +344,7 @@ public class LatencyTracker { ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, ACTION_DESKTOP_MODE_EXIT_MODE, ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }; /** @hide */ Loading Loading @@ -372,6 +382,7 @@ public class LatencyTracker { ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, ACTION_DESKTOP_MODE_EXIT_MODE, ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }) @Retention(RetentionPolicy.SOURCE) public @interface Action {} Loading Loading @@ -411,6 +422,7 @@ public class LatencyTracker { UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE, UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, }; private final Object mLock = new Object(); Loading Loading @@ -617,6 +629,8 @@ public class LatencyTracker { return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE: return "ACTION_DESKTOP_MODE_EXIT_MODE"; case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE: return "ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE"; default: throw new IllegalArgumentException("Invalid action"); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +18 −10 Original line number Diff line number Diff line Loading @@ -235,6 +235,7 @@ class DesktopTasksController( private var userId: Int private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = DesktopModeShellCommandHandler(this, focusTransitionObserver) private val latencyTracker: LatencyTracker private val mOnAnimationFinishedCallback = { releaseVisualIndicator() } private lateinit var snapEventHandler: SnapEventHandler Loading Loading @@ -284,6 +285,7 @@ class DesktopTasksController( } userId = ActivityManager.getCurrentUser() taskRepository = userRepositories.getProfile(userId) latencyTracker = LatencyTracker.getInstance(context) if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { desktopRepositoryInitializer.deskRecreationFactory = Loading Loading @@ -750,8 +752,7 @@ class DesktopTasksController( taskRepository.setActiveDesk(displayId = taskInfo.displayId, deskId = deskId) } } else { LatencyTracker.getInstance(context) .onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) latencyTracker.onActionCancel(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) } } Loading Loading @@ -1045,7 +1046,8 @@ class DesktopTasksController( && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ) { desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } } Loading Loading @@ -2006,7 +2008,8 @@ class DesktopTasksController( ): RunOnTransitStart? { if (!willExitDesktop) return null desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome, ) // No need to clean up the wallpaper / reorder home when coming from a recents transition. if ( Loading Loading @@ -3562,8 +3565,9 @@ class DesktopTasksController( val indicatorType = indicator.updateIndicatorType(inputCoordinates) when (indicatorType) { IndicatorType.TO_DESKTOP_INDICATOR -> { LatencyTracker.getInstance(context) .onActionStart(LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG) latencyTracker.onActionStart( LatencyTracker.ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG ) // Start a new jank interaction for the drag release to desktop window animation. interactionJankMonitor.begin( taskSurface, Loading Loading @@ -3942,14 +3946,18 @@ class DesktopTasksController( } } override fun onExitDesktopModeTransitionStarted(transitionDuration: Int) { override fun onExitDesktopModeTransitionStarted( transitionDuration: Int, shouldEndUpAtHome: Boolean, ) { ProtoLog.v( WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: onExitDesktopModeTransitionStarted transitionTime=%s", "IDesktopModeImpl: onExitDesktopModeTransitionStarted transitionTime=%s shouldEndUpAtHome=%b", transitionDuration, shouldEndUpAtHome, ) remoteListener.call { l -> l.onExitDesktopModeTransitionStarted(transitionDuration) l.onExitDesktopModeTransitionStarted(transitionDuration, shouldEndUpAtHome) } } } Loading Loading @@ -4164,7 +4172,7 @@ class DesktopTasksController( fun onEnterDesktopModeTransitionStarted(transitionDuration: Int) /** [transitionDuration] time it takes to run exit desktop mode transition */ fun onExitDesktopModeTransitionStarted(transitionDuration: Int) fun onExitDesktopModeTransitionStarted(transitionDuration: Int, shouldEndUpAtHome: Boolean) } /** The positions on a screen that a task can snap to. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopTaskListener.aidl +5 −2 Original line number Diff line number Diff line Loading @@ -45,8 +45,11 @@ oneway interface IDesktopTaskListener { /** Entering desktop mode transition is started, send the signal with transition duration. */ void onEnterDesktopModeTransitionStarted(int transitionDuration); /** Exiting desktop mode transition is started, send the signal with transition duration. */ void onExitDesktopModeTransitionStarted(int transitionDuration); /** Exiting desktop mode transition is started, send the signal with transition duration * and whether the display will end up at the home activity (as opposed to an app's full screen * mode). */ void onExitDesktopModeTransitionStarted(int transitionDuration, boolean shouldEndUpAtHome); /** * Called when the conditions that allow the creation of a new desk changes. This is a global Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +46 −47 Original line number Diff line number Diff line Loading @@ -2234,7 +2234,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() controller.moveToFullscreen(task.taskId, transitionSource = UNKNOWN) val wct = getLatestExitDesktopWct() verify(desktopModeEnterExitTransitionListener, times(1)) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) } Loading @@ -2256,7 +2259,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) assertThat(wct.hierarchyOps).hasSize(3) // Removes wallpaper activity when leaving desktop Loading Loading @@ -2285,7 +2291,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // Removes wallpaper activity when leaving desktop wct.assertReorder(wallpaperToken, toTop = false) Loading @@ -2310,7 +2319,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) // Moves home task behind the fullscreen task val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true) Loading @@ -2335,7 +2347,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val wct = getLatestExitDesktopWct() verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Removes wallpaper activity when leaving desktop but doesn't reorder home or the task wct.assertReorder(wallpaperToken, toTop = false) wct.assertWithoutHop(ReorderPredicate(homeTask.token, toTop = null)) Loading @@ -2351,7 +2366,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } @Test Loading @@ -2373,7 +2391,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) assertThat(wct.hierarchyOps).hasSize(3) // Removes wallpaper activity when leaving desktop wct.assertReorderAt(index = 0, wallpaperToken, toTop = false) Loading Loading @@ -2402,7 +2423,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Removes wallpaper activity when leaving desktop wct.assertReorder(wallpaperToken, toTop = false) } Loading @@ -2428,7 +2452,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val taskChange = assertNotNull(wct.changes[task.token.asBinder()]) assertThat(taskChange.windowingMode).isEqualTo(WINDOWING_MODE_FULLSCREEN) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Moves home task behind the fullscreen task val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true) val fullscreenReorderIndex = wct.indexOfReorder(task, toTop = true) Loading Loading @@ -2459,7 +2486,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task1Change = assertNotNull(wct.changes[task1.token.asBinder()]) assertThat(task1Change.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) // Does not remove wallpaper activity, as desktop still has a visible desktop task assertThat(wct.hierarchyOps).hasSize(2) // Moves home task behind the fullscreen task Loading @@ -2485,7 +2515,10 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(changes.keys).doesNotContain(taskSecondDisplay.token.asBinder()) } verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION) .onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION, shouldEndUpAtHome = false, ) } @Test Loading Loading @@ -6214,41 +6247,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() ) } @Test @EnableFlags( Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG, Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, ) fun onDesktopDragEnd_noIndicatorAndMoveToNewDisplay_reparentToDesk() { val deskId = 5 val task = setUpFreeformTask() val spyController = spy(controller) val mockSurface = mock(SurfaceControl::class.java) val mockDisplayLayout = mock(DisplayLayout::class.java) taskRepository.addDesk(displayId = SECONDARY_DISPLAY_ID, deskId = deskId) whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout) whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000)) spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000)) val currentDragBounds = Rect(100, 200, 500, 1000) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) whenever(motionEvent.displayId).thenReturn(SECONDARY_DISPLAY_ID) spyController.onDragPositioningEnd( task, mockSurface, inputCoordinate = PointF(200f, 300f), currentDragBounds, validDragArea = Rect(0, 50, 2000, 2000), dragStartBounds = Rect(), motionEvent, ) verify(desksOrganizer).moveTaskToDesk(any(), eq(deskId), eq(task)) } @Test fun onDesktopDragEnd_fullscreenIndicator_dragToExitDesktop() { val task = setUpFreeformTask(bounds = Rect(0, 0, 100, 100)) Loading Loading @@ -7947,7 +7945,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() returnToApp = false, ) verify(desktopModeEnterExitTransitionListener).onExitDesktopModeTransitionStarted(any()) verify(desktopModeEnterExitTransitionListener) .onExitDesktopModeTransitionStarted(any(), any()) } @Test Loading