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

Commit 6ad1e984 authored by Massimo Carli's avatar Massimo Carli
Browse files

[83/n] Fix Enter to Desktop and improve empty letterbox bounds case

The check on eligible task needs to be used at this stage.

When the letterboxBounds are empty we must assume the activity
is not letterboxed.

Flag: EXEMPT Refactoring
Bug: 430486865
Test: atest WMShellUnitTests:LetterboxLifecycleControllerImplTest

Change-Id: I85c6d455b6cd06525db7f77449e1993f77363fd4
parent 35aee866
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.window.flags.Flags.appCompatRefactoring
import com.android.wm.shell.compatui.letterbox.lifecycle.LetterboxLifecycleController
import com.android.wm.shell.compatui.letterbox.lifecycle.LetterboxLifecycleEventFactory
import com.android.wm.shell.compatui.letterbox.lifecycle.isChangeForALeafTask
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_APP_COMPAT
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
@@ -64,7 +65,7 @@ class DelegateLetterboxTransitionObserver(
            return
        }
        info.changes.forEach { change ->
            if (letterboxLifecycleEventFactory.canHandle(change)) {
            if (change.isChangeForALeafTask() && letterboxLifecycleEventFactory.canHandle(change)) {
                letterboxLifecycleEventFactory.createLifecycleEvent(change)?.let { event ->
                    letterboxLifecycleController.onLetterboxLifecycleEvent(
                        event,
+12 −9
Original line number Diff line number Diff line
@@ -37,8 +37,9 @@ class LetterboxLifecycleControllerImpl(
        // Each [LetterboxController] will handle its own Surfaces and will be responsible to
        // avoid the creation happens twice or that some visibility/size change operation
        // happens on missing surfaces.
        val isLetterboxed = event.letterboxBounds?.isEmpty == false
        with(letterboxController) {
            if (event.letterboxBounds != null) {
            if (isLetterboxed) {
                // In this case the top Activity is letterboxed.
                event.taskLeash?.let { taskLeash ->
                    letterboxModeStrategy.configureLetterboxMode(event)
@@ -53,21 +54,23 @@ class LetterboxLifecycleControllerImpl(
            updateLetterboxSurfaceVisibility(
                key,
                startTransaction,
                visible = event.letterboxBounds != null
                visible = isLetterboxed
            )
            // This happens after the visibility update because it needs to
            // check if the surfaces to show have empty bounds. When that happens
            // the clipAndCrop() doesn't actually work because cropping an empty
            // Rect means "do not crop" with the result of a surface filling the
            // task completely.
            if (event.letterboxBounds != null) {
            if (isLetterboxed) {
                event.letterboxBounds?.let { activityBounds ->
                    updateLetterboxSurfaceBounds(
                        key,
                        startTransaction,
                        event.taskBounds,
                    event.letterboxBounds
                        activityBounds
                    )
                }
            }
        }
    }
}
+45 −5
Original line number Diff line number Diff line
@@ -80,7 +80,31 @@ class DelegateLetterboxTransitionObserverTest : ShellTestCase() {
                r.invokeShellInit()
                transitionInfo {
                    type = TRANSIT_MOVE_LETTERBOX_REACHABILITY
                    addChange { }
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(true)
                        }
                    }
                }
                validateOnTransitionReady {
                    r.checkLifecycleControllerInvoked(times = 0)
                }
            }
        }
    }

    @Test
    @EnableFlags(Flags.FLAG_APP_COMPAT_REFACTORING)
    fun `LetterboxLifecycleController for not leaf tasks`() {
        runTestScenario { r ->
            executeTransitionObserverTest(observerFactory = r.observerFactory) {
                r.invokeShellInit()
                transitionInfo {
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(false)
                        }
                    }
                }
                validateOnTransitionReady {
                    r.checkLifecycleControllerInvoked(times = 0)
@@ -111,7 +135,11 @@ class DelegateLetterboxTransitionObserverTest : ShellTestCase() {
            executeTransitionObserverTest(observerFactory = r.observerFactory) {
                r.invokeShellInit()
                transitionInfo {
                    addChange { }
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(true)
                        }
                    }
                }
                validateOnTransitionReady {
                    r.checkLifecycleControllerInvoked(times = 1)
@@ -127,9 +155,21 @@ class DelegateLetterboxTransitionObserverTest : ShellTestCase() {
            executeTransitionObserverTest(observerFactory = r.observerFactory) {
                r.invokeShellInit()
                transitionInfo {
                    addChange { }
                    addChange { }
                    addChange { }
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(true)
                        }
                    }
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(true)
                        }
                    }
                    addChange {
                        runningTaskInfo { ti ->
                            ti.appCompatTaskInfo.setIsLeafTask(true)
                        }
                    }
                }
                validateOnTransitionReady {
                    r.checkLifecycleControllerInvoked(times = 3)
+45 −1
Original line number Diff line number Diff line
@@ -27,13 +27,13 @@ import com.android.wm.shell.compatui.letterbox.LetterboxController
import com.android.wm.shell.compatui.letterbox.LetterboxControllerStrategy
import com.android.wm.shell.compatui.letterbox.LetterboxKey
import com.android.wm.shell.compatui.letterbox.asMode
import java.util.function.Consumer
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import java.util.function.Consumer

/**
 * Tests for [LetterboxLifecycleControllerImpl].
@@ -57,6 +57,19 @@ class LetterboxLifecycleControllerImplTest : ShellTestCase() {
        }
    }

    @Test
    fun `Letterbox is hidden with OPEN Transition but not letterboxed as empty`() {
        runTestScenario { r ->
            r.invokeLifecycleControllerWith(
                r.createLifecycleEvent(
                    type = LetterboxLifecycleEventType.OPEN,
                    letterboxBounds = Rect()
                )
            )
            r.verifyUpdateLetterboxSurfaceVisibility(expected = true)
        }
    }

    @Test
    fun `Surface created with OPEN Transition and letterboxed with leash`() {
        runTestScenario { r ->
@@ -71,6 +84,20 @@ class LetterboxLifecycleControllerImplTest : ShellTestCase() {
        }
    }

    @Test
    fun `Surface NOT created with OPEN Transition and NO letterboxed with leash`() {
        runTestScenario { r ->
            r.invokeLifecycleControllerWith(
                r.createLifecycleEvent(
                    type = LetterboxLifecycleEventType.OPEN,
                    letterboxBounds = Rect()
                )
            )
            r.verifyStrategyIsInvoked(expected = false)
            r.verifyCreateLetterboxSurface(expected = false)
        }
    }

    @Test
    fun `Surface NOT created with OPEN Transition and letterboxed with NO leash`() {
        runTestScenario { r ->
@@ -103,6 +130,23 @@ class LetterboxLifecycleControllerImplTest : ShellTestCase() {
        }
    }

    @Test
    fun `Surface Bounds NOT updated with OPEN Transition and NOT letterboxed`() {
        runTestScenario { r ->
            r.invokeLifecycleControllerWith(
                r.createLifecycleEvent(
                    type = LetterboxLifecycleEventType.OPEN,
                    letterboxBounds = Rect(),
                    eventTaskLeash = null
                )
            )
            r.verifyUpdateLetterboxSurfaceBounds(
                expected = false,
                letterboxBounds = Rect()
            )
        }
    }

    /**
     * Runs a test scenario providing a Robot.
     */