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

Commit 9f6aadfc authored by Eric Lin's avatar Eric Lin
Browse files

Revert^2 "Fix bubble relaunch by deferring TaskView animation."

This reverts commit b316b92c and
relaunches ag/35363328 with the following modification:

The TaskView animation readiness check is moved to occur after the basic
"house-keeping" validation. The previous logic incorrectly handled some
transitions that were house-keeping operations and should have been
passed to other handlers.

This change restructures the conditional logic to first check if a
transition is for house-keeping. Only then does it check for animation
readiness, deferring when TaskView changes cannot be animated due to
destroyed surfaces. This fixes the WindowUntrustedTouchTest regression
on Android Auto while preserving the original bubble relaunch fix.
Additionally, two new unit tests are added to cover the house-keeping
scenarios and prevent future regressions.

Reason for revert: Relaunch ag/35363328 with bug fix

Bug: 442478808
Flag: EXEMPT BUGFIX
Test: atest WMShellUnitTests:TaskViewTest
Test: atest WMShellUnitTests:TaskViewTransitionStartAnimationTest
Test: atest WMShellUnitTests:BubbleTransitionsTest
Test: atest CtsWindowManagerDeviceInput:WindowUntrustedTouchTest#testLongEnterAnimations_areLimited
Change-Id: I5755d03a585b7096dd8d7843a8fe8913caa4fcfe
parent b6a56c4f
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -816,6 +816,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
        }

        // Prepare taskViews for animation
        boolean isReadyForAnimation = true;
        for (int i = 0; i < taskViews.size(); ++i) {
            final TransitionInfo.Change task = taskViews.get(i);
            final ActivityManager.RunningTaskInfo taskInfo = task.getTaskInfo();
@@ -849,11 +850,13 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
                        // The task is being moved into taskView, so it is still "new" from
                        // TaskView's perspective (e.g. task being moved into a bubble)
                        stillNeedsMatchingLaunch = false;
                        prepareOpenAnimation(pending.mTaskView, true /* isNewInTaskView */,
                                startTransaction, finishTransaction, taskInfo, leash, wct);
                        isReadyForAnimation &= prepareOpenAnimation(pending.mTaskView,
                                true /* isNewInTaskView */, startTransaction, finishTransaction,
                                taskInfo, leash, wct);
                    } else {
                        prepareOpenAnimation(infoTv, false /* isNewInTaskView */,
                                startTransaction, finishTransaction, taskInfo, leash, wct);
                        isReadyForAnimation &= prepareOpenAnimation(infoTv,
                                false /* isNewInTaskView */, startTransaction, finishTransaction,
                                taskInfo, leash, wct);
                    }
                    break;
                case TRANSIT_CHANGE:
@@ -910,6 +913,11 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
        } else if (wct == null && pending == null && taskViews.size() != info.getChanges().size()) {
            // Just some house-keeping, let another handler animate.
            return false;
        } else if (!isReadyForAnimation) {
            // Animation could not be fully prepared. The surface for one or more TaskViews was
            // destroyed before the animation could start, let another handler animate.
            Slog.w(TAG, "Animation not ready for all TaskViews, deferring to another handler.");
            return false;
        }
        if (changingDisplayId > -1) {
            // Wait for setTaskBoundsInTransition -> mergeAnimation to let DefaultTransitionHandler
@@ -1092,8 +1100,21 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
        return true;
    }

    /**
     * Prepares the TaskView for an open animation.
     *
     * @param taskView the {@link TaskViewTaskController} for the TaskView being opened.
     * @param newTask whether the task is considered new within this {@link TaskView}.
     * @param startTransaction the transaction to apply before the animation starts.
     * @param finishTransaction the transaction to apply after the animation finishes.
     * @param taskInfo information about the running task to animate.
     * @param leash the surface leash representing the task's surface.
     * @param wct a {@link WindowContainerTransaction} to apply changes.
     * @return {@code true} if the TaskView's surface is created and ready for animation,
     * {@code false} if the surface was destroyed and the animation should be deferred.
     */
    @VisibleForTesting
    public void prepareOpenAnimation(TaskViewTaskController taskView,
    public boolean prepareOpenAnimation(TaskViewTaskController taskView,
            final boolean newTask,
            SurfaceControl.Transaction startTransaction,
            SurfaceControl.Transaction finishTransaction,
@@ -1102,7 +1123,8 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
        final Rect boundsOnScreen = taskView.prepareOpen(taskInfo, leash);
        ProtoLog.d(WM_SHELL_BUBBLES_NOISY, "Transitions.prepareOpenAnimation(): taskView=%d "
                        + "newTask=%b bounds=%s", taskView.hashCode(), newTask, boundsOnScreen);
        if (boundsOnScreen != null) {
        final boolean isSurfaceCreated = boundsOnScreen != null;
        if (isSurfaceCreated) {
            updateBounds(taskView, boundsOnScreen, startTransaction, finishTransaction, taskInfo,
                    leash, wct);
        } else {
@@ -1126,6 +1148,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
        wct.setTaskTrimmableFromRecents(taskInfo.token, false /* isTrimmableFromRecents */);

        taskView.notifyAppeared(newTask);
        return isSurfaceCreated;
    }

    /**
+48 −0
Original line number Diff line number Diff line
@@ -345,6 +345,21 @@ public class TaskViewTransitionStartAnimationTest extends ShellTestCase {
        prepareOpenAnimationAssertions(pending, wct, true /* newTask */, mTokenBinder);
    }

    @Test
    public void openTask_onlyAlienChanges_notHandled() {
        // Builds a transition with ONLY a non-TaskView change.
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
                .addChange(getTask(TRANSIT_OPEN, false /* registered */))
                .build();

        final boolean handled = mTaskViewTransitions.startAnimation(
                mock(IBinder.class), info, mStartTransaction, mFinishTransaction, mFinishCallback);

        assertWithMessage("Handler should not consume alien-only transition")
                .that(handled).isFalse();
        verify(mFinishCallback, never()).onTransitionFinished(any());
    }

    @Test
    public void showTaskViewHandled() {
        TaskViewTransitions.PendingTransition pending =
@@ -364,6 +379,23 @@ public class TaskViewTransitionStartAnimationTest extends ShellTestCase {
        prepareOpenAnimationAssertions(pending, wct, false /* newTask */, mTokenBinder);
    }

    @Test
    public void showTaskView_whenSurfaceDestroyed_notHandled() {
        assumeTrue(taskViewTransitionsRefactor());

        // Simulate the surface being destroyed (e.g. a collapsed bubble being relaunched).
        when(mTaskViewTaskController.prepareOpen(any(), any())).thenReturn(null);
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT)
                .addChange(getTaskView(TRANSIT_TO_FRONT)).build();

        final boolean handled = mTaskViewTransitions.startAnimation(mock(IBinder.class), info,
                mStartTransaction, mFinishTransaction, mFinishCallback);

        assertWithMessage("Handler should defer the transition when the surface is not ready")
                .that(handled).isFalse();
        verify(mFinishCallback, never()).onTransitionFinished(any());
    }

    @Test
    public void taskToTaskViewHandled() {
        assumeTrue(BubbleAnythingFlagHelper.enableCreateAnyBubble());
@@ -460,6 +492,22 @@ public class TaskViewTransitionStartAnimationTest extends ShellTestCase {
        verify(mTaskViewTaskController, never()).prepareCloseAnimation();
    }

    @Test
    public void closingTask_withMixedChanges_notHandled() {
        // Builds a transition with both a TaskView change and a non-TaskView change.
        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE)
                .addChange(getTaskView(TRANSIT_CLOSE))
                .addChange(getTask(TRANSIT_TO_FRONT, false /* registered */))
                .build();

        final boolean handled = mTaskViewTransitions.startAnimation(
                mock(IBinder.class), info, mStartTransaction, mFinishTransaction, mFinishCallback);

        assertWithMessage("Handler should not consume mixed changes transition")
                .that(handled).isFalse();
        verify(mFinishCallback, never()).onTransitionFinished(any());
    }

    /**
     * Refactor tests on non-taskViews
     */