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

Commit fff7314f authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Update rotation controller if rotation changed

Some non-activity windows perform rotation asynchronously. If a
window has not redrawn yet but display rotation changes again, it
should apply new transform based on new rotation. Especially the
screen decor windows should use SeamlessRotator with new rotation.

While for non-seamless windows, keep their existing state because
the fade animation may be running in progress, then just let it
continue to avoid changing alpha between 0 and 1 suddenly.

Also remove mAlwaysWaitForStartTransaction because since [1],
the condition becomes a dead code.
[1]: I7e1de5b5fe12cb30b5f48808ea6b0a2214c0f339

Bug: 290322702
Test: Open app in a different orientation from home.
      Return to home and launch the app again in a short time.
      The screen decorations should not be flickering.
Change-Id: Ib7594486703468605fc0d01c0e4256ba0aa87bef
parent 842ba6f0
Loading
Loading
Loading
Loading
+32 −16
Original line number Diff line number Diff line
@@ -93,15 +93,12 @@ class AsyncRotationController extends FadeAnimationController implements Consume
    /** Whether the start transaction of the transition is committed (by shell). */
    private boolean mIsStartTransactionCommitted;

    /** Whether all windows should wait for the start transaction. */
    private boolean mAlwaysWaitForStartTransaction;

    /** Whether the target windows have been requested to sync their draw transactions. */
    private boolean mIsSyncDrawRequested;

    private SeamlessRotator mRotator;

    private final int mOriginalRotation;
    private int mOriginalRotation;
    private final boolean mHasScreenRotationAnimation;

    AsyncRotationController(DisplayContent displayContent) {
@@ -147,15 +144,6 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        if (mTransitionOp == OP_LEGACY) {
            mIsStartTransactionCommitted = true;
        } else if (displayContent.mTransitionController.isCollecting(displayContent)) {
            final Transition transition =
                    mDisplayContent.mTransitionController.getCollectingTransition();
            if (transition != null) {
                final BLASTSyncEngine.SyncGroup syncGroup =
                        mDisplayContent.mWmService.mSyncEngine.getSyncSet(transition.getSyncId());
                if (syncGroup != null && syncGroup.mSyncMethod == BLASTSyncEngine.METHOD_BLAST) {
                    mAlwaysWaitForStartTransaction = true;
                }
            }
            keepAppearanceInPreviousRotation();
        }
    }
@@ -279,10 +267,12 @@ class AsyncRotationController extends FadeAnimationController implements Consume
            // The previous animation leash will be dropped when preparing fade-in animation, so
            // simply apply new animation without restoring the transformation.
            fadeWindowToken(true /* show */, windowToken, ANIMATION_TYPE_TOKEN_TRANSFORM);
        } else if (op.mAction == Operation.ACTION_SEAMLESS && mRotator != null
        } else if (op.mAction == Operation.ACTION_SEAMLESS
                && op.mLeash != null && op.mLeash.isValid()) {
            if (DEBUG) Slog.d(TAG, "finishOp undo seamless " + windowToken.getTopChild());
            mRotator.setIdentityMatrix(windowToken.getSyncTransaction(), op.mLeash);
            final SurfaceControl.Transaction t = windowToken.getSyncTransaction();
            t.setMatrix(op.mLeash, 1, 0, 0, 1);
            t.setPosition(op.mLeash, 0, 0);
        }
    }

@@ -365,6 +355,32 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        }
    }

    /**
     * Re-initialize the states if the current display rotation has changed to a different rotation.
     * This is mainly for seamless rotation to update the transform based on new rotation.
     */
    void updateRotation() {
        if (mRotator == null) return;
        final int currentRotation = mDisplayContent.getWindowConfiguration().getRotation();
        if (mOriginalRotation == currentRotation) {
            return;
        }
        Slog.d(TAG, "Update original rotation " + currentRotation);
        mOriginalRotation = currentRotation;
        mDisplayContent.forAllWindows(w -> {
            if (w.mForceSeamlesslyRotate && w.mHasSurface
                    && !mTargetWindowTokens.containsKey(w.mToken)) {
                final Operation op = new Operation(Operation.ACTION_SEAMLESS);
                op.mLeash = w.mToken.mSurfaceControl;
                mTargetWindowTokens.put(w.mToken, op);
            }
        }, true /* traverseTopToBottom */);
        mRotator = null;
        mIsStartTransactionCommitted = false;
        mIsSyncDrawRequested = false;
        keepAppearanceInPreviousRotation();
    }

    private void scheduleTimeout() {
        if (mTimeoutRunnable == null) {
            mTimeoutRunnable = () -> {
@@ -589,7 +605,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
     * start transaction of rotation transition is applied.
     */
    private boolean canDrawBeforeStartTransaction(Operation op) {
        return !mAlwaysWaitForStartTransaction && op.mAction != Operation.ACTION_SEAMLESS;
        return op.mAction != Operation.ACTION_SEAMLESS;
    }

    /** The operation to control the rotation appearance associated with window token. */
+5 −0
Original line number Diff line number Diff line
@@ -3457,6 +3457,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                this, this, null /* remoteTransition */, displayChange);
        if (t != null) {
            mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
            if (mAsyncRotationController != null) {
                // Give a chance to update the transform if the current rotation is changed when
                // some windows haven't finished previous rotation.
                mAsyncRotationController.updateRotation();
            }
            if (mFixedRotationLaunchingApp != null) {
                // A fixed-rotation transition is done, then continue to start a seamless display
                // transition.