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

Commit d37a9688 authored by Massimo Carli's avatar Massimo Carli Committed by Android (Google) Code Review
Browse files

Merge "[83/n] Fix Enter to Desktop and improve empty letterbox bounds case" into main

parents eee2c2d8 6ad1e984
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.
     */