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

Commit 2fdf42cc authored by Vinit Nayak's avatar Vinit Nayak Committed by Android Build Coastguard Worker
Browse files

Add new Transit type to pass through from split to remote animation

* Revert of ag/27904335 with additions
* For the original bug, we were consuming the transition because
we want to monitor things while split is active, but we weren't
allowing the remote animation to run even though split did not
have any animation to play.
* If we consume a transition that has a remote, keep track of it
and invoke it's start animation in StageCoordinator's startAnimation

Fixes: 353120156
Test: Original bug from revert doesn't repro, new bug
also doesn't repro. General split cases work
Flag: EXEMPT bugfix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8880016686308d33178af0a194c898272a4295f5)
Merged-In: Ib55d677a7c662b198cddeaef8a234d4c6d5cee26
Change-Id: Ib55d677a7c662b198cddeaef8a234d4c6d5cee26
parent 1e23f6f1
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ class SplitScreenTransitions {
    DismissSession mPendingDismiss = null;
    EnterSession mPendingEnter = null;
    TransitSession mPendingResize = null;
    TransitSession mPendingRemotePassthrough = null;

    private IBinder mAnimatingTransition = null;
    private OneShotRemoteHandler mActiveRemoteHandler = null;
@@ -320,6 +321,11 @@ class SplitScreenTransitions {
        return mPendingResize != null && mPendingResize.mTransition == transition;
    }

    boolean isPendingPassThrough(IBinder transition) {
        return mPendingRemotePassthrough != null &&
                mPendingRemotePassthrough.mTransition == transition;
    }

    @Nullable
    private TransitSession getPendingTransition(IBinder transition) {
        if (isPendingEnter(transition)) {
@@ -331,6 +337,9 @@ class SplitScreenTransitions {
        } else if (isPendingResize(transition)) {
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "\tresolved resize transition");
            return mPendingResize;
        } else if (isPendingPassThrough(transition)) {
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "\tresolved passThrough transition");
            return mPendingRemotePassthrough;
        }
        return null;
    }
@@ -378,6 +387,19 @@ class SplitScreenTransitions {
                extraTransitType, resizeAnim);
    }

    /** Sets a transition to enter split. */
    void setRemotePassThroughTransition(@NonNull IBinder transition,
            @Nullable RemoteTransition remoteTransition) {
        mPendingRemotePassthrough = new TransitSession(
                transition, null, null,
                remoteTransition, Transitions.TRANSIT_SPLIT_PASSTHROUGH);

        ProtoLog.v(WM_SHELL_TRANSITIONS, "  splitTransition "
                + " deduced remote passthrough split screen");
        ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setRemotePassThrough: transitType=%d remote=%s",
                Transitions.TRANSIT_SPLIT_PASSTHROUGH, remoteTransition);
    }

    /** Starts a transition to dismiss split. */
    IBinder startDismissTransition(WindowContainerTransaction wct,
            Transitions.TransitionHandler handler, @SplitScreen.StageType int dismissTop,
@@ -474,6 +496,12 @@ class SplitScreenTransitions {
            mPendingResize.onConsumed(aborted);
            mPendingResize = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for resize transition");
        } else if (isPendingPassThrough(transition)) {
            mPendingRemotePassthrough.onConsumed(aborted);
            mPendingRemotePassthrough.mRemoteHandler.onTransitionConsumed(transition, aborted,
                    finishT);
            mPendingRemotePassthrough = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTransitionConsumed for passThrough transition");
        }

        // TODO: handle transition consumed for active remote handler
@@ -495,6 +523,10 @@ class SplitScreenTransitions {
            mPendingResize.onFinished(wct, mFinishTransaction);
            mPendingResize = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onFinish for resize transition");
        } else if (isPendingPassThrough(mAnimatingTransition)) {
            mPendingRemotePassthrough.onFinished(wct, mFinishTransaction);
            mPendingRemotePassthrough = null;
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onFinish for passThrough transition");
        }

        mActiveRemoteHandler = null;
+12 −1
Original line number Diff line number Diff line
@@ -2649,7 +2649,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            @Nullable TransitionRequestInfo request) {
        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
        if (triggerTask == null) {
            if (isSplitScreenVisible()) {
            if (isSplitActive()) {
                ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "handleRequest: transition=%d display rotation",
                        request.getDebugId());
                // Check if the display is rotating.
@@ -2659,6 +2659,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                        && displayChange.getStartRotation() != displayChange.getEndRotation()) {
                    mSplitLayout.setFreezeDividerWindow(true);
                }
                if (request.getRemoteTransition() != null) {
                    mSplitTransitions.setRemotePassThroughTransition(transition,
                            request.getRemoteTransition());
                }
                // Still want to monitor everything while in split-screen, so return non-null.
                return new WindowContainerTransaction();
            } else {
@@ -2985,6 +2989,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                notifySplitAnimationFinished();
                return true;
            }
        } else if (mSplitTransitions.isPendingPassThrough(transition)) {
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN,
                    "startAnimation: passThrough transition=%d", info.getDebugId());
            mSplitTransitions.mPendingRemotePassthrough.mRemoteHandler.startAnimation(transition,
                    info, startTransaction, finishTransaction, finishCallback);
            notifySplitAnimationFinished();
            return true;
        }

        return startPendingAnimation(transition, info, startTransaction, finishTransaction,
+3 −0
Original line number Diff line number Diff line
@@ -189,6 +189,9 @@ public class Transitions implements RemoteCallable<Transitions>,
            // TRANSIT_FIRST_CUSTOM + 17
            TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_DRAG_RESIZE;

    /** Remote Transition that split accepts but ultimately needs to be animated by the remote. */
    public static final int TRANSIT_SPLIT_PASSTHROUGH = TRANSIT_FIRST_CUSTOM + 18;

    /** Transition type for desktop mode transitions. */
    public static final int TRANSIT_DESKTOP_MODE_TYPES =
            WindowManager.TRANSIT_FIRST_CUSTOM + 100;
+28 −0
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@ import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.IRemoteTransition;
import android.window.RemoteTransition;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
@@ -324,6 +326,32 @@ public class SplitTransitionTests extends ShellTestCase {
        assertFalse(mStageCoordinator.isSplitScreenVisible());
    }

    @Test
    @UiThreadTest
    public void testRemotePassThroughInvoked() throws RemoteException {
        RemoteTransition remoteWrapper = mock(RemoteTransition.class);
        IRemoteTransition remoteTransition = mock(IRemoteTransition.class);
        IBinder remoteBinder = mock(IBinder.class);
        doReturn(remoteBinder).when(remoteTransition).asBinder();
        doReturn(remoteTransition).when(remoteWrapper).getRemoteTransition();

        TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_CHANGE, null,
                remoteWrapper);
        IBinder transition = mock(IBinder.class);
        mMainStage.activate(new WindowContainerTransaction(), false);
        mStageCoordinator.handleRequest(transition, request);
        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CHANGE, 0)
                .build();
        boolean accepted = mStageCoordinator.startAnimation(transition, info,
                mock(SurfaceControl.Transaction.class),
                mock(SurfaceControl.Transaction.class),
                mock(Transitions.TransitionFinishCallback.class));
        assertTrue(accepted);

        verify(remoteTransition, times(1)).startAnimation(any(),
                any(), any(), any());
    }

    @Test
    @UiThreadTest
    public void testEnterRecentsAndRestore() {