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

Commit a307e5be authored by Saho Kobayashi's avatar Saho Kobayashi Committed by Android (Google) Code Review
Browse files

Merge "Migrate DesktopTilingWindowDecoration to FocusTransitionObserver" into main

parents 0e1a06b5 11b57704
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -815,7 +815,9 @@ public abstract class WMShellModule {
            ReturnToDragStartAnimator returnToDragStartAnimator,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            DesktopModeEventLogger desktopModeEventLogger,
            WindowDecorTaskResourceLoader windowDecorTaskResourceLoader) {
            WindowDecorTaskResourceLoader windowDecorTaskResourceLoader,
            FocusTransitionObserver focusTransitionObserver,
            @ShellMainThread ShellExecutor mainExecutor) {
        return new DesktopTilingDecorViewModel(
                context,
                mainDispatcher,
@@ -829,7 +831,9 @@ public abstract class WMShellModule {
                returnToDragStartAnimator,
                desktopUserRepositories,
                desktopModeEventLogger,
                windowDecorTaskResourceLoader
                windowDecorTaskResourceLoader,
                focusTransitionObserver,
                mainExecutor
        );
    }

+8 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.common.DisplayChangeController
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopTasksController
@@ -37,6 +38,7 @@ import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
@@ -58,6 +60,8 @@ class DesktopTilingDecorViewModel(
    private val desktopUserRepositories: DesktopUserRepositories,
    private val desktopModeEventLogger: DesktopModeEventLogger,
    private val taskResourceLoader: WindowDecorTaskResourceLoader,
    private val focusTransitionObserver: FocusTransitionObserver,
    private val mainExecutor: ShellExecutor,
) : DisplayChangeController.OnDisplayChangingListener {
    @VisibleForTesting
    var tilingTransitionHandlerByDisplayId = SparseArray<DesktopTilingWindowDecoration>()
@@ -94,6 +98,8 @@ class DesktopTilingDecorViewModel(
                            returnToDragStartAnimator,
                            desktopUserRepositories,
                            desktopModeEventLogger,
                            focusTransitionObserver,
                            mainExecutor,
                        )
                    tilingTransitionHandlerByDisplayId.put(displayId, newHandler)
                    newHandler
@@ -112,9 +118,10 @@ class DesktopTilingDecorViewModel(
    }

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

    fun onOverviewAnimationStateChange(isRunning: Boolean) {
+65 −40
Original line number Diff line number Diff line
@@ -35,11 +35,14 @@ import android.window.TransitionRequestInfo
import android.window.WindowContainerTransaction
import com.android.internal.annotations.VisibleForTesting
import com.android.launcher3.icons.BaseIconFactory
import com.android.window.flags.Flags
import com.android.wm.shell.shared.FocusTransitionListener
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
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.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -49,6 +52,7 @@ import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.transition.Transitions.TRANSIT_MINIMIZE
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
@@ -78,13 +82,16 @@ class DesktopTilingWindowDecoration(
    private val returnToDragStartAnimator: ReturnToDragStartAnimator,
    private val desktopUserRepositories: DesktopUserRepositories,
    private val desktopModeEventLogger: DesktopModeEventLogger,
    private val focusTransitionObserver: FocusTransitionObserver,
    @ShellMainThread private val mainExecutor: ShellExecutor,
    private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() },
) :
    Transitions.TransitionHandler,
    ShellTaskOrganizer.FocusListener,
    ShellTaskOrganizer.TaskVanishedListener,
    DragEventListener,
    Transitions.TransitionObserver {
    Transitions.TransitionObserver,
    FocusTransitionListener {
    companion object {
        private val TAG: String = DesktopTilingWindowDecoration::class.java.simpleName
        private const val TILING_DIVIDER_TAG = "Tiling Divider"
@@ -176,9 +183,14 @@ class DesktopTilingWindowDecoration(
            if (!isTilingManagerInitialised) {
                desktopTilingDividerWindowManager = initTilingManagerForDisplay(displayId, config)
                isTilingManagerInitialised = true

                if (Flags.enableDisplayFocusInShellTransitions()) {
                    focusTransitionObserver.setLocalFocusTransitionListener(this, mainExecutor)
                } else {
                    shellTaskOrganizer.addFocusListener(this)
                    isTilingFocused = true
                }
            }
            leftTaskResizingHelper?.initIfNeeded()
            rightTaskResizingHelper?.initIfNeeded()
            leftTaskResizingHelper
@@ -474,23 +486,33 @@ class DesktopTilingWindowDecoration(
        }
    }

    // Only called if [taskInfo] relates to a focused task
    private fun isTilingFocusRemoved(taskInfo: RunningTaskInfo): Boolean {
    // Only called if [taskId] relates to a focused task
    private fun isTilingFocusRemoved(taskId: Int): Boolean {
        return isTilingFocused &&
            taskInfo.taskId != leftTaskResizingHelper?.taskInfo?.taskId &&
            taskInfo.taskId != rightTaskResizingHelper?.taskInfo?.taskId
            taskId != leftTaskResizingHelper?.taskInfo?.taskId &&
            taskId != rightTaskResizingHelper?.taskInfo?.taskId
    }

    // Overriding ShellTaskOrganizer.FocusListener
    override fun onFocusTaskChanged(taskInfo: RunningTaskInfo?) {
        if (Flags.enableDisplayFocusInShellTransitions()) return
        if (taskInfo != null) {
            moveTiledPairToFront(taskInfo)
            moveTiledPairToFront(taskInfo.taskId, taskInfo.isFocused)
        }
    }

    // Overriding FocusTransitionListener
    override fun onFocusedTaskChanged(taskId: Int,
            isFocusedOnDisplay: Boolean,
            isFocusedGlobally: Boolean) {
        if (!Flags.enableDisplayFocusInShellTransitions()) return
        moveTiledPairToFront(taskId, isFocusedOnDisplay)
    }

    // Only called if [taskInfo] relates to a focused task
    private fun isTilingRefocused(taskInfo: RunningTaskInfo): Boolean {
        return taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
                taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId
    private fun isTilingRefocused(taskId: Int): Boolean {
        return taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
                taskId == rightTaskResizingHelper?.taskInfo?.taskId
    }

    private fun buildTiledTasksMoveToFront(leftOnTop: Boolean): WindowContainerTransaction {
@@ -582,14 +604,13 @@ class DesktopTilingWindowDecoration(
     * If specified, [isTaskFocused] will override [RunningTaskInfo.isFocused]. This is to be used
     * when called when the task will be focused, but the [taskInfo] hasn't been updated yet.
     */
    fun moveTiledPairToFront(taskInfo: RunningTaskInfo, isTaskFocused: Boolean? = null): Boolean {
    fun moveTiledPairToFront(taskId: Int, isFocusedOnDisplay: Boolean): Boolean {
        if (!isTilingManagerInitialised) return false

        val isFocused = isTaskFocused ?: taskInfo.isFocused
        if (!isFocused) return false
        if (!isFocusedOnDisplay) return false

        // If a task that isn't tiled is being focused, let the generic handler do the work.
        if (isTilingFocusRemoved(taskInfo)) {
        if (!Flags.enableDisplayFocusInShellTransitions() && isTilingFocusRemoved(taskId)) {
            isTilingFocused = false
            return false
        }
@@ -597,17 +618,17 @@ class DesktopTilingWindowDecoration(
        val leftTiledTask = leftTaskResizingHelper ?: return false
        val rightTiledTask = rightTaskResizingHelper ?: return false
        if (!allTiledTasksVisible()) return false
        val isLeftOnTop = taskInfo.taskId == leftTiledTask.taskInfo.taskId
        if (isTilingRefocused(taskInfo)) {
        val isLeftOnTop = taskId == leftTiledTask.taskInfo.taskId
        if (!isTilingRefocused(taskId)) return false
        val t = transactionSupplier.get()
            isTilingFocused = true
            if (taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId) {
        if (!Flags.enableDisplayFocusInShellTransitions()) isTilingFocused = true
        if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) {
          desktopTilingDividerWindowManager?.onRelativeLeashChanged(
              leftTiledTask.getLeash(),
              t,
          )
        }
            if (taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId) {
        if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) {
          desktopTilingDividerWindowManager?.onRelativeLeashChanged(
              rightTiledTask.getLeash(),
              t,
@@ -621,8 +642,6 @@ class DesktopTilingWindowDecoration(
        t.apply()
        return true
    }
        return false
    }

    private fun allTiledTasksVisible(): Boolean {
        val leftTiledTask = leftTaskResizingHelper ?: return false
@@ -706,7 +725,13 @@ class DesktopTilingWindowDecoration(
    }

    private fun tearDownTiling() {
        if (isTilingManagerInitialised) shellTaskOrganizer.removeFocusListener(this)
        if (isTilingManagerInitialised) {
            if (Flags.enableDisplayFocusInShellTransitions()) {
                focusTransitionObserver.unsetLocalFocusTransitionListener(this)
            } else {
                shellTaskOrganizer.removeFocusListener(this)
            }
        }

        if (leftTaskResizingHelper == null && rightTaskResizingHelper == null) {
            shellTaskOrganizer.removeTaskVanishedListener(this)
+7 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopUserRepositories
@@ -30,6 +31,7 @@ import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
@@ -67,6 +69,8 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
    private val desktopModeWindowDecorationMock: DesktopModeWindowDecoration = mock()
    private val desktopTilingDecoration: DesktopTilingWindowDecoration = mock()
    private val taskResourceLoader: WindowDecorTaskResourceLoader = mock()
    private val focusTransitionObserver: FocusTransitionObserver = mock()
    private val mainExecutor: ShellExecutor = mock()
    private lateinit var desktopTilingDecorViewModel: DesktopTilingDecorViewModel

    @Before
@@ -86,6 +90,8 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
                userRepositories,
                desktopModeEventLogger,
                taskResourceLoader,
                focusTransitionObserver,
                mainExecutor
            )
        whenever(contextMock.createContextAsUser(any(), any())).thenReturn(contextMock)
    }
@@ -140,7 +146,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
        desktopTilingDecorViewModel.moveTaskToFrontIfTiled(task1)

        verify(desktopTilingDecoration, times(1))
            .moveTiledPairToFront(any(), isTaskFocused = eq(true))
            .moveTiledPairToFront(any(), isFocusedOnDisplay = eq(true))
    }

    @Test
+13 −7
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
@@ -42,6 +43,7 @@ import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.FocusTransitionObserver
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
import com.android.wm.shell.windowdecor.DragResizeWindowGeometry
@@ -105,6 +107,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
    private val mainDispatcher: MainCoroutineDispatcher = mock()
    private val bgScope: CoroutineScope = mock()
    private val taskResourceLoader: WindowDecorTaskResourceLoader = mock()
    private val focusTransitionObserver: FocusTransitionObserver = mock()
    private val mainExecutor: ShellExecutor = mock()
    private lateinit var tilingDecoration: DesktopTilingWindowDecoration

    private val split_divider_width = 10
@@ -129,6 +133,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
                returnToDragStartAnimator,
                userRepositories,
                desktopModeEventLogger,
                focusTransitionObserver,
                mainExecutor
            )
        whenever(context.createContextAsUser(any(), any())).thenReturn(context)
        whenever(userRepositories.current).thenReturn(desktopRepository)
@@ -242,7 +248,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
            BOUNDS,
        )

        assertThat(tilingDecoration.moveTiledPairToFront(task2)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task2.taskId, false)).isFalse()
        verify(transitions, never()).startTransition(any(), any(), any())
    }

@@ -272,7 +278,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
            BOUNDS,
        )

        assertThat(tilingDecoration.moveTiledPairToFront(task3)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, false)).isFalse()
        verify(transitions, never()).startTransition(any(), any(), any())
    }

@@ -304,7 +310,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
        )
        task1.isFocused = true

        assertThat(tilingDecoration.moveTiledPairToFront(task1, isTaskFocused = true)).isTrue()
        assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true)).isTrue()
        verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
    }

@@ -336,8 +342,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
        task1.isFocused = true
        task3.isFocused = true

        assertThat(tilingDecoration.moveTiledPairToFront(task3)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task1)).isTrue()
        assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, true)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, true)).isTrue()
        verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
    }

@@ -367,8 +373,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
            BOUNDS,
        )

        assertThat(tilingDecoration.moveTiledPairToFront(task3, isTaskFocused = true)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task1, isTaskFocused = true)).isTrue()
        assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, isFocusedOnDisplay = true)).isFalse()
        assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true)).isTrue()
        verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
    }