From 3228322d49707dbc494735d5c12e023ec412f5d2 Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Thu, 3 Nov 2022 16:07:29 +0800 Subject: [PATCH] Transfer the animation bounds to another coordinate if needed. For a remote close animation target, because the orientation can be different from launcher, so when launcher applying surface animation to it, there should do another coordinate transfer based on it's coordinate. Also for closing animation, there shouldn't use #getWindowTargetBounds because it only search for opening target. There is no change when launcher's orientation matches animation target. Bug: 254805643 Bug: 298318284 Test: close activity in each oritation, verify the position of remote animaiton target is aligned with the floating view. Change-Id: I7799357695a467f1bfc653e4f058a5e646ea2405 --- .../launcher3/QuickstepTransitionManager.java | 84 ++++++++++++++++++- .../LauncherBackAnimationController.java | 6 +- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index f8ea9320c4..b7e28770c8 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -22,6 +22,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_OPEN; @@ -239,6 +241,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private RemoteAnimationFactory mWallpaperOpenTransitionRunner; private RemoteTransition mLauncherOpenTransition; + private final RemoteAnimationCoordinateTransfer mCoordinateTransfer; + private LauncherBackAnimationController mBackAnimationController; private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() { @Override @@ -287,6 +291,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x); mOpeningInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.emphasized_interpolator); + mCoordinateTransfer = new RemoteAnimationCoordinateTransfer(mLauncher); } @Override @@ -1388,8 +1393,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener targetRect)); // Hook up floating views to the closing window animators. - final int rotationChange = getRotationChange(targets); - Rect windowTargetBounds = getWindowTargetBounds(targets, rotationChange); + // note the coordinate of closingWindowStartRect is based on launcher + Rect windowTargetBounds = new Rect(); + closingWindowStartRect.round(windowTargetBounds); if (floatingIconView != null) { anim.addAnimatorListener(floatingIconView); floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged); @@ -1693,8 +1699,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener RectF windowTargetBounds = new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets))); + + final RectF resolveRectF = new RectF(windowTargetBounds); + for (RemoteAnimationTarget t : appTargets) { + if (t.mode == MODE_CLOSING) { + transferRectToTargetCoordinate( + t, windowTargetBounds, true, resolveRectF); + break; + } + } + Pair pair = createWallpaperOpenAnimations( - appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds, + appTargets, wallpaperTargets, mFromUnlock, resolveRectF, QuickStepContract.getWindowCornerRadius(mLauncher), false /* fromPredictiveBack */); @@ -1935,6 +1951,52 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } + /** + * Transfer the rectangle to another coordinate if needed. + * @param toLauncher which one is the anchor of this transfer, if true then transfer from + * animation target to launcher, false transfer from launcher to animation + * target. + */ + public void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect, + boolean toLauncher, RectF resultRect) { + mCoordinateTransfer.transferRectToTargetCoordinate( + target, currentRect, toLauncher, resultRect); + } + + private static class RemoteAnimationCoordinateTransfer { + private final QuickstepLauncher mLauncher; + private final Rect mDisplayRect = new Rect(); + private final Rect mTmpResult = new Rect(); + + RemoteAnimationCoordinateTransfer(QuickstepLauncher launcher) { + mLauncher = launcher; + } + + void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect, + boolean toLauncher, RectF resultRect) { + final int taskRotation = target.windowConfiguration.getRotation(); + final DeviceProfile profile = mLauncher.getDeviceProfile(); + + final int rotationDelta = toLauncher + ? android.util.RotationUtils.deltaRotation(taskRotation, profile.rotationHint) + : android.util.RotationUtils.deltaRotation(profile.rotationHint, taskRotation); + if (rotationDelta != ROTATION_0) { + // Get original display size when task is on top but with different rotation + if (rotationDelta % 2 != 0 && toLauncher && (profile.rotationHint == ROTATION_0 + || profile.rotationHint == ROTATION_180)) { + mDisplayRect.set(0, 0, profile.heightPx, profile.widthPx); + } else { + mDisplayRect.set(0, 0, profile.widthPx, profile.heightPx); + } + currentRect.round(mTmpResult); + android.util.RotationUtils.rotateBounds(mTmpResult, mDisplayRect, rotationDelta); + resultRect.set(mTmpResult); + } else { + resultRect.set(currentRect); + } + } + } + /** * RectFSpringAnim update listener to be used for app to home animation. */ @@ -1957,6 +2019,20 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mEndRadius = Math.max(1, targetRect.width()) / 2f; mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer); mWindowTargetBounds.set(windowTargetBounds); + + // transfer the coordinate based on animation target. + if (mAppTargets != null) { + for (RemoteAnimationTarget t : mAppTargets) { + if (t.mode == MODE_CLOSING) { + final RectF targetBounds = new RectF(mWindowTargetBounds); + final RectF result = new RectF(); + transferRectToTargetCoordinate( + t, targetBounds, false, result); + result.round(mWindowTargetBounds); + break; + } + } + } } public float getCornerRadius(float progress) { @@ -1977,6 +2053,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } if (target.mode == MODE_CLOSING) { + final RectF before = new RectF(currentRectF); + transferRectToTargetCoordinate(target, currentRectF, false, currentRectF); currentRectF.round(mCurrentRect); // Scale the target window to match the currentRectF. diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 857c83106b..1f8ddf0122 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -404,12 +404,16 @@ public class LauncherBackAnimationController { AbstractFloatingView.closeAllOpenViewsExcept(mLauncher, false, TYPE_REBIND_SAFE); float cornerRadius = Utilities.mapRange( mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius); + final RectF resolveRectF = new RectF(); + mQuickstepTransitionManager.transferRectToTargetCoordinate( + mBackTarget, mCurrentRect, true, resolveRectF); + Pair pair = mQuickstepTransitionManager.createWallpaperOpenAnimations( new RemoteAnimationTarget[]{mBackTarget}, new RemoteAnimationTarget[0], false /* fromUnlock */, - mCurrentRect, + resolveRectF, cornerRadius, mBackInProgress /* fromPredictiveBack */); startTransitionAnimations(pair.first, pair.second);