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

Commit 0165c9e7 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Support shell rotation transition on general window container

This eliminate the limitation of rotation animation that it could
only have one instance for display. Now the rotation animations
can be tracked by them self so there could have multiple instances
run at the same time, such as for multiple display or individual
child window container.

The first usage is: (also see commit d16620e8)
The fixed rotation transform of activity is canceled so display
doesn't have rotation change but the activity has. Then only the
activity needs to animate.

Bug: 223397858
Test: adb shell setprop persist.wm.debug.shell_transit 1; reboot
      Enable auto rotation. Launch an app without fixed orientation
      from portrait launcher while device is in landscape. Before
      the launch animation is done, rotate the device to portrait
      (there is no display orientation change). The launched app
      should rotate from landscape to portrait without flickering.

Change-Id: Ic47960e812f07365965df4ab2913e2003289a315
parent 86725073
Loading
Loading
Loading
Loading
+34 −13
Original line number Diff line number Diff line
@@ -152,8 +152,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {

    private final int mCurrentUserId;

    private ScreenRotationAnimation mRotationAnimation;

    private Drawable mEnterpriseThumbnailDrawable;

    private BroadcastReceiver mEnterpriseResourceUpdatedReceiver = new BroadcastReceiver() {
@@ -332,12 +330,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {

        final Runnable onAnimFinish = () -> {
            if (!animations.isEmpty()) return;

            if (mRotationAnimation != null) {
                mRotationAnimation.kill();
                mRotationAnimation = null;
            }

            mAnimations.remove(transition);
            finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
        };
@@ -357,11 +349,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                    isSeamlessDisplayChange = isRotationSeamless(info, mDisplayController);
                    final int anim = getRotationAnimation(info);
                    if (!(isSeamlessDisplayChange || anim == ROTATION_ANIMATION_JUMPCUT)) {
                        mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession,
                                mTransactionPool, startTransaction, change, info.getRootLeash(),
                                anim);
                        mRotationAnimation.startAnimation(animations, onAnimFinish,
                                mTransitionAnimationScaleSetting, mMainExecutor, mAnimExecutor);
                        startRotationAnimation(startTransaction, change, info, anim, animations,
                                onAnimFinish);
                        continue;
                    }
                } else {
@@ -405,6 +394,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                    startTransaction.setWindowCrop(change.getLeash(),
                            change.getEndAbsBounds().width(), change.getEndAbsBounds().height());
                }
                // Rotation change of independent non display window container.
                if (change.getParent() == null
                        && change.getStartRotation() != change.getEndRotation()) {
                    startRotationAnimation(startTransaction, change, info,
                            ROTATION_ANIMATION_ROTATE, animations, onAnimFinish);
                    continue;
                }
            }

            // Don't animate anything that isn't independent.
@@ -535,6 +531,31 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        }
    }

    private void startRotationAnimation(SurfaceControl.Transaction startTransaction,
            TransitionInfo.Change change, TransitionInfo info, int animHint,
            ArrayList<Animator> animations, Runnable onAnimFinish) {
        final ScreenRotationAnimation anim = new ScreenRotationAnimation(mContext, mSurfaceSession,
                mTransactionPool, startTransaction, change, info.getRootLeash(), animHint);
        // 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
        // animation is finished. Then if the list becomes empty, the rotation animation is done.
        final ArrayList<Animator> animGroup = new ArrayList<>(3);
        final ArrayList<Animator> animGroupStore = new ArrayList<>(3);
        final Runnable finishCallback = () -> {
            if (!animGroup.isEmpty()) return;
            anim.kill();
            animations.removeAll(animGroupStore);
            onAnimFinish.run();
        };
        anim.startAnimation(animGroup, finishCallback, mTransitionAnimationScaleSetting,
                mMainExecutor, mAnimExecutor);
        for (int i = animGroup.size() - 1; i >= 0; i--) {
            final Animator animator = animGroup.get(i);
            animGroupStore.add(animator);
            animations.add(animator);
        }
    }

    private void edgeExtendWindow(TransitionInfo.Change change,
            Animation a, SurfaceControl.Transaction startTransaction,
            SurfaceControl.Transaction finishTransaction) {
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ class ScreenRotationAnimation {
    private final Context mContext;
    private final TransactionPool mTransactionPool;
    private final float[] mTmpFloats = new float[9];
    /** The leash of display. */
    /** The leash of the changing window container. */
    private final SurfaceControl mSurfaceControl;
    private final Rect mStartBounds = new Rect();
    private final Rect mEndBounds = new Rect();
+1 −1
Original line number Diff line number Diff line
@@ -358,7 +358,7 @@ public class Transitions implements RemoteCallable<Transitions> {
            // Put all the OPEN/SHOW on top
            if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
                // Wallpaper is always at the bottom.
                layer = 0;
                layer = -zSplitLine;
            } else if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
                if (isOpening) {
                    // put on top
+10 −4
Original line number Diff line number Diff line
@@ -2453,8 +2453,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            dc.setImeLayeringTarget(null);
            dc.computeImeTarget(true /* updateImeTarget */);
        }
        if (dc.getImeInputTarget() == this
                && (mActivityRecord == null || !mActivityRecord.isRelaunching())) {
        if (dc.getImeInputTarget() == this && !inRelaunchingActivity()) {
            dc.updateImeInputAndControlTarget(null);
        }

@@ -2581,7 +2580,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                // usually unnoticeable (e.g. covered by rotation animation) and the animation
                // bounds could be inconsistent, such as depending on when the window applies
                // its draw transaction with new rotation.
                final boolean allowExitAnimation = !getDisplayContent().inTransition();
                final boolean allowExitAnimation = !getDisplayContent().inTransition()
                        // There will be a new window so the exit animation may not be visible or
                        // look weird if its orientation is changed.
                        && !inRelaunchingActivity();

                if (wasVisible) {
                    final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
@@ -3871,7 +3873,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        // If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now
        // since it will be destroyed anyway. This also prevents the client from receiving
        // windowing mode change before it is destroyed.
        if (mActivityRecord != null && mActivityRecord.isRelaunching()) {
        if (inRelaunchingActivity()) {
            return;
        }
        // If this is an activity or wallpaper and is invisible or going invisible, don't report
@@ -3957,6 +3959,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

    boolean inRelaunchingActivity() {
        return mActivityRecord != null && mActivityRecord.isRelaunching();
    }

    boolean isClientLocal() {
        return mClient instanceof IWindow.Stub;
    }
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams.WindowType;
import android.window.WindowContext;

@@ -558,6 +559,12 @@ class WindowToken extends WindowContainer<WindowState> {
            // The window may be detached or detaching.
            return;
        }
        if (mTransitionController.isShellTransitionsEnabled()
                && asActivityRecord() != null && isVisible()) {
            // Trigger an activity level rotation transition.
            mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_CHANGE, this);
            mTransitionController.setReady(this);
        }
        final int originalRotation = getWindowConfiguration().getRotation();
        onConfigurationChanged(parent.getConfiguration());
        onCancelFixedRotationTransform(originalRotation);