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

Commit 06daf899 authored by wilsonshih's avatar wilsonshih
Browse files

Use sync transaction for prepare open transition.

Make transaction synchronized when animation happen.

Bug: 347168362
Flag: com.android.window.flags.migrate_predictive_back_transition
Test: verify PB back-to-home animation apply with start transation
Change-Id: Ia918568af83b90397d1627355a2f5279860015a3
parent 2ffa33c0
Loading
Loading
Loading
Loading
+51 −32
Original line number Diff line number Diff line
@@ -1072,8 +1072,10 @@ class BackNavigationController {
            return close.asWindowState() != null;
        }

        private void initiate(@NonNull WindowContainer close, @NonNull WindowContainer[] open,
        private void initiate(ScheduleAnimationBuilder builder,
                @NonNull ActivityRecord[] openingActivities)  {
            WindowContainer close = builder.mCloseTarget;
            WindowContainer[] open = builder.mOpenTargets;
            if (isActivitySwitch(close, open)) {
                mSwitchType = ACTIVITY_SWITCH;
                if (Flags.migratePredictiveBackTransition()) {
@@ -1091,9 +1093,17 @@ class BackNavigationController {
                return;
            }

            mCloseAdaptor = createAdaptor(close, false, mSwitchType);
            final Transition prepareTransition = builder.prepareTransitionIfNeeded(
                    openingActivities);
            final SurfaceControl.Transaction st = openingActivities[0].getSyncTransaction();
            final SurfaceControl.Transaction ct = prepareTransition != null
                    ? st : close.getPendingTransaction();
            mCloseAdaptor = createAdaptor(close, false, mSwitchType, ct);
            if (mCloseAdaptor.mAnimationTarget == null) {
                Slog.w(TAG, "composeNewAnimations fail, skip");
                if (prepareTransition != null) {
                    prepareTransition.abort();
                }
                clearBackAnimateTarget(true /* cancel */);
                return;
            }
@@ -1110,12 +1120,17 @@ class BackNavigationController {
                            next.getWindowConfiguration().getRotation());
                }
            }
            mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(true, mSwitchType, open);
            mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(
                    true, mSwitchType, st, open);
            if (!mOpenAnimAdaptor.isValid()) {
                Slog.w(TAG, "compose animations fail, skip");
                if (prepareTransition != null) {
                    prepareTransition.abort();
                }
                clearBackAnimateTarget(true /* cancel */);
                return;
            }
            mOpenAnimAdaptor.mPreparedOpenTransition = prepareTransition;
            mOpenActivities = openingActivities;
        }

@@ -1147,19 +1162,21 @@ class BackNavigationController {
            return new Pair<>(replaceClose, replaceOpen);
        }

        private boolean composeAnimations(@NonNull WindowContainer close,
                @NonNull WindowContainer[] open, @NonNull ActivityRecord[] openingActivities) {
        private boolean composeAnimations(@NonNull ScheduleAnimationBuilder builder,
                @NonNull ActivityRecord[] openingActivities) {
            if (mComposed || mWaitTransition) {
                Slog.e(TAG, "Previous animation is running " + this);
                return false;
            }
            clearBackAnimateTarget(true /* cancel */);
            if (close == null || open == null || open.length == 0 || open.length > 2) {
            final WindowContainer[] open = builder.mOpenTargets;
            if (builder.mCloseTarget == null || open == null || open.length == 0
                    || open.length > 2) {
                Slog.e(TAG, "reset animation with null target close: "
                        + close + " open: " + Arrays.toString(open));
                        + builder.mCloseTarget + " open: " + Arrays.toString(open));
                return false;
            }
            initiate(close, open, openingActivities);
            initiate(builder, openingActivities);
            if (mSwitchType == UNKNOWN) {
                return false;
            }
@@ -1384,10 +1401,10 @@ class BackNavigationController {
        }

        @NonNull private static BackWindowAnimationAdaptor createAdaptor(
                @NonNull WindowContainer target, boolean isOpen, int switchType) {
                @NonNull WindowContainer target, boolean isOpen, int switchType,
                SurfaceControl.Transaction st) {
            final BackWindowAnimationAdaptor adaptor =
                    new BackWindowAnimationAdaptor(target, isOpen, switchType);
            final SurfaceControl.Transaction pt = target.getPendingTransaction();
            // Workaround to show TaskFragment which can be hide in Transitions and won't show
            // during isAnimating.
            if (isOpen && target.asActivityRecord() != null) {
@@ -1395,10 +1412,10 @@ class BackNavigationController {
                if (fragment != null) {
                    // Ensure task fragment surface has updated, in case configuration has changed.
                    fragment.updateOrganizedTaskFragmentSurface();
                    pt.show(fragment.mSurfaceControl);
                    st.show(fragment.mSurfaceControl);
                }
            }
            target.startAnimation(pt, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
            target.startAnimation(st, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
            return adaptor;
        }

@@ -1417,12 +1434,12 @@ class BackNavigationController {
            private Transition mPreparedOpenTransition;

            BackWindowAnimationAdaptorWrapper(boolean isOpen, int switchType,
                    @NonNull WindowContainer... targets) {
                    SurfaceControl.Transaction st, @NonNull WindowContainer... targets) {
                mAdaptors = new BackWindowAnimationAdaptor[targets.length];
                for (int i = targets.length - 1; i >= 0; --i) {
                    mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType);
                    mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType, st);
                }
                mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget()
                mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget(st)
                        : mAdaptors[0].mAnimationTarget;
            }

@@ -1448,7 +1465,7 @@ class BackNavigationController {
                mPreparedOpenTransition = null;
            }

            private RemoteAnimationTarget createWrapTarget() {
            private RemoteAnimationTarget createWrapTarget(SurfaceControl.Transaction st) {
                // Special handle for opening two activities together.
                // If we animate both activities separately, the animation area and rounded corner
                // would also being handled separately. To make them seem like "open" together, wrap
@@ -1470,12 +1487,11 @@ class BackNavigationController {
                        .build();
                mCloseTransaction = new SurfaceControl.Transaction();
                mCloseTransaction.reparent(leashSurface, null);
                final SurfaceControl.Transaction pt = wc.getPendingTransaction();
                pt.setLayer(leashSurface, wc.getLastLayer());
                st.setLayer(leashSurface, wc.getLastLayer());
                for (int i = mAdaptors.length - 1; i >= 0; --i) {
                    BackWindowAnimationAdaptor adaptor = mAdaptors[i];
                    pt.reparent(adaptor.mAnimationTarget.leash, leashSurface);
                    pt.setPosition(adaptor.mAnimationTarget.leash,
                    st.reparent(adaptor.mAnimationTarget.leash, leashSurface);
                    st.setPosition(adaptor.mAnimationTarget.leash,
                            adaptor.mAnimationTarget.localBounds.left,
                            adaptor.mAnimationTarget.localBounds.top);
                    // For adjacent activity embedded, reparent Activity to TaskFragment when
@@ -1738,6 +1754,7 @@ class BackNavigationController {
            WindowContainer mCloseTarget;
            WindowContainer[] mOpenTargets;
            boolean mIsLaunchBehind;
            TaskSnapshot mSnapshot;

            ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter,
                    NavigationMonitor monitor) {
@@ -1771,6 +1788,13 @@ class BackNavigationController {
                return wc == mCloseTarget || mCloseTarget.hasChild(wc) || wc.hasChild(mCloseTarget);
            }

            private Transition prepareTransitionIfNeeded(ActivityRecord[] visibleOpenActivities) {
                if (mSnapshot == null) {
                    return setLaunchBehind(visibleOpenActivities);
                }
                return null;
            }

            /**
             * Apply preview strategy on the opening target
             *
@@ -1780,26 +1804,17 @@ class BackNavigationController {
            private void applyPreviewStrategy(
                    @NonNull BackWindowAnimationAdaptorWrapper openAnimationAdaptor,
                    @NonNull ActivityRecord[] visibleOpenActivities) {
                boolean needsLaunchBehind = true;
                if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
                    boolean activitiesAreDrawn = false;
                    for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
                        // If the activity hasn't stopped, it's window should remain drawn.
                        activitiesAreDrawn |= visibleOpenActivities[i].firstWindowDrawn;
                    }
                    final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
                    final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
                    // Don't create starting surface if previous activities haven't stopped or
                    // the snapshot does not exist.
                    if (snapshot != null || !activitiesAreDrawn) {
                        openAnimationAdaptor.createStartingSurface(snapshot);
                    }
                    // Only use LaunchBehind if snapshot does not exist.
                    needsLaunchBehind = snapshot == null;
                    if (mSnapshot != null || !activitiesAreDrawn) {
                        openAnimationAdaptor.createStartingSurface(mSnapshot);
                    }
                if (needsLaunchBehind) {
                    openAnimationAdaptor.mPreparedOpenTransition =
                            setLaunchBehind(visibleOpenActivities);
                }
                // Force update mLastSurfaceShowing for opening activity and its task.
                if (mWindowManagerService.mRoot.mTransitionController.isShellTransitionsEnabled()) {
@@ -1821,7 +1836,11 @@ class BackNavigationController {
                    return null;
                }

                if (!composeAnimations(mCloseTarget, mOpenTargets, openingActivities)) {
                if (!shouldLaunchBehind && mShowWindowlessSurface) {
                    mSnapshot = getSnapshot(mOpenTargets[0], openingActivities);
                }

                if (!composeAnimations(this, openingActivities)) {
                    return null;
                }
                mCloseTarget.mTransitionController.mSnapshotController