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

Commit a93517d6 authored by Omar Elmekkawy's avatar Omar Elmekkawy
Browse files

Add display reconnect support for tiling.

Bug: 426198281
Test: Disconnect a display with desks and tiling, then reconnect it
Flag: com.android.window.flags.enable_display_disconnect_interaction
Flag: com.android.window.flags.enable_display_reconnect_interaction
Change-Id: I2563502fc3261c01dabdf4a313c2d150a56be4c8
parent 4cabd1d8
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -61,6 +61,9 @@ class DesktopRepository(
    /** Specific [TaskInfo] data related to top transparent fullscreen task handling. */
    data class TopTransparentFullscreenTaskData(val taskId: Int, val token: WindowContainerToken)

    /** Tiling data preserved after a display got disconnected. */
    data class PreservedTiledAppData(val leftTiledTask: Int?, val rightTiledTask: Int?)

    /**
     * Task data tracked per desk.
     *
@@ -228,6 +231,17 @@ class DesktopRepository(
    fun getPreservedActiveDesk(uniqueDisplayId: String): Int? =
        preservedDisplaysByUniqueId[uniqueDisplayId]?.activeDeskId

    /** Returns a preserved desk data post a display reconnect event. */
    fun getPreservedTilingData(
        uniqueDisplayId: String,
        preservedDeskId: Int?,
    ): PreservedTiledAppData? =
        preservedDisplaysByUniqueId[uniqueDisplayId]
            ?.orderedDesks
            ?.firstOrNull { desk -> desk.deskId == preservedDeskId }
            ?.let { PreservedTiledAppData(it.leftTiledTaskId, it.rightTiledTaskId) }
            ?.takeIf { it.leftTiledTask != null || it.rightTiledTask != null }

    /**
     * Checks if the provided task is minimized on the preserved display with the provided
     * uniqueDisplayId.
+25 −4
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.android.wm.shell.windowdecor.extension.isMultiWindow
import com.android.wm.shell.windowdecor.extension.requestingImmersive
import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
import com.android.wm.shell.windowdecor.tiling.TilingDisplayReconnectEventHandler
import java.io.PrintWriter
import java.util.Optional
import java.util.concurrent.Executor
@@ -710,7 +711,7 @@ class DesktopTasksController(
                    "destinationDisplayId=$destinationDisplayId"
            )
        }
        snapEventHandler.onDisplayDisconnected(disconnectedDisplayId, desktopModeSupportedOnDisplay)
        snapEventHandler.onDisplayDisconnected(disconnectedDisplayId)
        removeWallpaperTask(wct, disconnectedDisplayId)
        removeHomeTask(wct, disconnectedDisplayId)
        userRepositories.forAllRepositories { desktopRepository ->
@@ -822,7 +823,13 @@ class DesktopTasksController(
        val wct = WindowContainerTransaction()
        var runOnTransitStart: RunOnTransitStart? = null
        val destDisplayLayout = displayController.getDisplayLayout(displayId) ?: return

        val tilingReconnectHandler =
            TilingDisplayReconnectEventHandler(
                taskRepository,
                snapEventHandler,
                transitions,
                displayId,
            )
        mainScope.launch {
            preservedTaskIdsByDeskId.forEach { (preservedDeskId, preservedTaskIds) ->
                val newDeskId =
@@ -835,8 +842,8 @@ class DesktopTasksController(
                    "restoreDisplay: created new desk deskId=$newDeskId " +
                        "from preserved deskId=$preservedDeskId"
                )

                if (preservedDeskId == activeDeskId) {
                val isActiveDesk = preservedDeskId == activeDeskId
                if (isActiveDesk) {
                    runOnTransitStart = addDeskActivationChanges(deskId = newDeskId, wct = wct)
                }

@@ -850,8 +857,22 @@ class DesktopTasksController(
                        boundsByTaskId[taskId],
                    )
                }

                val preservedTilingData =
                    taskRepository.getPreservedTilingData(uniqueDisplayId, preservedDeskId)
                if (preservedTilingData != null) {
                    tilingReconnectHandler.addTilingDisplayReconnectSession(
                        TilingDisplayReconnectEventHandler.TilingDisplayReconnectSession(
                            preservedTilingData.leftTiledTask,
                            preservedTilingData.rightTiledTask,
                            newDeskId,
                            isActiveDesk,
                        )
                    )
                }
            }
            val transition = transitions.startTransition(TRANSIT_CHANGE, wct, null)
            tilingReconnectHandler.activationBinder = transition
            runOnTransitStart?.invoke(transition)
            taskRepository.removePreservedDisplay(uniqueDisplayId)
        }
+2 −5
Original line number Diff line number Diff line
@@ -967,7 +967,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        if (!mDesktopTilingDecorViewModel.onDeskActivated(deskId)) {
            return;
        }

        final DesktopRepository repository = mDesktopUserRepositories.getCurrent();
        final Integer leftTaskId = repository.getLeftTiledTask(deskId);
        final Integer rightTaskId =  repository.getRightTiledTask(deskId);
@@ -1024,10 +1023,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    }

    @Override
    public void onDisplayDisconnected(int disconnectedDisplayId,
            boolean desktopModeSupportedOnNewDisplay) {
        mDesktopTilingDecorViewModel.onDisplayDisconnected(disconnectedDisplayId,
                desktopModeSupportedOnNewDisplay);
    public void onDisplayDisconnected(int disconnectedDisplayId) {
        mDesktopTilingDecorViewModel.onDisplayDisconnected(disconnectedDisplayId);
    }

    @Override
+5 −7
Original line number Diff line number Diff line
@@ -189,23 +189,20 @@ class DesktopTilingDecorViewModel(
     */
    fun onDisplayDisconnected(
        disconnectedDisplayId: Int,
        desktopModeSupportedOnNewDisplay: Boolean,
    ) {
        if (!desktopModeSupportedOnNewDisplay) {
            resetAllDesksWithDisplayId(disconnectedDisplayId)
            return
        }
        // Reset the tiling session but keep the persistence data for when the moved desks
        // are activated again.
        for (userHandlerList in tilingHandlerByUserAndDeskId.valueIterator()) {
            val desksToRemove = ArrayList<Int>()
            for (desk in userHandlerList.keyIterator()) {
                val handler = userHandlerList[desk]
                if (disconnectedDisplayId == handler.displayId) {
                    handler.resetTilingSession(shouldPersistTilingData = true)
                    userHandlerList.remove(desk)
                    desksToRemove.add(desk)
                    disconnectedDisplayDesks.add(desk)
                }
            }
            desksToRemove.forEach { desk -> userHandlerList.remove(desk) }
        }
    }

@@ -282,7 +279,8 @@ class DesktopTilingDecorViewModel(
    }

    /** Removes [deskId] from the previously deactivated desks to mark it's activation. */
    fun onDeskActivated(deskId: Int): Boolean = disconnectedDisplayDesks.remove(deskId)
    fun onDeskActivated(deskId: Int): Boolean =
        disconnectedDisplayDesks.remove(deskId) || !tilingHandlerByUserAndDeskId.contains(deskId)

    /** Destroys a tiling session for a removed desk. */
    fun onDeskRemoved(deskId: Int) {
+1 −5
Original line number Diff line number Diff line
@@ -67,12 +67,8 @@ interface SnapEventHandler {

    /**
     * Notifies the snap event handler of a display disconnect event.
     *
     * [desktopModeSupportedOnNewDisplay] is a boolean that indicates whether a display supports
     * desktop mode after the external display disconnection, for example a tablet or a secondary
     * display.
     */
    fun onDisplayDisconnected(disconnectedDisplayId: Int, desktopModeSupportedOnNewDisplay: Boolean)
    fun onDisplayDisconnected(disconnectedDisplayId: Int)

    /**
     * Notifies the snap event handler of a desk being activated.
Loading