Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt +21 −0 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.TaskInfo import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.content.Context import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK Loading @@ -37,11 +39,14 @@ import android.graphics.Rect import android.os.SystemProperties import android.util.Size import android.window.DesktopModeFlags import android.window.SplashScreen.SPLASH_SCREEN_STYLE_ICON import com.android.internal.policy.DesktopModeCompatUtils import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.desktopmode.data.DesktopRepository import com.android.wm.shell.desktopmode.data.DesktopRepository.Companion.INVALID_DESK_ID import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.recents.RecentTasksController import kotlin.math.ceil import kotlin.math.max Loading Loading @@ -458,6 +463,22 @@ private fun isClosingExitingInstance(intentFlags: Int) = (intentFlags and FLAG_ACTIVITY_CLEAR_TASK) != 0 || (intentFlags and FLAG_ACTIVITY_MULTIPLE_TASK) == 0 /** Creates basic activity options to be used for starting a task in desktop mode. */ fun createActivityOptionsForStartTask( deskId: Int = INVALID_DESK_ID, desksOrganizer: DesksOrganizer, ): ActivityOptions { val activityOptions = ActivityOptions.makeBasic().apply { launchWindowingMode = WINDOWING_MODE_FREEFORM splashScreenStyle = SPLASH_SCREEN_STYLE_ICON } if (deskId != INVALID_DESK_ID) { desksOrganizer.addLaunchDeskToActivityOptions(activityOptions, deskId) } return activityOptions } /** * Calculates the desired initial bounds for applications in desktop windowing. This is done as a * scale of the screen bounds. Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +13 −16 Original line number Diff line number Diff line Loading @@ -1057,9 +1057,12 @@ class DesktopTasksController( "addRestoreTaskToDeskChanges: taskId=$taskId; deskId=$deskId; userId=$userId; " + "taskBounds=$taskBounds; uniqueDisplayId=$uniqueDisplayId" ) val repository = userRepositories.getProfile(userId) val minimized = repository.isPreservedTaskMinimized(uniqueDisplayId, taskId) val task = shellTaskOrganizer.getRunningTaskInfo(taskId) val task = shellTaskOrganizer.getRunningTaskInfo(taskId) ?: recentTasksController?.findTaskInBackground(taskId) if (task == null) { logE("restoreDisplay: Could not find running task info for taskId=$taskId.") return null Loading Loading @@ -2979,7 +2982,10 @@ class DesktopTasksController( } else if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // Task is not running, start it val startDesk = repository.getDefaultDeskId(displayId) ?: INVALID_DESK_ID wct.startTask(taskId, createActivityOptionsForStartTask(startDesk).toBundle()) wct.startTask( taskId, createActivityOptionsForStartTask(startDesk, desksOrganizer).toBundle(), ) } } Loading Loading @@ -4815,7 +4821,10 @@ class DesktopTasksController( .forEach { taskId -> val runningTaskInfo = shellTaskOrganizer.getRunningTaskInfo(taskId) if (runningTaskInfo == null) { wct.startTask(taskId, createActivityOptionsForStartTask(deskId).toBundle()) wct.startTask( taskId, createActivityOptionsForStartTask(deskId, desksOrganizer).toBundle(), ) } else { desksOrganizer.reorderTaskToFront(wct, deskId, runningTaskInfo) } Loading Loading @@ -5020,7 +5029,7 @@ class DesktopTasksController( // Task is not running, start it. wct.startTask( taskIdToReorderToFront, createActivityOptionsForStartTask(deskId).toBundle(), createActivityOptionsForStartTask(deskId, desksOrganizer).toBundle(), ) } else -> { Loading Loading @@ -5878,18 +5887,6 @@ class DesktopTasksController( } } private fun createActivityOptionsForStartTask(deskId: Int = INVALID_DESK_ID): ActivityOptions { val activityOptions = ActivityOptions.makeBasic().apply { launchWindowingMode = WINDOWING_MODE_FREEFORM splashScreenStyle = SPLASH_SCREEN_STYLE_ICON } if (deskId != INVALID_DESK_ID) { desksOrganizer.addLaunchDeskToActivityOptions(activityOptions, deskId) } return activityOptions } private fun dump(pw: PrintWriter, prefix: String) { val innerPrefix = "$prefix " pw.println("${prefix}DesktopTasksController") Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.desktopmode.multidesks import android.app.ActivityManager import android.app.ActivityOptions import android.app.TaskInfo import android.window.TransitionInfo import android.window.WindowContainerTransaction Loading Loading @@ -48,7 +49,7 @@ interface DesksOrganizer { fun moveTaskToDesk( wct: WindowContainerTransaction, deskId: Int, task: ActivityManager.RunningTaskInfo, task: TaskInfo, minimized: Boolean = false, ) Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt +8 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.wm.shell.desktopmode.multidesks import android.annotation.SuppressLint import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.ActivityTaskManager.INVALID_TASK_ID import android.app.TaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM Loading @@ -40,6 +42,7 @@ import com.android.internal.protolog.ProtoLog import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.LaunchAdjacentController import com.android.wm.shell.desktopmode.createActivityOptionsForStartTask import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer.OnCreateCallback import com.android.wm.shell.freeform.TaskChangeListener import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE Loading Loading @@ -294,11 +297,14 @@ class RootTaskDesksOrganizer( override fun moveTaskToDesk( wct: WindowContainerTransaction, deskId: Int, task: RunningTaskInfo, task: TaskInfo, minimized: Boolean, ) { logV("moveTaskToDesk task=${task.taskId} desk=$deskId minimized=$minimized") val root = deskRootsByDeskId[deskId] ?: error("Root not found for desk: $deskId") if (task is RecentTaskInfo) { wct.startTask(task.taskId, createActivityOptionsForStartTask(deskId, this).toBundle()) } wct.setWindowingMode(task.token, WINDOWING_MODE_UNDEFINED) if (!minimized) { wct.reparent(task.token, root.taskInfo.token, /* onTop= */ true) Loading Loading @@ -344,7 +350,7 @@ class RootTaskDesksOrganizer( private fun minimizeTaskInner( wct: WindowContainerTransaction, deskId: Int, task: RunningTaskInfo, task: TaskInfo, enforceTaskInDesk: Boolean = true, ) { logV( Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt +13 −0 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.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD Loading @@ -25,10 +26,14 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_PINNED import android.content.ComponentName import android.graphics.Point import android.graphics.Rect import android.view.Display.DEFAULT_DISPLAY import android.window.IWindowContainerToken import android.window.WindowContainerToken import com.android.wm.shell.MockToken import com.android.wm.shell.TestRunningTaskInfoBuilder import org.mockito.Mockito.mock object DesktopTestHelpers { /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ Loading Loading @@ -72,6 +77,14 @@ object DesktopTestHelpers { fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo = createFullscreenTaskBuilder(displayId).build() fun createRecentTaskInfo(taskId: Int, displayId: Int = DEFAULT_DISPLAY): RecentTaskInfo = RecentTaskInfo().apply { this.taskId = taskId this.displayId = displayId token = WindowContainerToken(mock(IWindowContainerToken::class.java)) positionInParent = Point() } /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */ fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo = TestRunningTaskInfoBuilder() Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt +21 −0 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ package com.android.wm.shell.desktopmode import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.TaskInfo import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.content.Context import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK Loading @@ -37,11 +39,14 @@ import android.graphics.Rect import android.os.SystemProperties import android.util.Size import android.window.DesktopModeFlags import android.window.SplashScreen.SPLASH_SCREEN_STYLE_ICON import com.android.internal.policy.DesktopModeCompatUtils import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.desktopmode.data.DesktopRepository import com.android.wm.shell.desktopmode.data.DesktopRepository.Companion.INVALID_DESK_ID import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.recents.RecentTasksController import kotlin.math.ceil import kotlin.math.max Loading Loading @@ -458,6 +463,22 @@ private fun isClosingExitingInstance(intentFlags: Int) = (intentFlags and FLAG_ACTIVITY_CLEAR_TASK) != 0 || (intentFlags and FLAG_ACTIVITY_MULTIPLE_TASK) == 0 /** Creates basic activity options to be used for starting a task in desktop mode. */ fun createActivityOptionsForStartTask( deskId: Int = INVALID_DESK_ID, desksOrganizer: DesksOrganizer, ): ActivityOptions { val activityOptions = ActivityOptions.makeBasic().apply { launchWindowingMode = WINDOWING_MODE_FREEFORM splashScreenStyle = SPLASH_SCREEN_STYLE_ICON } if (deskId != INVALID_DESK_ID) { desksOrganizer.addLaunchDeskToActivityOptions(activityOptions, deskId) } return activityOptions } /** * Calculates the desired initial bounds for applications in desktop windowing. This is done as a * scale of the screen bounds. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +13 −16 Original line number Diff line number Diff line Loading @@ -1057,9 +1057,12 @@ class DesktopTasksController( "addRestoreTaskToDeskChanges: taskId=$taskId; deskId=$deskId; userId=$userId; " + "taskBounds=$taskBounds; uniqueDisplayId=$uniqueDisplayId" ) val repository = userRepositories.getProfile(userId) val minimized = repository.isPreservedTaskMinimized(uniqueDisplayId, taskId) val task = shellTaskOrganizer.getRunningTaskInfo(taskId) val task = shellTaskOrganizer.getRunningTaskInfo(taskId) ?: recentTasksController?.findTaskInBackground(taskId) if (task == null) { logE("restoreDisplay: Could not find running task info for taskId=$taskId.") return null Loading Loading @@ -2979,7 +2982,10 @@ class DesktopTasksController( } else if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // Task is not running, start it val startDesk = repository.getDefaultDeskId(displayId) ?: INVALID_DESK_ID wct.startTask(taskId, createActivityOptionsForStartTask(startDesk).toBundle()) wct.startTask( taskId, createActivityOptionsForStartTask(startDesk, desksOrganizer).toBundle(), ) } } Loading Loading @@ -4815,7 +4821,10 @@ class DesktopTasksController( .forEach { taskId -> val runningTaskInfo = shellTaskOrganizer.getRunningTaskInfo(taskId) if (runningTaskInfo == null) { wct.startTask(taskId, createActivityOptionsForStartTask(deskId).toBundle()) wct.startTask( taskId, createActivityOptionsForStartTask(deskId, desksOrganizer).toBundle(), ) } else { desksOrganizer.reorderTaskToFront(wct, deskId, runningTaskInfo) } Loading Loading @@ -5020,7 +5029,7 @@ class DesktopTasksController( // Task is not running, start it. wct.startTask( taskIdToReorderToFront, createActivityOptionsForStartTask(deskId).toBundle(), createActivityOptionsForStartTask(deskId, desksOrganizer).toBundle(), ) } else -> { Loading Loading @@ -5878,18 +5887,6 @@ class DesktopTasksController( } } private fun createActivityOptionsForStartTask(deskId: Int = INVALID_DESK_ID): ActivityOptions { val activityOptions = ActivityOptions.makeBasic().apply { launchWindowingMode = WINDOWING_MODE_FREEFORM splashScreenStyle = SPLASH_SCREEN_STYLE_ICON } if (deskId != INVALID_DESK_ID) { desksOrganizer.addLaunchDeskToActivityOptions(activityOptions, deskId) } return activityOptions } private fun dump(pw: PrintWriter, prefix: String) { val innerPrefix = "$prefix " pw.println("${prefix}DesktopTasksController") Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt +2 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.desktopmode.multidesks import android.app.ActivityManager import android.app.ActivityOptions import android.app.TaskInfo import android.window.TransitionInfo import android.window.WindowContainerTransaction Loading Loading @@ -48,7 +49,7 @@ interface DesksOrganizer { fun moveTaskToDesk( wct: WindowContainerTransaction, deskId: Int, task: ActivityManager.RunningTaskInfo, task: TaskInfo, minimized: Boolean = false, ) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt +8 −2 Original line number Diff line number Diff line Loading @@ -16,9 +16,11 @@ package com.android.wm.shell.desktopmode.multidesks import android.annotation.SuppressLint import android.app.ActivityManager.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.ActivityOptions import android.app.ActivityTaskManager.INVALID_TASK_ID import android.app.TaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM Loading @@ -40,6 +42,7 @@ import com.android.internal.protolog.ProtoLog import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.LaunchAdjacentController import com.android.wm.shell.desktopmode.createActivityOptionsForStartTask import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer.OnCreateCallback import com.android.wm.shell.freeform.TaskChangeListener import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE Loading Loading @@ -294,11 +297,14 @@ class RootTaskDesksOrganizer( override fun moveTaskToDesk( wct: WindowContainerTransaction, deskId: Int, task: RunningTaskInfo, task: TaskInfo, minimized: Boolean, ) { logV("moveTaskToDesk task=${task.taskId} desk=$deskId minimized=$minimized") val root = deskRootsByDeskId[deskId] ?: error("Root not found for desk: $deskId") if (task is RecentTaskInfo) { wct.startTask(task.taskId, createActivityOptionsForStartTask(deskId, this).toBundle()) } wct.setWindowingMode(task.token, WINDOWING_MODE_UNDEFINED) if (!minimized) { wct.reparent(task.token, root.taskInfo.token, /* onTop= */ true) Loading Loading @@ -344,7 +350,7 @@ class RootTaskDesksOrganizer( private fun minimizeTaskInner( wct: WindowContainerTransaction, deskId: Int, task: RunningTaskInfo, task: TaskInfo, enforceTaskInDesk: Boolean = true, ) { logV( Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt +13 −0 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.RecentTaskInfo import android.app.ActivityManager.RunningTaskInfo import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD Loading @@ -25,10 +26,14 @@ import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_PINNED import android.content.ComponentName import android.graphics.Point import android.graphics.Rect import android.view.Display.DEFAULT_DISPLAY import android.window.IWindowContainerToken import android.window.WindowContainerToken import com.android.wm.shell.MockToken import com.android.wm.shell.TestRunningTaskInfoBuilder import org.mockito.Mockito.mock object DesktopTestHelpers { /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ Loading Loading @@ -72,6 +77,14 @@ object DesktopTestHelpers { fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo = createFullscreenTaskBuilder(displayId).build() fun createRecentTaskInfo(taskId: Int, displayId: Int = DEFAULT_DISPLAY): RecentTaskInfo = RecentTaskInfo().apply { this.taskId = taskId this.displayId = displayId token = WindowContainerToken(mock(IWindowContainerToken::class.java)) positionInParent = Point() } /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */ fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo = TestRunningTaskInfoBuilder() Loading