diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java index 5c3af3ee5330f..8ac9a7a479db4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java @@ -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 { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index e152633063bef..e66be66c8ef4f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -99,9 +99,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; @@ -264,6 +265,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. */ @@ -492,6 +500,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 @@ -501,6 +522,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) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 62ae1d5d600c6..f505e60de61e2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -116,7 +116,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. @@ -124,6 +125,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