Loading packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +56 −36 Original line number Diff line number Diff line Loading @@ -94,6 +94,36 @@ public class PipTaskOrganizer extends TaskOrganizer implements private static final int MSG_FINISH_RESIZE = 4; private static final int MSG_RESIZE_USER = 5; // Not a complete set of states but serves what we want right now. private enum State { UNDEFINED(0), TASK_APPEARED(1), ENTERING_PIP(2), EXITING_PIP(3); private final int mStateValue; State(int value) { mStateValue = value; } private boolean isInPip() { return mStateValue >= TASK_APPEARED.mStateValue && mStateValue != EXITING_PIP.mStateValue; } /** * Resize request can be initiated in other component, ignore if we are no longer in PIP, * still waiting for animation or we're exiting from it. * * @return {@code true} if the resize request should be blocked/ignored. */ private boolean shouldBlockResizeRequest() { return mStateValue < ENTERING_PIP.mStateValue || mStateValue == EXITING_PIP.mStateValue; } } private final Handler mMainHandler; private final Handler mUpdateHandler; private final PipBoundsHandler mPipBoundsHandler; Loading Loading @@ -188,8 +218,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private ActivityManager.RunningTaskInfo mTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; private boolean mInPip; private boolean mExitingPip; private State mState = State.UNDEFINED; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; Loading Loading @@ -241,11 +270,11 @@ public class PipTaskOrganizer extends TaskOrganizer implements } public boolean isInPip() { return mInPip; return mState.isInPip(); } public boolean isDeferringEnterPipAnimation() { return mInPip && mShouldDeferEnteringPip; return mState.isInPip() && mShouldDeferEnteringPip; } /** Loading Loading @@ -274,9 +303,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void exitPip(int animationDurationMs) { if (!mInPip || mExitingPip || mToken == null) { if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) { Log.wtf(TAG, "Not allowed to exitPip in current state" + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + " mState=" + mState + " mToken=" + mToken); return; } Loading @@ -293,6 +322,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; if (orientationDiffers) { mState = State.EXITING_PIP; // Send started callback though animation is ignored. sendOnPipTransitionStarted(direction); // Don't bother doing an animation if the display rotation differs or if it's in Loading @@ -301,7 +331,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements WindowOrganizer.applyTransaction(wct); // Send finished callback though animation is ignored. sendOnPipTransitionFinished(direction); mInPip = false; } else { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); Loading @@ -320,11 +349,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, null /* sourceHintRect */, direction, animationDurationMs, null /* updateBoundsCallback */); mInPip = false; mState = State.EXITING_PIP; } }); } mExitingPip = true; } private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) { Loading @@ -341,9 +369,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * Removes PiP immediately. */ public void removePip() { if (!mInPip || mExitingPip || mToken == null) { if (!mState.isInPip() || mToken == null) { Log.wtf(TAG, "Not allowed to removePip in current state" + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + " mState=" + mState + " mToken=" + mToken); return; } Loading @@ -355,7 +383,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setDuration(mEnterExitAnimationDuration) .start()); mCompactState.remove(mToken.asBinder()); mExitingPip = true; mState = State.EXITING_PIP; } private void removePipImmediately() { Loading @@ -377,8 +405,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements Objects.requireNonNull(info, "Requires RunningTaskInfo"); mTaskInfo = info; mToken = mTaskInfo.token; mInPip = true; mExitingPip = false; mState = State.TASK_APPEARED; mLeash = leash; mCompactState.put(mToken.asBinder(), new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration)); Loading Loading @@ -410,6 +437,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); mState = State.ENTERING_PIP; } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration); mOneShotAnimationType = ANIM_TYPE_BOUNDS; Loading Loading @@ -455,6 +483,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start()); // mState is set right after the animation is kicked off to block any resize // requests such as offsetPip that may have been called prior to the transition. mState = State.ENTERING_PIP; } }); } Loading Loading @@ -507,7 +538,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { if (!mInPip) { if (!mState.isInPip()) { return; } final WindowContainerToken token = info.token; Loading @@ -518,8 +549,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements } mShouldDeferEnteringPip = false; mPictureInPictureParams = null; mInPip = false; mExitingPip = false; mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); } Loading Loading @@ -554,7 +584,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements @Override public void onFixedRotationFinished(int displayId) { if (mShouldDeferEnteringPip && mInPip) { if (mShouldDeferEnteringPip && mState.isInPip()) { final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); Loading @@ -575,7 +605,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { if (mInPip && fromRotation) { if (mState.isInPip() && fromRotation) { // If we are rotating while there is a current animation, immediately cancel the // animation (remove the listeners so we don't trigger the normal finish resize // call that should only happen on the update thread) Loading Loading @@ -661,10 +691,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds, Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer<Rect> updateBoundsCallback) { if (!mInPip) { if (!mState.isInPip()) { // TODO: tend to use shouldBlockResizeRequest here as well but need to consider // the fact that when in exitPip, scheduleAnimateResizePip is executed in the window // container transaction callback and we want to set the mExitingPip immediately. // container transaction callback and we want to set the mState immediately. return; } Loading Loading @@ -721,7 +751,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleFinishResizePip(Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer<Rect> updateBoundsCallback) { if (shouldBlockResizeRequest()) { if (mState.shouldBlockResizeRequest()) { return; } Loading @@ -740,7 +770,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .resetScale(tx, mLeash, destinationBounds) .round(tx, mLeash, mInPip); .round(tx, mLeash, mState.isInPip()); return tx; } Loading @@ -749,7 +779,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer<Rect> updateBoundsCallback) { if (shouldBlockResizeRequest()) { if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { Loading Loading @@ -794,7 +824,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .round(tx, mLeash, mInPip); .round(tx, mLeash, mState.isInPip()); tx.apply(); } Loading Loading @@ -925,16 +955,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements : params.getAspectRatio(); } /** * Resize request can be initiated in other component, ignore if we are no longer in PIP * or we're exiting from it. * * @return {@code true} if the resize request should be blocked/ignored. */ private boolean shouldBlockResizeRequest() { return !mInPip || mExitingPip; } /** * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen. * Loading Loading @@ -963,7 +983,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements pw.println(innerPrefix + "mToken=" + mToken + " binder=" + (mToken != null ? mToken.asBinder() : null)); pw.println(innerPrefix + "mLeash=" + mLeash); pw.println(innerPrefix + "mInPip=" + mInPip); pw.println(innerPrefix + "mState=" + mState); pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); Loading Loading
packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +56 −36 Original line number Diff line number Diff line Loading @@ -94,6 +94,36 @@ public class PipTaskOrganizer extends TaskOrganizer implements private static final int MSG_FINISH_RESIZE = 4; private static final int MSG_RESIZE_USER = 5; // Not a complete set of states but serves what we want right now. private enum State { UNDEFINED(0), TASK_APPEARED(1), ENTERING_PIP(2), EXITING_PIP(3); private final int mStateValue; State(int value) { mStateValue = value; } private boolean isInPip() { return mStateValue >= TASK_APPEARED.mStateValue && mStateValue != EXITING_PIP.mStateValue; } /** * Resize request can be initiated in other component, ignore if we are no longer in PIP, * still waiting for animation or we're exiting from it. * * @return {@code true} if the resize request should be blocked/ignored. */ private boolean shouldBlockResizeRequest() { return mStateValue < ENTERING_PIP.mStateValue || mStateValue == EXITING_PIP.mStateValue; } } private final Handler mMainHandler; private final Handler mUpdateHandler; private final PipBoundsHandler mPipBoundsHandler; Loading Loading @@ -188,8 +218,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private ActivityManager.RunningTaskInfo mTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; private boolean mInPip; private boolean mExitingPip; private State mState = State.UNDEFINED; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; Loading Loading @@ -241,11 +270,11 @@ public class PipTaskOrganizer extends TaskOrganizer implements } public boolean isInPip() { return mInPip; return mState.isInPip(); } public boolean isDeferringEnterPipAnimation() { return mInPip && mShouldDeferEnteringPip; return mState.isInPip() && mShouldDeferEnteringPip; } /** Loading Loading @@ -274,9 +303,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void exitPip(int animationDurationMs) { if (!mInPip || mExitingPip || mToken == null) { if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) { Log.wtf(TAG, "Not allowed to exitPip in current state" + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + " mState=" + mState + " mToken=" + mToken); return; } Loading @@ -293,6 +322,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; if (orientationDiffers) { mState = State.EXITING_PIP; // Send started callback though animation is ignored. sendOnPipTransitionStarted(direction); // Don't bother doing an animation if the display rotation differs or if it's in Loading @@ -301,7 +331,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements WindowOrganizer.applyTransaction(wct); // Send finished callback though animation is ignored. sendOnPipTransitionFinished(direction); mInPip = false; } else { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); Loading @@ -320,11 +349,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, null /* sourceHintRect */, direction, animationDurationMs, null /* updateBoundsCallback */); mInPip = false; mState = State.EXITING_PIP; } }); } mExitingPip = true; } private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) { Loading @@ -341,9 +369,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements * Removes PiP immediately. */ public void removePip() { if (!mInPip || mExitingPip || mToken == null) { if (!mState.isInPip() || mToken == null) { Log.wtf(TAG, "Not allowed to removePip in current state" + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + " mState=" + mState + " mToken=" + mToken); return; } Loading @@ -355,7 +383,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setDuration(mEnterExitAnimationDuration) .start()); mCompactState.remove(mToken.asBinder()); mExitingPip = true; mState = State.EXITING_PIP; } private void removePipImmediately() { Loading @@ -377,8 +405,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements Objects.requireNonNull(info, "Requires RunningTaskInfo"); mTaskInfo = info; mToken = mTaskInfo.token; mInPip = true; mExitingPip = false; mState = State.TASK_APPEARED; mLeash = leash; mCompactState.put(mToken.asBinder(), new PipWindowConfigurationCompact(mTaskInfo.configuration.windowConfiguration)); Loading Loading @@ -410,6 +437,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); mState = State.ENTERING_PIP; } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration); mOneShotAnimationType = ANIM_TYPE_BOUNDS; Loading Loading @@ -455,6 +483,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start()); // mState is set right after the animation is kicked off to block any resize // requests such as offsetPip that may have been called prior to the transition. mState = State.ENTERING_PIP; } }); } Loading Loading @@ -507,7 +538,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { if (!mInPip) { if (!mState.isInPip()) { return; } final WindowContainerToken token = info.token; Loading @@ -518,8 +549,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements } mShouldDeferEnteringPip = false; mPictureInPictureParams = null; mInPip = false; mExitingPip = false; mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); } Loading Loading @@ -554,7 +584,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements @Override public void onFixedRotationFinished(int displayId) { if (mShouldDeferEnteringPip && mInPip) { if (mShouldDeferEnteringPip && mState.isInPip()) { final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); Loading @@ -575,7 +605,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { if (mInPip && fromRotation) { if (mState.isInPip() && fromRotation) { // If we are rotating while there is a current animation, immediately cancel the // animation (remove the listeners so we don't trigger the normal finish resize // call that should only happen on the update thread) Loading Loading @@ -661,10 +691,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds, Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer<Rect> updateBoundsCallback) { if (!mInPip) { if (!mState.isInPip()) { // TODO: tend to use shouldBlockResizeRequest here as well but need to consider // the fact that when in exitPip, scheduleAnimateResizePip is executed in the window // container transaction callback and we want to set the mExitingPip immediately. // container transaction callback and we want to set the mState immediately. return; } Loading Loading @@ -721,7 +751,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements private void scheduleFinishResizePip(Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer<Rect> updateBoundsCallback) { if (shouldBlockResizeRequest()) { if (mState.shouldBlockResizeRequest()) { return; } Loading @@ -740,7 +770,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .resetScale(tx, mLeash, destinationBounds) .round(tx, mLeash, mInPip); .round(tx, mLeash, mState.isInPip()); return tx; } Loading @@ -749,7 +779,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer<Rect> updateBoundsCallback) { if (shouldBlockResizeRequest()) { if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { Loading Loading @@ -794,7 +824,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .round(tx, mLeash, mInPip); .round(tx, mLeash, mState.isInPip()); tx.apply(); } Loading Loading @@ -925,16 +955,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements : params.getAspectRatio(); } /** * Resize request can be initiated in other component, ignore if we are no longer in PIP * or we're exiting from it. * * @return {@code true} if the resize request should be blocked/ignored. */ private boolean shouldBlockResizeRequest() { return !mInPip || mExitingPip; } /** * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen. * Loading Loading @@ -963,7 +983,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements pw.println(innerPrefix + "mToken=" + mToken + " binder=" + (mToken != null ? mToken.asBinder() : null)); pw.println(innerPrefix + "mLeash=" + mLeash); pw.println(innerPrefix + "mInPip=" + mInPip); pw.println(innerPrefix + "mState=" + mState); pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); Loading