diff options
| author | 2024-10-29 20:24:06 +0000 | |
|---|---|---|
| committer | 2024-10-29 20:24:06 +0000 | |
| commit | cd6e7cd4a6cdba0cf1bf560f33f382d668d032fd (patch) | |
| tree | 0591da593fc236f3f9aeaad78d34cc8f3d5ebbaf | |
| parent | 1d18b26bd9bdca520da1ccd31523838afa1725a0 (diff) | |
| parent | 0f56f674448d226f2d080c9ee1cf74723b8745d1 (diff) | |
Merge "Refactor PiP2 resize transitions" into main
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 |