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

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

Pause updating surface position while seamless rotating

Since shell transition doesn't use mPendingSeamlessRotate anymore,
it needs to check the equivalent state from AsyncRotationController
to have the same behavior as legacy transition.

If the device doesn't support HWC ScreenDecoration, it will have
non-fullscreen windows with non-zero position. Then it will hit
the case that the surface is un-rotated to previous rotation but
the position is changed to be in new rotation.

Fix: 308735235
Test: atest TransitionTests#testDisplayRotationChange
Test: Display cutout is not flickering when rotating 180 degree.

Change-Id: I6c88be283e7086d81531bc3f710e2714275129e2
parent 488eb985
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -465,6 +465,12 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        return op != null && op.mAction == Operation.ACTION_FADE;
    }

    /** Returns {@code true} if the window is un-rotated to original rotation. */
    boolean hasSeamlessOperation(WindowToken token) {
        final Operation op = mTargetWindowTokens.get(token);
        return op != null && op.mAction == Operation.ACTION_SEAMLESS;
    }

    /**
     * Whether the insets animation leash should use previous position when running fade animation
     * or seamless transformation in a rotated display.
+11 −4
Original line number Diff line number Diff line
@@ -5262,10 +5262,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            mSurfacePosition.offset(mXOffset, mYOffset);
        }

        // Freeze position while we're unrotated, so the surface remains at the position it was
        // prior to the rotation.
        if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null
                && !mLastSurfacePosition.equals(mSurfacePosition)) {
        final AsyncRotationController asyncRotationController =
                mDisplayContent.getAsyncRotationController();
        if ((asyncRotationController != null
                && asyncRotationController.hasSeamlessOperation(mToken))
                || mPendingSeamlessRotate != null) {
            // Freeze position while un-rotating the window, so its surface remains at the position
            // corresponding to the original rotation.
            return;
        }

        if (!mSurfaceAnimator.hasLeash() && !mLastSurfacePosition.equals(mSurfacePosition)) {
            final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported();
            final boolean surfaceInsetsChanged = surfaceInsetsChanging();
            final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged;
+6 −0
Original line number Diff line number Diff line
@@ -1115,6 +1115,12 @@ public class TransitionTests extends WindowTestsBase {
        assertFalse(asyncRotationController.handleFinishDrawing(statusBar, mMockT));
        assertTrue(asyncRotationController.isTargetToken(statusBar.mToken));

        // Window surface position is frozen while seamless rotation state is active.
        final Point prevPos = new Point(screenDecor.mLastSurfacePosition);
        screenDecor.getFrame().left += 1;
        screenDecor.updateSurfacePosition(mMockT);
        assertEquals(prevPos, screenDecor.mLastSurfacePosition);

        final SurfaceControl.Transaction startTransaction = mock(SurfaceControl.Transaction.class);
        final SurfaceControl.TransactionCommittedListener transactionCommittedListener =
                onRotationTransactionReady(player, startTransaction);