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

Commit 499d1ded authored by Omar Elmekkawy's avatar Omar Elmekkawy
Browse files

Add support for tiling session persistence.

This CL initializes tiled apps as soon as the decoration is created upon
entering desktop mode after device restart.

Flag: com.android.window.flags.enable_tile_resizing

Flag: com.android.window.flags.enable_desktop_windowing_persistence

Test: unit tests and on device testing

Bug: 400973989
Change-Id: I66967998ee5bc356196128d8b13be033d1d8150a
parent 421044be
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,

        if (decoration == null) {
            createWindowDecoration(taskInfo, taskSurface, startT, finishT);
            initializeTiling(taskInfo);
        } else {
            decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                    false /* shouldSetTaskPositionAndCrop */,
@@ -640,6 +641,30 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        }
    }

    private void initializeTiling(RunningTaskInfo taskInfo) {
        DesktopRepository taskRepository = mDesktopUserRepositories.getCurrent();
        Integer leftTiledTaskId = taskRepository.getLeftTiledTask(taskInfo.displayId);
        Integer rightTiledTaskId = taskRepository.getRightTiledTask(taskInfo.displayId);
        boolean tilingAndPersistenceEnabled = DesktopModeFlags.ENABLE_TILE_RESIZING.isTrue()
                && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue();
        if (leftTiledTaskId != null && leftTiledTaskId == taskInfo.taskId
                && tilingAndPersistenceEnabled) {
            snapPersistedTaskToHalfScreen(
                    taskInfo,
                    taskInfo.configuration.windowConfiguration.getBounds(),
                    SnapPosition.LEFT
            );
        }
        if (rightTiledTaskId != null && rightTiledTaskId == taskInfo.taskId
                && tilingAndPersistenceEnabled) {
            snapPersistedTaskToHalfScreen(
                    taskInfo,
                    taskInfo.configuration.windowConfiguration.getBounds(),
                    SnapPosition.RIGHT
            );
        }
    }

    @Override
    public void onTaskClosing(
            RunningTaskInfo taskInfo,
@@ -950,7 +975,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    public boolean snapToHalfScreen(@NonNull RunningTaskInfo taskInfo,
            @NonNull Rect currentDragBounds, @NonNull SnapPosition position) {
        return mDesktopTilingDecorViewModel.snapToHalfScreen(taskInfo,
                mWindowDecorByTaskId.get(taskInfo.taskId), position, currentDragBounds);
                mWindowDecorByTaskId.get(taskInfo.taskId), position, currentDragBounds, null);
    }

    @Override
    public boolean snapPersistedTaskToHalfScreen(@NotNull RunningTaskInfo taskInfo,
            @NotNull Rect currentDragBounds, @NotNull SnapPosition position) {
        return mDesktopTilingDecorViewModel.snapToHalfScreen(taskInfo,
                mWindowDecorByTaskId.get(taskInfo.taskId), position, currentDragBounds,
                currentDragBounds);
    }

    @Override
+8 −4
Original line number Diff line number Diff line
@@ -80,7 +80,8 @@ class DesktopTilingDecorViewModel(
        taskInfo: ActivityManager.RunningTaskInfo,
        desktopModeWindowDecoration: DesktopModeWindowDecoration,
        position: DesktopTasksController.SnapPosition,
        destinationBounds: Rect,
        currentBounds: Rect,
        destinationBounds: Rect? = null,
    ): Boolean {
        val displayId = taskInfo.displayId
        val handler =
@@ -110,12 +111,15 @@ class DesktopTilingDecorViewModel(
                    newHandler
                }
        transitions.registerObserver(handler)
        return handler.onAppTiled(
        return destinationBounds?.let { handler.onAppTiled(
            taskInfo,
            desktopModeWindowDecoration,
            position,
            destinationBounds,
        )
            currentBounds, it)} ?: handler.onAppTiled(
            taskInfo = taskInfo,
            desktopModeWindowDecoration = desktopModeWindowDecoration,
            position = position,
            currentBounds = currentBounds)
    }

    fun removeTaskIfTiled(displayId: Int, taskId: Int) {
+1 −1
Original line number Diff line number Diff line
@@ -119,8 +119,8 @@ class DesktopTilingWindowDecoration(
        desktopModeWindowDecoration: DesktopModeWindowDecoration,
        position: SnapPosition,
        currentBounds: Rect,
        destinationBounds: Rect = getSnapBounds(position)
    ): Boolean {
        val destinationBounds = getSnapBounds(position)
        val resizeMetadata =
            AppResizingHelper(
                taskInfo,
+7 −0
Original line number Diff line number Diff line
@@ -30,6 +30,13 @@ interface SnapEventHandler {
        position: SnapPosition,
    ): Boolean

    /** Snaps an app to half the screen for tiling after a persistence trigger. */
    fun snapPersistedTaskToHalfScreen(
        taskInfo: RunningTaskInfo,
        currentDragBounds: Rect,
        position: SnapPosition,
    ): Boolean

    /** Removes a task from tiling if it's tiled, for example on task exiting. */
    fun removeTaskIfTiled(displayId: Int, taskId: Int)

+25 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import com.android.wm.shell.desktopmode.DesktopImmersiveController
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction
import com.android.wm.shell.recents.RecentsTransitionStateListener
@@ -94,6 +95,8 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.mockito.quality.Strictness
import org.mockito.kotlin.isNotNull
import org.mockito.kotlin.isNull

/**
 * Tests of [DesktopModeWindowDecorViewModel]
@@ -192,6 +195,28 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
        verify(mockInputMonitor, times(1)).dispose()
    }

    @Test
    fun snapToHalfScreen_callsCorrectPersistenceFunction() {
        val task = createTask(displayId = DEFAULT_DISPLAY, windowingMode = WINDOWING_MODE_FREEFORM)
        desktopModeWindowDecorViewModel.snapToHalfScreen(
            task,
            INITIAL_BOUNDS,
            DesktopTasksController.SnapPosition.LEFT,
        )

        verify(mockTilingWindowDecoration, times(1))
            .snapToHalfScreen(any(), anyOrNull(), any(), any(), isNull())

        desktopModeWindowDecorViewModel.snapPersistedTaskToHalfScreen(
            task,
            INITIAL_BOUNDS,
            DesktopTasksController.SnapPosition.LEFT,
        )

        verify(mockTilingWindowDecoration, times(1))
            .snapToHalfScreen(any(), anyOrNull(), any(), any(), isNotNull())
    }

    @Test
    fun testBackEventHasRightDisplayId() {
        val secondaryDisplay = createVirtualDisplay() ?: return