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

Commit 21da8120 authored by Jorge Gil's avatar Jorge Gil
Browse files

No-op when deactivating non-existent desk roots instead of throwing

When a display is disconnected while recents was running in that
display, two things happen roughly at the same time:
1) A new core-started transit request is sent to Shell for handling
the disconnection, which usually leads to the desk root getting removed
2) The ongoing recents transition is finished, which can lead to a desk
deactivation if recents had been entered through a desk

(1) and (2) can race, and if (1) is faster (all the way through
RootTaskDesksOrganizer received the onTaskVanished callback), then by
the time (2) attemps to add the deactivation changes for that root, the
root will no longer exist.

Instead of throwing an error, just no-op since the deactivation changes
for this desk aren't needed anyway if it was removed by the
disconnection.

Flag: EXEMPT bugfix
Fix: 427563407
Test: atest RootTaskDesksOrganizerTest
Change-Id: I848a3e678383b621a56d07a0e5cb90c11b5bafb9
parent 5a7d6c00
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -240,7 +240,17 @@ class RootTaskDesksOrganizer(
            "RootTaskDesksOrganizer#deactivateDesk: $deskId",
        )
        logV("deactivateDesk %d", deskId)
        val root = checkNotNull(deskRootsByDeskId[deskId]) { "Root not found for desk: $deskId" }
        val root = deskRootsByDeskId[deskId]
        if (root == null) {
            // This is possible because a deactivation might be requested soon after a removal as
            // part of the same two-part recents transition (so not the same WCT), so if the
            // removal (all the way through onTaskVanish) is faster than the second part of the
            // transition, the desk root will have been removed already. See b/427563407.
            // No-op in this case, since the desk is already gone anyway it doesn't matter whether
            // it is deactivated.
            logW("Attempted to deactivate non-existent desk=%d", deskId)
            return
        }
        if (!skipReorder) wct.reorder(root.taskInfo.token, /* onTop= */ false)
        updateLaunchRoot(wct, deskId, enabled = false)
        updateTaskMoveAllowed(wct, deskId, allowed = false)
+16 −0
Original line number Diff line number Diff line
@@ -752,6 +752,22 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
            .isFalse()
    }

    @Test
    fun testDeactivateDesk_deskWasRemoved_skipsInsteadOfThrowing() = runTest {
        val desk = createDeskSuspending(userId = PRIMARY_USER_ID)
        organizer.removeDesk(
            wct = WindowContainerTransaction(),
            deskId = desk.deskRoot.deskId,
            userId = PRIMARY_USER_ID,
        )
        organizer.onTaskVanished(desk.deskRoot.taskInfo)

        val wct = WindowContainerTransaction()
        organizer.deactivateDesk(wct, desk.deskRoot.deskId)

        assertThat(wct.isEmpty).isTrue()
    }

    @Test
    fun isDeskChange_forDeskId() = runTest {
        val desk = createDeskSuspending()