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

Commit 82b01320 authored by Orhan Uysal's avatar Orhan Uysal
Browse files

eefer dispatching recents transition changes

When the recents transition happen, defer dispatch of tasks that are
going to be hidden until we know the end state of them.

Bug: 400787468
Test: atest DesktopTaskChangeListenerTest
Test: atest FreeformTasksTransitionObserverTest
Flag: com.android.window.flags.enable_windowing_transition_handlers_observers
Change-Id: Ib32c92a014e48449b78642a27d6aa9452977ec5f
parent 1418b9e4
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.freeform;

import static com.android.wm.shell.transition.Transitions.TRANSIT_START_RECENTS_TRANSITION;

import android.app.ActivityManager;
import android.content.Context;
import android.os.IBinder;
@@ -57,6 +59,8 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs

    private final Map<IBinder, List<ActivityManager.RunningTaskInfo>> mTransitionToTaskInfo =
            new HashMap<>();
    private final Map<Integer, ActivityManager.RunningTaskInfo> mPendingHiddenTasks =
            new HashMap<>();

    public FreeformTaskTransitionObserver(
            Context context,
@@ -135,9 +139,15 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
                case WindowManager.TRANSIT_TO_FRONT:
                    onToFrontTransitionReady(change, startT, finishT);
                    break;
                case WindowManager.TRANSIT_TO_BACK:
                case WindowManager.TRANSIT_TO_BACK: {
                    if (info.getType() == TRANSIT_START_RECENTS_TRANSITION) {
                        // The tasks will be transiently hidden, which means they are still visible.
                        mPendingHiddenTasks.put(taskInfo.taskId, taskInfo);
                    } else {
                        onToBackTransitionReady(change, startT, finishT);
                    }
                    break;
                }
                case WindowManager.TRANSIT_CLOSE: {
                    taskInfoList.add(change.getTaskInfo());
                    onCloseTransitionReady(change, startT, finishT);
@@ -158,6 +168,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
        mTaskChangeListener.ifPresent(listener -> listener.onTaskOpening(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskOpening(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
        mPendingHiddenTasks.remove(change.getTaskInfo().taskId);
    }

    private void onCloseTransitionReady(
@@ -175,6 +186,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
        mTaskChangeListener.ifPresent(listener -> listener.onTaskChanging(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskChanging(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
        mPendingHiddenTasks.remove(change.getTaskInfo().taskId);
    }

    private void onToFrontTransitionReady(
@@ -185,6 +197,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
                listener -> listener.onTaskMovingToFront(change.getTaskInfo()));
        mWindowDecorViewModel.onTaskChanging(
                change.getTaskInfo(), change.getLeash(), startT, finishT);
        mPendingHiddenTasks.remove(change.getTaskInfo().taskId);
    }

    private void onToBackTransitionReady(
@@ -245,5 +258,9 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
        for (int i = 0; i < taskInfo.size(); ++i) {
            mWindowDecorViewModel.destroyWindowDecoration(taskInfo.get(i));
        }

        for (ActivityManager.RunningTaskInfo task: mPendingHiddenTasks.values()) {
            mTaskChangeListener.ifPresent(it -> it.onTaskMovingToBack(task));
        }
    }
}
+27 −0
Original line number Diff line number Diff line
@@ -17,12 +17,15 @@
package com.android.wm.shell.freeform;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;

import static com.android.wm.shell.transition.Transitions.TRANSIT_START_RECENTS_TRANSITION;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -171,6 +174,30 @@ public class FreeformTaskTransitionObserverTest extends ShellTestCase {
        verify(mTaskChangeListener).onTaskMovingToBack(change.getTaskInfo());
    }

    @Test
    public void recentsTransition_onTransitionFinished_notifiesOnTaskMovingToBack() {
        final TransitionInfo.Change change =
                createChange(TRANSIT_TO_BACK, /* taskId= */ 1, WINDOWING_MODE_FREEFORM);
        final TransitionInfo.Change homeChange =
                createChange(TRANSIT_TO_FRONT, /* taskId= */ 2, WINDOWING_MODE_FULLSCREEN);
        final TransitionInfo info =
                new TransitionInfoBuilder(TRANSIT_START_RECENTS_TRANSITION, /* flags= */ 0)
                        .addChange(homeChange)
                        .addChange(change)
                        .build();

        final IBinder transition = mock(IBinder.class);
        final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
        final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
        mTransitionObserver.onTransitionReady(transition, info, startT, finishT);
        mTransitionObserver.onTransitionStarting(transition);

        verify(mTaskChangeListener, never()).onTaskMovingToBack(change.getTaskInfo());

        mTransitionObserver.onTransitionFinished(transition, false);
        verify(mTaskChangeListener).onTaskMovingToBack(change.getTaskInfo());
    }

    @Test
    public void changeTransition_notifiesOnTaskChange() {
        final TransitionInfo.Change change =