diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index e77d2c6e01..d6ab54e039 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -239,7 +239,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener || Global.getFloat(mLauncher.getContentResolver(), Global.TRANSITION_ANIMATION_SCALE, 1f) > 0; } - };; + }; private DeviceProfile mDeviceProfile; @@ -329,7 +329,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener ItemInfo tag = (ItemInfo) v.getTag(); if (tag != null && tag.shouldUseBackgroundAnimation()) { ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from( - v, mLauncher, mStartingWindowListener, onEndCallback); + v, mLauncher, mStartingWindowListener, onEndCallback); if (containerAnimationRunner != null) { mAppLaunchRunner = containerAnimationRunner; } @@ -491,9 +491,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Content is everything on screen except the background and the floating view (if any). * - * @param isAppOpening True when this is called when an app is opening. - * False when this is called when an app is closing. - * @param startDelay Start delay duration. + * @param isAppOpening True when this is called when an app is opening. + * False when this is called when an app is closing. + * @param startDelay Start delay duration. * @param skipAllAppsScale True if we want to avoid scaling All Apps */ private Pair getLauncherContentAnimator(boolean isAppOpening, @@ -1060,7 +1060,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener LaunchDepthController depthController = new LaunchDepthController(mLauncher); ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController.stateDepth, MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher)) - .setDuration(APP_LAUNCH_DURATION); + .setDuration(APP_LAUNCH_DURATION); if (allowBlurringLauncher) { // Create a temporary effect layer, that lives on top of launcher, so we can apply @@ -1309,7 +1309,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return null; } - final ComponentName[] taskInfoActivities = new ComponentName[] { + final ComponentName[] taskInfoActivities = new ComponentName[]{ runningTaskTarget.taskInfo.baseActivity, runningTaskTarget.taskInfo.origActivity, runningTaskTarget.taskInfo.realActivity, @@ -1355,7 +1355,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener .getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx); float secondaryDimension = orientationHandler .getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx); - final float targetX = primaryDimension / 2f; + final float targetX = primaryDimension / 2f; final float targetY = secondaryDimension - dp.hotseatBarSizePx; return new RectF(targetX - halfIconSize, targetY - halfIconSize, targetX + halfIconSize, targetY + halfIconSize); @@ -1366,7 +1366,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener */ protected RectFSpringAnim getClosingWindowAnimators(AnimatorSet animation, RemoteAnimationTarget[] targets, View launcherView, PointF velocityPxPerS, - RectF closingWindowStartRect, float startWindowCornerRadius) { + RectF closingWindowStartRectF, float startWindowCornerRadius) { FloatingIconView floatingIconView = null; FloatingWidgetView floatingWidget = null; RectF targetRect = new RectF(); @@ -1406,14 +1406,16 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean useTaskbarHotseatParams = mDeviceProfile.isTaskbarPresent && isInHotseat; RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams - ? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRect, targetRect) - : new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRect, + ? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRectF, targetRect) + : new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRectF, targetRect)); // Hook up floating views to the closing window animators. // note the coordinate of closingWindowStartRect is based on launcher - Rect windowTargetBounds = new Rect(); - closingWindowStartRect.round(windowTargetBounds); + Rect closingWindowStartRect = new Rect(); + closingWindowStartRectF.round(closingWindowStartRect); + Rect closingWindowOriginalRect = + new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx); if (floatingIconView != null) { anim.addAnimatorListener(floatingIconView); floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged); @@ -1425,7 +1427,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION; RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect, - windowTargetBounds, startWindowCornerRadius) { + closingWindowStartRect, closingWindowOriginalRect, startWindowCornerRadius) { @Override public void onUpdate(RectF currentRectF, float progress) { finalFloatingIconView.update(1f, currentRectF, progress, windowAlphaThreshold, @@ -1443,7 +1445,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final float floatingWidgetAlpha = isTransluscent ? 0 : 1; FloatingWidgetView finalFloatingWidget = floatingWidget; RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect, - windowTargetBounds, startWindowCornerRadius) { + closingWindowStartRect, closingWindowOriginalRect, startWindowCornerRadius) { @Override public void onUpdate(RectF currentRectF, float progress) { final float fallbackBackgroundAlpha = @@ -1461,7 +1463,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // If no floating icon or widget is present, animate the to the default window // target rect. anim.addOnUpdateListener(new SpringAnimRunner( - targets, targetRect, windowTargetBounds, startWindowCornerRadius)); + targets, targetRect, closingWindowStartRect, closingWindowOriginalRect, + startWindowCornerRadius)); } // Use a fixed velocity to start the animation. @@ -1647,7 +1650,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // is initialized. if (launcherIsForceInvisibleOrOpening) { addCujInstrumentation(anim, playFallBackAnimation - ? CUJ_APP_CLOSE_TO_HOME_FALLBACK : CUJ_APP_CLOSE_TO_HOME); + ? CUJ_APP_CLOSE_TO_HOME_FALLBACK : CUJ_APP_CLOSE_TO_HOME); // Only register the content animation for cancellation when state changes mLauncher.getStateManager().setCurrentAnimation(anim); @@ -1961,6 +1964,7 @@ 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. @@ -2016,27 +2020,45 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private final float mStartRadius; private final float mEndRadius; private final SurfaceTransactionApplier mSurfaceApplier; - private final Rect mWindowTargetBounds = new Rect(); + private final Rect mWindowStartBounds = new Rect(); + private final Rect mWindowOriginalBounds = new Rect(); private final Rect mTmpRect = new Rect(); + /** + * Constructor for SpringAnimRunner + * + * @param appTargets the list of opening/closing apps + * @param targetRect target rectangle + * @param closingWindowStartRect start position of the window when the spring animation + * is started. In the predictive back to home case this + * will be smaller than closingWindowOriginalRect because + * the window is already scaled by the user gesture + * @param closingWindowOriginalRect Original unscaled window rect + * @param startWindowCornerRadius corner radius of window at the start position + */ SpringAnimRunner(RemoteAnimationTarget[] appTargets, RectF targetRect, - Rect windowTargetBounds, float startWindowCornerRadius) { + Rect closingWindowStartRect, Rect closingWindowOriginalRect, + float startWindowCornerRadius) { mAppTargets = appTargets; mStartRadius = startWindowCornerRadius; mEndRadius = Math.max(1, targetRect.width()) / 2f; mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer); - mWindowTargetBounds.set(windowTargetBounds); + mWindowStartBounds.set(closingWindowStartRect); + mWindowOriginalBounds.set(closingWindowOriginalRect); // 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 transferRect = new RectF(mWindowStartBounds); final RectF result = new RectF(); - transferRectToTargetCoordinate( - t, targetBounds, false, result); - result.round(mWindowTargetBounds); + transferRectToTargetCoordinate(t, transferRect, false, result); + result.round(mWindowStartBounds); + + transferRect.set(closingWindowOriginalRect); + transferRectToTargetCoordinate(t, transferRect, false, result); + result.round(mWindowOriginalBounds); break; } } @@ -2061,7 +2083,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } if (target.mode == MODE_CLOSING) { - final RectF before = new RectF(currentRectF); transferRectToTargetCoordinate(target, currentRectF, false, currentRectF); currentRectF.round(mCurrentRect); @@ -2069,20 +2090,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final float scale; // We need to infer the crop (we crop the window to match the currentRectF). - if (mWindowTargetBounds.height() > mWindowTargetBounds.width()) { - scale = Math.min(1f, currentRectF.width() / mWindowTargetBounds.width()); + if (mWindowStartBounds.height() > mWindowStartBounds.width()) { + scale = Math.min(1f, currentRectF.width() / mWindowOriginalBounds.width()); int unscaledHeight = (int) (mCurrentRect.height() * (1f / scale)); - int croppedHeight = mWindowTargetBounds.height() - unscaledHeight; - mTmpRect.set(0, 0, mWindowTargetBounds.width(), - mWindowTargetBounds.height() - croppedHeight); + int croppedHeight = mWindowStartBounds.height() - unscaledHeight; + mTmpRect.set(0, 0, mWindowOriginalBounds.width(), + mWindowStartBounds.height() - croppedHeight); } else { - scale = Math.min(1f, currentRectF.height() / mWindowTargetBounds.height()); + scale = Math.min(1f, currentRectF.height() + / mWindowOriginalBounds.height()); int unscaledWidth = (int) (mCurrentRect.width() * (1f / scale)); - int croppedWidth = mWindowTargetBounds.width() - unscaledWidth; - mTmpRect.set(0, 0, mWindowTargetBounds.width() - croppedWidth, - mWindowTargetBounds.height()); + int croppedWidth = mWindowStartBounds.width() - unscaledWidth; + mTmpRect.set(0, 0, mWindowStartBounds.width() - croppedWidth, + mWindowOriginalBounds.height()); } // Match size and position of currentRect.