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

Commit 3fd1a21c authored by Eric Sum's avatar Eric Sum Committed by Android (Google) Code Review
Browse files

Merge "Add ACTION_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE latency." into main

parents f39298ab 13409d5d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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,
@@ -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 */
@@ -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 {}
@@ -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();
@@ -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");
        }
+18 −10
Original line number Diff line number Diff line
@@ -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
@@ -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 =
@@ -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)
        }
    }

@@ -1045,7 +1046,8 @@ class DesktopTasksController(
            && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
        ) {
            desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted(
                FULLSCREEN_ANIMATION_DURATION
                FULLSCREEN_ANIMATION_DURATION,
                shouldEndUpAtHome = false,
            )
        }
    }
@@ -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 (
@@ -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,
@@ -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)
                    }
                }
            }
@@ -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. */
+5 −2
Original line number Diff line number Diff line
@@ -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
+46 −47
Original line number Diff line number Diff line
@@ -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)
    }
@@ -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
@@ -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)
@@ -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)
@@ -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))
@@ -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
@@ -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)
@@ -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)
    }
@@ -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)
@@ -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
@@ -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
@@ -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))
@@ -7947,7 +7945,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
            returnToApp = false,
        )

        verify(desktopModeEnterExitTransitionListener).onExitDesktopModeTransitionStarted(any())
        verify(desktopModeEnterExitTransitionListener)
            .onExitDesktopModeTransitionStarted(any(), any())
    }

    @Test