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

Commit 6eedff10 authored by Liran Binyamin's avatar Liran Binyamin
Browse files

Fix stale pending task view transition

LaunchNewTaskBubbleForExistingTransition enqueues an external transition in
TaskViewTransitions after the bubble is inflated. The external transition
is cleaned up after the transition starts playing. There could be cases
where the transition starts playing before the bubble finished inflating, so
we would end up enqueuing a transition and not cleaning it up.

This change moves the external transition cleanup until after the bubble
starts expanding, which requires the bubble to be inflated already.

Fix: 425726457
Flag: com.android.wm.shell.enable_create_any_bubble
Test: atest BubbleTransitionsTest
Test: manual
       - Repeatedly bubble google tv and interrupt the open animation by
         tapping outside it
Change-Id: Ic208e533350097f6e76c3bcffaade73c9c505a67
parent abf8df45
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -535,9 +535,7 @@ public class BubbleTransitions {
            // Remove any intermediate queued transitions that were started as a result of the
            // inflation (the task view will be in the right bounds)
            mTaskViewTransitions.removePendingTransitions(tv.getController());
            mTaskViewTransitions.enqueueExternal(tv.getController(), () -> {
                return mTransition;
            });
            mTaskViewTransitions.enqueueExternal(tv.getController(), () -> mTransition);
        }

        @Override
@@ -639,7 +637,6 @@ public class BubbleTransitions {
            }
            startTransaction.apply();

            mTaskViewTransitions.onExternalDone(mTransition);
            mTransitionProgress.setTransitionReady();
            startExpandAnim();
            return true;
@@ -684,6 +681,7 @@ public class BubbleTransitions {
            ProtoLog.d(WM_SHELL_BUBBLES_NOISY,
                    "LaunchNewTaskBubble.playAnimation(): playConvert=%b",
                    mPlayConvertTaskAnimation);
            mTaskViewTransitions.onExternalDone(mTransition);
            final TaskViewTaskController tv = mBubble.getTaskView().getController();
            final SurfaceControl.Transaction startT = new SurfaceControl.Transaction();
            // Set task position to 0,0 as it will be placed inside the TaskView
+47 −0
Original line number Diff line number Diff line
@@ -919,4 +919,51 @@ public class BubbleTransitionsTest extends ShellTestCase {
        assertThat(mBubbleTransitions.mPendingEnterTransitions).doesNotContainKey(
                bt.mLaunchCookie.binder);
    }

    @Test
    public void launchNewTaskBubbleForExistingTransition_startTransitionBeforeBubbleInflated() {
        final ActivityManager.RunningTaskInfo taskInfo = setupAppBubble();

        when(mLayerView.canExpandView(mBubble)).thenReturn(true);

        final IBinder transition = mock(IBinder.class);
        final BubbleTransitions.LaunchNewTaskBubbleForExistingTransition bt =
                (BubbleTransitions.LaunchNewTaskBubbleForExistingTransition) mBubbleTransitions
                        .startLaunchNewTaskBubbleForExistingTransition(
                                mBubble, mExpandedViewManager, mTaskViewFactory, mBubblePositioner,
                                mStackView, mLayerView, mIconFactory, false /* inflateSync */,
                                transition, transitionHandler -> {});

        verify(mBubble).setPreparingTransition(bt);

        // Prepare for startAnimation call
        final SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build();
        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
        final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash);
        chg.setTaskInfo(taskInfo);
        chg.setMode(TRANSIT_CHANGE);
        info.addChange(chg);
        info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0));

        final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
        final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
        final Transitions.TransitionFinishCallback finishCb = wct -> {};

        // Start playing the transition
        bt.startAnimation(transition, info, startT, finishT, finishCb);

        verify(mBubble, never()).setPreparingTransition(null);

        // Simulate inflating the bubble
        bt.onInflated(mBubble);

        assertThat(mTaskViewTransitions.hasPending()).isTrue();

        // Simulate surfaceCreated so the animation can start
        bt.surfaceCreated();
        bt.continueExpand();

        verify(mBubble).setPreparingTransition(null);
        assertThat(mTaskViewTransitions.hasPending()).isFalse();
    }
}