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

Commit 6ea05424 authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Adapt transition merge during recents into onTaskAppeared." into sc-dev am: aadebf0a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14297820

Change-Id: Ib07681dd19925d8a211deeae0167ecc61b48c869
parents e4fb1838 aadebf0a
Loading
Loading
Loading
Loading
+75 −11
Original line number Diff line number Diff line
@@ -101,6 +101,9 @@ public class RemoteTransitionCompat implements Parcelable {
    public RemoteTransitionCompat(RecentsAnimationListener recents,
            RecentsAnimationControllerCompat controller) {
        mTransition = new IRemoteTransition.Stub() {
            final RecentsControllerWrap mRecentsSession = new RecentsControllerWrap();
            IBinder mToken = null;

            @Override
            public void startAnimation(IBinder transition, TransitionInfo info,
                    SurfaceControl.Transaction t,
@@ -110,6 +113,7 @@ public class RemoteTransitionCompat implements Parcelable {
                final RemoteAnimationTargetCompat[] wallpapers =
                        RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */);
                // TODO(b/177438007): Move this set-up logic into launcher's animation impl.
                mToken = transition;
                // This transition is for opening recents, so recents is on-top. We want to draw
                // the current going-away task on top of recents, though, so move it to front
                WindowContainerToken pausingTask = null;
@@ -127,9 +131,8 @@ public class RemoteTransitionCompat implements Parcelable {
                    t.setAlpha(wallpapers[i].leash.mSurfaceControl, 1);
                }
                t.apply();
                final RecentsAnimationControllerCompat wrapControl =
                        new RecentsControllerWrap(controller, info, finishedCallback, pausingTask);
                recents.onAnimationStart(wrapControl, apps, wallpapers, new Rect(0, 0, 0, 0),
                mRecentsSession.setup(controller, info, finishedCallback, pausingTask);
                recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0),
                        new Rect());
            }

@@ -137,7 +140,13 @@ public class RemoteTransitionCompat implements Parcelable {
            public void mergeAnimation(IBinder transition, TransitionInfo info,
                    SurfaceControl.Transaction t, IBinder mergeTarget,
                    IRemoteTransitionFinishedCallback finishedCallback) {
                // TODO: hook up merge to onTaskAppeared. Until then, just ignore incoming merges.
                if (!mergeTarget.equals(mToken)) return;
                if (!mRecentsSession.merge(info, t, recents)) return;
                try {
                    finishedCallback.onTransitionFinished(null /* wct */);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error merging transition.", e);
                }
            }
        };
    }
@@ -159,19 +168,57 @@ public class RemoteTransitionCompat implements Parcelable {
     */
    @VisibleForTesting
    static class RecentsControllerWrap extends RecentsAnimationControllerCompat {
        private final RecentsAnimationControllerCompat mWrapped;
        private final IRemoteTransitionFinishedCallback mFinishCB;
        private final WindowContainerToken mPausingTask;
        private final TransitionInfo mInfo;
        private RecentsAnimationControllerCompat mWrapped = null;
        private IRemoteTransitionFinishedCallback mFinishCB = null;
        private WindowContainerToken mPausingTask = null;
        private TransitionInfo mInfo = null;
        private SurfaceControl mOpeningLeash = null;

        RecentsControllerWrap(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
        void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
                IRemoteTransitionFinishedCallback finishCB, WindowContainerToken pausingTask) {
            if (mInfo != null) {
                throw new IllegalStateException("Trying to run a new recents animation while"
                        + " recents is already active.");
            }
            mWrapped = wrapped;
            mInfo = info;
            mFinishCB = finishCB;
            mPausingTask = pausingTask;
        }

        @SuppressLint("NewApi")
        boolean merge(TransitionInfo info, SurfaceControl.Transaction t,
                RecentsAnimationListener recents) {
            TransitionInfo.Change openingTask = null;
            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                final TransitionInfo.Change change = info.getChanges().get(i);
                if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) {
                    if (change.getTaskInfo() != null) {
                        if (openingTask != null) {
                            Log.w(TAG, " Expecting to merge a task-open, but got >1 opening "
                                    + "tasks");
                        }
                        openingTask = change;
                    }
                }
            }
            if (openingTask == null) return false;
            mOpeningLeash = openingTask.getLeash();
            if (openingTask.getContainer().equals(mPausingTask)) {
                // In this case, we are "returning" to the already running app, so just consume
                // the merge and do nothing.
                return true;
            }
            // We are receiving a new opening task, so convert to onTaskAppeared.
            final int layer = mInfo.getChanges().size() * 3;
            t.reparent(mOpeningLeash, mInfo.getRootLeash());
            t.setLayer(mOpeningLeash, layer);
            t.hide(mOpeningLeash);
            t.apply();
            recents.onTaskAppeared(new RemoteAnimationTargetCompat(openingTask, layer));
            return true;
        }

        @Override public ThumbnailData screenshotTask(int taskId) {
            return mWrapped != null ? mWrapped.screenshotTask(taskId) : null;
        }
@@ -198,25 +245,42 @@ public class RemoteTransitionCompat implements Parcelable {
        @Override
        @SuppressLint("NewApi")
        public void finish(boolean toHome, boolean sendUserLeaveHint) {
            if (mFinishCB == null) {
                Log.e(TAG, "Duplicate call to finish", new RuntimeException());
                return;
            }
            if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint);
            try {
                if (!toHome && mPausingTask != null) {
                if (!toHome && mPausingTask != null && mOpeningLeash == null) {
                    // The gesture went back to opening the app rather than continuing with
                    // recents, so end the transition by moving the app back to the top.
                    final WindowContainerTransaction wct = new WindowContainerTransaction();
                    wct.reorder(mPausingTask, true /* onTop */);
                    mFinishCB.onTransitionFinished(wct);
                } else {
                    if (mOpeningLeash != null) {
                        // TODO: the launcher animation should handle this
                        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
                        t.show(mOpeningLeash);
                        t.setAlpha(mOpeningLeash, 1.f);
                        t.apply();
                    }
                    mFinishCB.onTransitionFinished(null /* wct */);
                }
            } catch (RemoteException e) {
                Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e);
            }
            if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint);
            // Release surface references now. This is apparently to free GPU
            // memory while doing quick operations (eg. during CTS).
            for (int i = 0; i < mInfo.getChanges().size(); ++i) {
                mInfo.getChanges().get(i).getLeash().release();
            }
            // Reset all members.
            mWrapped = null;
            mFinishCB = null;
            mPausingTask = null;
            mInfo = null;
            mOpeningLeash = null;
        }

        @Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {