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

Commit e2e8ecbf authored by Omar Elmekkawy's avatar Omar Elmekkawy Committed by Android (Google) Code Review
Browse files

Merge "Add multi user support for tiling." into main

parents 7e8e08a4 70398e94
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -900,7 +900,8 @@ public abstract class WMShellModule {
            WindowDecorTaskResourceLoader windowDecorTaskResourceLoader,
            FocusTransitionObserver focusTransitionObserver,
            @ShellMainThread ShellExecutor mainExecutor,
            DesktopState desktopState) {
            DesktopState desktopState,
            ShellInit shellInit) {
        return new DesktopTilingDecorViewModel(
                context,
                mainDispatcher,
@@ -917,7 +918,8 @@ public abstract class WMShellModule {
                windowDecorTaskResourceLoader,
                focusTransitionObserver,
                mainExecutor,
                desktopState
                desktopState,
                shellInit
        );
    }

+1 −1
Original line number Diff line number Diff line
@@ -4067,7 +4067,7 @@ class DesktopTasksController(
        userId = newUserId
        taskRepository = userRepositories.getProfile(userId)
        if (this::snapEventHandler.isInitialized) {
            snapEventHandler.onUserChange()
            snapEventHandler.onUserChange(userId)
        }
    }

+2 −2
Original line number Diff line number Diff line
@@ -993,8 +993,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    }

    @Override
    public void onUserChange() {
        mDesktopTilingDecorViewModel.onUserChange();
    public void onUserChange(int userId) {
        mDesktopTilingDecorViewModel.onUserChange(userId);
    }

    @Override
+40 −19
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.Rect
import android.util.SparseArray
import android.window.DisplayAreaInfo
import android.window.WindowContainerTransaction
import androidx.core.util.getOrElse
import androidx.core.util.valueIterator
import com.android.internal.annotations.VisibleForTesting
import com.android.wm.shell.R
@@ -41,6 +42,7 @@ import com.android.wm.shell.recents.RecentsTransitionStateListener
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopState
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
@@ -66,14 +68,16 @@ class DesktopTilingDecorViewModel(
    private val focusTransitionObserver: FocusTransitionObserver,
    private val mainExecutor: ShellExecutor,
    private val desktopState: DesktopState,
    private val shellInit: ShellInit,
) : DisplayChangeController.OnDisplayChangingListener {
    @VisibleForTesting
    var tilingTransitionHandlerByDisplayId = SparseArray<DesktopTilingWindowDecoration>()
    var tilingHandlerByUserAndDisplayId = SparseArray<SparseArray<DesktopTilingWindowDecoration>>()
    var currentUserId: Int = -1

    init {
        // TODO(b/374309287): Move this interface implementation to
        // [DesktopModeWindowDecorViewModel] when the migration is done.
        displayController.addDisplayChangingController(this)
        shellInit.addInitCallback({ displayController.addDisplayChangingController(this) }, this)
    }

    fun snapToHalfScreen(
@@ -85,9 +89,14 @@ class DesktopTilingDecorViewModel(
    ): Boolean {
        val displayId = taskInfo.displayId
        val handler =
            tilingTransitionHandlerByDisplayId.get(displayId)
                ?: run {
                    val newHandler =
            tilingHandlerByUserAndDisplayId
                .getOrElse(currentUserId) {
                    SparseArray<DesktopTilingWindowDecoration>().also {
                        tilingHandlerByUserAndDisplayId[currentUserId] = it
                    }
                }
                .getOrElse(displayId) {
                    val userHandlerList = tilingHandlerByUserAndDisplayId[currentUserId]
                    DesktopTilingWindowDecoration(
                            context,
                            mainDispatcher,
@@ -107,8 +116,7 @@ class DesktopTilingDecorViewModel(
                            mainExecutor,
                            desktopState,
                        )
                    tilingTransitionHandlerByDisplayId.put(displayId, newHandler)
                    newHandler
                        .also { userHandlerList[displayId] = it }
                }
        transitions.registerObserver(handler)
        return destinationBounds?.let { handler.onAppTiled(
@@ -123,32 +131,41 @@ class DesktopTilingDecorViewModel(
    }

    fun removeTaskIfTiled(displayId: Int, taskId: Int) {
        tilingTransitionHandlerByDisplayId.get(displayId)?.removeTaskIfTiled(taskId)
        tilingHandlerByUserAndDisplayId[currentUserId]?.get(displayId)?.removeTaskIfTiled(taskId)
    }

    fun moveTaskToFrontIfTiled(taskInfo: RunningTaskInfo): Boolean {
        // Always pass focus=true because taskInfo.isFocused is not updated yet.
        return tilingTransitionHandlerByDisplayId
            .get(taskInfo.displayId)
        return tilingHandlerByUserAndDisplayId[currentUserId]
            ?.get(taskInfo.displayId)
            ?.moveTiledPairToFront(taskInfo.taskId, isFocusedOnDisplay = true) ?: false
    }

    fun onOverviewAnimationStateChange(
        @RecentsTransitionStateListener.RecentsTransitionState state: Int
    ) {
        for (tilingHandler in tilingTransitionHandlerByDisplayId.valueIterator()) {
        val activeUserHandlers = tilingHandlerByUserAndDisplayId[currentUserId] ?: return
        for (tilingHandler in activeUserHandlers.valueIterator()) {
            tilingHandler.onOverviewAnimationStateChange(state)
        }
    }

    fun onUserChange() {
        for (tilingHandler in tilingTransitionHandlerByDisplayId.valueIterator()) {
            tilingHandler.resetTilingSession()
    fun onUserChange(userId: Int) {
        if (userId == currentUserId) return
        try {
            val activeUserHandlers = tilingHandlerByUserAndDisplayId[currentUserId] ?: return
            for (tilingHandler in activeUserHandlers.valueIterator()) {
                tilingHandler.hideDividerBar()
            }
        } finally {
            currentUserId = userId
        }
    }

    fun onTaskInfoChange(taskInfo: RunningTaskInfo) {
        tilingTransitionHandlerByDisplayId.get(taskInfo.displayId)?.onTaskInfoChange(taskInfo)
        tilingHandlerByUserAndDisplayId[currentUserId]
            ?.get(taskInfo.displayId)
            ?.onTaskInfoChange(taskInfo)
    }

    override fun onDisplayChange(
@@ -161,12 +178,14 @@ class DesktopTilingDecorViewModel(
        // Exit if the rotation hasn't changed or is changed by 180 degrees. [fromRotation] and
        // [toRotation] can be one of the [@Surface.Rotation] values.
        if ((fromRotation % 2 == toRotation % 2)) return
        tilingTransitionHandlerByDisplayId.get(displayId)?.resetTilingSession()
        tilingHandlerByUserAndDisplayId[currentUserId]?.get(displayId)?.resetTilingSession()
    }

    fun getRightSnapBoundsIfTiled(displayId: Int): Rect {
        val tilingBounds =
            tilingTransitionHandlerByDisplayId.get(displayId)?.getRightSnapBoundsIfTiled()
            tilingHandlerByUserAndDisplayId[currentUserId]
                ?.get(displayId)
                ?.getRightSnapBoundsIfTiled()
        if (tilingBounds != null) {
            return tilingBounds
        }
@@ -187,7 +206,9 @@ class DesktopTilingDecorViewModel(

    fun getLeftSnapBoundsIfTiled(displayId: Int): Rect {
        val tilingBounds =
            tilingTransitionHandlerByDisplayId.get(displayId)?.getLeftSnapBoundsIfTiled()
            tilingHandlerByUserAndDisplayId[currentUserId]
                ?.get(displayId)
                ?.getLeftSnapBoundsIfTiled()
        if (tilingBounds != null) {
            return tilingBounds
        }
+6 −3
Original line number Diff line number Diff line
@@ -445,7 +445,7 @@ class DesktopTilingWindowDecoration(
                    removeTaskIfTiled(it.taskId, /* taskVanished= */ false, it.isFullscreen)
                } else if (isEnteringPip(change, info.type)) {
                    removeTaskIfTiled(it.taskId, /* taskVanished= */ true, it.isFullscreen)
                } else if (isTransitionToFront(change.mode, info.type)) {
                } else if (isTransitionToFront(change.mode)) {
                    handleTaskBroughtToFront(it.taskId)
                    leftTaskBroughtToFront =
                        leftTaskBroughtToFront ||
@@ -496,8 +496,8 @@ class DesktopTilingWindowDecoration(
        return false
    }

    private fun isTransitionToFront(changeMode: Int, transitionType: Int): Boolean =
        changeMode == TRANSIT_TO_FRONT && transitionType == TRANSIT_TO_FRONT
    private fun isTransitionToFront(changeMode: Int): Boolean =
        changeMode == TRANSIT_TO_FRONT

    class AppResizingHelper(
        val taskInfo: RunningTaskInfo,
@@ -707,6 +707,9 @@ class DesktopTilingWindowDecoration(
        removeTaskIfTiled(taskId, taskVanished = true, shouldDelayUpdate = true)
    }

    fun hideDividerBar() {
        desktopTilingDividerWindowManager?.hideDividerBar()
    }
    /**
     * Moves the tiled pair to the front of the task stack, if the [taskInfo] is focused and one of
     * the two tiled tasks.
Loading