From 509eb388cc185305abd9b878f62401daa6f53b38 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 14 Jan 2022 19:09:55 +0800 Subject: [PATCH] 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 --- .../android/wm/shell/pip/PipTransition.java | 4 +-- .../transition/CounterRotatorHelper.java | 29 ++++++++++++++-- .../transition/DefaultTransitionHandler.java | 34 +++++++++---------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index 69e78364c5e16..3e5d5f6457259 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -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()); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java index 8c71f749b2c36..19133e29de4bc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java @@ -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 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 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; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 5054e60d09f88..13e81bdb3c0b4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -124,6 +124,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { /** Keeps track of the currently-running animations associated with each transition. */ private final ArrayMap> 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 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);