Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt +28 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.ActivityManager.RunningTaskInfo import android.content.Context import android.os.IBinder import android.view.SurfaceControl Loading Loading @@ -162,11 +163,7 @@ class DesktopTasksLimiter( !taskRepository.isClosingTask(it) } logV("runOnIdle, expandedTasks=$expandedTaskIds, after transition=$transition") val taskIdToMinimize = getTaskIdToMinimize(expandedTaskIds, /* launchingNewIntent= */ false) if (taskIdToMinimize != null) { triggerMinimizeTransition(launchDetails.deskId, taskIdToMinimize) } triggerMinimizeTransition(launchDetails.deskId, expandedTaskIds) } } Loading Loading @@ -194,8 +191,8 @@ class DesktopTasksLimiter( } } private fun triggerMinimizeTransition(deskId: Int, taskIdToMinimize: Int) { val task = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize) ?: return private fun triggerMinimizeTransition(deskId: Int, expandedTaskIds: List<Int>) { val task = getRunningTaskToMinimize(expandedTaskIds) ?: return logV("triggerMinimizeTransition, found running task -> start transition, %s", task) val wct = WindowContainerTransaction() addMinimizeChange(deskId, task, wct) Loading @@ -209,6 +206,26 @@ class DesktopTasksLimiter( ) } private fun getRunningTaskToMinimize(expandedTaskIds: List<Int>): RunningTaskInfo? { var taskIds = expandedTaskIds for (i in 1..expandedTaskIds.size) { val taskIdToMinimize = getTaskIdToMinimize(taskIds, /* launchingNewIntent= */ false) ?: return null val task = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize) if (task != null) { return task } else { logW( "Tried to minimize non-running task#%s, Try next task instead.", taskIdToMinimize, ) } // Ignore the non-existing task taskIds = taskIds.minus(taskIdToMinimize) } return null } private fun handleMinimizeTransitionReady( taskRepository: DesktopRepository, transition: IBinder, Loading Loading @@ -461,6 +478,10 @@ class DesktopTasksLimiter( ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } private fun logW(msg: String, vararg arguments: Any?) { ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } private companion object { const val TAG = "DesktopTasksLimiter" } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt +57 −0 Original line number Diff line number Diff line Loading @@ -724,6 +724,63 @@ class DesktopTasksLimiterTest : ShellTestCase() { .isEqualTo(existingTasks.first().taskId) } @Test fun onTransitionReady_taskLimitTransition_taskNotAvailable_minimizesNextTask() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0) val transition = Binder() val minimizeTransition = Binder() val existingTasks = (1..MAX_TASK_LIMIT + 1).map { setUpFreeformTask() } // Make the bottom task non-available `when`(shellTaskOrganizer.getRunningTaskInfo(existingTasks.first().taskId)).thenReturn(null) val launchTask = setUpFreeformTask() desktopTasksLimiter.addPendingTaskLimitTransition( transition, deskId = 0, taskId = launchTask.taskId, ) val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, launchTask).build() whenever(desktopMixedTransitionHandler.startTaskLimitMinimizeTransition(any(), anyInt())) .thenReturn(minimizeTransition) callOnTransitionReady(transition, transitionInfo) val onIdleArgumentCaptor = argumentCaptor<Runnable>() verify(transitions).runOnIdle(onIdleArgumentCaptor.capture()) onIdleArgumentCaptor.lastValue.run() verify(desktopMixedTransitionHandler).startTaskLimitMinimizeTransition(any(), any()) // Ensure we minimize the second task, since the first one is not available assertThat(desktopTasksLimiter.getMinimizingTask(minimizeTransition)?.taskId) .isEqualTo(existingTasks[1].taskId) } @Test fun onTransitionReady_taskLimitTransition_taskNotAvailable_nextTaskBelowLimit_doesntMinimize() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0) val transition = Binder() val existingTasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() } // Make the bottom task non-available `when`(shellTaskOrganizer.getRunningTaskInfo(existingTasks.first().taskId)).thenReturn(null) val launchTask = setUpFreeformTask() desktopTasksLimiter.addPendingTaskLimitTransition( transition, deskId = 0, taskId = launchTask.taskId, ) val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, launchTask).build() callOnTransitionReady(transition, transitionInfo) val onIdleArgumentCaptor = argumentCaptor<Runnable>() verify(transitions).runOnIdle(onIdleArgumentCaptor.capture()) onIdleArgumentCaptor.lastValue.run() verify(desktopMixedTransitionHandler, never()) .startTaskLimitMinimizeTransition(any(), any()) } @Test fun onTransitionReady_noPendingTaskLimitTransition_doesntTriggerOnIdle() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt +28 −7 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager import android.app.ActivityManager.RunningTaskInfo import android.content.Context import android.os.IBinder import android.view.SurfaceControl Loading Loading @@ -162,11 +163,7 @@ class DesktopTasksLimiter( !taskRepository.isClosingTask(it) } logV("runOnIdle, expandedTasks=$expandedTaskIds, after transition=$transition") val taskIdToMinimize = getTaskIdToMinimize(expandedTaskIds, /* launchingNewIntent= */ false) if (taskIdToMinimize != null) { triggerMinimizeTransition(launchDetails.deskId, taskIdToMinimize) } triggerMinimizeTransition(launchDetails.deskId, expandedTaskIds) } } Loading Loading @@ -194,8 +191,8 @@ class DesktopTasksLimiter( } } private fun triggerMinimizeTransition(deskId: Int, taskIdToMinimize: Int) { val task = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize) ?: return private fun triggerMinimizeTransition(deskId: Int, expandedTaskIds: List<Int>) { val task = getRunningTaskToMinimize(expandedTaskIds) ?: return logV("triggerMinimizeTransition, found running task -> start transition, %s", task) val wct = WindowContainerTransaction() addMinimizeChange(deskId, task, wct) Loading @@ -209,6 +206,26 @@ class DesktopTasksLimiter( ) } private fun getRunningTaskToMinimize(expandedTaskIds: List<Int>): RunningTaskInfo? { var taskIds = expandedTaskIds for (i in 1..expandedTaskIds.size) { val taskIdToMinimize = getTaskIdToMinimize(taskIds, /* launchingNewIntent= */ false) ?: return null val task = shellTaskOrganizer.getRunningTaskInfo(taskIdToMinimize) if (task != null) { return task } else { logW( "Tried to minimize non-running task#%s, Try next task instead.", taskIdToMinimize, ) } // Ignore the non-existing task taskIds = taskIds.minus(taskIdToMinimize) } return null } private fun handleMinimizeTransitionReady( taskRepository: DesktopRepository, transition: IBinder, Loading Loading @@ -461,6 +478,10 @@ class DesktopTasksLimiter( ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } private fun logW(msg: String, vararg arguments: Any?) { ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } private companion object { const val TAG = "DesktopTasksLimiter" } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt +57 −0 Original line number Diff line number Diff line Loading @@ -724,6 +724,63 @@ class DesktopTasksLimiterTest : ShellTestCase() { .isEqualTo(existingTasks.first().taskId) } @Test fun onTransitionReady_taskLimitTransition_taskNotAvailable_minimizesNextTask() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0) val transition = Binder() val minimizeTransition = Binder() val existingTasks = (1..MAX_TASK_LIMIT + 1).map { setUpFreeformTask() } // Make the bottom task non-available `when`(shellTaskOrganizer.getRunningTaskInfo(existingTasks.first().taskId)).thenReturn(null) val launchTask = setUpFreeformTask() desktopTasksLimiter.addPendingTaskLimitTransition( transition, deskId = 0, taskId = launchTask.taskId, ) val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, launchTask).build() whenever(desktopMixedTransitionHandler.startTaskLimitMinimizeTransition(any(), anyInt())) .thenReturn(minimizeTransition) callOnTransitionReady(transition, transitionInfo) val onIdleArgumentCaptor = argumentCaptor<Runnable>() verify(transitions).runOnIdle(onIdleArgumentCaptor.capture()) onIdleArgumentCaptor.lastValue.run() verify(desktopMixedTransitionHandler).startTaskLimitMinimizeTransition(any(), any()) // Ensure we minimize the second task, since the first one is not available assertThat(desktopTasksLimiter.getMinimizingTask(minimizeTransition)?.taskId) .isEqualTo(existingTasks[1].taskId) } @Test fun onTransitionReady_taskLimitTransition_taskNotAvailable_nextTaskBelowLimit_doesntMinimize() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) desktopTaskRepo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 0) val transition = Binder() val existingTasks = (1..MAX_TASK_LIMIT).map { setUpFreeformTask() } // Make the bottom task non-available `when`(shellTaskOrganizer.getRunningTaskInfo(existingTasks.first().taskId)).thenReturn(null) val launchTask = setUpFreeformTask() desktopTasksLimiter.addPendingTaskLimitTransition( transition, deskId = 0, taskId = launchTask.taskId, ) val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN).addChange(TRANSIT_OPEN, launchTask).build() callOnTransitionReady(transition, transitionInfo) val onIdleArgumentCaptor = argumentCaptor<Runnable>() verify(transitions).runOnIdle(onIdleArgumentCaptor.capture()) onIdleArgumentCaptor.lastValue.run() verify(desktopMixedTransitionHandler, never()) .startTaskLimitMinimizeTransition(any(), any()) } @Test fun onTransitionReady_noPendingTaskLimitTransition_doesntTriggerOnIdle() { desktopTaskRepo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 0) Loading