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

Commit 33ded4d4 authored by Ats Jenk's avatar Ats Jenk
Browse files

Enable drag from app handle on foldables

On devices without desktop, enable drag from app handle.
When dragging, default to no change in app running mode (fullscreen
stays fullscreen by default etc).

Bug: 388851898
Test: atest WMShellUnitTests:DesktopModeVisualIndicatorTest
Flag: com.android.wm.shell.enable_bubble_to_fullscreen
Change-Id: Ib1b5e9f4363f8f0791ae853f176fb1dbf8947750
parent bbd48bf2
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;

/**
 * Animated visual indicator for Desktop Mode windowing transitions.
@@ -149,12 +151,19 @@ public class DesktopModeVisualIndicator {
        // left, and split right for the right edge. This is universal across all drag event types.
        if (inputCoordinates.x < 0) return TO_SPLIT_LEFT_INDICATOR;
        if (inputCoordinates.x > layout.width()) return TO_SPLIT_RIGHT_INDICATOR;
        IndicatorType result;
        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()
                && !DesktopModeStatus.canEnterDesktopMode(mContext)) {
            // If desktop is not available, default to "no indicator"
            result = NO_INDICATOR;
        } else {
            // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
            // In drags not originating on a freeform caption, we should default to a TO_DESKTOP
            // indicator.
        IndicatorType result = mDragStartState == DragStartState.FROM_FREEFORM
            result = mDragStartState == DragStartState.FROM_FREEFORM
                    ? NO_INDICATOR
                    : TO_DESKTOP_INDICATOR;
        }
        final int transitionAreaWidth = mContext.getResources().getDimensionPixelSize(
                com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness);
        // Because drags in freeform use task position for indicator calculation, we need to
+6 −1
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ import com.android.wm.shell.recents.RecentsTransitionStateListener;
import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.desktopmode.DesktopModeCompatPolicy;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
@@ -1440,13 +1441,17 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
                mDragToDesktopAnimationStartBounds.set(
                        relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
                boolean dragFromStatusBarAllowed = false;
                final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
                if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
                    // In proto2 any full screen or multi-window task can be dragged to
                    // freeform.
                    final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
                    dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
                            || windowingMode == WINDOWING_MODE_MULTI_WINDOW;
                }
                if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
                    // TODO(b/388851898): add support for split screen (multi-window wm mode)
                    dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN;
                }
                final boolean shouldStartTransitionDrag =
                        relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)
                                || DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue();
+55 −1
Original line number Diff line number Diff line
@@ -19,22 +19,30 @@ package com.android.wm.shell.desktopmode
import android.app.ActivityManager.RunningTaskInfo
import android.graphics.PointF
import android.graphics.Rect
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.SurfaceControl
import androidx.test.filters.SmallTest
import com.android.internal.policy.SystemBarUtils
import com.android.modules.utils.testing.ExtendedMockitoRule
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.kotlin.any
import org.mockito.kotlin.whenever

/**
@@ -43,9 +51,19 @@ import org.mockito.kotlin.whenever
 * Usage: atest WMShellUnitTests:DesktopModeVisualIndicatorTest
 */
@SmallTest
@RunWithLooper
@RunWith(AndroidTestingRunner::class)
@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
class DesktopModeVisualIndicatorTest : ShellTestCase() {
    @Mock private lateinit var taskInfo: RunningTaskInfo

    @JvmField @Rule val setFlagsRule = SetFlagsRule()

    @JvmField
    @Rule
    val extendedMockitoRule =
        ExtendedMockitoRule.Builder(this).mockStatic(DesktopModeStatus::class.java).build()!!

    private lateinit var taskInfo: RunningTaskInfo
    @Mock private lateinit var syncQueue: SyncTransactionQueue
    @Mock private lateinit var displayController: DisplayController
    @Mock private lateinit var taskSurface: SurfaceControl
@@ -56,10 +74,13 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {

    @Before
    fun setUp() {
        whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(true)
        whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
        whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
        whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
        whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
        whenever(displayController.getDisplay(anyInt())).thenReturn(mContext.display)
        taskInfo = DesktopTestHelpers.createFullscreenTask()
    }

    @Test
@@ -190,6 +211,39 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
    }

    @Test
    @EnableFlags(
        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
    )
    fun testDefaultIndicatorWithNoDesktop() {
        whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(false)

        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
        var result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)

        result = visualIndicator.updateIndicatorType(PointF(10000f, 500f))
        assertThat(result)
            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)

        result = visualIndicator.updateIndicatorType(PointF(-10000f, 500f))
        assertThat(result)
            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)

        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)

        result = visualIndicator.updateIndicatorType(PointF(500f, 0f))
        assertThat(result)
            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)

        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
    }

    private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) {
        visualIndicator =
            DesktopModeVisualIndicator(