summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDisplayLayoutState.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java55
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java45
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java3
5 files changed, 107 insertions, 12 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDisplayLayoutState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDisplayLayoutState.java
index ed42117a55af..d5e47187dac2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDisplayLayoutState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipDisplayLayoutState.java
@@ -115,6 +115,12 @@ public class PipDisplayLayoutState {
mDisplayLayout.rotateTo(mContext.getResources(), targetRotation);
}
+ /** Returns the current display rotation of this layout state. */
+ @Surface.Rotation
+ public int getRotation() {
+ return mDisplayLayout.rotation();
+ }
+
/** Get the current display id */
public int getDisplayId() {
return mDisplayId;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 3c7713d30714..c7f693d8de50 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -286,6 +286,12 @@ public class PipTransition extends PipTransitionController {
// Entering PIP.
if (isEnteringPip(info)) {
+ if (handleEnteringPipWithDisplayChange(transition, info, startTransaction,
+ finishTransaction, finishCallback)) {
+ // The destination position is applied directly and let default transition handler
+ // run the display change animation.
+ return true;
+ }
startEnterAnimation(info, startTransaction, finishTransaction, finishCallback);
return true;
}
@@ -300,6 +306,25 @@ public class PipTransition extends PipTransitionController {
return false;
}
+ private boolean handleEnteringPipWithDisplayChange(@NonNull IBinder transition,
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT,
+ @NonNull SurfaceControl.Transaction finishT,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ if (mFixedRotationState != FIXED_ROTATION_UNDEFINED
+ || !TransitionUtil.hasDisplayChange(info)) {
+ return false;
+ }
+ final TransitionInfo.Change pipChange = getPipChange(info);
+ if (pipChange == null) {
+ return false;
+ }
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: handle entering PiP with display change", TAG);
+ mMixedHandler.animateEnteringPipWithDisplayChange(transition, info, pipChange,
+ startT, finishT, finishCallback);
+ return true;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -882,19 +907,24 @@ public class PipTransition extends PipTransitionController {
mEnterAnimationType = type;
}
- private void startEnterAnimation(@NonNull TransitionInfo info,
- @NonNull SurfaceControl.Transaction startTransaction,
- @NonNull SurfaceControl.Transaction finishTransaction,
- @NonNull Transitions.TransitionFinishCallback finishCallback) {
- // Search for an Enter PiP transition
- TransitionInfo.Change enterPip = null;
+ @Nullable
+ private static TransitionInfo.Change getPipChange(@NonNull TransitionInfo info) {
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getTaskInfo() != null
&& change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) {
- enterPip = change;
+ return change;
}
}
+ return null;
+ }
+
+ private void startEnterAnimation(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // Search for an Enter PiP transition
+ final TransitionInfo.Change enterPip = getPipChange(info);
if (enterPip == null) {
throw new IllegalStateException("Trying to start PiP animation without a pip"
+ "participant");
@@ -968,8 +998,8 @@ public class PipTransition extends PipTransitionController {
Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
taskInfo.pictureInPictureParams, currentBounds, destinationBounds);
if (rotationDelta != Surface.ROTATION_0
- && mFixedRotationState == FIXED_ROTATION_TRANSITION) {
- // Need to get the bounds of new rotation in old rotation for fixed rotation,
+ && endRotation != mPipDisplayLayoutState.getRotation()) {
+ // Computes the destination bounds in new rotation.
computeEnterPipRotatedBounds(rotationDelta, startRotation, endRotation, taskInfo,
destinationBounds, sourceHintRect);
}
@@ -1061,8 +1091,11 @@ public class PipTransition extends PipTransitionController {
final Rect displayBounds = mPipDisplayLayoutState.getDisplayBounds();
outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
- // Transform the destination bounds to current display coordinates.
- rotateBounds(outDestinationBounds, displayBounds, endRotation, startRotation);
+ if (mFixedRotationState == FIXED_ROTATION_TRANSITION) {
+ // Transform the destination bounds to current display coordinates.
+ // With fixed rotation, the bounds of new rotation shows in old rotation.
+ rotateBounds(outDestinationBounds, displayBounds, endRotation, startRotation);
+ }
// When entering PiP (from button navigation mode), adjust the source rect hint by
// display cutout if applicable.
if (outSourceHintRect != null && taskInfo.displayCutoutInsets != null) {
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 7730285c86c8..1d1a4e2be3e4 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
@@ -49,6 +49,7 @@ import com.android.wm.shell.common.pip.PipMenuController;
import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.DefaultMixedHandler;
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
@@ -67,6 +68,7 @@ public abstract class PipTransitionController implements Transitions.TransitionH
protected final Transitions mTransitions;
private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
protected PipTaskOrganizer mPipOrganizer;
+ protected DefaultMixedHandler mMixedHandler;
protected final PipAnimationController.PipAnimationCallback mPipAnimationCallback =
new PipAnimationController.PipAnimationCallback() {
@@ -168,6 +170,14 @@ public abstract class PipTransitionController implements Transitions.TransitionH
mPipOrganizer = pto;
}
+ public void setMixedHandler(DefaultMixedHandler mixedHandler) {
+ mMixedHandler = mixedHandler;
+ }
+
+ public void applyTransaction(WindowContainerTransaction wct) {
+ mShellTaskOrganizer.applyTransaction(wct);
+ }
+
/**
* Registers {@link PipTransitionCallback} to receive transition callbacks.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index bcacecbd8981..8ee1efa90a30 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -107,6 +107,9 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
/** Entering Pip from split, but replace the Pip stage instead of breaking split. */
static final int TYPE_ENTER_PIP_REPLACE_FROM_SPLIT = 10;
+ /** The display changes when pip is entering. */
+ static final int TYPE_ENTER_PIP_WITH_DISPLAY_CHANGE = 11;
+
/** The default animation for this mixed transition. */
static final int ANIM_TYPE_DEFAULT = 0;
@@ -233,6 +236,7 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
// Add after dependencies because it is higher priority
shellInit.addInitCallback(() -> {
mPipHandler = pipTransitionController;
+ pipTransitionController.setMixedHandler(this);
mSplitHandler = splitScreenControllerOptional.get().getTransitionHandler();
mPlayer.addHandler(this);
if (mSplitHandler != null) {
@@ -550,6 +554,47 @@ public class DefaultMixedHandler implements MixedTransitionHandler,
return true;
}
+ /**
+ * For example: pip is entering in rotation 0, and then the display changes to rotation 90
+ * before the pip transition is ready. So the info contains both the entering pip and display
+ * change. In this case, the pip can go to the end state in new rotation directly, and let the
+ * display level animation cover all changed participates.
+ */
+ public void animateEnteringPipWithDisplayChange(@NonNull IBinder transition,
+ @NonNull TransitionInfo info, @NonNull TransitionInfo.Change pipChange,
+ @NonNull SurfaceControl.Transaction startT,
+ @NonNull SurfaceControl.Transaction finishT,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // In order to play display level animation, force the type to CHANGE (it could be PIP).
+ final TransitionInfo changeInfo = info.getType() != TRANSIT_CHANGE
+ ? subCopy(info, TRANSIT_CHANGE, true /* withChanges */) : info;
+ final MixedTransition mixed = createDefaultMixedTransition(
+ MixedTransition.TYPE_ENTER_PIP_WITH_DISPLAY_CHANGE, transition);
+ mActiveTransitions.add(mixed);
+ mixed.mInFlightSubAnimations = 2;
+ final Transitions.TransitionFinishCallback finishCB = wct -> {
+ --mixed.mInFlightSubAnimations;
+ mixed.joinFinishArgs(wct);
+ if (mixed.mInFlightSubAnimations > 0) return;
+ mActiveTransitions.remove(mixed);
+ finishCallback.onTransitionFinished(mixed.mFinishWCT);
+ };
+ // Perform the display animation first.
+ mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, changeInfo,
+ startT, finishT, finishCB, mPipHandler);
+ // Use a standalone finish transaction for pip because it will apply immediately.
+ final SurfaceControl.Transaction pipFinishT = new SurfaceControl.Transaction();
+ mPipHandler.startEnterAnimation(pipChange, startT, pipFinishT, wct -> {
+ // Apply immediately to avoid potential flickering by bounds change at the end of
+ // display animation.
+ mPipHandler.applyTransaction(wct);
+ finishCB.onTransitionFinished(null /* wct */);
+ });
+ // Jump to the pip end state directly and make sure the real finishT have the latest state.
+ mPipHandler.end();
+ mPipHandler.syncPipSurfaceState(info, startT, finishT);
+ }
+
private static boolean animateKeyguard(@NonNull final MixedTransition mixed,
@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index 0ada74937df4..c33fb80fdefc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -70,7 +70,7 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
return switch (mType) {
- case TYPE_DISPLAY_AND_SPLIT_CHANGE -> false;
+ case TYPE_DISPLAY_AND_SPLIT_CHANGE, TYPE_ENTER_PIP_WITH_DISPLAY_CHANGE -> false;
case TYPE_ENTER_PIP_FROM_ACTIVITY_EMBEDDING ->
animateEnterPipFromActivityEmbedding(
info, startTransaction, finishTransaction, finishCallback);
@@ -253,6 +253,7 @@ class DefaultMixedTransition extends DefaultMixedHandler.MixedTransition {
@NonNull Transitions.TransitionFinishCallback finishCallback) {
switch (mType) {
case TYPE_DISPLAY_AND_SPLIT_CHANGE:
+ case TYPE_ENTER_PIP_WITH_DISPLAY_CHANGE:
// queue since no actual animation.
return;
case TYPE_ENTER_PIP_FROM_ACTIVITY_EMBEDDING: