summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java196
2 files changed, 130 insertions, 75 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 63a6dd20482a..4c09a4e9938f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -69,7 +69,6 @@ import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
import android.window.TaskOrganizer;
-import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -869,14 +868,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
}
- /** Whether the given {@link TransitionInfo.Change} is for the PIP window. */
- boolean isPipChange(TransitionInfo.Change change) {
- if (mToken == null) {
- Log.e(TAG, "We no longer keep track of the PIP token");
- }
- return mToken.equals(change.getContainer());
- }
-
private void fadeExistingPip(boolean show) {
final float alphaStart = show ? 0 : 1;
final float alphaEnd = show ? 1 : 0;
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 7bcdb2630fb1..c6794b84c42d 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
@@ -83,7 +83,11 @@ public class PipTransition extends PipTransitionController {
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
private Transitions.TransitionFinishCallback mFinishCallback;
private final Rect mExitDestinationBounds = new Rect();
- private IBinder mExitTransition = null;
+ @Nullable
+ private IBinder mExitTransition;
+ /** The Task window that is currently in PIP windowing mode. */
+ @Nullable
+ private WindowContainerToken mCurrentPipTaskToken;
public PipTransition(Context context,
PipBoundsState pipBoundsState,
@@ -134,6 +138,7 @@ public class PipTransition extends PipTransitionController {
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // Exiting PIP.
final int type = info.getType();
if (transition.equals(mExitTransition)) {
mExitDestinationBounds.setEmpty();
@@ -145,7 +150,7 @@ public class PipTransition extends PipTransitionController {
throw new RuntimeException("Previous callback not called, aborting exit PIP.");
}
- final TransitionInfo.Change exitPipChange = findPipChange(info);
+ final TransitionInfo.Change exitPipChange = findCurrentPipChange(info);
if (exitPipChange == null) {
throw new RuntimeException("Cannot find the pip window for exit-pip transition.");
}
@@ -159,78 +164,26 @@ public class PipTransition extends PipTransitionController {
finishCallback, exitPipChange);
break;
case TRANSIT_REMOVE_PIP:
- startTransaction.apply();
- finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
- mPipBoundsState.getDisplayBounds());
- mPipOrganizer.onExitPipFinished(exitPipChange.getTaskInfo());
- finishCallback.onTransitionFinished(null, null);
+ removePipImmediately(info, startTransaction, finishTransaction, finishCallback,
+ exitPipChange);
break;
default:
throw new IllegalStateException("mExitTransition with unexpected transit type="
+ transitTypeToString(type));
}
+ mCurrentPipTaskToken = null;
return true;
}
- // We only support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps
- // that enter PiP instantly on opening, mostly from CTS/Flicker tests)
- if (type != TRANSIT_PIP && type != TRANSIT_OPEN) {
- // In case the PIP window is part of rotation transition, reset the bounds and rounded
- // corner.
- for (int i = info.getChanges().size() - 1; i >= 0; --i) {
- final TransitionInfo.Change change = info.getChanges().get(i);
- if (change.getMode() == TRANSIT_CHANGE && change.getTaskInfo() != null
- && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode()
- == WINDOWING_MODE_PINNED) {
- final SurfaceControl leash = change.getLeash();
- final Rect destBounds = mPipBoundsState.getBounds();
- final boolean isInPip = mPipTransitionState.isInPip();
- mSurfaceTransactionHelper
- .crop(startTransaction, leash, destBounds)
- .round(startTransaction, leash, isInPip);
- mSurfaceTransactionHelper
- .crop(finishTransaction, leash, destBounds)
- .round(finishTransaction, leash, isInPip);
- break;
- }
- }
- return false;
- }
-
- // Search for an Enter PiP transition (along with a show wallpaper one)
- TransitionInfo.Change enterPip = null;
- TransitionInfo.Change wallpaper = null;
- for (int i = info.getChanges().size() - 1; i >= 0; --i) {
- final TransitionInfo.Change change = info.getChanges().get(i);
- if (change.getTaskInfo() != null
- && change.getTaskInfo().configuration.windowConfiguration.getWindowingMode()
- == WINDOWING_MODE_PINNED) {
- enterPip = change;
- } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
- wallpaper = change;
- }
- }
- if (enterPip == null) {
- return false;
- }
-
- if (mFinishCallback != null) {
- mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
- mFinishCallback = null;
- throw new RuntimeException("Previous callback not called, aborting entering PIP.");
+ // Entering PIP.
+ if (isEnteringPip(info, mCurrentPipTaskToken)) {
+ return startEnterAnimation(info, startTransaction, finishTransaction, finishCallback);
}
- // Show the wallpaper if there is a wallpaper change.
- if (wallpaper != null) {
- startTransaction.show(wallpaper.getLeash());
- startTransaction.setAlpha(wallpaper.getLeash(), 1.f);
- }
-
- mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
- mFinishCallback = finishCallback;
- return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
- startTransaction, finishTransaction, enterPip.getStartRotation(),
- enterPip.getEndRotation());
+ // For transition that we don't animate, we may need to update the PIP surface, otherwise it
+ // will be reset after the transition.
+ updatePipForUnhandledTransition(info, startTransaction, finishTransaction);
+ return false;
}
@Nullable
@@ -272,6 +225,7 @@ public class PipTransition extends PipTransitionController {
new Rect(mExitDestinationBounds));
}
mExitDestinationBounds.setEmpty();
+ mCurrentPipTaskToken = null;
}
@Override
@@ -305,10 +259,13 @@ public class PipTransition extends PipTransitionController {
}
@Nullable
- private TransitionInfo.Change findPipChange(@NonNull TransitionInfo info) {
+ private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) {
+ if (mCurrentPipTaskToken == null) {
+ return null;
+ }
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
- if (change.getTaskInfo() != null && mPipOrganizer.isPipChange(change)) {
+ if (mCurrentPipTaskToken.equals(change.getContainer())) {
return change;
}
}
@@ -449,6 +406,87 @@ public class PipTransition extends PipTransitionController {
.start();
}
+ /** For {@link Transitions#TRANSIT_REMOVE_PIP}, we just immediately remove the PIP Task. */
+ private void removePipImmediately(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback,
+ @NonNull TransitionInfo.Change pipChange) {
+ startTransaction.apply();
+ finishTransaction.setWindowCrop(info.getChanges().get(0).getLeash(),
+ mPipBoundsState.getDisplayBounds());
+ mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
+ finishCallback.onTransitionFinished(null, null);
+ }
+
+ /** Whether we should handle the given {@link TransitionInfo} animation as entering PIP. */
+ private static boolean isEnteringPip(@NonNull TransitionInfo info,
+ @Nullable WindowContainerToken currentPipTaskToken) {
+ 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
+ && !change.getContainer().equals(currentPipTaskToken)) {
+ // We support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps
+ // that enter PiP instantly on opening, mostly from CTS/Flicker tests)
+ if (info.getType() == TRANSIT_PIP || info.getType() == TRANSIT_OPEN) {
+ return true;
+ }
+ // This can happen if the request to enter PIP happens when we are collecting for
+ // another transition, such as TRANSIT_CHANGE (display rotation).
+ if (info.getType() == TRANSIT_CHANGE) {
+ return true;
+ }
+
+ // Please file a bug to handle the unexpected transition type.
+ throw new IllegalStateException("Entering PIP with unexpected transition type="
+ + transitTypeToString(info.getType()));
+ }
+ }
+ return false;
+ }
+
+ private boolean startEnterAnimation(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // Search for an Enter PiP transition (along with a show wallpaper one)
+ TransitionInfo.Change enterPip = null;
+ TransitionInfo.Change wallpaper = null;
+ 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;
+ } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+ wallpaper = change;
+ }
+ }
+ if (enterPip == null) {
+ return false;
+ }
+ // Keep track of the PIP task.
+ mCurrentPipTaskToken = enterPip.getContainer();
+
+ if (mFinishCallback != null) {
+ mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
+ mFinishCallback = null;
+ throw new RuntimeException("Previous callback not called, aborting entering PIP.");
+ }
+
+ // Show the wallpaper if there is a wallpaper change.
+ if (wallpaper != null) {
+ startTransaction.show(wallpaper.getLeash());
+ startTransaction.setAlpha(wallpaper.getLeash(), 1.f);
+ }
+
+ mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
+ mFinishCallback = finishCallback;
+ return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
+ startTransaction, finishTransaction, enterPip.getStartRotation(),
+ enterPip.getEndRotation());
+ }
+
private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
final SurfaceControl.Transaction startTransaction,
final SurfaceControl.Transaction finishTransaction,
@@ -559,6 +597,32 @@ public class PipTransition extends PipTransitionController {
finishCallback.onTransitionFinished(null, null);
}
+ private void updatePipForUnhandledTransition(@NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction) {
+ if (mCurrentPipTaskToken == null) {
+ return;
+ }
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (!mCurrentPipTaskToken.equals(change.getContainer())) {
+ continue;
+ }
+ // When the PIP window is visible and being a part of the transition, such as display
+ // rotation, we need to update its bounds and rounded corner.
+ final SurfaceControl leash = change.getLeash();
+ final Rect destBounds = mPipBoundsState.getBounds();
+ final boolean isInPip = mPipTransitionState.isInPip();
+ mSurfaceTransactionHelper
+ .crop(startTransaction, leash, destBounds)
+ .round(startTransaction, leash, isInPip);
+ mSurfaceTransactionHelper
+ .crop(finishTransaction, leash, destBounds)
+ .round(finishTransaction, leash, isInPip);
+ break;
+ }
+ }
+
private void finishResizeForMenu(Rect destinationBounds) {
mPipMenuController.movePipMenu(null, null, destinationBounds);
mPipMenuController.updateMenuBounds(destinationBounds);