Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -770,6 +770,7 @@ public class PipAnimationController { } if (mContentOverlay != null) { mContentOverlay.onAnimationEnd(tx, destBounds); clearContentOverlay(); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +3 −3 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { // Do nothing. Color overlay should be fully opaque by now. // Do nothing. Color overlay should be fully opaque by now, ready for fade out. } private float[] getContentOverlayColor(Context context) { Loading Loading @@ -167,7 +167,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { atomicTx.remove(mLeash); // Do nothing. Snapshot overlay should be fully opaque by now, ready for fade out. } } Loading Loading @@ -256,7 +256,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { atomicTx.remove(mLeash); // Do nothing. Icon overlay should be fully opaque by now, ready for fade out. } @Override Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +91 −72 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { private boolean mIsCancelled; @Override public void onPipAnimationStart(TaskInfo taskInfo, PipAnimationController.PipTransitionAnimator animator) { Loading @@ -176,9 +177,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } final int animationType = animator.getAnimationType(); final Rect destinationBounds = animator.getDestinationBounds(); if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay*/); if (isInPipDirection(direction) && mPipOverlay != null) { fadeOutAndRemoveOverlay(mPipOverlay, null /* callback */, true /* withStartDelay*/); } if (mWaitForFixedRotation && animationType == ANIM_TYPE_BOUNDS && direction == TRANSITION_DIRECTION_TO_PIP) { Loading @@ -186,8 +187,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.scheduleFinishEnterPip(mToken, destinationBounds); mTaskOrganizer.applyTransaction(wct); // The final task bounds will be applied by onFixedRotationFinished so that all // coordinates are in new rotation. // The final task bounds will be applied by onFixedRotationFinished so // that all coordinates are in new rotation. mSurfaceTransactionHelper.round(tx, mLeash, isInPip()); mDeferredAnimEndTransaction = tx; return; Loading @@ -196,15 +197,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, || isRemovePipDirection(direction); if (mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP || isExitPipDirection) { // execute the finish resize callback if needed after the transaction is committed // execute the finish resize callback if needed after the transaction is // committed tx.addTransactionCommittedListener(mMainExecutor, PipTaskOrganizer.this::maybePerformFinishResizeCallback); // Finish resize as long as we're not exiting PIP, or, if we are, only if this is // the end of an exit PIP animation. // This is necessary in case there was a resize animation ongoing when exit PIP // started, in which case the first resize will be skipped to let the exit // operation handle the final resize out of PIP mode. See b/185306679. // Finish resize as long as we're not exiting PIP, or, if we are, only if // this is the end of an exit PIP animation. // This is necessary in case there was a resize animation ongoing when // exit PIP started, in which case the first resize will be skipped to // let the exit operation handle the final resize out of PIP mode. // See b/185306679. finishResizeDelayedIfNeeded(() -> { finishResize(tx, destinationBounds, direction, animationType); sendOnPipTransitionFinished(direction); Loading @@ -217,9 +220,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, PipAnimationController.PipTransitionAnimator animator) { final int direction = animator.getTransitionDirection(); mIsCancelled = true; if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay */); if (isInPipDirection(direction) && mPipOverlay != null) { fadeOutAndRemoveOverlay(mPipOverlay, null /* callback */, true /* withStartDelay */); } sendOnPipTransitionCancelled(direction); } Loading Loading @@ -327,11 +330,18 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, /** * An optional overlay used to mask content changing between an app in/out of PiP, only set if * {@link PipTransitionState#getInSwipePipToHomeTransition()} is true. * {@link PipTransitionState#getInSwipePipToHomeTransition()} is true, only in gesture nav. */ @Nullable SurfaceControl mSwipePipToHomeOverlay; /** * An optional overlay used to mask content changing between an app in/out of PiP, only set if * {@link PipTransitionState#getInSwipePipToHomeTransition()} is false. */ @Nullable SurfaceControl mPipOverlay; public PipTaskOrganizer(Context context, @NonNull SyncTransactionQueue syncTransactionQueue, @NonNull PipTransitionState pipTransitionState, Loading Loading @@ -1766,6 +1776,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, animator.setSnapshotContentOverlay(snapshot, sourceHintRect); } } mPipOverlay = animator.getContentOverlayLeash(); // The destination bounds are used for the end rect of animation and the final bounds // after animation finishes. So after the animation is started, the destination bounds // can be updated to new rotation (computeRotatedBounds has changed the DisplayLayout Loading Loading @@ -1879,6 +1890,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } private void removeContentOverlay(SurfaceControl surface, Runnable callback) { if (mPipOverlay != null) { if (mPipOverlay != surface) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: trying to remove overlay (%s) which is not local reference (%s)", TAG, surface, mPipOverlay); } mPipOverlay = null; } if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) { // Avoid double removal, which is fatal. return; Loading Loading @@ -1907,11 +1926,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private void cancelCurrentAnimator() { final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController.getCurrentAnimator(); if (animator != null) { if (animator.getContentOverlayLeash() != null) { removeContentOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay); // remove any overlays if present if (mPipOverlay != null) { removeContentOverlay(mPipOverlay, null /* callback */); } if (animator != null) { PipAnimationController.quietCancel(animator); mPipAnimationController.resetAnimatorState(); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +1 −0 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,7 @@ public class PipTransition extends PipTransitionController { } else { throw new RuntimeException("Unrecognized animation type: " + enterAnimationType); } mPipOrganizer.mPipOverlay = animator.getContentOverlayLeash(); animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(mEnterExitAnimationDuration); Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +6 −6 Original line number Diff line number Diff line Loading @@ -78,9 +78,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH if (direction == TRANSITION_DIRECTION_REMOVE_STACK) { return; } if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { mPipOrganizer.fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay*/); if (isInPipDirection(direction) && mPipOrganizer.mPipOverlay != null) { mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay, null /* callback */, true /* withStartDelay*/); } onFinishResize(taskInfo, animator.getDestinationBounds(), direction, tx); sendOnPipTransitionFinished(direction); Loading @@ -90,9 +90,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH public void onPipAnimationCancel(TaskInfo taskInfo, PipAnimationController.PipTransitionAnimator animator) { final int direction = animator.getTransitionDirection(); if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { mPipOrganizer.fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay */); if (isInPipDirection(direction) && mPipOrganizer.mPipOverlay != null) { mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay, null /* callback */, true /* withStartDelay */); } sendOnPipTransitionCancelled(animator.getTransitionDirection()); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +1 −0 Original line number Diff line number Diff line Loading @@ -770,6 +770,7 @@ public class PipAnimationController { } if (mContentOverlay != null) { mContentOverlay.onAnimationEnd(tx, destBounds); clearContentOverlay(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java +3 −3 Original line number Diff line number Diff line Loading @@ -109,7 +109,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { // Do nothing. Color overlay should be fully opaque by now. // Do nothing. Color overlay should be fully opaque by now, ready for fade out. } private float[] getContentOverlayColor(Context context) { Loading Loading @@ -167,7 +167,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { atomicTx.remove(mLeash); // Do nothing. Snapshot overlay should be fully opaque by now, ready for fade out. } } Loading Loading @@ -256,7 +256,7 @@ public abstract class PipContentOverlay { @Override public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) { atomicTx.remove(mLeash); // Do nothing. Icon overlay should be fully opaque by now, ready for fade out. } @Override Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +91 −72 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipAnimationController.PipAnimationCallback mPipAnimationCallback = new PipAnimationController.PipAnimationCallback() { private boolean mIsCancelled; @Override public void onPipAnimationStart(TaskInfo taskInfo, PipAnimationController.PipTransitionAnimator animator) { Loading @@ -176,9 +177,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } final int animationType = animator.getAnimationType(); final Rect destinationBounds = animator.getDestinationBounds(); if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay*/); if (isInPipDirection(direction) && mPipOverlay != null) { fadeOutAndRemoveOverlay(mPipOverlay, null /* callback */, true /* withStartDelay*/); } if (mWaitForFixedRotation && animationType == ANIM_TYPE_BOUNDS && direction == TRANSITION_DIRECTION_TO_PIP) { Loading @@ -186,8 +187,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.scheduleFinishEnterPip(mToken, destinationBounds); mTaskOrganizer.applyTransaction(wct); // The final task bounds will be applied by onFixedRotationFinished so that all // coordinates are in new rotation. // The final task bounds will be applied by onFixedRotationFinished so // that all coordinates are in new rotation. mSurfaceTransactionHelper.round(tx, mLeash, isInPip()); mDeferredAnimEndTransaction = tx; return; Loading @@ -196,15 +197,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, || isRemovePipDirection(direction); if (mPipTransitionState.getTransitionState() != PipTransitionState.EXITING_PIP || isExitPipDirection) { // execute the finish resize callback if needed after the transaction is committed // execute the finish resize callback if needed after the transaction is // committed tx.addTransactionCommittedListener(mMainExecutor, PipTaskOrganizer.this::maybePerformFinishResizeCallback); // Finish resize as long as we're not exiting PIP, or, if we are, only if this is // the end of an exit PIP animation. // This is necessary in case there was a resize animation ongoing when exit PIP // started, in which case the first resize will be skipped to let the exit // operation handle the final resize out of PIP mode. See b/185306679. // Finish resize as long as we're not exiting PIP, or, if we are, only if // this is the end of an exit PIP animation. // This is necessary in case there was a resize animation ongoing when // exit PIP started, in which case the first resize will be skipped to // let the exit operation handle the final resize out of PIP mode. // See b/185306679. finishResizeDelayedIfNeeded(() -> { finishResize(tx, destinationBounds, direction, animationType); sendOnPipTransitionFinished(direction); Loading @@ -217,9 +220,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, PipAnimationController.PipTransitionAnimator animator) { final int direction = animator.getTransitionDirection(); mIsCancelled = true; if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay */); if (isInPipDirection(direction) && mPipOverlay != null) { fadeOutAndRemoveOverlay(mPipOverlay, null /* callback */, true /* withStartDelay */); } sendOnPipTransitionCancelled(direction); } Loading Loading @@ -327,11 +330,18 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, /** * An optional overlay used to mask content changing between an app in/out of PiP, only set if * {@link PipTransitionState#getInSwipePipToHomeTransition()} is true. * {@link PipTransitionState#getInSwipePipToHomeTransition()} is true, only in gesture nav. */ @Nullable SurfaceControl mSwipePipToHomeOverlay; /** * An optional overlay used to mask content changing between an app in/out of PiP, only set if * {@link PipTransitionState#getInSwipePipToHomeTransition()} is false. */ @Nullable SurfaceControl mPipOverlay; public PipTaskOrganizer(Context context, @NonNull SyncTransactionQueue syncTransactionQueue, @NonNull PipTransitionState pipTransitionState, Loading Loading @@ -1766,6 +1776,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, animator.setSnapshotContentOverlay(snapshot, sourceHintRect); } } mPipOverlay = animator.getContentOverlayLeash(); // The destination bounds are used for the end rect of animation and the final bounds // after animation finishes. So after the animation is started, the destination bounds // can be updated to new rotation (computeRotatedBounds has changed the DisplayLayout Loading Loading @@ -1879,6 +1890,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } private void removeContentOverlay(SurfaceControl surface, Runnable callback) { if (mPipOverlay != null) { if (mPipOverlay != surface) { ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: trying to remove overlay (%s) which is not local reference (%s)", TAG, surface, mPipOverlay); } mPipOverlay = null; } if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) { // Avoid double removal, which is fatal. return; Loading Loading @@ -1907,11 +1926,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private void cancelCurrentAnimator() { final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController.getCurrentAnimator(); if (animator != null) { if (animator.getContentOverlayLeash() != null) { removeContentOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay); // remove any overlays if present if (mPipOverlay != null) { removeContentOverlay(mPipOverlay, null /* callback */); } if (animator != null) { PipAnimationController.quietCancel(animator); mPipAnimationController.resetAnimatorState(); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +1 −0 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,7 @@ public class PipTransition extends PipTransitionController { } else { throw new RuntimeException("Unrecognized animation type: " + enterAnimationType); } mPipOrganizer.mPipOverlay = animator.getContentOverlayLeash(); animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) .setPipAnimationCallback(mPipAnimationCallback) .setDuration(mEnterExitAnimationDuration); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +6 −6 Original line number Diff line number Diff line Loading @@ -78,9 +78,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH if (direction == TRANSITION_DIRECTION_REMOVE_STACK) { return; } if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { mPipOrganizer.fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay*/); if (isInPipDirection(direction) && mPipOrganizer.mPipOverlay != null) { mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay, null /* callback */, true /* withStartDelay*/); } onFinishResize(taskInfo, animator.getDestinationBounds(), direction, tx); sendOnPipTransitionFinished(direction); Loading @@ -90,9 +90,9 @@ public abstract class PipTransitionController implements Transitions.TransitionH public void onPipAnimationCancel(TaskInfo taskInfo, PipAnimationController.PipTransitionAnimator animator) { final int direction = animator.getTransitionDirection(); if (isInPipDirection(direction) && animator.getContentOverlayLeash() != null) { mPipOrganizer.fadeOutAndRemoveOverlay(animator.getContentOverlayLeash(), animator::clearContentOverlay, true /* withStartDelay */); if (isInPipDirection(direction) && mPipOrganizer.mPipOverlay != null) { mPipOrganizer.fadeOutAndRemoveOverlay(mPipOrganizer.mPipOverlay, null /* callback */, true /* withStartDelay */); } sendOnPipTransitionCancelled(animator.getTransitionDirection()); } Loading