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

Commit 53d6cddb authored by Jorge Gil's avatar Jorge Gil
Browse files

Desks: Do not move the desk layer back in drag-to-desktop anim

Moving freeform tasks back behind the dragged tasks is needed for actual
desktop tasks with content, but also moving the desk root task ends up
moving the dragged task with it, making it disappear behind the
wallpaper for a few frames.

The root has no content, so there's no need to touch it at all, nor
include it as a "freeform" task.

Flag: com.android.window.flags.enable_multiple_desktops_backend
Fix: 406297899
Test: drag to desktop, observe no flicker
Test: atest DragToDesktopTransitionHandlerTest
Change-Id: If7fe221a8f887395b1514e8ee2cf1da8368de854
parent 465c4874
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1007,17 +1007,19 @@ public abstract class WMShellModule {
            Context context,
            Transitions transitions,
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            DesksOrganizer desksOrganizer,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            InteractionJankMonitor interactionJankMonitor,
            Optional<BubbleController> bubbleController,
            DesktopState desktopState) {
        return ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS_BUGFIX.isTrue()
                ? new SpringDragToDesktopTransitionHandler(
                context, transitions, rootTaskDisplayAreaOrganizer, desktopUserRepositories,
                interactionJankMonitor, bubbleController, desktopState)
                context, transitions, rootTaskDisplayAreaOrganizer, desksOrganizer,
                desktopUserRepositories, interactionJankMonitor, bubbleController, desktopState)
                : new DefaultDragToDesktopTransitionHandler(
                        context, transitions, rootTaskDisplayAreaOrganizer, desktopUserRepositories,
                        interactionJankMonitor, bubbleController, desktopState);
                        context, transitions, rootTaskDisplayAreaOrganizer, desksOrganizer,
                        desktopUserRepositories, interactionJankMonitor, bubbleController,
                        desktopState);
    }

    @WMSingleton
+11 −2
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.wm.shell.bubbles.BubbleTransitions
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.animation.Interpolators
@@ -84,6 +85,7 @@ sealed class DragToDesktopTransitionHandler(
    private val context: Context,
    private val transitions: Transitions,
    private val taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    private val desksOrganizer: DesksOrganizer,
    private val desktopUserRepositories: DesktopUserRepositories,
    protected val interactionJankMonitor: InteractionJankMonitor,
    private val bubbleController: Optional<BubbleController>,
@@ -861,8 +863,11 @@ sealed class DragToDesktopTransitionHandler(
                        startTransaction.setLayer(change.leash, it.dragLayer)
                    }
                }
                change.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM -> {
                    // Other freeform tasks that are being restored go behind the dragged task.
                // Other desktop tasks that are being restored go behind the dragged task.
                change.taskInfo?.windowingMode == WINDOWING_MODE_FREEFORM
                // Except for the desk root, that should not be sent back or it might
                // take the dragged task surface back with it.
                && !desksOrganizer.isDeskChange(change) -> {
                    val draggedTaskLeash =
                        state.draggedTaskChange?.leash
                            ?: error("Expected dragged leash to be non-null")
@@ -1255,6 +1260,7 @@ constructor(
    context: Context,
    transitions: Transitions,
    taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    desksOrganizer: DesksOrganizer,
    desktopUserRepositories: DesktopUserRepositories,
    interactionJankMonitor: InteractionJankMonitor,
    bubbleController: Optional<BubbleController>,
@@ -1267,6 +1273,7 @@ constructor(
        context,
        transitions,
        taskDisplayAreaOrganizer,
        desksOrganizer,
        desktopUserRepositories,
        interactionJankMonitor,
        bubbleController,
@@ -1297,6 +1304,7 @@ constructor(
    context: Context,
    transitions: Transitions,
    taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    desksOrganizer: DesksOrganizer,
    desktopUserRepositories: DesktopUserRepositories,
    interactionJankMonitor: InteractionJankMonitor,
    bubbleController: Optional<BubbleController>,
@@ -1309,6 +1317,7 @@ constructor(
        context,
        transitions,
        taskDisplayAreaOrganizer,
        desksOrganizer,
        desktopUserRepositories,
        interactionJankMonitor,
        bubbleController,
+46 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKT
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.CancelState
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.Companion.DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.shared.desktopmode.FakeDesktopState
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -80,6 +81,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {

    @Mock private lateinit var transitions: Transitions
    @Mock private lateinit var taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
    @Mock private lateinit var desksOrganizer: DesksOrganizer
    @Mock private lateinit var splitScreenController: SplitScreenController
    @Mock private lateinit var dragAnimator: MoveToDesktopAnimator
    @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
@@ -114,6 +116,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
                    context,
                    transitions,
                    taskDisplayAreaOrganizer,
                    desksOrganizer,
                    desktopUserRepositories,
                    mockInteractionJankMonitor,
                    Optional.of(bubbleController),
@@ -130,6 +133,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
                    context,
                    transitions,
                    taskDisplayAreaOrganizer,
                    desksOrganizer,
                    desktopUserRepositories,
                    mockInteractionJankMonitor,
                    Optional.of(bubbleController),
@@ -542,6 +546,40 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
        verify(finishCallback).onTransitionFinished(null)
    }

    @Test
    fun mergeAnimation_endTransition_hasDeskChange_doesNotMoveBehindDraggedTask() {
        val playingFinishTransaction = mock<SurfaceControl.Transaction>()
        val mergedStartTransaction = mock<SurfaceControl.Transaction>()
        val mergedFinishTransaction = mock<SurfaceControl.Transaction>()
        val finishCallback = mock<Transitions.TransitionFinishCallback>()
        val deskChange = createDeskChange()
        val task = createTask()
        val startTransition =
            startDrag(defaultHandler, task, finishTransaction = playingFinishTransaction)
        defaultHandler.onTaskResizeAnimationListener = mock()
        whenever(desksOrganizer.isDeskChange(deskChange)).thenReturn(true)

        defaultHandler.mergeAnimation(
            transition = mock<IBinder>(),
            info =
                createTransitionInfo(
                    type = TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP,
                    draggedTask = task,
                    deskChange = deskChange,
                ),
            startT = mergedStartTransaction,
            finishT = mergedFinishTransaction,
            mergeTarget = startTransition,
            finishCallback = finishCallback,
        )

        // Don't move the desk leash back, or it will take the dragged task with it.
        verify(mergedStartTransaction, never())
            .setRelativeLayer(eq(deskChange.leash), eq(draggedTaskLeash), anyInt())
        verify(playingFinishTransaction, never())
            .setRelativeLayer(eq(deskChange.leash), eq(draggedTaskLeash), anyInt())
    }

    @Test
    fun mergeAnimation_endTransition_springHandler_hidesHome() {
        whenever(dragAnimator.computeCurrentVelocity()).thenReturn(PointF())
@@ -1192,6 +1230,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
        draggedTask: RunningTaskInfo,
        homeChange: TransitionInfo.Change? = createHomeChange(),
        rootLeash: SurfaceControl = mock(),
        deskChange: TransitionInfo.Change? = null,
    ) =
        TransitionInfo(type, /* flags= */ 0).apply {
            homeChange?.let { addChange(it) }
@@ -1201,6 +1240,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
                    taskInfo = draggedTask
                }
            )
            deskChange?.let { addChange(it) }
            addChange( // Wallpaper.
                TransitionInfo.Change(mock(), wallpaperLeash).apply {
                    parent = null
@@ -1218,6 +1258,12 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
            flags = flags or FLAG_IS_WALLPAPER
        }

    private fun createDeskChange() =
        TransitionInfo.Change(mock(), mock()).apply {
            parent = null
            taskInfo = TestRunningTaskInfoBuilder().build()
        }

    private fun systemPropertiesKey(name: String) =
        "${SpringDragToDesktopTransitionHandler.SYSTEM_PROPERTIES_GROUP}.$name"