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

Commit 48ffbbe6 authored by Matt Sziklay's avatar Matt Sziklay Committed by mattsziklay
Browse files

Restore background tasks on reconnect.

If a search for a RunningTaskInfo returns null, look for a RecentTaskInfo instead. Also genericizes DesksOrganizer#moveTaskToDesk to accept RecentTaskInfos and start the task if one is passed in.

Bug: 433379799
Test: Manual
Flag: com.android.window.flags.enable_display_reconnect_interaction
Change-Id: If357900676e1ac2cbfc5085d18e809d48f025163
parent b0dff323
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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.
+13 −16
Original line number Diff line number Diff line
@@ -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
@@ -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(),
                    )
                }
            }

@@ -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)
                    }
@@ -5020,7 +5029,7 @@ class DesktopTasksController(
                    // Task is not running, start it.
                    wct.startTask(
                        taskIdToReorderToFront,
                        createActivityOptionsForStartTask(deskId).toBundle(),
                        createActivityOptionsForStartTask(deskId, desksOrganizer).toBundle(),
                    )
                }
                else -> {
@@ -5866,18 +5875,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")
+2 −1
Original line number Diff line number Diff line
@@ -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

@@ -48,7 +49,7 @@ interface DesksOrganizer {
    fun moveTaskToDesk(
        wct: WindowContainerTransaction,
        deskId: Int,
        task: ActivityManager.RunningTaskInfo,
        task: TaskInfo,
        minimized: Boolean = false,
    )

+8 −2
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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)
@@ -344,7 +350,7 @@ class RootTaskDesksOrganizer(
    private fun minimizeTaskInner(
        wct: WindowContainerTransaction,
        deskId: Int,
        task: RunningTaskInfo,
        task: TaskInfo,
        enforceTaskInDesk: Boolean = true,
    ) {
        logV(
+13 −0
Original line number Diff line number Diff line
@@ -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
@@ -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] */
@@ -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