summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ikram Gabiyev <gabiyev@google.com> 2024-10-29 20:24:06 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-10-29 20:24:06 +0000
commitcd6e7cd4a6cdba0cf1bf560f33f382d668d032fd (patch)
tree0591da593fc236f3f9aeaad78d34cc8f3d5ebbaf
parent1d18b26bd9bdca520da1ccd31523838afa1725a0 (diff)
parent0f56f674448d226f2d080c9ee1cf74723b8745d1 (diff)
Merge "Refactor PiP2 resize transitions" into main
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java113
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