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

Commit b606b4ce authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "Desks: Exclude desk roots when looking for focused desktop tasks" into main

parents a8fc2ddf dbac9229
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1114,6 +1114,7 @@ public abstract class WMShellModule {
            Context context,
            Optional<DesktopModeWindowDecorViewModel> desktopModeWindowDecorViewModel,
            Optional<DesktopTasksController> desktopTasksController,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            InputManager inputManager,
            ShellTaskOrganizer shellTaskOrganizer,
            FocusTransitionObserver focusTransitionObserver,
@@ -1125,6 +1126,7 @@ public abstract class WMShellModule {
                || DesktopModeFlags.ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS.isTrue())) {
            return Optional.of(new DesktopModeKeyGestureHandler(context,
                    desktopModeWindowDecorViewModel, desktopTasksController,
                    desktopUserRepositories,
                    inputManager, shellTaskOrganizer, focusTransitionObserver,
                    mainExecutor, displayController));
        }
+21 −8
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.hardware.input.InputManager
import android.hardware.input.InputManager.KeyGestureEventHandler
import android.hardware.input.KeyGestureEvent
import android.os.IBinder
import android.window.DesktopExperienceFlags
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.common.DisplayController
@@ -40,6 +41,7 @@ class DesktopModeKeyGestureHandler(
    private val context: Context,
    private val desktopModeWindowDecorViewModel: Optional<DesktopModeWindowDecorViewModel>,
    private val desktopTasksController: Optional<DesktopTasksController>,
    private val desktopUserRepositories: DesktopUserRepositories,
    inputManager: InputManager,
    private val shellTaskOrganizer: ShellTaskOrganizer,
    private val focusTransitionObserver: FocusTransitionObserver,
@@ -67,7 +69,7 @@ class DesktopModeKeyGestureHandler(
        when (event.keyGestureType) {
            KeyGestureEvent.KEY_GESTURE_TYPE_MOVE_TO_NEXT_DISPLAY -> {
                logV("Key gesture MOVE_TO_NEXT_DISPLAY is handled")
                getGloballyFocusedFreeformTask()?.let {
                getGloballyFocusedDesktopTask()?.let {
                    mainExecutor.execute {
                        desktopTasksController.get().moveToNextDesktopDisplay(it.taskId)
                    }
@@ -91,7 +93,7 @@ class DesktopModeKeyGestureHandler(
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW -> {
                logV("Key gesture SNAP_LEFT_FREEFORM_WINDOW is handled")
                getGloballyFocusedFreeformTask()?.let {
                getGloballyFocusedDesktopTask()?.let {
                    mainExecutor.execute {
                        desktopModeWindowDecorViewModel
                            .get()
@@ -106,7 +108,7 @@ class DesktopModeKeyGestureHandler(
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW -> {
                logV("Key gesture SNAP_RIGHT_FREEFORM_WINDOW is handled")
                getGloballyFocusedFreeformTask()?.let {
                getGloballyFocusedDesktopTask()?.let {
                    mainExecutor.execute {
                        desktopModeWindowDecorViewModel
                            .get()
@@ -121,7 +123,7 @@ class DesktopModeKeyGestureHandler(
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW -> {
                logV("Key gesture TOGGLE_MAXIMIZE_FREEFORM_WINDOW is handled")
                getGloballyFocusedFreeformTask()?.let { taskInfo ->
                getGloballyFocusedDesktopTask()?.let { taskInfo ->
                    mainExecutor.execute {
                        desktopTasksController
                            .get()
@@ -139,7 +141,7 @@ class DesktopModeKeyGestureHandler(
            }
            KeyGestureEvent.KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW -> {
                logV("Key gesture MINIMIZE_FREEFORM_WINDOW is handled")
                getGloballyFocusedFreeformTask()?.let {
                getGloballyFocusedDesktopTask()?.let {
                    mainExecutor.execute {
                        desktopTasksController.get().minimizeTask(it, MinimizeReason.KEY_GESTURE)
                    }
@@ -151,11 +153,22 @@ class DesktopModeKeyGestureHandler(
    //  TODO: b/364154795 - wait for the completion of moveToNextDisplay transition, otherwise it
    //  will pick a wrong task when a user quickly perform other actions with keyboard shortcuts
    //  after moveToNextDisplay, and move this to FocusTransitionObserver class.
    private fun getGloballyFocusedFreeformTask(): RunningTaskInfo? =
        shellTaskOrganizer.getRunningTasks().find { taskInfo ->
    private fun getGloballyFocusedDesktopTask(): RunningTaskInfo? {
        if (
            !DesktopExperienceFlags.EXCLUDE_DESK_ROOTS_FROM_DESKTOP_TASKS.isTrue ||
                !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
        ) {
            return shellTaskOrganizer.getRunningTasks().find { taskInfo ->
                taskInfo.windowingMode == WINDOWING_MODE_FREEFORM &&
                    focusTransitionObserver.hasGlobalFocus(taskInfo)
            }
        }
        val repository = desktopUserRepositories.current
        return shellTaskOrganizer.getRunningTasks().find { taskInfo ->
            repository.isActiveTask(taskInfo.taskId) &&
                focusTransitionObserver.hasGlobalFocus(taskInfo)
        }
    }

    private fun logV(msg: String, vararg arguments: Any?) {
        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+26 −10
Original line number Diff line number Diff line
@@ -456,11 +456,17 @@ class DesktopTasksController(
     * the home activity.
     */
    private fun getFocusedNonDesktopTasks(displayId: Int): List<RunningTaskInfo> =
        shellTaskOrganizer.getRunningTasks(displayId).filter {
            it.isFocused &&
                (it.windowingMode == WINDOWING_MODE_FULLSCREEN ||
                    it.windowingMode == WINDOWING_MODE_MULTI_WINDOW) &&
                it.activityType != ACTIVITY_TYPE_HOME
        shellTaskOrganizer.getRunningTasks(displayId).filter { taskInfo ->
            val focused = taskInfo.isFocused
            val isNotDesktop =
                if (DesktopExperienceFlags.EXCLUDE_DESK_ROOTS_FROM_DESKTOP_TASKS.isTrue) {
                    !taskRepository.isActiveTask(taskInfo.taskId)
                } else {
                    taskInfo.windowingMode == WINDOWING_MODE_FULLSCREEN ||
                        taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW
                }
            val isHome = taskInfo.activityType == ACTIVITY_TYPE_HOME
            return@filter focused && isNotDesktop && !isHome
        }

    /** Returns child task from two focused tasks in split screen mode. */
@@ -1394,7 +1400,7 @@ class DesktopTasksController(

    /** Enter fullscreen by moving the focused freeform task in given `displayId` to fullscreen. */
    fun enterFullscreen(displayId: Int, transitionSource: DesktopModeTransitionSource) {
        getFocusedFreeformTask(displayId)?.let {
        getFocusedDesktopTask(displayId)?.let {
            snapEventHandler.removeTaskIfTiled(displayId, it.taskId)
            moveToFullscreenWithAnimation(it, it.positionInParent, transitionSource)
        }
@@ -4164,13 +4170,23 @@ class DesktopTasksController(

    /** Enter split by using the focused desktop task in given `displayId`. */
    fun enterSplit(displayId: Int, leftOrTop: Boolean) {
        getFocusedFreeformTask(displayId)?.let { requestSplit(it, leftOrTop) }
        getFocusedDesktopTask(displayId)?.let { requestSplit(it, leftOrTop) }
    }

    private fun getFocusedFreeformTask(displayId: Int): RunningTaskInfo? =
        shellTaskOrganizer.getRunningTasks(displayId).find { taskInfo ->
    private fun getFocusedDesktopTask(displayId: Int): RunningTaskInfo? {
        if (
            !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ||
                !DesktopExperienceFlags.EXCLUDE_DESK_ROOTS_FROM_DESKTOP_TASKS.isTrue
        ) {
            return shellTaskOrganizer.getRunningTasks(displayId).find { taskInfo ->
                taskInfo.isFocused && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM
            }
        }
        val deskId = taskRepository.getActiveDeskId(displayId) ?: return null
        return shellTaskOrganizer.getRunningTasks(displayId).find { taskInfo ->
            taskInfo.isFocused && taskRepository.isActiveTaskInDesk(taskInfo.taskId, deskId)
        }
    }

    /**
     * Requests a task be transitioned from desktop to split select. Applies needed windowing
+24 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.app.WindowConfiguration.windowingModeToString
import android.util.SparseArray
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_TO_FRONT
@@ -485,6 +486,12 @@ class RootTaskDesksOrganizer(
            // Appearing root matches desk request.
            val deskId = taskInfo.taskId
            logV("Desk #$deskId appeared")
            if (taskInfo.windowingMode != WINDOWING_MODE_FREEFORM) {
                logW(
                    "Desk is not in FREEFORM mode: %s",
                    windowingModeToString(taskInfo.windowingMode),
                )
            }
            deskRootsByDeskId[deskId] =
                DeskRoot(
                    deskId = deskId,
@@ -523,6 +530,12 @@ class RootTaskDesksOrganizer(
                taskInfo.isVisible,
                deskRootsByDeskId[deskId].children,
            )
            if (taskInfo.windowingMode != WINDOWING_MODE_FREEFORM) {
                logW(
                    "Desk is not in FREEFORM mode: %s",
                    windowingModeToString(taskInfo.windowingMode),
                )
            }
            return
        }
        val minimizationRoot =
@@ -727,14 +740,23 @@ class RootTaskDesksOrganizer(
            val minimizationRoot = deskMinimizationRootsByDeskId[deskId]
            pw.println("$innerPrefix  #$deskId visible=${root.taskInfo.isVisible}")
            pw.println("$innerPrefix    displayId=${root.taskInfo.displayId}")
            pw.println(
                "$innerPrefix    winMode=" + windowingModeToString(root.taskInfo.windowingMode)
            )
            pw.println("$innerPrefix    isLaunchRootRequested=${root.isLaunchRootRequested}")
            pw.println("$innerPrefix    isTaskMoveAllowed=${root.isTaskMoveAllowed}")
            pw.println("$innerPrefix    children=${root.children}")
            pw.println("$innerPrefix    users=${root.users}")
            pw.println("$innerPrefix    minimization root:")
            pw.println("$innerPrefix      rootId=${minimizationRoot?.rootId}")
            if (minimizationRoot != null) {
                pw.println("$innerPrefix    minimization root:")
                pw.println("$innerPrefix      rootId=${minimizationRoot.rootId}")
                pw.println(
                    "$innerPrefix      winMode=" +
                        windowingModeToString(minimizationRoot.taskInfo.windowingMode)
                )
                pw.println("$innerPrefix      children=${minimizationRoot.children}")
            } else {
                pw.println("$innerPrefix    minimization root=null")
            }
        }
    }
+18 −1
Original line number Diff line number Diff line
@@ -34,12 +34,15 @@ import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.SparseArray;
import android.window.DesktopExperienceFlags;
import android.window.TransitionInfo;

import com.android.wm.shell.shared.FocusTransitionListener;
import com.android.wm.shell.shared.IFocusTransitionListener;
import com.android.wm.shell.shared.TransitionUtil.LeafTaskFilter;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -74,12 +77,26 @@ public class FocusTransitionObserver {
        final SparseArray<RunningTaskInfo> lastTransitionFocusedTasks =
                mFocusedTaskOnDisplay.clone();

        // Find all leaf tasks in the transition.
        final List<Integer> leafTasks = new ArrayList<>();
        final LeafTaskFilter leafTaskFilter = new LeafTaskFilter();
        for (int i = 0; i < info.getChanges().size(); i++) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            if (leafTaskFilter.test(change)) {
                leafTasks.add(change.getTaskInfo().taskId);
            }
        }
        final List<TransitionInfo.Change> changes = info.getChanges();
        // Iterate in reverse, so front-most tasks are processed last.
        for (int i = changes.size() - 1; i >= 0; i--) {
            final TransitionInfo.Change change = changes.get(i);

            final RunningTaskInfo task = change.getTaskInfo();
            if (task != null) {
            final boolean updateTaskFocus =
                    DesktopExperienceFlags.EXCLUDE_DESK_ROOTS_FROM_DESKTOP_TASKS.isTrue()
                            ? (task != null && leafTasks.contains(task.taskId))
                            : task != null;
            if (updateTaskFocus) {
                if (change.hasFlags(FLAG_MOVED_TO_TOP) || change.getMode() == TRANSIT_OPEN) {
                    updateFocusedTaskPerDisplay(task, task.displayId);
                } else {
Loading