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

Commit 852f1301 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Tweak animation for non-app windows with shell fixed rotation" into tm-dev

parents 2261bacc 77b2b34f
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -348,12 +348,13 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
            final TransitionInfo.Change change = info.getChanges().get(i);
            final boolean isTask = change.getTaskInfo() != null;
            boolean isSeamlessDisplayChange = false;

            if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
                if (info.getType() == TRANSIT_CHANGE) {
                    boolean isSeamless = isRotationSeamless(info, mDisplayController);
                    isSeamlessDisplayChange = isRotationSeamless(info, mDisplayController);
                    final int anim = getRotationAnimation(info);
                    if (!(isSeamless || anim == ROTATION_ANIMATION_JUMPCUT)) {
                    if (!(isSeamlessDisplayChange || anim == ROTATION_ANIMATION_JUMPCUT)) {
                        mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession,
                                mTransactionPool, startTransaction, change, info.getRootLeash(),
                                anim);
@@ -387,6 +388,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                startTransaction.setPosition(change.getLeash(),
                        change.getEndAbsBounds().left - info.getRootOffset().x,
                        change.getEndAbsBounds().top - info.getRootOffset().y);
                // Seamless display transition doesn't need to animate.
                if (isSeamlessDisplayChange) continue;
                if (isTask) {
                    // Skip non-tasks since those usually have null bounds.
                    startTransaction.setWindowCrop(change.getLeash(),
+32 −17
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@ class AsyncRotationController extends FadeAnimationController implements Consume
    /** Whether the start transaction of the transition is committed (by shell). */
    private boolean mIsStartTransactionCommitted;

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

    private SeamlessRotator mRotator;

    private final int mOriginalRotation;
@@ -139,22 +142,10 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        displayContent.forAllWindows(this, true /* traverseTopToBottom */);

        // Legacy animation doesn't need to wait for the start transaction.
        mIsStartTransactionCommitted = mTransitionOp == OP_LEGACY;
        if (mIsStartTransactionCommitted) return;
        // The transition sync group may be finished earlier because it doesn't wait for these
        // target windows. But the windows still need to use sync transaction to keep the appearance
        // in previous rotation, so request a no-op sync to keep the state.
        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
            if (mHasScreenRotationAnimation
                    && mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
                // The windows are hidden (leash is alpha 0) before finishing drawing so it is
                // unnecessary to request sync.
                continue;
            }
            final WindowToken token = mTargetWindowTokens.keyAt(i);
            for (int j = token.getChildCount() - 1; j >= 0; j--) {
                token.getChildAt(j).applyWithNextDraw(t -> {});
            }
        if (mTransitionOp == OP_LEGACY) {
            mIsStartTransactionCommitted = true;
        } else if (displayContent.mTransitionController.useShellTransitionsRotation()) {
            keepAppearanceInPreviousRotation();
        }
    }

@@ -194,6 +185,30 @@ class AsyncRotationController extends FadeAnimationController implements Consume
        mTargetWindowTokens.put(w.mToken, new Operation(action));
    }

    /**
     * Enables {@link #handleFinishDrawing(WindowState, SurfaceControl.Transaction)} to capture the
     * draw transactions of the target windows if needed.
     */
    void keepAppearanceInPreviousRotation() {
        // The transition sync group may be finished earlier because it doesn't wait for these
        // target windows. But the windows still need to use sync transaction to keep the appearance
        // in previous rotation, so request a no-op sync to keep the state.
        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
            if (mHasScreenRotationAnimation
                    && mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
                // The windows are hidden (leash is alpha 0) before finishing drawing so it is
                // unnecessary to request sync.
                continue;
            }
            final WindowToken token = mTargetWindowTokens.keyAt(i);
            for (int j = token.getChildCount() - 1; j >= 0; j--) {
                token.getChildAt(j).applyWithNextDraw(t -> {});
            }
        }
        mIsSyncDrawRequested = true;
        if (DEBUG) Slog.d(TAG, "Requested to sync draw transaction");
    }

    /** Lets the window fit in new rotation naturally. */
    private void finishOp(WindowToken windowToken) {
        final Operation op = mTargetWindowTokens.remove(windowToken);
@@ -433,7 +448,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
     */
    boolean handleFinishDrawing(WindowState w, SurfaceControl.Transaction postDrawTransaction) {
        if (mTransitionOp == OP_LEGACY || postDrawTransaction == null
                || !w.mTransitionController.inTransition()) {
                || !mIsSyncDrawRequested || !w.mTransitionController.inTransition()) {
            return false;
        }
        final Operation op = mTargetWindowTokens.get(w.mToken);
+19 −12
Original line number Diff line number Diff line
@@ -1735,19 +1735,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) {
        final boolean useAsyncRotation = !mTransitionController.isShellTransitionsEnabled();
        if (mFixedRotationLaunchingApp == null && r != null) {
            mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this,
                    rotation);
            if (useAsyncRotation) {
                startAsyncRotation(
                        // Delay the hide animation to avoid blinking by clicking navigation bar
                        // that may toggle fixed rotation in a short time.
                        r == mFixedRotationTransitionListener.mAnimatingRecents);
            }
            mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation);
            // Delay the hide animation to avoid blinking by clicking navigation bar that may
            // toggle fixed rotation in a short time.
            final boolean shouldDebounce = r == mFixedRotationTransitionListener.mAnimatingRecents
                    || mTransitionController.isTransientLaunch(r);
            startAsyncRotation(shouldDebounce);
        } else if (mFixedRotationLaunchingApp != null && r == null) {
            mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this);
            if (useAsyncRotation) finishAsyncRotationIfPossible();
            // Keep async rotation controller if the next transition of display is requested.
            if (!mTransitionController.isCollecting(this)) {
                finishAsyncRotationIfPossible();
            }
        }
        mFixedRotationLaunchingApp = r;
    }
@@ -1805,7 +1805,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }
        // Update directly because the app which will change the orientation of display is ready.
        if (mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */)) {
            mTransitionController.setSeamlessRotation(this);
            sendNewConfiguration();
            return;
        }
@@ -3234,7 +3233,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                this, this, null /* remoteTransition */, displayChange);
        if (t != null) {
            mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
            if (isRotationChanging()) {
            if (mFixedRotationLaunchingApp != null) {
                // A fixed-rotation transition is done, then continue to start a seamless display
                // transition. And be fore the start transaction is applied, the non-app windows
                // need to keep in previous rotation to avoid showing inconsistent content.
                t.setSeamlessRotation(this);
                if (mAsyncRotationController != null) {
                    mAsyncRotationController.keepAppearanceInPreviousRotation();
                }
            } else if (isRotationChanging()) {
                mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
                controller.mTransitionMetricsReporter.associate(t,
                        startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN));
+2 −2
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        for (int i = 0; i < mTargetDisplays.size(); ++i) {
            final DisplayContent dc = mTargetDisplays.get(i);
            final AsyncRotationController asyncRotationController = dc.getAsyncRotationController();
            if (asyncRotationController != null) {
            if (asyncRotationController != null && mTargets.contains(dc)) {
                asyncRotationController.onTransitionFinished();
            }
            if (mTransientLaunches != null) {
@@ -696,7 +696,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        // This is non-null only if display has changes. It handles the visible windows that don't
        // need to be participated in the transition.
        final AsyncRotationController controller = dc.getAsyncRotationController();
        if (controller != null) {
        if (controller != null && mTargets.contains(dc)) {
            controller.setupStartTransaction(transaction);
        }
        mStartTransaction = transaction;
+0 −5
Original line number Diff line number Diff line
@@ -519,11 +519,6 @@ class TransitionController {
        }
    }

    void setSeamlessRotation(@NonNull WindowContainer wc) {
        if (mCollectingTransition == null) return;
        mCollectingTransition.setSeamlessRotation(wc);
    }

    void legacyDetachNavigationBarFromApp(@NonNull IBinder token) {
        final Transition transition = Transition.fromBinder(token);
        if (transition == null || !mPlayingTransitions.contains(transition)) {
Loading