Use animation end bounds in previous rotation for closing

The surface of closing change will be put in a rotated surface
in previous rotation, so the animation bounds also need to be
in same rotation.

Bug: 214504681
Test: adb shell setprop persist.debug.shell_transit 1; reboot
      Launch a landscape activity, and it launches a portrait
      activity in new task. The animation should not be cropped.
Change-Id: I680e335786beedc1cac8847cbc9db5fc1bb11807
This commit is contained in:
Riddle Hsu
2022-01-14 19:09:55 +08:00
parent a895201d05
commit 509eb388cc
3 changed files with 45 additions and 22 deletions

View File

@@ -330,12 +330,10 @@ public class PipTransition extends PipTransitionController {
@NonNull TransitionInfo.Change pipChange) {
final int rotateDelta = deltaRotation(displayRotationChange.getStartRotation(),
displayRotationChange.getEndRotation());
final int displayW = displayRotationChange.getEndAbsBounds().width();
final int displayH = displayRotationChange.getEndAbsBounds().height();
// Counter-rotate all "going-away" things since they are still in the old orientation.
final CounterRotatorHelper rotator = new CounterRotatorHelper();
rotator.handleClosingChanges(info, startTransaction, rotateDelta, displayW, displayH);
rotator.handleClosingChanges(info, startTransaction, displayRotationChange);
mFinishCallback = (wct, wctCB) -> {
mPipOrganizer.onExitPipFinished(pipChange.getTaskInfo());

View File

@@ -18,7 +18,9 @@ package com.android.wm.shell.transition;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.RotationUtils;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
@@ -35,11 +37,21 @@ import java.util.List;
*/
public class CounterRotatorHelper {
private final ArrayMap<WindowContainerToken, CounterRotator> mRotatorMap = new ArrayMap<>();
private final Rect mLastDisplayBounds = new Rect();
private int mLastRotationDelta;
/** Puts the surface controls of closing changes to counter-rotated surfaces. */
public void handleClosingChanges(@NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
int rotateDelta, int displayW, int displayH) {
@NonNull TransitionInfo.Change displayRotationChange) {
final int rotationDelta = RotationUtils.deltaRotation(
displayRotationChange.getStartRotation(), displayRotationChange.getEndRotation());
final Rect displayBounds = displayRotationChange.getEndAbsBounds();
final int displayW = displayBounds.width();
final int displayH = displayBounds.height();
mLastRotationDelta = rotationDelta;
mLastDisplayBounds.set(displayBounds);
final List<TransitionInfo.Change> changes = info.getChanges();
final int numChanges = changes.size();
for (int i = numChanges - 1; i >= 0; --i) {
@@ -53,7 +65,7 @@ public class CounterRotatorHelper {
CounterRotator crot = mRotatorMap.get(parent);
if (crot == null) {
crot = new CounterRotator();
crot.setup(startTransaction, info.getChange(parent).getLeash(), rotateDelta,
crot.setup(startTransaction, info.getChange(parent).getLeash(), rotationDelta,
displayW, displayH);
final SurfaceControl rotatorSc = crot.getSurface();
if (rotatorSc != null) {
@@ -69,6 +81,18 @@ public class CounterRotatorHelper {
}
}
/**
* Returns the rotated end bounds if the change is put in previous rotation. Otherwise the
* original end bounds are returned.
*/
@NonNull
public Rect getEndBoundsInStartRotation(@NonNull TransitionInfo.Change change) {
if (mLastRotationDelta == 0) return change.getEndAbsBounds();
final Rect rotatedBounds = new Rect(change.getEndAbsBounds());
RotationUtils.rotateBounds(rotatedBounds, mLastDisplayBounds, mLastRotationDelta);
return rotatedBounds;
}
/**
* Removes the counter rotation surface in the finish transaction. No need to reparent the
* children as the finish transaction should have already taken care of that.
@@ -80,5 +104,6 @@ public class CounterRotatorHelper {
mRotatorMap.valueAt(i).cleanUp(finishTransaction);
}
mRotatorMap.clear();
mLastRotationDelta = 0;
}
}

View File

@@ -124,6 +124,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
/** Keeps track of the currently-running animations associated with each transition. */
private final ArrayMap<IBinder, ArrayList<Animator>> mAnimations = new ArrayMap<>();
private final CounterRotatorHelper mRotator = new CounterRotatorHelper();
private final Rect mInsets = new Rect(0, 0, 0, 0);
private float mTransitionAnimationScaleSetting = 1.0f;
@@ -277,8 +278,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final ArrayList<Animator> animations = new ArrayList<>();
mAnimations.put(transition, animations);
final CounterRotatorHelper rotator = new CounterRotatorHelper();
final Runnable onAnimFinish = () -> {
if (!animations.isEmpty()) return;
@@ -298,9 +297,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final boolean isTask = change.getTaskInfo() != null;
if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
int rotateDelta = change.getEndRotation() - change.getStartRotation();
int displayW = change.getEndAbsBounds().width();
int displayH = change.getEndAbsBounds().height();
if (info.getType() == TRANSIT_CHANGE) {
boolean isSeamless = isRotationSeamless(info, mDisplayController);
final int anim = getRotationAnimation(info);
@@ -314,8 +310,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
} else {
// Opening/closing an app into a new orientation.
rotator.handleClosingChanges(info, startTransaction, rotateDelta,
displayW, displayH);
mRotator.handleClosingChanges(info, startTransaction, change);
}
}
@@ -384,9 +379,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
}
final Rect clipRect = Transitions.isClosingType(change.getMode())
? mRotator.getEndBoundsInStartRotation(change)
: change.getEndAbsBounds();
startSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
mTransactionPool, mMainExecutor, mAnimExecutor, null /* position */,
cornerRadius, change.getEndAbsBounds());
cornerRadius, clipRect);
if (info.getAnimationOptions() != null) {
attachThumbnail(animations, onAnimFinish, change, info.getAnimationOptions(),
@@ -401,7 +399,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
startTransaction.apply();
rotator.cleanUp(finishTransaction);
mRotator.cleanUp(finishTransaction);
TransitionMetrics.getInstance().reportAnimationStart(transition);
// run finish now in-case there are no animations
onAnimFinish.run();
@@ -458,6 +456,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
final int overrideType = options != null ? options.getType() : ANIM_NONE;
final boolean canCustomContainer = isTask ? !sDisableCustomTaskAnimationProperty : true;
final Rect endBounds = Transitions.isClosingType(changeMode)
? mRotator.getEndBoundsInStartRotation(change)
: change.getEndAbsBounds();
if (info.isKeyguardGoingAway()) {
a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
@@ -475,8 +476,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a = new AlphaAnimation(1.f, 1.f);
a.setDuration(TransitionAnimation.DEFAULT_APP_TRANSITION_DURATION);
} else if (type == TRANSIT_RELAUNCH) {
a = mTransitionAnimation.createRelaunchAnimation(
change.getEndAbsBounds(), mInsets, change.getEndAbsBounds());
a = mTransitionAnimation.createRelaunchAnimation(endBounds, mInsets, endBounds);
} else if (overrideType == ANIM_CUSTOM
&& (canCustomContainer || options.getOverrideTaskTransition())) {
a = mTransitionAnimation.loadAnimationRes(options.getPackageName(), enter
@@ -485,16 +485,15 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a = mTransitionAnimation.loadCrossProfileAppEnterAnimation();
} else if (overrideType == ANIM_CLIP_REVEAL) {
a = mTransitionAnimation.createClipRevealAnimationLocked(type, wallpaperTransit, enter,
change.getEndAbsBounds(), change.getEndAbsBounds(),
options.getTransitionBounds());
endBounds, endBounds, options.getTransitionBounds());
} else if (overrideType == ANIM_SCALE_UP) {
a = mTransitionAnimation.createScaleUpAnimationLocked(type, wallpaperTransit, enter,
change.getEndAbsBounds(), options.getTransitionBounds());
endBounds, options.getTransitionBounds());
} else if (overrideType == ANIM_THUMBNAIL_SCALE_UP
|| overrideType == ANIM_THUMBNAIL_SCALE_DOWN) {
final boolean scaleUp = overrideType == ANIM_THUMBNAIL_SCALE_UP;
a = mTransitionAnimation.createThumbnailEnterExitAnimationLocked(enter, scaleUp,
change.getEndAbsBounds(), type, wallpaperTransit, options.getThumbnail(),
endBounds, type, wallpaperTransit, options.getThumbnail(),
options.getTransitionBounds());
} else if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0 && isOpeningType) {
// This received a transferred starting window, so don't animate
@@ -567,8 +566,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
if (a != null) {
if (!a.isInitialized()) {
Rect end = change.getEndAbsBounds();
a.initialize(end.width(), end.height(), end.width(), end.height());
final int width = endBounds.width();
final int height = endBounds.height();
a.initialize(width, height, width, height);
}
a.restrictDuration(MAX_ANIMATION_DURATION);
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);