Merge "Exit PIP with fixed rotation with Shell transition" into tm-dev

This commit is contained in:
Chris Li
2022-02-23 01:52:19 +00:00
committed by Android (Google) Code Review
4 changed files with 92 additions and 67 deletions

View File

@@ -138,8 +138,8 @@ public class PipSurfaceTransactionHelper {
// destination are different.
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
final Rect crop = mTmpDestinationRect;
crop.set(0, 0, Transitions.ENABLE_SHELL_TRANSITIONS ? destH
: destW, Transitions.ENABLE_SHELL_TRANSITIONS ? destW : destH);
crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH
: destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH);
// Inverse scale for crop to fit in screen coordinates.
crop.scale(1 / scale);
crop.offset(insets.left, insets.top);

View File

@@ -97,7 +97,7 @@ public class PipTransition extends PipTransitionController {
* meaningful if {@link #mInFixedRotation} is true.
*/
@Surface.Rotation
private int mFixedRotation;
private int mEndFixedRotation;
/** Whether the PIP window has fade out for fixed rotation. */
private boolean mHasFadeOut;
@@ -153,7 +153,7 @@ public class PipTransition extends PipTransitionController {
final TransitionInfo.Change currentPipChange = findCurrentPipChange(info);
final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
mInFixedRotation = fixedRotationChange != null;
mFixedRotation = mInFixedRotation
mEndFixedRotation = mInFixedRotation
? fixedRotationChange.getEndFixedRotation()
: ROTATION_UNDEFINED;
@@ -257,7 +257,7 @@ public class PipTransition extends PipTransitionController {
final ActivityManager.RunningTaskInfo taskInfo = mPipOrganizer.getTaskInfo();
if (taskInfo != null) {
startExpandAnimation(taskInfo, mPipOrganizer.getSurfaceControl(),
new Rect(mExitDestinationBounds));
new Rect(mExitDestinationBounds), Surface.ROTATION_0);
}
mExitDestinationBounds.setEmpty();
mCurrentPipTaskToken = null;
@@ -332,30 +332,31 @@ public class PipTransition extends PipTransitionController {
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull TransitionInfo.Change pipChange) {
TransitionInfo.Change displayRotationChange = null;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getMode() == TRANSIT_CHANGE
&& (change.getFlags() & FLAG_IS_DISPLAY) != 0
&& change.getStartRotation() != change.getEndRotation()) {
displayRotationChange = change;
break;
}
}
if (displayRotationChange != null) {
// Exiting PIP to fullscreen with orientation change.
startExpandAndRotationAnimation(info, startTransaction, finishTransaction,
finishCallback, displayRotationChange, pipChange);
return;
}
// When there is no rotation, we can simply expand the PIP window.
mFinishCallback = (wct, wctCB) -> {
mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
finishCallback.onTransitionFinished(wct, wctCB);
};
// Check if it is Shell rotation.
if (Transitions.SHELL_TRANSITIONS_ROTATION) {
TransitionInfo.Change displayRotationChange = null;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (change.getMode() == TRANSIT_CHANGE
&& (change.getFlags() & FLAG_IS_DISPLAY) != 0
&& change.getStartRotation() != change.getEndRotation()) {
displayRotationChange = change;
break;
}
}
if (displayRotationChange != null) {
// Exiting PIP to fullscreen with orientation change.
startExpandAndRotationAnimation(info, startTransaction, finishTransaction,
displayRotationChange, pipChange);
return;
}
}
// Set the initial frame as scaling the end to the start.
final Rect destinationBounds = new Rect(pipChange.getEndAbsBounds());
final Point offset = pipChange.getEndRelOffset();
@@ -364,13 +365,41 @@ public class PipTransition extends PipTransitionController {
mSurfaceTransactionHelper.scale(startTransaction, pipChange.getLeash(),
destinationBounds, mPipBoundsState.getBounds());
startTransaction.apply();
startExpandAnimation(pipChange.getTaskInfo(), pipChange.getLeash(), destinationBounds);
// Check if it is fixed rotation.
final int rotationDelta;
if (mInFixedRotation) {
final int startRotation = pipChange.getStartRotation();
final int endRotation = mEndFixedRotation;
rotationDelta = deltaRotation(startRotation, endRotation);
final Rect endBounds = new Rect(destinationBounds);
// Set the end frame since the display won't rotate until fixed rotation is finished
// in the next display change transition.
rotateBounds(endBounds, destinationBounds, rotationDelta);
final int degree, x, y;
if (rotationDelta == ROTATION_90) {
degree = 90;
x = destinationBounds.right;
y = destinationBounds.top;
} else {
degree = -90;
x = destinationBounds.left;
y = destinationBounds.bottom;
}
mSurfaceTransactionHelper.rotateAndScaleWithCrop(finishTransaction,
pipChange.getLeash(), endBounds, endBounds, new Rect(), degree, x, y,
true /* isExpanding */, rotationDelta == ROTATION_270 /* clockwise */);
} else {
rotationDelta = Surface.ROTATION_0;
}
startExpandAnimation(pipChange.getTaskInfo(), pipChange.getLeash(), destinationBounds,
rotationDelta);
}
private void startExpandAndRotationAnimation(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback,
@NonNull TransitionInfo.Change displayRotationChange,
@NonNull TransitionInfo.Change pipChange) {
final int rotateDelta = deltaRotation(displayRotationChange.getStartRotation(),
@@ -380,11 +409,6 @@ public class PipTransition extends PipTransitionController {
final CounterRotatorHelper rotator = new CounterRotatorHelper();
rotator.handleClosingChanges(info, startTransaction, displayRotationChange);
mFinishCallback = (wct, wctCB) -> {
mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());
finishCallback.onTransitionFinished(wct, wctCB);
};
// Get the start bounds in new orientation.
final Rect startBounds = new Rect(pipChange.getStartAbsBounds());
rotateBounds(startBounds, displayRotationChange.getStartAbsBounds(), rotateDelta);
@@ -425,12 +449,11 @@ public class PipTransition extends PipTransitionController {
}
private void startExpandAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
final Rect destinationBounds) {
PipAnimationController.PipTransitionAnimator animator =
final Rect destinationBounds, final int rotationDelta) {
final PipAnimationController.PipTransitionAnimator animator =
mPipAnimationController.getAnimator(taskInfo, leash, mPipBoundsState.getBounds(),
mPipBoundsState.getBounds(), destinationBounds, null,
TRANSITION_DIRECTION_LEAVE_PIP, 0 /* startingAngle */, Surface.ROTATION_0);
TRANSITION_DIRECTION_LEAVE_PIP, 0 /* startingAngle */, rotationDelta);
animator.setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP)
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(mEnterExitAnimationDuration)
@@ -526,7 +549,7 @@ public class PipTransition extends PipTransitionController {
mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
mFinishCallback = finishCallback;
final int endRotation = mInFixedRotation ? mFixedRotation : enterPip.getEndRotation();
final int endRotation = mInFixedRotation ? mEndFixedRotation : enterPip.getEndRotation();
return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
startTransaction, finishTransaction, enterPip.getStartRotation(),
endRotation);
@@ -545,8 +568,8 @@ public class PipTransition extends PipTransitionController {
taskInfo.pictureInPictureParams, currentBounds);
if (rotationDelta != Surface.ROTATION_0 && mInFixedRotation) {
// Need to get the bounds of new rotation in old rotation for fixed rotation,
sourceHintRect = computeRotatedBounds(rotationDelta, startRotation, endRotation,
taskInfo, TRANSITION_DIRECTION_TO_PIP, destinationBounds, sourceHintRect);
computeEnterPipRotatedBounds(rotationDelta, startRotation, endRotation, taskInfo,
destinationBounds, sourceHintRect);
}
PipAnimationController.PipTransitionAnimator animator;
// Set corner radius for entering pip.
@@ -583,8 +606,6 @@ public class PipTransition extends PipTransitionController {
startTransaction.setMatrix(leash, tmpTransform, new float[9]);
}
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
// Reverse the rotation for Shell transition animation.
rotationDelta = deltaRotation(rotationDelta, 0);
animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
0 /* startingAngle */, rotationDelta);
@@ -617,33 +638,22 @@ public class PipTransition extends PipTransitionController {
return true;
}
/** Computes destination bounds in old rotation and returns source hint rect if available. */
@Nullable
private Rect computeRotatedBounds(int rotationDelta, int startRotation, int endRotation,
TaskInfo taskInfo, int direction, Rect outDestinationBounds,
@Nullable Rect sourceHintRect) {
if (direction == TRANSITION_DIRECTION_TO_PIP) {
mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
final Rect displayBounds = mPipBoundsState.getDisplayBounds();
outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
// Transform the destination bounds to current display coordinates.
rotateBounds(outDestinationBounds, displayBounds, endRotation, startRotation);
// When entering PiP (from button navigation mode), adjust the source rect hint by
// display cutout if applicable.
if (sourceHintRect != null && taskInfo.displayCutoutInsets != null) {
if (rotationDelta == Surface.ROTATION_270) {
sourceHintRect.offset(taskInfo.displayCutoutInsets.left,
taskInfo.displayCutoutInsets.top);
}
/** Computes destination bounds in old rotation and updates source hint rect if available. */
private void computeEnterPipRotatedBounds(int rotationDelta, int startRotation, int endRotation,
TaskInfo taskInfo, Rect outDestinationBounds, @Nullable Rect outSourceHintRect) {
mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
final Rect displayBounds = mPipBoundsState.getDisplayBounds();
outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
// Transform the destination bounds to current display coordinates.
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) {
if (rotationDelta == Surface.ROTATION_270) {
outSourceHintRect.offset(taskInfo.displayCutoutInsets.left,
taskInfo.displayCutoutInsets.top);
}
} else if (direction == TRANSITION_DIRECTION_LEAVE_PIP) {
final Rect rotatedDestinationBounds = new Rect(outDestinationBounds);
rotateBounds(rotatedDestinationBounds, mPipBoundsState.getDisplayBounds(),
rotationDelta);
return PipBoundsAlgorithm.getValidSourceHintRect(taskInfo.pictureInPictureParams,
rotatedDestinationBounds);
}
return sourceHintRect;
}
private void startExitToSplitAnimation(TransitionInfo info,

View File

@@ -30,6 +30,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IApplicationThread;
import android.app.WindowConfiguration;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
@@ -296,6 +297,17 @@ class TransitionController {
return ci.mVisible;
}
@WindowConfiguration.WindowingMode
int getWindowingModeAtStart(@NonNull WindowContainer wc) {
if (mCollectingTransition == null) return wc.getWindowingMode();
final Transition.ChangeInfo ci = mCollectingTransition.mChanges.get(wc);
if (ci == null) {
// not part of transition, so use current state.
return wc.getWindowingMode();
}
return ci.mWindowingMode;
}
@WindowManager.TransitionType
int getCollectingTransitionType() {
return mCollectingTransition != null ? mCollectingTransition.mType : TRANSIT_NONE;

View File

@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -645,8 +646,10 @@ class WindowToken extends WindowContainer<WindowState> {
final ActivityRecord r = asActivityRecord();
if (r != null) {
final Task rootTask = r.getRootTask();
// Don't transform the activity in PiP because the PiP task organizer will handle it.
if (rootTask != null && rootTask.inPinnedWindowingMode()) {
// Don't transform the activity exiting PiP because the PiP task organizer will handle
// it.
if (rootTask != null && mTransitionController.getWindowingModeAtStart(rootTask)
== WINDOWING_MODE_PINNED) {
return;
}
}