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

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

Merge "[62/n] Improve letterbox surfaces bounds calculation on Activity Transitions" into main

parents ef00818c 94a80319
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.compatui.letterbox.lifecycle

import android.graphics.Rect
import android.window.TransitionInfo.Change
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.compatui.letterbox.state.LetterboxTaskInfoRepository
@@ -36,25 +37,34 @@ class ActivityLetterboxLifecycleEventFactory(

    override fun canHandle(change: Change): Boolean = change.activityTransitionInfo != null

    // TODO(b/382423480): Extract common behaviour from different LetterboxLifecycleEventFactories.
    override fun createLifecycleEvent(change: Change): LetterboxLifecycleEvent? {
        val activityTransitionInfo = change.activityTransitionInfo
        val taskBounds = change.endAbsBounds
        val taskBoundsAbs = change.endAbsBounds

        val letterboxBoundsTmp = activityTransitionInfo?.appCompatTransitionInfo?.letterboxBounds
        val taskId = activityTransitionInfo?.taskId ?: -1
        taskRepository.find(taskId)?.let {
            val isLetterboxed = letterboxBoundsTmp != taskBounds
        taskRepository.find(taskId)?.let { taskItem ->
            val isLetterboxed = letterboxBoundsTmp != taskBoundsAbs
            // Letterbox bounds are null when the activity is not letterboxed.
            val letterboxBounds = if (isLetterboxed) letterboxBoundsTmp else null
            val taskToken = it.containerToken
            val taskLeash = it.containerLeash
            val letterboxBoundsAbs = if (isLetterboxed) letterboxBoundsTmp else null

            val taskBounds = Rect(taskBoundsAbs).apply {
                offset(-taskBoundsAbs.left, -taskBoundsAbs.top)
            }
            val letterboxBounds = letterboxBoundsAbs?.let { absBounds ->
                Rect(absBounds).apply {
                    offset(-taskBoundsAbs.left, -taskBoundsAbs.top)
                }
            }

            return LetterboxLifecycleEvent(
                type = change.asLetterboxLifecycleEventType(),
                taskId = taskId,
                taskBounds = taskBounds,
                letterboxBounds = letterboxBounds,
                taskLeash = taskLeash,
                containerToken = taskToken
                taskLeash = taskItem.containerLeash,
                containerToken = taskItem.containerToken
            )
        }
        ProtoLog.w(WM_SHELL_APP_COMPAT, "$TAG: Task not found for taskId: $taskId")
+81 −3
Original line number Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.wm.shell.compatui.letterbox.lifecycle

import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.view.SurfaceControl
import android.window.WindowContainerToken
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.compatui.letterbox.state.LetterboxTaskInfoRepository
import com.android.wm.shell.compatui.letterbox.state.LetterboxTaskInfoState
import com.android.wm.shell.util.testLetterboxLifecycleEventFactory
import java.util.function.Consumer
import org.junit.Test
@@ -56,13 +59,84 @@ class ActivityLetterboxLifecycleEventFactoryTest : ShellTestCase() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                inputChange {
                    endAbsBounds = Rect(0, 0, 500, 1000)
                    endAbsBounds = Rect(100, 50, 2000, 1500)
                }
                validateCanHandle { canHandle ->
                    assert(canHandle == false)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event?.taskBounds == Rect(0, 0, 500, 1000))
                    assert(event?.taskBounds == Rect(0, 0, 1900, 1450))
                }
            }
        }
    }

    @Test
    fun `Read Letterbox bounds from activityTransitionInfo and endAbsBounds in Change`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                inputChange {
                    endAbsBounds = Rect(100, 50, 2000, 1500)
                    activityTransitionInfo {
                        appCompatTransitionInfo {
                            letterboxBounds = Rect(500, 50, 1500, 800)
                        }
                    }
                }
                validateCanHandle { canHandle ->
                    assert(canHandle == false)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event?.taskBounds == Rect(0, 0, 1900, 1450))
                    assert(event?.letterboxBounds == Rect(400, 0, 1400, 750))
                }
            }
        }
    }

    @Test
    fun `Uses leash and token from the repository`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                val testLeash = mock<SurfaceControl>()
                val testToken = mock<WindowContainerToken>()
                r.addToTaskRepository(10, LetterboxTaskInfoState(testToken, testLeash))
                inputChange {
                    leash { testLeash }
                    token { testToken }
                    runningTaskInfo { ti ->
                        ti.taskId = 10
                    }
                }
                validateCanHandle { canHandle ->
                    assert(canHandle == false)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event?.taskLeash == testLeash)
                    assert(event?.containerToken == testToken)
                }
            }
        }
    }

    @Test
    fun `Event is null if repository has no task data`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                val testLeash = mock<SurfaceControl>()
                val testToken = mock<WindowContainerToken>()
                inputChange {
                    leash { testLeash }
                    token { testToken }
                    runningTaskInfo { ti ->
                        ti.taskId = 10
                    }
                }
                validateCanHandle { canHandle ->
                    assert(canHandle == false)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event == null)
                }
            }
        }
@@ -82,10 +156,14 @@ class ActivityLetterboxLifecycleEventFactoryTest : ShellTestCase() {
    class ActivityLetterboxLifecycleEventFactoryRobotTest {

        private val letterboxTaskInfoRepository: LetterboxTaskInfoRepository =
            mock<LetterboxTaskInfoRepository>()
            LetterboxTaskInfoRepository()

        fun getLetterboxLifecycleEventFactory(): () -> LetterboxLifecycleEventFactory = {
            ActivityLetterboxLifecycleEventFactory(letterboxTaskInfoRepository)
        }

        fun addToTaskRepository(key: Int, state: LetterboxTaskInfoState) {
            letterboxTaskInfoRepository.insert(key = key, item = state, overrideIfPresent = true)
        }
    }
}