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

Commit 666c6b12 authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas
Browse files

Clear topTransparentFullscreenTask from repository if another task opens

The DesktopTransistionObserver does not receive the close or to back
transition for the top transparent fullscreen task causing it to not be
cleared correctly. This leads to freeform windows opening outside of
desktop as we think desktop stop is still showing.

Instead, if the top transparent fullscreen task has not been cleared as
another task opens, or is brought to front, clear the top transparent
fullscreen task as it is no longer needed.

Flag: com.android.window.flags.include_top_transparent_fullscreen_task_in_desktop_heuristic
Fixes: 398167855

Test: atest WMShellUnitTests:DesktopTasksTransitionObserverTest
Change-Id: I737d24c1f143843270f554d4828b7f6a5fce063c
parent 55d8b4bf
Loading
Loading
Loading
Loading
+25 −12
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.isExitDesktop
import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.TransitionUtil.isClosingMode
import com.android.wm.shell.shared.TransitionUtil.isOpeningMode
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
@@ -345,18 +347,29 @@ class DesktopTasksTransitionObserver(
    }

    private fun updateTopTransparentFullscreenTaskId(info: TransitionInfo) {
        run forEachLoop@{
            info.changes.forEach { change ->
                change.taskInfo?.let { task ->
                    val desktopRepository = desktopUserRepositories.getProfile(task.userId)
                    val displayId = task.displayId
                    val transparentTaskId =
                        desktopRepository.getTopTransparentFullscreenTaskId(displayId)
                    if (transparentTaskId == null) return@forEachLoop
                    val changeMode = change.mode
                    val taskId = task.taskId
                    val isTopTransparentFullscreenTaskClosing =
                        taskId == transparentTaskId && isClosingMode(changeMode)
                    val isNonTopTransparentFullscreenTaskOpening =
                        taskId != transparentTaskId && isOpeningMode(changeMode)
                    // Clear `topTransparentFullscreenTask` information from repository if task
                // is closed or sent to back.
                    // is closed, sent to back or if a different task is opened, brought to front.
                    if (
                    TransitionUtil.isClosingMode(change.mode) &&
                        task.taskId ==
                            desktopRepository.getTopTransparentFullscreenTaskId(displayId)
                        isTopTransparentFullscreenTaskClosing ||
                            isNonTopTransparentFullscreenTaskOpening
                    ) {
                        desktopRepository.clearTopTransparentFullscreenTaskId(displayId)
                        return@forEachLoop
                    }
                }
            }
        }
+44 −0
Original line number Diff line number Diff line
@@ -335,6 +335,50 @@ class DesktopTasksTransitionObserverTest {
        verify(taskRepository).clearTopTransparentFullscreenTaskId(topTransparentTask.displayId)
    }

    @Test
    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
        Flags.FLAG_INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC,
    )
    fun nonTopTransparentTaskOpened_clearTopTransparentTaskIdFromRepository() {
        val mockTransition = Mockito.mock(IBinder::class.java)
        val topTransparentTask = createTaskInfo(1)
        val nonTopTransparentTask = createTaskInfo(2)
        whenever(taskRepository.getTopTransparentFullscreenTaskId(any()))
            .thenReturn(topTransparentTask.taskId)

        transitionObserver.onTransitionReady(
            transition = mockTransition,
            info = createOpenChangeTransition(nonTopTransparentTask),
            startTransaction = mock(),
            finishTransaction = mock(),
        )

        verify(taskRepository).clearTopTransparentFullscreenTaskId(topTransparentTask.displayId)
    }

    @Test
    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
        Flags.FLAG_INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC,
    )
    fun nonTopTransparentTaskSentToFront_clearTopTransparentTaskIdFromRepository() {
        val mockTransition = Mockito.mock(IBinder::class.java)
        val topTransparentTask = createTaskInfo(1)
        val nonTopTransparentTask = createTaskInfo(2)
        whenever(taskRepository.getTopTransparentFullscreenTaskId(any()))
            .thenReturn(topTransparentTask.taskId)

        transitionObserver.onTransitionReady(
            transition = mockTransition,
            info = createToFrontTransition(nonTopTransparentTask),
            startTransaction = mock(),
            finishTransaction = mock(),
        )

        verify(taskRepository).clearTopTransparentFullscreenTaskId(topTransparentTask.displayId)
    }

    @Test
    fun transitCloseWallpaper_wallpaperActivityVisibilitySaved() {
        val wallpaperTask = createWallpaperTaskInfo()