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. // destination are different.
final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH; final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH;
final Rect crop = mTmpDestinationRect; final Rect crop = mTmpDestinationRect;
crop.set(0, 0, Transitions.ENABLE_SHELL_TRANSITIONS ? destH crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH
: destW, Transitions.ENABLE_SHELL_TRANSITIONS ? destW : destH); : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH);
// Inverse scale for crop to fit in screen coordinates. // Inverse scale for crop to fit in screen coordinates.
crop.scale(1 / scale); crop.scale(1 / scale);
crop.offset(insets.left, insets.top); crop.offset(insets.left, insets.top);

View File

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

View File

@@ -30,6 +30,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.IApplicationThread; import android.app.IApplicationThread;
import android.app.WindowConfiguration;
import android.os.IBinder; import android.os.IBinder;
import android.os.IRemoteCallback; import android.os.IRemoteCallback;
import android.os.RemoteException; import android.os.RemoteException;
@@ -296,6 +297,17 @@ class TransitionController {
return ci.mVisible; 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 @WindowManager.TransitionType
int getCollectingTransitionType() { int getCollectingTransitionType() {
return mCollectingTransition != null ? mCollectingTransition.mType : TRANSIT_NONE; return mCollectingTransition != null ? mCollectingTransition.mType : TRANSIT_NONE;

View File

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