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

Commit 3c83ef19 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Sync insets leash position with shell seamless rotation

With shell transition, the individual seamless rotated windows
are managed by AsyncRotationController. When the window is drawn
in new rotation, its seamless transformation will be cleared to
fit in new screen coordinate. If the update of insets surface
position is in a different transaction, the position may be updated
before restoring the transformation. That causes the window to show
at a weird position.

Instead of using legacy startSeamlessRotation/finishSeamlessRotation
of InsetsSourceProvider which stops the insets animation, the
synchronization can be done by merging the transaction to the one
that will update the transformation. This may be also more efficiency
because no need to remove/recreate the leash.

Bug: 223396866
Test: Use 3-button navigation.
      Launch landscape app from portrait launcher.
      The navigation bar should not disappear for a split second.
Change-Id: I51ebd9f2c90b2b4d12f77d1361acc66ab7777b38
parent e7b17199
Loading
Loading
Loading
Loading
+30 −11
Original line number Diff line number Diff line
@@ -144,8 +144,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        // Legacy animation doesn't need to wait for the start transaction.
        if (mTransitionOp == OP_LEGACY) {
            mIsStartTransactionCommitted = true;
        } else if (displayContent.mTransitionController.useShellTransitionsRotation()
                || displayContent.mTransitionController.isCollecting(displayContent)) {
        } else if (displayContent.mTransitionController.isCollecting(displayContent)) {
            keepAppearanceInPreviousRotation();
        }
    }
@@ -214,10 +213,10 @@ class AsyncRotationController extends FadeAnimationController implements Consume
    private void finishOp(WindowToken windowToken) {
        final Operation op = mTargetWindowTokens.remove(windowToken);
        if (op == null) return;
        if (op.mCapturedDrawTransaction != null) {
        if (op.mDrawTransaction != null) {
            // Unblock the window to show its latest content.
            mDisplayContent.getPendingTransaction().merge(op.mCapturedDrawTransaction);
            op.mCapturedDrawTransaction = null;
            mDisplayContent.getPendingTransaction().merge(op.mDrawTransaction);
            op.mDrawTransaction = null;
            if (DEBUG) Slog.d(TAG, "finishOp merge transaction " + windowToken.getTopChild());
        }
        if (op.mAction == Operation.ACTION_FADE) {
@@ -351,14 +350,34 @@ class AsyncRotationController extends FadeAnimationController implements Consume
    }

    /**
     * Whether the insets animation leash should use previous position when running fade out
     * animation in rotated display.
     * Whether the insets animation leash should use previous position when running fade animation
     * or seamless transformation in a rotated display.
     */
    boolean shouldFreezeInsetsPosition(WindowState w) {
        return mTransitionOp == OP_APP_SWITCH && w.mTransitionController.inTransition()
                && isTargetToken(w.mToken);
    }

    /**
     * Returns the transaction which will be applied after the window redraws in new rotation.
     * This is used to update the position of insets animation leash synchronously.
     */
    SurfaceControl.Transaction getDrawTransaction(WindowToken token) {
        if (mTransitionOp == OP_LEGACY) {
            // Legacy transition uses startSeamlessRotation and finishSeamlessRotation of
            // InsetsSourceProvider.
            return null;
        }
        final Operation op = mTargetWindowTokens.get(token);
        if (op != null) {
            if (op.mDrawTransaction == null) {
                op.mDrawTransaction = new SurfaceControl.Transaction();
            }
            return op.mDrawTransaction;
        }
        return null;
    }

    void setOnShowRunnable(Runnable onShowRunnable) {
        mOnShowRunnable = onShowRunnable;
    }
@@ -463,10 +482,10 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        final boolean keepUntilStartTransaction =
                !mIsStartTransactionCommitted && op.mAction == Operation.ACTION_SEAMLESS;
        if (!keepUntilTransitionFinish && !keepUntilStartTransaction) return false;
        if (op.mCapturedDrawTransaction == null) {
            op.mCapturedDrawTransaction = postDrawTransaction;
        if (op.mDrawTransaction == null) {
            op.mDrawTransaction = postDrawTransaction;
        } else {
            op.mCapturedDrawTransaction.merge(postDrawTransaction);
            op.mDrawTransaction.merge(postDrawTransaction);
        }
        if (DEBUG) Slog.d(TAG, "Capture draw transaction " + w);
        return true;
@@ -512,7 +531,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
         * the start transaction of transition, so there won't be a flickering such as the window
         * has redrawn during fading out.
         */
        SurfaceControl.Transaction mCapturedDrawTransaction;
        SurfaceControl.Transaction mDrawTransaction;

        Operation(@Action int action) {
            mAction = action;
+21 −8
Original line number Diff line number Diff line
@@ -290,7 +290,22 @@ abstract class InsetsSourceProvider {
                        && windowState.mWinAnimator.getShown() && mWindowContainer.okToDisplay()) {
                    windowState.applyWithNextDraw(mSetLeashPositionConsumer);
                } else {
                    mSetLeashPositionConsumer.accept(mWindowContainer.getSyncTransaction());
                    Transaction t = mWindowContainer.getSyncTransaction();
                    if (windowState != null) {
                        // Make the buffer, token transformation, and leash position to be updated
                        // together when the window is drawn for new rotation. Otherwise the window
                        // may be outside the screen by the inconsistent orientations.
                        final AsyncRotationController rotationController =
                                mDisplayContent.getAsyncRotationController();
                        if (rotationController != null) {
                            final Transaction drawT =
                                    rotationController.getDrawTransaction(windowState.mToken);
                            if (drawT != null) {
                                t = drawT;
                            }
                        }
                    }
                    mSetLeashPositionConsumer.accept(t);
                }
            }
            if (mServerVisible && !mLastSourceFrame.equals(mSource.getFrame())) {
@@ -310,17 +325,15 @@ abstract class InsetsSourceProvider {
    }

    private Point getWindowFrameSurfacePosition() {
        WindowState win = mWindowContainer.asWindowState();
        if (mControl != null) {
            final AsyncRotationController controller =
                    win.mDisplayContent.getAsyncRotationController();
        final WindowState win = mWindowContainer.asWindowState();
        if (win != null && mControl != null) {
            final AsyncRotationController controller = mDisplayContent.getAsyncRotationController();
            if (controller != null && controller.shouldFreezeInsetsPosition(win)) {
                // Use previous position because the fade-out animation runs in old rotation.
                // Use previous position because the window still shows with old rotation.
                return mControl.getSurfacePosition();
            }
        }
        final Rect frame = mWindowContainer.asWindowState() != null
                ? mWindowContainer.asWindowState().getFrame() : mWindowContainer.getBounds();
        final Rect frame = win != null ? win.getFrame() : mWindowContainer.getBounds();
        final Point position = new Point();
        mWindowContainer.transformFrameToSurfacePosition(frame.left, frame.top, position);
        return position;