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

Commit 94f55920 authored by Orhan Uysal's avatar Orhan Uysal
Browse files

Make TaskStackTransitionObserver...

- Update tasks moved to front on all tasks rather than just freeform
- Do the updates onTransitionReady so that the launcher is updated
  before the animation plays.

Fix: 369975365
Fix: 356619247
Test: atest TaskStackTransitionObserverTest
Flag: com.android.window.flags.enable_task_stack_observer_in_shell

Change-Id: I08404b2dfbd42169f0be33c4f7c7b7d53ee6aa11
parent b82fcf5c
Loading
Loading
Loading
Loading
+8 −64
Original line number Diff line number Diff line
@@ -17,14 +17,12 @@
package com.android.wm.shell.recents

import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.os.IBinder
import android.util.ArrayMap
import android.view.SurfaceControl
import android.view.WindowManager
import android.window.TransitionInfo
import com.android.wm.shell.shared.TransitionUtil
import android.window.flags.DesktopModeFlags
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import dagger.Lazy
@@ -40,9 +38,6 @@ class TaskStackTransitionObserver(
    private val transitions: Lazy<Transitions>,
    shellInit: ShellInit
) : Transitions.TransitionObserver {

    private val transitionToTransitionChanges: MutableMap<IBinder, TransitionChanges> =
        mutableMapOf()
    private val taskStackTransitionObserverListeners =
        ArrayMap<TaskStackTransitionObserverListener, Executor>()

@@ -63,9 +58,6 @@ class TaskStackTransitionObserver(
        finishTransaction: SurfaceControl.Transaction
    ) {
        if (DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue) {
            val taskInfoList = mutableListOf<RunningTaskInfo>()
            val transitionTypeList = mutableListOf<Int>()

            for (change in info.changes) {
                if (change.flags and TransitionInfo.FLAG_IS_WALLPAPER != 0) {
                    continue
@@ -76,59 +68,21 @@ class TaskStackTransitionObserver(
                    continue
                }

                // Filter out changes that we care about
                if (change.mode == WindowManager.TRANSIT_OPEN) {
                    change.taskInfo?.let { taskInfoList.add(it) }
                    transitionTypeList.add(change.mode)
                }
                // Find the first task that is opening, this should be the one at the front after
                // the transition
                if (TransitionUtil.isOpeningType(change.mode)) {
                    notifyTaskStackTransitionObserverListeners(taskInfo)
                    break
                }
            // Only add the transition to map if it has a change we care about
            if (taskInfoList.isNotEmpty()) {
                transitionToTransitionChanges.put(
                    transition,
                    TransitionChanges(taskInfoList, transitionTypeList)
                )
            }
        }
    }

    override fun onTransitionStarting(transition: IBinder) {}

    override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
        val mergedTransitionChanges =
            transitionToTransitionChanges.get(merged)
                ?:
                // We are adding changes of the merged transition to changes of the playing
                // transition so if there is no changes nothing to do.
                return
    override fun onTransitionMerged(merged: IBinder, playing: IBinder) {}

        transitionToTransitionChanges.remove(merged)
        val playingTransitionChanges = transitionToTransitionChanges.get(playing)
        if (playingTransitionChanges != null) {
            playingTransitionChanges.merge(mergedTransitionChanges)
        } else {
            transitionToTransitionChanges.put(playing, mergedTransitionChanges)
        }
    }

    override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
        val taskInfoList =
            transitionToTransitionChanges.getOrDefault(transition, TransitionChanges()).taskInfoList
        val typeList =
            transitionToTransitionChanges
                .getOrDefault(transition, TransitionChanges())
                .transitionTypeList
        transitionToTransitionChanges.remove(transition)

        for ((index, taskInfo) in taskInfoList.withIndex()) {
            if (
                TransitionUtil.isOpeningType(typeList[index]) &&
                    taskInfo.windowingMode == WINDOWING_MODE_FREEFORM
            ) {
                notifyTaskStackTransitionObserverListeners(taskInfo)
            }
        }
    }
    override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {}

    fun addTaskStackTransitionObserverListener(
        taskStackTransitionObserverListener: TaskStackTransitionObserverListener,
@@ -154,14 +108,4 @@ class TaskStackTransitionObserver(
        /** Called when a task is moved to front. */
        fun onTaskMovedToFrontThroughTransition(taskInfo: RunningTaskInfo) {}
    }

    private data class TransitionChanges(
        val taskInfoList: MutableList<RunningTaskInfo> = ArrayList(),
        val transitionTypeList: MutableList<Int> = ArrayList(),
    ) {
        fun merge(transitionChanges: TransitionChanges) {
            taskInfoList.addAll(transitionChanges.taskInfoList)
            transitionTypeList.addAll(transitionChanges.transitionTypeList)
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ class TaskStackTransitionObserverTest {

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
    fun taskCreated_fullscreenWindow_listenerNotNotified() {
    fun taskCreated_fullscreenWindow_listenerNotified() {
        val listener = TestListener()
        val executor = TestShellExecutor()
        transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
@@ -130,9 +130,9 @@ class TaskStackTransitionObserverTest {
        callOnTransitionFinished()
        executor.flushAll()

        assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(0)
        assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(1)
        assertThat(listener.taskInfoToBeNotified.windowingMode)
            .isEqualTo(WindowConfiguration.WINDOWING_MODE_UNDEFINED)
            .isEqualTo(WindowConfiguration.WINDOWING_MODE_FULLSCREEN)
    }

    @Test