Loading libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/lifecycle/ActivityLetterboxLifecycleEventFactory.kt +18 −8 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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") Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/lifecycle/ActivityLetterboxLifecycleEventFactoryTest.kt +81 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) } } } Loading @@ -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) } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/lifecycle/ActivityLetterboxLifecycleEventFactory.kt +18 −8 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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") Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/lifecycle/ActivityLetterboxLifecycleEventFactoryTest.kt +81 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) } } } Loading @@ -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) } } }