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

Commit 7993d237 authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Add support for multiple roots in a transition" into udc-dev am: f8bbb00c

parents 016642d4 f8bbb00c
Loading
Loading
Loading
Loading
+175 −28
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.app.ActivityOptions.ANIM_SCALE_UP;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_CLOSE;
@@ -58,6 +59,7 @@ import java.util.List;
 * @hide
 * @hide
 */
 */
public final class TransitionInfo implements Parcelable {
public final class TransitionInfo implements Parcelable {
    private static final String TAG = "TransitionInfo";


    /**
    /**
     * Modes are only a sub-set of all the transit-types since they are per-container
     * Modes are only a sub-set of all the transit-types since they are per-container
@@ -184,9 +186,7 @@ public final class TransitionInfo implements Parcelable {
    private final @TransitionType int mType;
    private final @TransitionType int mType;
    private final @TransitionFlags int mFlags;
    private final @TransitionFlags int mFlags;
    private final ArrayList<Change> mChanges = new ArrayList<>();
    private final ArrayList<Change> mChanges = new ArrayList<>();

    private final ArrayList<Root> mRoots = new ArrayList<>();
    private SurfaceControl mRootLeash;
    private final Point mRootOffset = new Point();


    private AnimationOptions mOptions;
    private AnimationOptions mOptions;


@@ -200,10 +200,7 @@ public final class TransitionInfo implements Parcelable {
        mType = in.readInt();
        mType = in.readInt();
        mFlags = in.readInt();
        mFlags = in.readInt();
        in.readTypedList(mChanges, Change.CREATOR);
        in.readTypedList(mChanges, Change.CREATOR);
        mRootLeash = new SurfaceControl();
        in.readTypedList(mRoots, Root.CREATOR);
        mRootLeash.readFromParcel(in);
        mRootLeash.setUnreleasedWarningCallSite("TransitionInfo");
        mRootOffset.readFromParcel(in);
        mOptions = in.readTypedObject(AnimationOptions.CREATOR);
        mOptions = in.readTypedObject(AnimationOptions.CREATOR);
    }
    }


@@ -213,8 +210,7 @@ public final class TransitionInfo implements Parcelable {
        dest.writeInt(mType);
        dest.writeInt(mType);
        dest.writeInt(mFlags);
        dest.writeInt(mFlags);
        dest.writeTypedList(mChanges);
        dest.writeTypedList(mChanges);
        mRootLeash.writeToParcel(dest, flags);
        dest.writeTypedList(mRoots, flags);
        mRootOffset.writeToParcel(dest, flags);
        dest.writeTypedObject(mOptions, flags);
        dest.writeTypedObject(mOptions, flags);
    }
    }


@@ -238,10 +234,15 @@ public final class TransitionInfo implements Parcelable {
        return 0;
        return 0;
    }
    }


    /** @see #getRootLeash() */
    /** @see #getRoot */
    public void setRootLeash(@NonNull SurfaceControl leash, int offsetLeft, int offsetTop) {
    public void addRootLeash(int displayId, @NonNull SurfaceControl leash,
        mRootLeash = leash;
            int offsetLeft, int offsetTop) {
        mRootOffset.set(offsetLeft, offsetTop);
        mRoots.add(new Root(displayId, leash, offsetLeft, offsetTop));
    }

    /** @see #getRoot */
    public void addRoot(Root other) {
        mRoots.add(other);
    }
    }


    public void setAnimationOptions(AnimationOptions options) {
    public void setAnimationOptions(AnimationOptions options) {
@@ -256,24 +257,53 @@ public final class TransitionInfo implements Parcelable {
        return mFlags;
        return mFlags;
    }
    }


    /**
     * @return The number of animation roots. Most transitions should have 1, but there may be more
     *         in some cases (such as a transition spanning multiple displays).
     */
    public int getRootCount() {
        return mRoots.size();
    }

    /**
     * @return the transition-root at a specific index.
     */
    @NonNull
    public Root getRoot(int idx) {
        return mRoots.get(idx);
    }

    /**
     * @return the index of the transition-root associated with `displayId` or -1 if not found.
     */
    public int findRootIndex(int displayId) {
        for (int i = 0; i < mRoots.size(); ++i) {
            if (mRoots.get(i).mDisplayId == displayId) {
                return i;
            }
        }
        return -1;
    }

    /**
    /**
     * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing
     * @return a surfacecontrol that can serve as a parent surfacecontrol for all the changing
     * participants to animate within. This will generally be placed at the highest-z-order
     * participants to animate within. This will generally be placed at the highest-z-order
     * shared ancestor of all participants. While this is non-null, it's possible for the rootleash
     * shared ancestor of all participants. While this is non-null, it's possible for the rootleash
     * to be invalid if the transition is a no-op.
     * to be invalid if the transition is a no-op.
     *
     * @deprecated Use {@link #getRoot} instead. This call assumes there is only one root.
     */
     */
    @Deprecated
    @NonNull
    @NonNull
    public SurfaceControl getRootLeash() {
    public SurfaceControl getRootLeash() {
        if (mRootLeash == null) {
        if (mRoots.isEmpty()) {
            throw new IllegalStateException("Trying to get a leash which wasn't set");
            throw new IllegalStateException("Trying to get a root leash from a no-op transition.");
        }
        }
        return mRootLeash;
        if (mRoots.size() > 1) {
            android.util.Log.e(TAG, "Assuming one animation root when there are more.",
                    new Throwable());
        }
        }

        return mRoots.get(0).mLeash;
    /** @return the offset (relative to the screen) of the root leash. */
    @NonNull
    public Point getRootOffset() {
        return mRootOffset;
    }
    }


    public AnimationOptions getAnimationOptions() {
    public AnimationOptions getAnimationOptions() {
@@ -320,8 +350,15 @@ public final class TransitionInfo implements Parcelable {
    @Override
    @Override
    public String toString() {
    public String toString() {
        StringBuilder sb = new StringBuilder();
        StringBuilder sb = new StringBuilder();
        sb.append("{t=" + transitTypeToString(mType) + " f=0x" + Integer.toHexString(mFlags)
        sb.append("{t=").append(transitTypeToString(mType)).append(" f=0x")
                + " ro=" + mRootOffset + " c=[");
                .append(Integer.toHexString(mFlags)).append(" r=[");
        for (int i = 0; i < mRoots.size(); ++i) {
            if (i > 0) {
                sb.append(',');
            }
            sb.append(mRoots.get(i).mDisplayId).append("@").append(mRoots.get(i).mOffset);
        }
        sb.append("] c=[");
        for (int i = 0; i < mChanges.size(); ++i) {
        for (int i = 0; i < mChanges.size(); ++i) {
            if (i > 0) {
            if (i > 0) {
                sb.append(',');
                sb.append(',');
@@ -448,8 +485,8 @@ public final class TransitionInfo implements Parcelable {
                c.mSnapshot = null;
                c.mSnapshot = null;
            }
            }
        }
        }
        if (mRootLeash != null) {
        for (int i = 0; i < mRoots.size(); ++i) {
            mRootLeash.release();
            mRoots.get(i).mLeash.release();
        }
        }
    }
    }


@@ -476,10 +513,11 @@ public final class TransitionInfo implements Parcelable {
        for (int i = 0; i < mChanges.size(); ++i) {
        for (int i = 0; i < mChanges.size(); ++i) {
            out.mChanges.add(mChanges.get(i).localRemoteCopy());
            out.mChanges.add(mChanges.get(i).localRemoteCopy());
        }
        }
        out.mRootLeash = mRootLeash != null ? new SurfaceControl(mRootLeash, "localRemote") : null;
        for (int i = 0; i < mRoots.size(); ++i) {
            out.mRoots.add(mRoots.get(i).localRemoteCopy());
        }
        // Doesn't have any native stuff, so no need for actual copy
        // Doesn't have any native stuff, so no need for actual copy
        out.mOptions = mOptions;
        out.mOptions = mOptions;
        out.mRootOffset.set(mRootOffset);
        return out;
        return out;
    }
    }


@@ -496,6 +534,8 @@ public final class TransitionInfo implements Parcelable {
        private final Point mEndRelOffset = new Point();
        private final Point mEndRelOffset = new Point();
        private ActivityManager.RunningTaskInfo mTaskInfo = null;
        private ActivityManager.RunningTaskInfo mTaskInfo = null;
        private boolean mAllowEnterPip;
        private boolean mAllowEnterPip;
        private int mStartDisplayId = INVALID_DISPLAY;
        private int mEndDisplayId = INVALID_DISPLAY;
        private @Surface.Rotation int mStartRotation = ROTATION_UNDEFINED;
        private @Surface.Rotation int mStartRotation = ROTATION_UNDEFINED;
        private @Surface.Rotation int mEndRotation = ROTATION_UNDEFINED;
        private @Surface.Rotation int mEndRotation = ROTATION_UNDEFINED;
        /**
        /**
@@ -526,6 +566,8 @@ public final class TransitionInfo implements Parcelable {
            mEndRelOffset.readFromParcel(in);
            mEndRelOffset.readFromParcel(in);
            mTaskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
            mTaskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
            mAllowEnterPip = in.readBoolean();
            mAllowEnterPip = in.readBoolean();
            mStartDisplayId = in.readInt();
            mEndDisplayId = in.readInt();
            mStartRotation = in.readInt();
            mStartRotation = in.readInt();
            mEndRotation = in.readInt();
            mEndRotation = in.readInt();
            mEndFixedRotation = in.readInt();
            mEndFixedRotation = in.readInt();
@@ -546,6 +588,8 @@ public final class TransitionInfo implements Parcelable {
            out.mEndRelOffset.set(mEndRelOffset);
            out.mEndRelOffset.set(mEndRelOffset);
            out.mTaskInfo = mTaskInfo;
            out.mTaskInfo = mTaskInfo;
            out.mAllowEnterPip = mAllowEnterPip;
            out.mAllowEnterPip = mAllowEnterPip;
            out.mStartDisplayId = mStartDisplayId;
            out.mEndDisplayId = mEndDisplayId;
            out.mStartRotation = mStartRotation;
            out.mStartRotation = mStartRotation;
            out.mEndRotation = mEndRotation;
            out.mEndRotation = mEndRotation;
            out.mEndFixedRotation = mEndFixedRotation;
            out.mEndFixedRotation = mEndFixedRotation;
@@ -607,6 +651,12 @@ public final class TransitionInfo implements Parcelable {
            mAllowEnterPip = allowEnterPip;
            mAllowEnterPip = allowEnterPip;
        }
        }


        /** Sets the start and end rotation of this container. */
        public void setDisplayId(int start, int end) {
            mStartDisplayId = start;
            mEndDisplayId = end;
        }

        /** Sets the start and end rotation of this container. */
        /** Sets the start and end rotation of this container. */
        public void setRotation(@Surface.Rotation int start, @Surface.Rotation int end) {
        public void setRotation(@Surface.Rotation int start, @Surface.Rotation int end) {
            mStartRotation = start;
            mStartRotation = start;
@@ -725,6 +775,14 @@ public final class TransitionInfo implements Parcelable {
            return mAllowEnterPip;
            return mAllowEnterPip;
        }
        }


        public int getStartDisplayId() {
            return mStartDisplayId;
        }

        public int getEndDisplayId() {
            return mEndDisplayId;
        }

        @Surface.Rotation
        @Surface.Rotation
        public int getStartRotation() {
        public int getStartRotation() {
            return mStartRotation;
            return mStartRotation;
@@ -776,6 +834,8 @@ public final class TransitionInfo implements Parcelable {
            mEndRelOffset.writeToParcel(dest, flags);
            mEndRelOffset.writeToParcel(dest, flags);
            dest.writeTypedObject(mTaskInfo, flags);
            dest.writeTypedObject(mTaskInfo, flags);
            dest.writeBoolean(mAllowEnterPip);
            dest.writeBoolean(mAllowEnterPip);
            dest.writeInt(mStartDisplayId);
            dest.writeInt(mEndDisplayId);
            dest.writeInt(mStartRotation);
            dest.writeInt(mStartRotation);
            dest.writeInt(mEndRotation);
            dest.writeInt(mEndRotation);
            dest.writeInt(mEndFixedRotation);
            dest.writeInt(mEndFixedRotation);
@@ -822,6 +882,11 @@ public final class TransitionInfo implements Parcelable {
            if (mEndRelOffset.x != 0 || mEndRelOffset.y != 0) {
            if (mEndRelOffset.x != 0 || mEndRelOffset.y != 0) {
                sb.append(" eo="); sb.append(mEndRelOffset);
                sb.append(" eo="); sb.append(mEndRelOffset);
            }
            }
            sb.append(" d=");
            if (mStartDisplayId != mEndDisplayId) {
                sb.append(mStartDisplayId).append("->");
            }
            sb.append(mEndDisplayId);
            if (mStartRotation != mEndRotation) {
            if (mStartRotation != mEndRotation) {
                sb.append(" r="); sb.append(mStartRotation);
                sb.append(" r="); sb.append(mStartRotation);
                sb.append("->"); sb.append(mEndRotation);
                sb.append("->"); sb.append(mEndRotation);
@@ -1108,4 +1173,86 @@ public final class TransitionInfo implements Parcelable {
                    };
                    };
        }
        }
    }
    }

    /**
     * An animation root in a transition. There is one of these for each display that contains
     * participants. It will be placed, in z-order, right above the top-most participant and at the
     * same position in the hierarchy. As a result, if all participants are animating within a
     * part of the screen, the root-leash will only be in that part of the screen. In these cases,
     * it's relative position (from the screen) is stored in {@link Root#getOffset}.
     */
    public static final class Root implements Parcelable {
        private final int mDisplayId;
        private final SurfaceControl mLeash;
        private final Point mOffset = new Point();

        public Root(int displayId, @NonNull SurfaceControl leash, int offsetLeft, int offsetTop) {
            mDisplayId = displayId;
            mLeash = leash;
            mOffset.set(offsetLeft, offsetTop);
        }

        private Root(Parcel in) {
            mDisplayId = in.readInt();
            mLeash = new SurfaceControl();
            mLeash.readFromParcel(in);
            mLeash.setUnreleasedWarningCallSite("TransitionInfo.Root");
            mOffset.readFromParcel(in);
        }

        private Root localRemoteCopy() {
            return new Root(mDisplayId, new SurfaceControl(mLeash, "localRemote"),
                    mOffset.x, mOffset.y);
        }

        /** @return the id of the display this root is on. */
        public int getDisplayId() {
            return mDisplayId;
        }

        /** @return the root's leash. Surfaces should be parented to this while animating. */
        @NonNull
        public SurfaceControl getLeash() {
            return mLeash;
        }

        /** @return the offset (relative to its screen) of the root leash. */
        @NonNull
        public Point getOffset() {
            return mOffset;
        }

        /** @hide */
        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            dest.writeInt(mDisplayId);
            mLeash.writeToParcel(dest, flags);
            mOffset.writeToParcel(dest, flags);
        }

        @NonNull
        public static final Creator<Root> CREATOR =
                new Creator<Root>() {
                    @Override
                    public Root createFromParcel(Parcel in) {
                        return new Root(in);
                    }

                    @Override
                    public Root[] newArray(int size) {
                        return new Root[size];
                    }
                };

        /** @hide */
        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public String toString() {
            return mDisplayId + "@" + mOffset + ":" + mLeash;
        }
    }
}
}
+3 −2
Original line number Original line Diff line number Diff line
@@ -489,10 +489,11 @@ public class PipTransition extends PipTransitionController {
        // Reparent the pip leash to the root with max layer so that we can animate it outside of
        // Reparent the pip leash to the root with max layer so that we can animate it outside of
        // parent crop, and make sure it is not covered by other windows.
        // parent crop, and make sure it is not covered by other windows.
        final SurfaceControl pipLeash = pipChange.getLeash();
        final SurfaceControl pipLeash = pipChange.getLeash();
        startTransaction.reparent(pipLeash, info.getRootLeash());
        final int rootIdx = TransitionUtil.rootIndexFor(pipChange, info);
        startTransaction.reparent(pipLeash, info.getRoot(rootIdx).getLeash());
        startTransaction.setLayer(pipLeash, Integer.MAX_VALUE);
        startTransaction.setLayer(pipLeash, Integer.MAX_VALUE);
        // Note: because of this, the bounds to animate should be translated to the root coordinate.
        // Note: because of this, the bounds to animate should be translated to the root coordinate.
        final Point offset = info.getRootOffset();
        final Point offset = info.getRoot(rootIdx).getOffset();
        final Rect currentBounds = mPipBoundsState.getBounds();
        final Rect currentBounds = mPipBoundsState.getBounds();
        currentBounds.offset(-offset.x, -offset.y);
        currentBounds.offset(-offset.x, -offset.y);
        startTransaction.setPosition(pipLeash, currentBounds.left, currentBounds.top);
        startTransaction.setPosition(pipLeash, currentBounds.left, currentBounds.top);
+6 −3
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.IBinder;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
@@ -128,6 +129,7 @@ class SplitScreenTransitions {
            final int mode = info.getChanges().get(i).getMode();
            final int mode = info.getChanges().get(i).getMode();


            if (mode == TRANSIT_CHANGE) {
            if (mode == TRANSIT_CHANGE) {
                final int rootIdx = TransitionUtil.rootIndexFor(change, info);
                if (change.getParent() != null) {
                if (change.getParent() != null) {
                    // This is probably reparented, so we want the parent to be immediately visible
                    // This is probably reparented, so we want the parent to be immediately visible
                    final TransitionInfo.Change parentChange = info.getChange(change.getParent());
                    final TransitionInfo.Change parentChange = info.getChange(change.getParent());
@@ -135,7 +137,7 @@ class SplitScreenTransitions {
                    t.setAlpha(parentChange.getLeash(), 1.f);
                    t.setAlpha(parentChange.getLeash(), 1.f);
                    // and then animate this layer outside the parent (since, for example, this is
                    // and then animate this layer outside the parent (since, for example, this is
                    // the home task animating from fullscreen to part-screen).
                    // the home task animating from fullscreen to part-screen).
                    t.reparent(leash, info.getRootLeash());
                    t.reparent(leash, info.getRoot(rootIdx).getLeash());
                    t.setLayer(leash, info.getChanges().size() - i);
                    t.setLayer(leash, info.getChanges().size() - i);
                    // build the finish reparent/reposition
                    // build the finish reparent/reposition
                    mFinishTransaction.reparent(leash, parentChange.getLeash());
                    mFinishTransaction.reparent(leash, parentChange.getLeash());
@@ -145,8 +147,9 @@ class SplitScreenTransitions {
                // TODO(shell-transitions): screenshot here
                // TODO(shell-transitions): screenshot here
                final Rect startBounds = new Rect(change.getStartAbsBounds());
                final Rect startBounds = new Rect(change.getStartAbsBounds());
                final Rect endBounds = new Rect(change.getEndAbsBounds());
                final Rect endBounds = new Rect(change.getEndAbsBounds());
                startBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
                final Point rootOffset = info.getRoot(rootIdx).getOffset();
                endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
                startBounds.offset(-rootOffset.x, -rootOffset.y);
                endBounds.offset(-rootOffset.x, -rootOffset.y);
                startExampleResizeAnimation(leash, startBounds, endBounds);
                startExampleResizeAnimation(leash, startBounds, endBounds);
            }
            }
            boolean isRootOrSplitSideRoot = change.getParent() == null
            boolean isRootOrSplitSideRoot = change.getParent() == null
+3 −1
Original line number Original line Diff line number Diff line
@@ -179,7 +179,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
                out.getChanges().add(info.getChanges().get(i));
                out.getChanges().add(info.getChanges().get(i));
            }
            }
        }
        }
        out.setRootLeash(info.getRootLeash(), info.getRootOffset().x, info.getRootOffset().y);
        for (int i = 0; i < info.getRootCount(); ++i) {
            out.addRoot(info.getRoot(i));
        }
        out.setAnimationOptions(info.getAnimationOptions());
        out.setAnimationOptions(info.getAnimationOptions());
        return out;
        return out;
    }
    }
+10 −5
Original line number Original line Diff line number Diff line
@@ -383,9 +383,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                    continue;
                    continue;
                }
                }
                // No default animation for this, so just update bounds/position.
                // No default animation for this, so just update bounds/position.
                final int rootIdx = TransitionUtil.rootIndexFor(change, info);
                startTransaction.setPosition(change.getLeash(),
                startTransaction.setPosition(change.getLeash(),
                        change.getEndAbsBounds().left - info.getRootOffset().x,
                        change.getEndAbsBounds().left - info.getRoot(rootIdx).getOffset().x,
                        change.getEndAbsBounds().top - info.getRootOffset().y);
                        change.getEndAbsBounds().top - info.getRoot(rootIdx).getOffset().y);
                // Seamless display transition doesn't need to animate.
                // Seamless display transition doesn't need to animate.
                if (isSeamlessDisplayChange) continue;
                if (isSeamlessDisplayChange) continue;
                if (isTask || (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)
                if (isTask || (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)
@@ -474,9 +475,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        }
        }


        if (backgroundColorForTransition != 0) {
        if (backgroundColorForTransition != 0) {
            addBackgroundToTransition(info.getRootLeash(), backgroundColorForTransition,
            for (int i = 0; i < info.getRootCount(); ++i) {
                addBackgroundToTransition(info.getRoot(i).getLeash(), backgroundColorForTransition,
                        startTransaction, finishTransaction);
                        startTransaction, finishTransaction);
            }
            }
        }


        if (postStartTransactionCallbacks.size() > 0) {
        if (postStartTransactionCallbacks.size() > 0) {
            // postStartTransactionCallbacks require that the start transaction is already
            // postStartTransactionCallbacks require that the start transaction is already
@@ -520,8 +523,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
    private void startRotationAnimation(SurfaceControl.Transaction startTransaction,
    private void startRotationAnimation(SurfaceControl.Transaction startTransaction,
            TransitionInfo.Change change, TransitionInfo info, int animHint,
            TransitionInfo.Change change, TransitionInfo info, int animHint,
            ArrayList<Animator> animations, Runnable onAnimFinish) {
            ArrayList<Animator> animations, Runnable onAnimFinish) {
        final int rootIdx = TransitionUtil.rootIndexFor(change, info);
        final ScreenRotationAnimation anim = new ScreenRotationAnimation(mContext, mSurfaceSession,
        final ScreenRotationAnimation anim = new ScreenRotationAnimation(mContext, mSurfaceSession,
                mTransactionPool, startTransaction, change, info.getRootLeash(), animHint);
                mTransactionPool, startTransaction, change, info.getRoot(rootIdx).getLeash(),
                animHint);
        // The rotation animation may consist of 3 animations: fade-out screenshot, fade-in real
        // The rotation animation may consist of 3 animations: fade-out screenshot, fade-in real
        // content, and background color. The item of "animGroup" will be removed if the sub
        // content, and background color. The item of "animGroup" will be removed if the sub
        // animation is finished. Then if the list becomes empty, the rotation animation is done.
        // animation is finished. Then if the list becomes empty, the rotation animation is done.
Loading