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

Commit 2ac2fc86 authored by Qijing Yao's avatar Qijing Yao
Browse files

Disable drag indicator for ineligible displays

An older change(I40b82ac54b58d8e58b7a87c8fe3c68cdda480e3c) was
implemented to disable the drag indicator for non-desktop-mode-supported
displays. But the fix was not comprehensive. This commit uses the
consolidated method in ShellDesktopState to verify a display's
eligibility as a drop target before showing the indicator.

Bug: b/383069176
Test: manual and atest
Flag: com.android.window.flags.enable_block_non_desktop_display_window_drag_bugfix
Change-Id: Iaad418172382e6c19845f83c3777ae0c28eb2284
parent 8d9a86bc
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ import android.graphics.RectF
import android.view.SurfaceControl
import android.window.DesktopExperienceFlags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.shared.desktopmode.DesktopState
import com.android.wm.shell.desktopmode.ShellDesktopState

/**
 * Controller to manage the indicators that show users the current position of the dragged window on
@@ -30,7 +30,7 @@ class MultiDisplayDragMoveIndicatorController(
    private val displayController: DisplayController,
    private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    private val indicatorSurfaceFactory: MultiDisplayDragMoveIndicatorSurface.Factory,
    private val desktopState: DesktopState,
    private val shellDesktopState: ShellDesktopState,
) {
    private val dragIndicators =
        mutableMapOf<Int, MutableMap<Int, MultiDisplayDragMoveIndicatorSurface>>()
@@ -55,10 +55,17 @@ class MultiDisplayDragMoveIndicatorController(
            displayController.getDisplayLayout(startDisplayId)?.densityDpi() ?: return
        val transaction = transactionSupplier()
        for (displayId in displayIds) {
            val allowDropToDisplay =
                if (
                    DesktopExperienceFlags.ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX
                        .isTrue
                )
                    shellDesktopState.isEligibleWindowDropTarget(displayId)
                else shellDesktopState.isDesktopModeSupportedOnDisplay(displayId)
            if (
                (displayId == startDisplayId &&
                    !DesktopExperienceFlags.ENABLE_WINDOW_DROP_SMOOTH_TRANSITION.isTrue) ||
                    !desktopState.isDesktopModeSupportedOnDisplay(displayId)
                    !allowDropToDisplay
            ) {
                // No need to render indicators on displays that do not support desktop mode.
                continue
+2 −2
Original line number Diff line number Diff line
@@ -1291,11 +1291,11 @@ public abstract class WMShellModule {
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            MultiDisplayDragMoveIndicatorSurface.Factory
                multiDisplayDragMoveIndicatorSurfaceFactory,
            DesktopState desktopState
            ShellDesktopState shellDesktopState
    ) {
        return new MultiDisplayDragMoveIndicatorController(
                displayController, rootTaskDisplayAreaOrganizer,
                multiDisplayDragMoveIndicatorSurfaceFactory, desktopState);
                multiDisplayDragMoveIndicatorSurfaceFactory, shellDesktopState);
    }

    @WMSingleton
+17 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.MultiDisplayTestUtil.TestDisplay
import com.android.wm.shell.desktopmode.FakeShellDesktopState
import com.android.wm.shell.shared.desktopmode.FakeDesktopState
import java.util.function.Supplier
import org.junit.Before
@@ -52,7 +53,7 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
    private val displayController = mock<DisplayController>()
    private val rootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>()
    private val indicatorSurfaceFactory = mock<MultiDisplayDragMoveIndicatorSurface.Factory>()
    private val desktopState = FakeDesktopState()
    private val shellDesktopState = FakeShellDesktopState(FakeDesktopState())
    private val indicatorSurface0 = mock<MultiDisplayDragMoveIndicatorSurface>()
    private val indicatorSurface1 = mock<MultiDisplayDragMoveIndicatorSurface>()
    private val transaction = mock<SurfaceControl.Transaction>()
@@ -80,7 +81,7 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
                displayController,
                rootTaskDisplayAreaOrganizer,
                indicatorSurfaceFactory,
                desktopState,
                shellDesktopState,
            )

        TestDisplay.DISPLAY_0.getSpyDisplayLayout(resources.resources)
@@ -97,7 +98,7 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
        whenever(indicatorSurfaceFactory.create(eq(displayContext1), eq(taskLeash)))
            .thenReturn(indicatorSurface1)
        whenever(transactionSupplier.get()).thenReturn(transaction)
        desktopState.canEnterDesktopMode = true
        shellDesktopState.canBeWindowDropTarget = true
    }

    @Test
@@ -117,7 +118,10 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION)
    @EnableFlags(
        Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION,
        Flags.FLAG_ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX,
    )
    fun onDrag_boundsIntersectWithStartDisplay_showIndicator() {
        controller.onDragMove(
            RectF(100f, 100f, 200f, 200f), // intersect with display 0
@@ -144,9 +148,12 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION)
    @EnableFlags(
        Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION,
        Flags.FLAG_ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX,
    )
    fun onDrag_boundsIntersectWithDesktopModeUnsupportedDisplay_noIndicatorOnThatDisplay() {
        desktopState.overrideDesktopModeSupportPerDisplay[1] = false
        shellDesktopState.overrideWindowDropTargetEligibility[1] = false

        controller.onDragMove(
            RectF(100f, -100f, 200f, 200f), // intersect with display 0 and 1
@@ -163,7 +170,10 @@ class MultiDisplayDragMoveIndicatorControllerTest : ShellTestCase() {
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION)
    @EnableFlags(
        Flags.FLAG_ENABLE_WINDOW_DROP_SMOOTH_TRANSITION,
        Flags.FLAG_ENABLE_BLOCK_NON_DESKTOP_DISPLAY_WINDOW_DRAG_BUGFIX,
    )
    fun onDrag_boundsIntersectWithNonStartDisplayAndMoveAway_showHideAndDisposeIndicator() {
        controller.onDragMove(
            RectF(100f, -100f, 200f, 200f), // intersect with display 0 and 1