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);