Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +91 −8 Original line number Diff line number Diff line Loading @@ -17,12 +17,20 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.WindowConfiguration import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.app.WindowConfiguration.WindowingMode import android.content.Context import android.view.WindowManager import android.os.IBinder import android.view.SurfaceControl import android.view.WindowManager.TRANSIT_CHANGE import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.TransitionInfo import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import androidx.annotation.BinderThread import com.android.internal.protolog.common.ProtoLog Loading Loading @@ -51,7 +59,7 @@ class DesktopTasksController( private val transitions: Transitions, private val desktopModeTaskRepository: DesktopModeTaskRepository, @ShellMainThread private val mainExecutor: ShellExecutor ) : RemoteCallable<DesktopTasksController> { ) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler { private val desktopMode: DesktopModeImpl Loading @@ -69,6 +77,7 @@ class DesktopTasksController( { createExternalInterface() }, this ) transitions.addHandler(this) } /** Show all tasks, that are part of the desktop, on top of launcher */ Loading @@ -81,7 +90,7 @@ class DesktopTasksController( // Execute transaction if there are pending operations if (!wct.isEmpty) { if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_TO_FRONT, wct, null /* handler */) transitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading @@ -101,11 +110,11 @@ class DesktopTasksController( // Bring other apps to front first bringDesktopAppsToFront(wct) wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FREEFORM) wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FREEFORM) wct.reorder(task.getToken(), true /* onTop */) if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */) transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading @@ -121,10 +130,10 @@ class DesktopTasksController( ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId) val wct = WindowContainerTransaction() wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FULLSCREEN) wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FULLSCREEN) wct.setBounds(task.getToken(), null) if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */) transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading Loading @@ -181,6 +190,80 @@ class DesktopTasksController( return mainExecutor } override fun startAnimation( transition: IBinder, info: TransitionInfo, startTransaction: SurfaceControl.Transaction, finishTransaction: SurfaceControl.Transaction, finishCallback: Transitions.TransitionFinishCallback ): Boolean { // This handler should never be the sole handler, so should not animate anything. return false } override fun handleRequest( transition: IBinder, request: TransitionRequestInfo ): WindowContainerTransaction? { // Check if we should skip handling this transition val task: ActivityManager.RunningTaskInfo? = request.triggerTask val shouldHandleRequest = when { // Only handle open or to front transitions request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> false // Only handle when it is a task transition task == null -> false // Only handle standard type tasks task.activityType != ACTIVITY_TYPE_STANDARD -> false // Only handle fullscreen or freeform tasks task.windowingMode != WINDOWING_MODE_FULLSCREEN && task.windowingMode != WINDOWING_MODE_FREEFORM -> false // Otherwise process it else -> true } if (!shouldHandleRequest) { return null } val activeTasks = desktopModeTaskRepository.getActiveTasks() // Check if we should switch a fullscreen task to freeform if (task?.windowingMode == WINDOWING_MODE_FULLSCREEN) { // If there are any visible desktop tasks, switch the task to freeform if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) { ProtoLog.d( WM_SHELL_DESKTOP_MODE, "DesktopTasksController#handleRequest: switch fullscreen task to freeform," + " taskId=%d", task.taskId ) return WindowContainerTransaction().apply { setWindowingMode(task.token, WINDOWING_MODE_FREEFORM) } } } // CHeck if we should switch a freeform task to fullscreen if (task?.windowingMode == WINDOWING_MODE_FREEFORM) { // If no visible desktop tasks, switch this task to freeform as the transition came // outside of this controller if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) { ProtoLog.d( WM_SHELL_DESKTOP_MODE, "DesktopTasksController#handleRequest: switch freeform task to fullscreen," + " taskId=%d", task.taskId ) return WindowContainerTransaction().apply { setWindowingMode(task.token, WINDOWING_MODE_FULLSCREEN) setBounds(task.token, null) } } } return null } /** Creates a new instance of the external interface to pass to another process. */ private fun createExternalInterface(): ExternalInterfaceBinder { return IDesktopModeImpl(this) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +129 −2 Original line number Diff line number Diff line Loading @@ -17,10 +17,18 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.os.Binder import android.testing.AndroidTestingRunner import android.view.WindowManager import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER import androidx.test.filters.SmallTest Loading @@ -29,6 +37,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask Loading @@ -37,9 +46,11 @@ import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeT import com.android.wm.shell.sysui.ShellController import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -79,6 +90,7 @@ class DesktopTasksControllerTest : ShellTestCase() { desktopModeTaskRepository = DesktopModeTaskRepository() whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } controller = createController() Loading Loading @@ -221,6 +233,114 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(controller.getTaskWindowingMode(999)).isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask = setUpFreeformTask() markTaskVisible(freeformTask) val fullscreenTask = createFullscreenTask() val result = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } @Test fun handleRequest_fullscreenTask_freeformNotVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask = setUpFreeformTask() markTaskHidden(freeformTask) val fullscreenTask = createFullscreenTask() assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_fullscreenTask_noOtherTasks_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val fullscreenTask = createFullscreenTask() assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull() } @Test fun handleRequest_freeformTask_freeformNotVisible_returnSwitchToFullscreenWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskHidden(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest( Binder(), createTransition(freeformTask2, type = TRANSIT_TO_FRONT) ) assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) } @Test fun handleRequest_freeformTask_noOtherTasks_returnSwitchToFullscreenWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = createFreeformTask() val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) } @Test fun handleRequest_notOpenOrToFrontTransition_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder() .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_FULLSCREEN) .build() val transition = createTransition(task = task, type = WindowManager.TRANSIT_CLOSE) val result = controller.handleRequest(Binder(), transition) assertThat(result).isNull() } @Test fun handleRequest_noTriggerTask_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) assertThat(controller.handleRequest(Binder(), createTransition(task = null))).isNull() } @Test fun handleRequest_triggerTaskNotStandard_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build() assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull() } @Test fun handleRequest_triggerTaskNotFullscreenOrFreeform_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder() .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW) .build() assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull() } private fun setUpFreeformTask(): RunningTaskInfo { val task = createFreeformTask() whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) Loading Loading @@ -254,7 +374,7 @@ class DesktopTasksControllerTest : ShellTestCase() { private fun getLatestWct(): WindowContainerTransaction { val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { verify(transitions).startTransition(anyInt(), arg.capture(), isNull()) } else { verify(shellTaskOrganizer).applyTransaction(arg.capture()) Loading @@ -263,12 +383,19 @@ class DesktopTasksControllerTest : ShellTestCase() { } private fun verifyWCTNotExecuted() { if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { verify(transitions, never()).startTransition(anyInt(), any(), isNull()) } else { verify(shellTaskOrganizer, never()).applyTransaction(any()) } } private fun createTransition( task: RunningTaskInfo?, @WindowManager.TransitionType type: Int = TRANSIT_OPEN ): TransitionRequestInfo { return TransitionRequestInfo(type, task, null /* remoteTransition */) } } private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +91 −8 Original line number Diff line number Diff line Loading @@ -17,12 +17,20 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.WindowConfiguration import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.app.WindowConfiguration.WindowingMode import android.content.Context import android.view.WindowManager import android.os.IBinder import android.view.SurfaceControl import android.view.WindowManager.TRANSIT_CHANGE import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.TransitionInfo import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import androidx.annotation.BinderThread import com.android.internal.protolog.common.ProtoLog Loading Loading @@ -51,7 +59,7 @@ class DesktopTasksController( private val transitions: Transitions, private val desktopModeTaskRepository: DesktopModeTaskRepository, @ShellMainThread private val mainExecutor: ShellExecutor ) : RemoteCallable<DesktopTasksController> { ) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler { private val desktopMode: DesktopModeImpl Loading @@ -69,6 +77,7 @@ class DesktopTasksController( { createExternalInterface() }, this ) transitions.addHandler(this) } /** Show all tasks, that are part of the desktop, on top of launcher */ Loading @@ -81,7 +90,7 @@ class DesktopTasksController( // Execute transaction if there are pending operations if (!wct.isEmpty) { if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_TO_FRONT, wct, null /* handler */) transitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading @@ -101,11 +110,11 @@ class DesktopTasksController( // Bring other apps to front first bringDesktopAppsToFront(wct) wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FREEFORM) wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FREEFORM) wct.reorder(task.getToken(), true /* onTop */) if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */) transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading @@ -121,10 +130,10 @@ class DesktopTasksController( ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId) val wct = WindowContainerTransaction() wct.setWindowingMode(task.getToken(), WindowConfiguration.WINDOWING_MODE_FULLSCREEN) wct.setWindowingMode(task.getToken(), WINDOWING_MODE_FULLSCREEN) wct.setBounds(task.getToken(), null) if (Transitions.ENABLE_SHELL_TRANSITIONS) { transitions.startTransition(WindowManager.TRANSIT_CHANGE, wct, null /* handler */) transitions.startTransition(TRANSIT_CHANGE, wct, null /* handler */) } else { shellTaskOrganizer.applyTransaction(wct) } Loading Loading @@ -181,6 +190,80 @@ class DesktopTasksController( return mainExecutor } override fun startAnimation( transition: IBinder, info: TransitionInfo, startTransaction: SurfaceControl.Transaction, finishTransaction: SurfaceControl.Transaction, finishCallback: Transitions.TransitionFinishCallback ): Boolean { // This handler should never be the sole handler, so should not animate anything. return false } override fun handleRequest( transition: IBinder, request: TransitionRequestInfo ): WindowContainerTransaction? { // Check if we should skip handling this transition val task: ActivityManager.RunningTaskInfo? = request.triggerTask val shouldHandleRequest = when { // Only handle open or to front transitions request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> false // Only handle when it is a task transition task == null -> false // Only handle standard type tasks task.activityType != ACTIVITY_TYPE_STANDARD -> false // Only handle fullscreen or freeform tasks task.windowingMode != WINDOWING_MODE_FULLSCREEN && task.windowingMode != WINDOWING_MODE_FREEFORM -> false // Otherwise process it else -> true } if (!shouldHandleRequest) { return null } val activeTasks = desktopModeTaskRepository.getActiveTasks() // Check if we should switch a fullscreen task to freeform if (task?.windowingMode == WINDOWING_MODE_FULLSCREEN) { // If there are any visible desktop tasks, switch the task to freeform if (activeTasks.any { desktopModeTaskRepository.isVisibleTask(it) }) { ProtoLog.d( WM_SHELL_DESKTOP_MODE, "DesktopTasksController#handleRequest: switch fullscreen task to freeform," + " taskId=%d", task.taskId ) return WindowContainerTransaction().apply { setWindowingMode(task.token, WINDOWING_MODE_FREEFORM) } } } // CHeck if we should switch a freeform task to fullscreen if (task?.windowingMode == WINDOWING_MODE_FREEFORM) { // If no visible desktop tasks, switch this task to freeform as the transition came // outside of this controller if (activeTasks.none { desktopModeTaskRepository.isVisibleTask(it) }) { ProtoLog.d( WM_SHELL_DESKTOP_MODE, "DesktopTasksController#handleRequest: switch freeform task to fullscreen," + " taskId=%d", task.taskId ) return WindowContainerTransaction().apply { setWindowingMode(task.token, WINDOWING_MODE_FULLSCREEN) setBounds(task.token, null) } } } return null } /** Creates a new instance of the external interface to pass to another process. */ private fun createExternalInterface(): ExternalInterfaceBinder { return IDesktopModeImpl(this) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +129 −2 Original line number Diff line number Diff line Loading @@ -17,10 +17,18 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.os.Binder import android.testing.AndroidTestingRunner import android.view.WindowManager import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER import androidx.test.filters.SmallTest Loading @@ -29,6 +37,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask Loading @@ -37,9 +46,11 @@ import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeT import com.android.wm.shell.sysui.ShellController import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.After import org.junit.Assume.assumeTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -79,6 +90,7 @@ class DesktopTasksControllerTest : ShellTestCase() { desktopModeTaskRepository = DesktopModeTaskRepository() whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } controller = createController() Loading Loading @@ -221,6 +233,114 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(controller.getTaskWindowingMode(999)).isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask = setUpFreeformTask() markTaskVisible(freeformTask) val fullscreenTask = createFullscreenTask() val result = controller.handleRequest(Binder(), createTransition(fullscreenTask)) assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } @Test fun handleRequest_fullscreenTask_freeformNotVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask = setUpFreeformTask() markTaskHidden(freeformTask) val fullscreenTask = createFullscreenTask() assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_fullscreenTask_noOtherTasks_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val fullscreenTask = createFullscreenTask() assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull() } @Test fun handleRequest_freeformTask_freeformNotVisible_returnSwitchToFullscreenWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskHidden(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest( Binder(), createTransition(freeformTask2, type = TRANSIT_TO_FRONT) ) assertThat(result?.changes?.get(freeformTask2.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) } @Test fun handleRequest_freeformTask_noOtherTasks_returnSwitchToFullscreenWCT() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = createFreeformTask() val result = controller.handleRequest(Binder(), createTransition(task)) assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) } @Test fun handleRequest_notOpenOrToFrontTransition_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder() .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_FULLSCREEN) .build() val transition = createTransition(task = task, type = WindowManager.TRANSIT_CLOSE) val result = controller.handleRequest(Binder(), transition) assertThat(result).isNull() } @Test fun handleRequest_noTriggerTask_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) assertThat(controller.handleRequest(Binder(), createTransition(task = null))).isNull() } @Test fun handleRequest_triggerTaskNotStandard_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build() assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull() } @Test fun handleRequest_triggerTaskNotFullscreenOrFreeform_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val task = TestRunningTaskInfoBuilder() .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW) .build() assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull() } private fun setUpFreeformTask(): RunningTaskInfo { val task = createFreeformTask() whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) Loading Loading @@ -254,7 +374,7 @@ class DesktopTasksControllerTest : ShellTestCase() { private fun getLatestWct(): WindowContainerTransaction { val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { verify(transitions).startTransition(anyInt(), arg.capture(), isNull()) } else { verify(shellTaskOrganizer).applyTransaction(arg.capture()) Loading @@ -263,12 +383,19 @@ class DesktopTasksControllerTest : ShellTestCase() { } private fun verifyWCTNotExecuted() { if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { verify(transitions, never()).startTransition(anyInt(), any(), isNull()) } else { verify(shellTaskOrganizer, never()).applyTransaction(any()) } } private fun createTransition( task: RunningTaskInfo?, @WindowManager.TransitionType type: Int = TRANSIT_OPEN ): TransitionRequestInfo { return TransitionRequestInfo(type, task, null /* remoteTransition */) } } private fun WindowContainerTransaction.assertReorderAt(index: Int, task: RunningTaskInfo) { Loading