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

Commit bf5d97ba authored by jorgegil@google.com's avatar jorgegil@google.com
Browse files

Fix race when rotating the display during an entry into PIP

Rotating the display while the PIP task had just appeared caused
a race between the alpha entry animation starting and the rotation
controller handling that changes the PIP bounds, resulting in
a bounds mismatch between the surface that was animated and the
PipBoundsState.mBounds

This CL tracks whether we're still waiting for the alpha entry
animation to start when a rotation callback comes in, and
restarts the fade in after adjusting to the rotation.

Bug: 184664409
Test: In gesure nav, open YT go to fullscreen landscape mode and
launch another an activity from a notification - verify PIP fades
in and its bounds match the ones in PipBoundsState

Change-Id: I339d5088fb5f23f08fe8d548b9d02a34c16779d6
parent b5cc4a53
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.wm.shell.animation.Interpolators;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Controller class of PiP animations (both from and to PiP mode).
@@ -112,6 +113,7 @@ public class PipAnimationController {
                    PipTransitionAnimator.ofAlpha(taskInfo, leash, destinationBounds, alphaStart,
                            alphaEnd));
        } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
                && Objects.equals(destinationBounds, mCurrentAnimator.getDestinationBounds())
                && mCurrentAnimator.isRunning()) {
            mCurrentAnimator.updateEndValue(alphaEnd);
        } else {
+25 −3
Original line number Diff line number Diff line
@@ -98,9 +98,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    private enum State {
        UNDEFINED(0),
        TASK_APPEARED(1),
        ENTERING_PIP(2),
        ENTERED_PIP(3),
        EXITING_PIP(4);
        ENTRY_SCHEDULED(2),
        ENTERING_PIP(3),
        ENTERED_PIP(4),
        EXITING_PIP(5);

        private final int mStateValue;

@@ -263,6 +264,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        return mState.isInPip() && mWaitForFixedRotation;
    }

    /**
     * Returns whether the entry animation is waiting to be started.
     */
    public boolean isEntryScheduled() {
        return mState == State.ENTRY_SCHEDULED;
    }

    /**
     * Registers a callback when a display change has been detected when we enter PiP.
     */
@@ -481,6 +489,19 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }
    }

    /**
     * Called when the display rotation handling is skipped (e.g. when rotation happens while in
     * the middle of an entry transition).
     */
    public void onDisplayRotationSkipped() {
        if (isEntryScheduled()) {
            // The PIP animation is scheduled to start with the previous orientation's bounds,
            // re-calculate the entry bounds and restart the alpha animation.
            final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
            enterPipWithAlphaAnimation(destinationBounds, mEnterAnimationDuration);
        }
    }

    @VisibleForTesting
    void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) {
        // If we are fading the PIP in, then we should move the pip to the final location as
@@ -490,6 +511,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                mSurfaceControlTransactionFactory.getTransaction();
        tx.setAlpha(mLeash, 0f);
        tx.apply();
        mState = State.ENTRY_SCHEDULED;
        applyEnterPipSyncTransaction(destinationBounds, () -> {
            mPipAnimationController
                    .getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)
+3 −1
Original line number Diff line number Diff line
@@ -115,7 +115,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
        if (!mPipTaskOrganizer.isInPip()
                || mPipBoundsState.getDisplayLayout().rotation() == toRotation
                || mPipTaskOrganizer.isDeferringEnterPipAnimation()) {
                || mPipTaskOrganizer.isDeferringEnterPipAnimation()
                || mPipTaskOrganizer.isEntryScheduled()) {
            // Skip if the same rotation has been set or we aren't in PIP or haven't actually
            // entered PIP yet. We still need to update the display layout in the bounds handler
            // in this case.
@@ -123,6 +124,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            // do not forget to update the movement bounds as well.
            updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */,
                    false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t);
            mPipTaskOrganizer.onDisplayRotationSkipped();
            return;
        }
        // If there is an animation running (ie. from a shelf offset), then ensure that we calculate