Animate PiP with considering next rotation
- Make sure that fixed rotation state is set in
PipTransition#startEnterAnimation according to the change info.
- Call setEndFixedRotation if the display rotation will be changed
by a different task.
Also remove a dead code in handleSwipePipToHomeTransition which
was fixed by commit 19da8ae.
Bug: 285089607
Test: Case 1: Click notification which starts an activity in
a different orientation with remote animation
and make the pausing app enter PiP at the same time.
Case 2: A task contain 2 activities, its top activity enters
PiP in a new task from landscape. And the next activity
in the task is portrait.
Change-Id: Ibcf2bb90a0abd0c100d48aa27f1b7ab93e8d78ec
This commit is contained in:
@@ -816,6 +816,12 @@ public class PipTransition extends PipTransitionController {
|
||||
final ActivityManager.RunningTaskInfo taskInfo = pipChange.getTaskInfo();
|
||||
final SurfaceControl leash = pipChange.getLeash();
|
||||
final int startRotation = pipChange.getStartRotation();
|
||||
// Check again in case some callers use startEnterAnimation directly so the flag was not
|
||||
// set in startAnimation, e.g. from DefaultMixedHandler.
|
||||
if (!mInFixedRotation) {
|
||||
mEndFixedRotation = pipChange.getEndFixedRotation();
|
||||
mInFixedRotation = mEndFixedRotation != ROTATION_UNDEFINED;
|
||||
}
|
||||
final int endRotation = mInFixedRotation ? mEndFixedRotation : pipChange.getEndRotation();
|
||||
|
||||
setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,
|
||||
@@ -844,7 +850,7 @@ public class PipTransition extends PipTransitionController {
|
||||
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
|
||||
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
|
||||
handleSwipePipToHomeTransition(startTransaction, finishTransaction, leash,
|
||||
sourceHintRect, destinationBounds, rotationDelta, taskInfo);
|
||||
sourceHintRect, destinationBounds, taskInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -935,8 +941,15 @@ public class PipTransition extends PipTransitionController {
|
||||
@NonNull SurfaceControl.Transaction startTransaction,
|
||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||
@NonNull SurfaceControl leash, @Nullable Rect sourceHintRect,
|
||||
@NonNull Rect destinationBounds, int rotationDelta,
|
||||
@NonNull Rect destinationBounds,
|
||||
@NonNull ActivityManager.RunningTaskInfo pipTaskInfo) {
|
||||
if (mInFixedRotation) {
|
||||
// If rotation changes when returning to home, the transition should contain both the
|
||||
// entering PiP and the display change (PipController#startSwipePipToHome has updated
|
||||
// the display layout to new rotation). So it is not expected to see fixed rotation.
|
||||
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||
"%s: SwipePipToHome should not use fixed rotation %d", TAG, mEndFixedRotation);
|
||||
}
|
||||
final SurfaceControl swipePipToHomeOverlay = mPipOrganizer.mSwipePipToHomeOverlay;
|
||||
if (swipePipToHomeOverlay != null) {
|
||||
// Launcher fade in the overlay on top of the fullscreen Task. It is possible we
|
||||
@@ -947,12 +960,7 @@ public class PipTransition extends PipTransitionController {
|
||||
mPipOrganizer.mSwipePipToHomeOverlay = null;
|
||||
}
|
||||
|
||||
Rect sourceBounds = pipTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
if (!Transitions.SHELL_TRANSITIONS_ROTATION && rotationDelta % 2 == 1) {
|
||||
// PipController#startSwipePipToHome has updated the display layout to new rotation,
|
||||
// so flip the source bounds to match the same orientation.
|
||||
sourceBounds = new Rect(0, 0, sourceBounds.height(), sourceBounds.width());
|
||||
}
|
||||
final Rect sourceBounds = pipTaskInfo.configuration.windowConfiguration.getBounds();
|
||||
final PipAnimationController.PipTransitionAnimator animator =
|
||||
mPipAnimationController.getAnimator(pipTaskInfo, leash, sourceBounds, sourceBounds,
|
||||
destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
|
||||
|
||||
@@ -2317,23 +2317,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
task.fillTaskInfo(tinfo);
|
||||
change.setTaskInfo(tinfo);
|
||||
change.setRotationAnimation(getTaskRotationAnimation(task));
|
||||
final ActivityRecord topMostActivity = task.getTopMostActivity();
|
||||
change.setAllowEnterPip(topMostActivity != null
|
||||
&& topMostActivity.checkEnterPictureInPictureAppOpsState());
|
||||
final ActivityRecord topRunningActivity = task.topRunningActivity();
|
||||
if (topRunningActivity != null && task.mDisplayContent != null
|
||||
// Display won't be rotated for multi window Task, so the fixed rotation
|
||||
// won't be applied. This can happen when the windowing mode is changed
|
||||
// before the previous fixed rotation is applied.
|
||||
&& (!task.inMultiWindowMode() || !topRunningActivity.inMultiWindowMode())) {
|
||||
// If Activity is in fixed rotation, its will be applied with the next rotation,
|
||||
// when the Task is still in the previous rotation.
|
||||
final int taskRotation = task.getWindowConfiguration().getDisplayRotation();
|
||||
final int activityRotation = topRunningActivity.getWindowConfiguration()
|
||||
.getDisplayRotation();
|
||||
if (taskRotation != activityRotation) {
|
||||
change.setEndFixedRotation(activityRotation);
|
||||
if (topRunningActivity != null) {
|
||||
if (topRunningActivity.info.supportsPictureInPicture()) {
|
||||
change.setAllowEnterPip(
|
||||
topRunningActivity.checkEnterPictureInPictureAppOpsState());
|
||||
}
|
||||
setEndFixedRotationIfNeeded(change, task, topRunningActivity);
|
||||
}
|
||||
} else if ((info.mFlags & ChangeInfo.FLAG_SEAMLESS_ROTATION) != 0) {
|
||||
change.setRotationAnimation(ROTATION_ANIMATION_SEAMLESS);
|
||||
@@ -2441,6 +2431,48 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
}
|
||||
return animOptions;
|
||||
}
|
||||
|
||||
private static void setEndFixedRotationIfNeeded(@NonNull TransitionInfo.Change change,
|
||||
@NonNull Task task, @NonNull ActivityRecord taskTopRunning) {
|
||||
if (!taskTopRunning.isVisibleRequested()) {
|
||||
// Fixed rotation only applies to opening or changing activity.
|
||||
return;
|
||||
}
|
||||
if (task.inMultiWindowMode() && taskTopRunning.inMultiWindowMode()) {
|
||||
// Display won't be rotated for multi window Task, so the fixed rotation won't be
|
||||
// applied. This can happen when the windowing mode is changed before the previous
|
||||
// fixed rotation is applied. Check both task and activity because the activity keeps
|
||||
// fullscreen mode when the task is entering PiP.
|
||||
return;
|
||||
}
|
||||
final int taskRotation = task.getWindowConfiguration().getDisplayRotation();
|
||||
final int activityRotation = taskTopRunning.getWindowConfiguration()
|
||||
.getDisplayRotation();
|
||||
// If the Activity uses fixed rotation, its rotation will be applied to display after
|
||||
// the current transition is done, while the Task is still in the previous rotation.
|
||||
if (taskRotation != activityRotation) {
|
||||
change.setEndFixedRotation(activityRotation);
|
||||
return;
|
||||
}
|
||||
|
||||
// For example, the task is entering PiP so it no longer decides orientation. If the next
|
||||
// orientation source (it could be an activity which was behind the PiP or launching to top)
|
||||
// will change display rotation, then set the fixed rotation hint as well so the animation
|
||||
// can consider the rotated position.
|
||||
if (!task.inPinnedWindowingMode() || taskTopRunning.mDisplayContent.inTransition()) {
|
||||
return;
|
||||
}
|
||||
final WindowContainer<?> orientationSource =
|
||||
taskTopRunning.mDisplayContent.getLastOrientationSource();
|
||||
if (orientationSource == null) {
|
||||
return;
|
||||
}
|
||||
final int nextRotation = orientationSource.getWindowConfiguration().getDisplayRotation();
|
||||
if (taskRotation != nextRotation) {
|
||||
change.setEndFixedRotation(nextRotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the top-most common ancestor of app targets.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user