Merge "Enter PIP when exiting prev PIP with Shell transition"
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user