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

Commit 325cc9a5 authored by wilsonshih's avatar wilsonshih
Browse files

Combine launchBehind + solid color splash screen for back predictive.

Address for no snapshot case.
To reduce the possible flickering caused from the icon of splash
screen, using solid color splash screen surface for opening target, and
set launchBehind for the opening activity.
Once the activity has drawn, remove the splash screen surface.

Bug: 268563842
Test: disable record snapshot and enable predictShowStartingSurface.
Verify predictive back animation will first show splash screen surface
for the opening target, then shows app window once it report drawn.

Change-Id: I14f20b1c69874661f91da6e299e63e6c2d0d32ee
parent 12e867a9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -417,7 +417,7 @@ public class SplashscreenContentDrawer {
        final SplashViewBuilder builder = new SplashViewBuilder(context, ai);
        final SplashScreenView view = builder
                .setWindowBGColor(themeBGColor)
                .chooseStyle(STARTING_WINDOW_TYPE_SPLASH_SCREEN)
                .chooseStyle(STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN)
                .build();
        view.setNotCopyable();
        return view;
+1 −0
Original line number Diff line number Diff line
@@ -6825,6 +6825,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // stop tracking
        mSplashScreenStyleSolidColor = true;

        mAtmService.mBackNavigationController.removePredictiveSurfaceIfNeeded(this);
        if (mStartingWindow != null) {
            ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s"
                    + ": first real window is shown, no animation", win.mToken);
+36 −7
Original line number Diff line number Diff line
@@ -644,6 +644,10 @@ class BackNavigationController {
        return false;
    }

    void removePredictiveSurfaceIfNeeded(ActivityRecord openActivity) {
        mAnimationHandler.markWindowHasDrawn(openActivity);
    }

    private class NavigationMonitor {
        // The window which triggering the back navigation.
        private WindowState mNavigatingWindow;
@@ -1032,6 +1036,23 @@ class BackNavigationController {
            return isAnimateTarget(wc, mCloseAdaptor.mTarget, mSwitchType);
        }

        void markWindowHasDrawn(ActivityRecord activity) {
            if (!mComposed || mWaitTransition) {
                return;
            }
            boolean allWindowDrawn = true;
            for (int i = mOpenAnimAdaptor.mAdaptors.length - 1; i >= 0; --i) {
                final BackWindowAnimationAdaptor next = mOpenAnimAdaptor.mAdaptors[i];
                if (isAnimateTarget(activity, next.mTarget, mSwitchType)) {
                    next.mAppWindowDrawn = true;
                }
                allWindowDrawn &= next.mAppWindowDrawn;
            }
            if (allWindowDrawn) {
                mOpenAnimAdaptor.cleanUpWindowlessSurface(true);
            }
        }

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

@@ -1181,8 +1204,6 @@ class BackNavigationController {
                for (int i = mAdaptors.length - 1; i >= 0; --i) {
                    mAdaptors[i].mTarget.cancelAnimation();
                }
                mRequestedStartingSurfaceId = INVALID_TASK_ID;
                mStartingSurface = null;
                if (mCloseTransaction != null) {
                    mCloseTransaction.apply();
                    mCloseTransaction = null;
@@ -1235,7 +1256,7 @@ class BackNavigationController {
                        represent.allowEnterPip);
            }

            void createStartingSurface(ActivityRecord[] visibleOpenActivities) {
            void createStartingSurface(@Nullable TaskSnapshot snapshot) {
                if (mAdaptors[0].mSwitchType == DIALOG_CLOSE) {
                    return;
                }
@@ -1253,7 +1274,6 @@ class BackNavigationController {
                if (mainActivity == null) {
                    return;
                }
                final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
                // If there is only one adaptor, attach the windowless window to top activity,
                // because fixed rotation only applies on activity.
                // Note that embedded activity won't use fixed rotation.
@@ -1321,11 +1341,13 @@ class BackNavigationController {
                        .removeWindowlessStartingSurface(mRequestedStartingSurfaceId,
                                !openTransitionMatch);
                mRequestedStartingSurfaceId = INVALID_TASK_ID;
                mStartingSurface = null;
            }
        }

        private static class BackWindowAnimationAdaptor implements AnimationAdapter {
            SurfaceControl mCapturedLeash;
            boolean mAppWindowDrawn;
            private final Rect mBounds = new Rect();
            private final WindowContainer mTarget;
            private final boolean mIsOpen;
@@ -1507,9 +1529,16 @@ class BackNavigationController {
            private void applyPreviewStrategy(
                    @NonNull BackWindowAnimationAdaptorWrapper openAnimationAdaptor,
                    @NonNull ActivityRecord[] visibleOpenActivities) {
                boolean needsLaunchBehind = true;
                if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
                    openAnimationAdaptor.createStartingSurface(visibleOpenActivities);
                } else {
                    final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
                    final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
                    openAnimationAdaptor.createStartingSurface(snapshot);
                    // set LaunchBehind if we are creating splash screen surface.
                    needsLaunchBehind = snapshot == null
                            && openAnimationAdaptor.mRequestedStartingSurfaceId != INVALID_TASK_ID;
                }
                if (needsLaunchBehind) {
                    for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
                        setLaunchBehind(visibleOpenActivities[i]);
                    }