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

Commit 0da416b3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Desktop Windowing: Log task unminimize events" into main

parents ed20970b c2eda765
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.shared.desktopmode;

parcelable DesktopTaskToFrontReason;
 No newline at end of file
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.shared.desktopmode

import android.os.Parcel
import android.os.Parcelable

/** Reason for moving a task to front in Desktop Mode. */
enum class DesktopTaskToFrontReason : Parcelable {
    UNKNOWN,
    TASKBAR_TAP,
    ALT_TAB,
    TASKBAR_MANAGE_WINDOW;

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeString(name)
    }

    companion object {
        @JvmField
        val CREATOR = object : Parcelable.Creator<DesktopTaskToFrontReason> {
            override fun createFromParcel(parcel: Parcel): DesktopTaskToFrontReason {
                return parcel.readString()?.let { valueOf(it) } ?: UNKNOWN
            }

            override fun newArray(size: Int) = arrayOfNulls<DesktopTaskToFrontReason>(size)
        }
    }
}
+9 −1
Original line number Diff line number Diff line
@@ -407,7 +407,7 @@ class DesktopModeEventLogger {
         * @property taskX x-coordinate of the top-left corner
         * @property taskY y-coordinate of the top-left corner
         * @property minimizeReason the reason the task was minimized
         * @property unminimizeEvent the reason the task was unminimized
         * @property unminimizeReason the reason the task was unminimized
         */
        data class TaskUpdate(
            val instanceId: Int,
@@ -499,6 +499,14 @@ class DesktopModeEventLogger {
                FrameworkStatsLog
                    .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_TASK_LAUNCH
            ),
            APP_HANDLE_MENU_BUTTON(
                FrameworkStatsLog
                    .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_APP_HANDLE_MENU_BUTTON
            ),
            TASKBAR_MANAGE_WINDOW(
                FrameworkStatsLog
                    .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_TASKBAR_MANAGE_WINDOW
            ),
        }

        /**
+19 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterRe
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
@@ -297,7 +298,12 @@ class DesktopModeLoggerTransitionObserver(
            when {
                // new tasks added
                previousTaskInfo == null -> {
                    desktopModeEventLogger.logTaskAdded(currentTaskUpdate)
                    // The current task is now visible while before it wasn't - this might be the
                    // result of an unminimize action.
                    val unminimizeReason = getUnminimizeReason(transition, taskInfo)
                    desktopModeEventLogger.logTaskAdded(
                        currentTaskUpdate.copy(unminimizeReason = unminimizeReason)
                    )
                    Trace.setCounter(
                        Trace.TRACE_TAG_WINDOW_MANAGER,
                        VISIBLE_TASKS_COUNTER_NAME,
@@ -359,13 +365,24 @@ class DesktopModeLoggerTransitionObserver(
        return null
    }

    private fun getUnminimizeReason(transition: IBinder, taskInfo: TaskInfo): UnminimizeReason? {
        val unminimizingTask = desktopTasksLimiter.getOrNull()?.getUnminimizingTask(transition)
        if (unminimizingTask?.taskId == taskInfo.taskId) {
            return unminimizingTask.unminimizeReason
        }
        return null
    }

    private fun buildTaskUpdateForTask(
        taskInfo: TaskInfo,
        visibleTasks: Int,
        minimizeReason: MinimizeReason? = null,
        unminimizeReason: UnminimizeReason? = null,
    ): TaskUpdate {
        val screenBounds = taskInfo.configuration.windowConfiguration.bounds
        val positionInParent = taskInfo.positionInParent
        // We can't both minimize and unminimize the same task in one go.
        assert(minimizeReason == null || unminimizeReason == null)
        return TaskUpdate(
            instanceId = taskInfo.taskId,
            uid = taskInfo.effectiveUid,
@@ -375,6 +392,7 @@ class DesktopModeLoggerTransitionObserver(
            taskY = positionInParent.y,
            visibleTaskCount = visibleTasks,
            minimizeReason = minimizeReason,
            unminimizeReason = unminimizeReason,
        )
    }

+97 −31
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.wm.shell.compatui.isTransparentTask
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.DragStartState
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType
@@ -115,6 +116,7 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.useDesktopOverrideDensity
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.shared.desktopmode.DesktopTaskToFrontReason
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_INDEX_UNDEFINED
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -753,12 +755,16 @@ class DesktopTasksController(
     * Desktop task limit, so [remoteTransition] should also handle any such minimize change.
     */
    @JvmOverloads
    fun moveTaskToFront(taskId: Int, remoteTransition: RemoteTransition? = null) {
    fun moveTaskToFront(
        taskId: Int,
        remoteTransition: RemoteTransition? = null,
        unminimizeReason: UnminimizeReason,
    ) {
        val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
        if (task == null) {
            moveBackgroundTaskToFront(taskId, remoteTransition)
            moveBackgroundTaskToFront(taskId, remoteTransition, unminimizeReason)
        } else {
            moveTaskToFront(task, remoteTransition)
            moveTaskToFront(task, remoteTransition, unminimizeReason)
        }
    }

@@ -767,7 +773,11 @@ class DesktopTasksController(
     * desktop. If outside of desktop and want to launch a background task in desktop, use
     * [moveBackgroundTaskToDesktop] instead.
     */
    private fun moveBackgroundTaskToFront(taskId: Int, remoteTransition: RemoteTransition?) {
    private fun moveBackgroundTaskToFront(
        taskId: Int,
        remoteTransition: RemoteTransition?,
        unminimizeReason: UnminimizeReason,
    ) {
        logV("moveBackgroundTaskToFront taskId=%s", taskId)
        val wct = WindowContainerTransaction()
        wct.startTask(
@@ -776,7 +786,13 @@ class DesktopTasksController(
                .apply { launchWindowingMode = WINDOWING_MODE_FREEFORM }
                .toBundle(),
        )
        startLaunchTransition(TRANSIT_OPEN, wct, taskId, remoteTransition = remoteTransition)
        startLaunchTransition(
            TRANSIT_OPEN,
            wct,
            taskId,
            remoteTransition = remoteTransition,
            unminimizeReason = unminimizeReason,
        )
    }

    /**
@@ -786,7 +802,11 @@ class DesktopTasksController(
     * Desktop task limit, so [remoteTransition] should also handle any such minimize change.
     */
    @JvmOverloads
    fun moveTaskToFront(taskInfo: RunningTaskInfo, remoteTransition: RemoteTransition? = null) {
    fun moveTaskToFront(
        taskInfo: RunningTaskInfo,
        remoteTransition: RemoteTransition? = null,
        unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
    ) {
        logV("moveTaskToFront taskId=%s", taskInfo.taskId)
        // If a task is tiled, another task should be brought to foreground with it so let
        // tiling controller handle the request.
@@ -801,6 +821,7 @@ class DesktopTasksController(
            launchingTaskId = taskInfo.taskId,
            remoteTransition = remoteTransition,
            displayId = taskInfo.displayId,
            unminimizeReason = unminimizeReason,
        )
    }

@@ -810,6 +831,7 @@ class DesktopTasksController(
        launchingTaskId: Int?,
        remoteTransition: RemoteTransition? = null,
        displayId: Int = DEFAULT_DISPLAY,
        unminimizeReason: UnminimizeReason = UnminimizeReason.UNKNOWN,
    ): IBinder {
        val taskIdToMinimize =
            addAndGetMinimizeChanges(
@@ -825,8 +847,8 @@ class DesktopTasksController(
                excludeTaskId = launchingTaskId,
                reason = DesktopImmersiveController.ExitReason.TASK_LAUNCH,
            )
        if (remoteTransition == null) {
        val t =
            if (remoteTransition == null) {
                desktopMixedTransitionHandler.startLaunchTransition(
                    transitionType = transitionType,
                    wct = wct,
@@ -834,17 +856,12 @@ class DesktopTasksController(
                    minimizingTaskId = taskIdToMinimize,
                    exitingImmersiveTask = exitImmersiveResult.asExit()?.exitingTask,
                )
            taskIdToMinimize?.let { addPendingMinimizeTransition(t, it, MinimizeReason.TASK_LIMIT) }
            exitImmersiveResult.asExit()?.runOnTransitionStart?.invoke(t)
            return t
        }
        if (taskIdToMinimize == null) {
            } else if (taskIdToMinimize == null) {
                val remoteTransitionHandler = OneShotRemoteHandler(mainExecutor, remoteTransition)
            val t = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
            remoteTransitionHandler.setTransition(t)
            exitImmersiveResult.asExit()?.runOnTransitionStart?.invoke(t)
            return t
                transitions.startTransition(transitionType, wct, remoteTransitionHandler).also {
                    remoteTransitionHandler.setTransition(it)
                }
            } else {
                val remoteTransitionHandler =
                    DesktopWindowLimitRemoteHandler(
                        mainExecutor,
@@ -852,9 +869,16 @@ class DesktopTasksController(
                        remoteTransition,
                        taskIdToMinimize,
                    )
        val t = transitions.startTransition(transitionType, wct, remoteTransitionHandler)
        remoteTransitionHandler.setTransition(t)
        taskIdToMinimize.let { addPendingMinimizeTransition(t, it, MinimizeReason.TASK_LIMIT) }
                transitions.startTransition(transitionType, wct, remoteTransitionHandler).also {
                    remoteTransitionHandler.setTransition(it)
                }
            }
        if (taskIdToMinimize != null) {
            addPendingMinimizeTransition(t, taskIdToMinimize, MinimizeReason.TASK_LIMIT)
        }
        if (launchingTaskId != null && taskRepository.isMinimizedTask(launchingTaskId)) {
            addPendingUnminimizeTransition(t, displayId, launchingTaskId, unminimizeReason)
        }
        exitImmersiveResult.asExit()?.runOnTransitionStart?.invoke(t)
        return t
    }
@@ -1731,7 +1755,10 @@ class DesktopTasksController(
            val requestedTaskInfo = shellTaskOrganizer.getRunningTaskInfo(requestedTaskId)
            if (requestedTaskInfo?.isFreeform == true) {
                // If requested task is an already open freeform task, just move it to front.
                moveTaskToFront(requestedTaskId)
                moveTaskToFront(
                    requestedTaskId,
                    unminimizeReason = UnminimizeReason.APP_HANDLE_MENU_BUTTON,
                )
            } else {
                moveBackgroundTaskToDesktop(
                    requestedTaskId,
@@ -1894,6 +1921,16 @@ class DesktopTasksController(
        if (useDesktopOverrideDensity()) {
            wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE)
        }
        // The task that is launching might have been minimized before - in which case this is an
        // unminimize action.
        if (taskRepository.isMinimizedTask(task.taskId)) {
            addPendingUnminimizeTransition(
                transition,
                task.displayId,
                task.taskId,
                UnminimizeReason.TASK_LAUNCH,
            )
        }
        // Desktop Mode is showing and we're launching a new Task:
        // 1) Exit immersive if needed.
        desktopImmersiveController.exitImmersiveIfApplicable(
@@ -2206,6 +2243,22 @@ class DesktopTasksController(
        }
    }

    private fun addPendingUnminimizeTransition(
        transition: IBinder,
        displayId: Int,
        taskIdToUnminimize: Int,
        unminimizeReason: UnminimizeReason,
    ) {
        desktopTasksLimiter.ifPresent {
            it.addPendingUnminimizeChange(
                transition,
                displayId = displayId,
                taskId = taskIdToUnminimize,
                unminimizeReason,
            )
        }
    }

    private fun addPendingAppLaunchTransition(
        transition: IBinder,
        launchTaskId: Int,
@@ -2883,9 +2936,13 @@ class DesktopTasksController(
            }
        }

        override fun showDesktopApp(taskId: Int, remoteTransition: RemoteTransition?) {
        override fun showDesktopApp(
            taskId: Int,
            remoteTransition: RemoteTransition?,
            toFrontReason: DesktopTaskToFrontReason,
        ) {
            executeRemoteCallWithTaskPermission(controller, "showDesktopApp") { c ->
                c.moveTaskToFront(taskId, remoteTransition)
                c.moveTaskToFront(taskId, remoteTransition, toFrontReason.toUnminimizeReason())
            }
        }

@@ -2980,6 +3037,15 @@ class DesktopTasksController(
        private val APP_HANDLE_DRAG_HOLD_CUJ_TIMEOUT_MS: Long = TimeUnit.SECONDS.toMillis(10L)

        private const val TAG = "DesktopTasksController"

        private fun DesktopTaskToFrontReason.toUnminimizeReason(): UnminimizeReason =
            when (this) {
                DesktopTaskToFrontReason.UNKNOWN -> UnminimizeReason.UNKNOWN
                DesktopTaskToFrontReason.TASKBAR_TAP -> UnminimizeReason.TASKBAR_TAP
                DesktopTaskToFrontReason.ALT_TAB -> UnminimizeReason.ALT_TAB
                DesktopTaskToFrontReason.TASKBAR_MANAGE_WINDOW ->
                    UnminimizeReason.TASKBAR_MANAGE_WINDOW
            }
    }

    /** Defines interface for classes that can listen to changes for task resize. */
Loading