diff options
7 files changed, 89 insertions, 99 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java index 94b344fb575a..5ffc64f412f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java @@ -368,10 +368,8 @@ public abstract class PipTransitionController implements Transitions.TransitionH /** * Finish the current transition if possible. - * - * @param tx transaction to be applied with a potentially new draw after finishing. */ - public void finishTransition(@Nullable SurfaceControl.Transaction tx) { + public void finishTransition() { } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java index 740b9af56144..e5137582822d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java @@ -192,22 +192,7 @@ public class PipEnterAnimator extends ValueAnimator * calculated differently from generic transitions. * @param pipChange PiP change received as a transition target. */ - public void setEnterStartState(@NonNull TransitionInfo.Change pipChange, - @NonNull TransitionInfo.Change pipActivityChange) { - PipUtils.calcEndTransform(pipActivityChange, pipChange, mInitActivityScale, - mInitActivityPos); - if (mStartTransaction != null && pipActivityChange.getLeash() != null) { - mStartTransaction.setCrop(pipActivityChange.getLeash(), null); - mStartTransaction.setScale(pipActivityChange.getLeash(), mInitActivityScale.x, - mInitActivityScale.y); - mStartTransaction.setPosition(pipActivityChange.getLeash(), mInitActivityPos.x, - mInitActivityPos.y); - mFinishTransaction.setCrop(pipActivityChange.getLeash(), null); - mFinishTransaction.setScale(pipActivityChange.getLeash(), mInitActivityScale.x, - mInitActivityScale.y); - mFinishTransaction.setPosition(pipActivityChange.getLeash(), mInitActivityPos.x, - mInitActivityPos.y); - } + public void setEnterStartState(@NonNull TransitionInfo.Change pipChange) { PipUtils.calcStartTransform(pipChange, mInitScale, mInitPos, mInitCrop); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java index 810eff8a055c..17392bc521d8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java @@ -752,11 +752,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION)); break; case PipTransitionState.CHANGING_PIP_BOUNDS: - SurfaceControl.Transaction startTx = extra.getParcelable( + final SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); - SurfaceControl.Transaction finishTx = extra.getParcelable( + final SurfaceControl.Transaction finishTx = extra.getParcelable( PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class); - Rect destinationBounds = extra.getParcelable( + final Rect destinationBounds = extra.getParcelable( PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION, PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION); @@ -794,7 +794,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that the transition is done - should update transition state by default. - mPipScheduler.scheduleFinishResizePip(destinationBounds, false /* configAtEnd */); + mPipScheduler.scheduleFinishResizePip(destinationBounds); } private void startResizeAnimation(SurfaceControl.Transaction startTx, @@ -803,11 +803,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, Preconditions.checkState(pipLeash != null, "No leash cached by mPipTransitionState=" + mPipTransitionState); - startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(), - mPipBoundsState.getBounds().height()); - PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash, - startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), + startTx, finishTx, destinationBounds, mPipBoundsState.getBounds(), destinationBounds, duration, 0f /* angle */); animator.setAnimationEndCallback(() -> { // In case an ongoing drag/fling was present before a deterministic resize transition @@ -818,7 +815,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition - mPipScheduler.scheduleFinishResizePip(destinationBounds, true /* configAtEnd */); + mPipScheduler.scheduleFinishResizePip(destinationBounds); }); animator.start(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java index f5ef64dff94b..751175f0f3e9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java @@ -535,28 +535,26 @@ public class PipResizeGestureHandler implements Preconditions.checkState(pipLeash != null, "No leash cached by mPipTransitionState=" + mPipTransitionState); - SurfaceControl.Transaction startTx = extra.getParcelable( + final SurfaceControl.Transaction startTx = extra.getParcelable( PipTransition.PIP_START_TX, SurfaceControl.Transaction.class); - SurfaceControl.Transaction finishTx = extra.getParcelable( + final SurfaceControl.Transaction finishTx = extra.getParcelable( PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class); + final Rect destinationBounds = extra.getParcelable( + PipTransition.PIP_DESTINATION_BOUNDS, Rect.class); final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION, PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION); - startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(), - mPipBoundsState.getBounds().height()); - PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash, - startTx, finishTx, mPipBoundsState.getBounds(), mStartBoundsAfterRelease, - mLastResizeBounds, duration, mAngle); + startTx, finishTx, destinationBounds, mStartBoundsAfterRelease, + destinationBounds, duration, mAngle); animator.setAnimationEndCallback(() -> { // All motion operations have actually finished, so make bounds cache updates. - mUserResizeBounds.set(mLastResizeBounds); + mUserResizeBounds.set(destinationBounds); resetState(); cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition - mPipScheduler.scheduleFinishResizePip( - mLastResizeBounds, true /* configAtEnd */); + mPipScheduler.scheduleFinishResizePip(destinationBounds); }); animator.start(); break; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index fbbf6f3596d0..8b25b11e3a47 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -175,22 +175,12 @@ public class PipScheduler { * Note that we do not allow any actual WM Core changes at this point. * * @param toBounds destination bounds used only for internal state updates - not sent to Core. - * @param configAtEnd true if we are waiting for config updates at the end of the transition. */ - public void scheduleFinishResizePip(Rect toBounds, boolean configAtEnd) { - // Make updates to the internal state to reflect new bounds + public void scheduleFinishResizePip(Rect toBounds) { + // Make updates to the internal state to reflect new bounds before updating any transitions + // related state; transition state updates can trigger callbacks that use the cached bounds. onFinishingPipResize(toBounds); - - SurfaceControl.Transaction tx = null; - if (configAtEnd) { - tx = new SurfaceControl.Transaction(); - tx.addTransactionCommittedListener(mMainExecutor, () -> { - mPipTransitionState.setState(PipTransitionState.CHANGED_PIP_BOUNDS); - }); - } else { - mPipTransitionState.setState(PipTransitionState.CHANGED_PIP_BOUNDS); - } - mPipTransitionController.finishTransition(tx); + mPipTransitionController.finishTransition(); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java index 373ec806c40c..2c7584af1f07 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java @@ -177,8 +177,7 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, mPipBoundsState.getBounds(), destinationBounds, duration, 0f /* delta */); animator.setAnimationEndCallback(() -> { - mPipScheduler.scheduleFinishResizePip( - destinationBounds, false /* configAtEnd */); + mPipScheduler.scheduleFinishResizePip(destinationBounds); }); animator.start(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index e90b32cd01e7..64d8887ae5cd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -35,6 +35,7 @@ import android.app.ActivityManager; import android.app.PictureInPictureParams; import android.content.Context; import android.graphics.Point; +import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; @@ -276,21 +277,25 @@ public class PipTransition extends PipTransitionController implements if (pipChange == null) { return false; } - SurfaceControl pipLeash = pipChange.getLeash(); + // We expect the PiP activity as a separate change in a config-at-end transition; + // only flings are not using config-at-end for resize bounds changes + TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info, + pipChange.getTaskInfo().getToken()); + if (pipActivityChange != null) { + // Transform calculations use PiP params by default, so make sure they are null to + // default to using bounds for scaling calculations instead. + pipChange.getTaskInfo().pictureInPictureParams = null; + prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange, + pipActivityChange); + } - // Even though the final bounds and crop are applied with finishTransaction since - // this is a visible change, we still need to handle the app draw coming in. Snapshot - // covering app draw during collection will be removed by startTransaction. So we make - // the crop equal to the final bounds and then let the current - // animator scale the leash back to starting bounds. - // Note: animator is responsible for applying the startTx but NOT finishTx. + SurfaceControl pipLeash = pipChange.getLeash(); startTransaction.setWindowCrop(pipLeash, pipChange.getEndAbsBounds().width(), pipChange.getEndAbsBounds().height()); - // TODO: b/275910498 Couple this routine with a new implementation of the PiP animator. // Classes interested in continuing the animation would subscribe to this state update - // getting info such as endBounds, startTx, and finishTx as an extra Bundle once - // animators are in place. Once done state needs to be updated to CHANGED_PIP_BOUNDS. + // getting info such as endBounds, startTx, and finishTx as an extra Bundle + // Once done state needs to be updated to CHANGED_PIP_BOUNDS via {@link PipScheduler#}. Bundle extra = new Bundle(); extra.putParcelable(PIP_START_TX, startTransaction); extra.putParcelable(PIP_FINISH_TX, finishTransaction); @@ -353,10 +358,12 @@ public class PipTransition extends PipTransitionController implements sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint(); } + prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange, + pipActivityChange); startTransaction.merge(finishTransaction); PipEnterAnimator animator = new PipEnterAnimator(mContext, pipLeash, startTransaction, finishTransaction, destinationBounds, sourceRectHint, delta); - animator.setEnterStartState(pipChange, pipActivityChange); + animator.setEnterStartState(pipChange); animator.onEnterAnimationUpdate(1.0f /* fraction */, startTransaction); startTransaction.apply(); @@ -368,7 +375,7 @@ public class PipTransition extends PipTransitionController implements tx.apply(); }); } - finishInner(); + finishTransition(); return true; } @@ -393,14 +400,13 @@ public class PipTransition extends PipTransitionController implements final PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams; final float aspectRatio = mPipBoundsAlgorithm.getAspectRatioOrDefault(params); - final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, startBounds, endBounds); - - final SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash; final Rect adjustedSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint) : PipUtils.getEnterPipWithOverlaySrcRectHint(startBounds, aspectRatio); + final SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash; + // For opening type transitions, if there is a change of mode TO_FRONT/OPEN, // make sure that change has alpha of 1f, since it's init state might be set to alpha=0f // by the Transitions framework to simplify Task opening transitions. @@ -435,14 +441,16 @@ public class PipTransition extends PipTransitionController implements mContext, startBounds, endBounds, pipChange.getTaskInfo().topActivityInfo, mPipBoundsState.getLauncherState().getAppIconSizePx()); } - animator.setAnimationStartCallback(() -> animator.setEnterStartState(pipChange, - pipActivityChange)); + + prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange, + pipActivityChange); + animator.setAnimationStartCallback(() -> animator.setEnterStartState(pipChange)); animator.setAnimationEndCallback(() -> { if (animator.getContentOverlayLeash() != null) { startOverlayFadeoutAnimation(animator.getContentOverlayLeash(), animator::clearAppIconOverlay); } - finishInner(); + finishTransition(); }); animator.start(); return true; @@ -512,8 +520,7 @@ public class PipTransition extends PipTransitionController implements PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction, PipAlphaAnimator.FADE_IN); // This should update the pip transition state accordingly after we stop playing. - animator.setAnimationEndCallback(this::finishInner); - + animator.setAnimationEndCallback(this::finishTransition); animator.start(); return true; } @@ -569,12 +576,7 @@ public class PipTransition extends PipTransitionController implements PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, Surface.ROTATION_0); - - animator.setAnimationEndCallback(() -> { - mPipTransitionState.setState(PipTransitionState.EXITED_PIP); - finishCallback.onTransitionFinished(null); - }); - + animator.setAnimationEndCallback(this::finishTransition); animator.start(); return true; } @@ -698,33 +700,54 @@ public class PipTransition extends PipTransitionController implements return isPipMovedToBack || isPipClosed || isPipDismissed; } + private void prepareConfigAtEndActivity(@NonNull SurfaceControl.Transaction startTx, + @NonNull SurfaceControl.Transaction finishTx, + @NonNull TransitionInfo.Change pipChange, + @NonNull TransitionInfo.Change pipActivityChange) { + PointF initActivityScale = new PointF(); + PointF initActivityPos = new PointF(); + PipUtils.calcEndTransform(pipActivityChange, pipChange, initActivityScale, + initActivityPos); + if (pipActivityChange.getLeash() != null) { + startTx.setCrop(pipActivityChange.getLeash(), null); + startTx.setScale(pipActivityChange.getLeash(), initActivityScale.x, + initActivityScale.y); + startTx.setPosition(pipActivityChange.getLeash(), initActivityPos.x, + initActivityPos.y); + + finishTx.setCrop(pipActivityChange.getLeash(), null); + finishTx.setScale(pipActivityChange.getLeash(), initActivityScale.x, + initActivityScale.y); + finishTx.setPosition(pipActivityChange.getLeash(), initActivityPos.x, + initActivityPos.y); + } + } + // // Miscellaneous callbacks and listeners // - private void finishInner() { - finishTransition(null /* tx */); - if (mPipTransitionState.getState() == PipTransitionState.ENTERING_PIP) { - // If we were entering PiP (i.e. playing the animation) with a valid srcRectHint, - // and then we get a signal on client finishing its draw after the transition - // has ended, then we have fully entered PiP. - mPipTransitionState.setState(PipTransitionState.ENTERED_PIP); - } - } - @Override - public void finishTransition(@Nullable SurfaceControl.Transaction tx) { - WindowContainerTransaction wct = null; - if (tx != null && mPipTransitionState.mPipTaskToken != null) { - // Outside callers can only provide a transaction to be applied with the final draw. - // So no actual WM changes can be applied for this transition after this point. - wct = new WindowContainerTransaction(); - wct.setBoundsChangeTransaction(mPipTransitionState.mPipTaskToken, tx); - } + public void finishTransition() { if (mFinishCallback != null) { - mFinishCallback.onTransitionFinished(wct); + mFinishCallback.onTransitionFinished(null /* finishWct */); mFinishCallback = null; } + + final int currentState = mPipTransitionState.getState(); + int nextState = PipTransitionState.UNDEFINED; + switch (currentState) { + case PipTransitionState.ENTERING_PIP: + nextState = PipTransitionState.ENTERED_PIP; + break; + case PipTransitionState.CHANGING_PIP_BOUNDS: + nextState = PipTransitionState.CHANGED_PIP_BOUNDS; + break; + case PipTransitionState.EXITING_PIP: + nextState = PipTransitionState.EXITED_PIP; + break; + } + mPipTransitionState.setState(nextState); } @Override |