Merge "Enter PIP when exiting prev PIP with Shell transition"

This commit is contained in:
Chris Li
2022-01-07 13:46:22 +00:00
committed by Android (Google) Code Review
2 changed files with 61 additions and 31 deletions

View File

@@ -173,14 +173,25 @@ public class PipTransition extends PipTransitionController {
return true;
}
// The previous PIP Task is no longer in PIP, but this is not an exit transition (This can
// happen when a new activity requests enter PIP). In this case, we just show this Task in
// its end state, and play other animation as normal.
final TransitionInfo.Change currentPipChange = findCurrentPipChange(info);
if (currentPipChange != null
&& currentPipChange.getTaskInfo().getWindowingMode() != WINDOWING_MODE_PINNED) {
resetPrevPip(currentPipChange, startTransaction);
}
// Entering PIP.
if (isEnteringPip(info, mCurrentPipTaskToken)) {
return startEnterAnimation(info, startTransaction, finishTransaction, finishCallback);
}
// 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);
// For transition that we don't animate, but contains the PIP leash, we need to update the
// PIP surface, otherwise it will be reset after the transition.
if (currentPipChange != null) {
updatePipForUnhandledTransition(currentPipChange, startTransaction, finishTransaction);
}
return false;
}
@@ -571,30 +582,36 @@ public class PipTransition extends PipTransitionController {
finishCallback.onTransitionFinished(null, null);
}
private void updatePipForUnhandledTransition(@NonNull TransitionInfo info,
private void resetPrevPip(@NonNull TransitionInfo.Change prevPipChange,
@NonNull SurfaceControl.Transaction startTransaction) {
final SurfaceControl leash = prevPipChange.getLeash();
final Rect bounds = prevPipChange.getEndAbsBounds();
final Point offset = prevPipChange.getEndRelOffset();
bounds.offset(-offset.x, -offset.y);
startTransaction.setWindowCrop(leash, null);
startTransaction.setMatrix(leash, 1, 0, 0, 1);
startTransaction.setCornerRadius(leash, 0);
startTransaction.setPosition(leash, bounds.left, bounds.top);
mCurrentPipTaskToken = null;
mPipOrganizer.onExitPipFinished(prevPipChange.getTaskInfo());
}
private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
@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;
}
// 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 = pipChange.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);
}
private void finishResizeForMenu(Rect destinationBounds) {

View File

@@ -2051,19 +2051,25 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
try {
final Task task = r.getTask();
final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask();
// This will change the root pinned task's windowing mode to its original mode, ensuring
// we only have one root task that is in pinned mode.
// If the activity in current PIP task needs to be moved back to the parent Task of next
// PIP activity, we can't use that parent Task as the next PIP Task.
// Because we need to start the Shell transition from the root Task, we delay to dismiss
// the current PIP task until root Task is ready.
boolean origPipWillBeMovedToTask = false;
final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask();
if (rootPinnedTask != null) {
rootPinnedTask.dismissPip();
final ActivityRecord topPipActivity = rootPinnedTask.getTopMostActivity();
if (topPipActivity != null && topPipActivity.getLastParentBeforePip() == task) {
origPipWillBeMovedToTask = true;
}
}
// Set a transition to ensure that we don't immediately try and update the visibility
// of the activity entering PIP
r.getDisplayContent().prepareAppTransition(TRANSIT_NONE);
final boolean singleActivity = task.getChildCount() == 1;
final boolean singleActivity = task.getChildCount() == 1 && !origPipWillBeMovedToTask;
final Task rootTask;
if (singleActivity) {
rootTask = task;
@@ -2117,7 +2123,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final ActivityRecord oldTopActivity = task.getTopMostActivity();
if (oldTopActivity != null && oldTopActivity.isState(STOPPED)
&& task.getDisplayContent().mAppTransition.containsTransitRequest(
TRANSIT_TO_BACK)) {
TRANSIT_TO_BACK) && !origPipWillBeMovedToTask) {
task.getDisplayContent().mClosingApps.add(oldTopActivity);
oldTopActivity.mRequestForceTransition = true;
}
@@ -2133,6 +2139,13 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
rootTask.mTransitionController.requestTransitionIfNeeded(TRANSIT_PIP, rootTask);
// This will change the root pinned task's windowing mode to its original mode, ensuring
// we only have one root task that is in pinned mode.
if (rootPinnedTask != null) {
rootTask.mTransitionController.collect(rootPinnedTask);
rootPinnedTask.dismissPip();
}
// Defer the windowing mode change until after the transition to prevent the activity
// from doing work and changing the activity visuals while animating
// TODO(task-org): Figure-out more structured way to do this long term.