summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2019-07-17 11:38:59 -0700
committerSunny Goyal <sunnygoyal@google.com>2019-07-17 11:39:25 -0700
commite88d8acd85a670272c2d619980658730e6c558c7 (patch)
tree666e29af36597d4bbaabdc8ba54249e7c922d69a
parentbf0042107c433de499e10b91a412b6c3e4a3bcbc (diff)
downloadpackages_apps_Trebuchet-e88d8acd85a670272c2d619980658730e6c558c7.tar.gz
packages_apps_Trebuchet-e88d8acd85a670272c2d619980658730e6c558c7.tar.bz2
packages_apps_Trebuchet-e88d8acd85a670272c2d619980658730e6c558c7.zip
Adding spring animation when swiping up to home in 3P Launcher
Bug: 137197916 Change-Id: Ic9808a30e8cd4e0b2a221c4b03bc29489038e092
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java119
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java8
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java103
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java84
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java2
-rw-r--r--quickstep/src/com/android/quickstep/ActivityControlHelper.java10
6 files changed, 198 insertions, 128 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 72a9da6a3..e3d622f97 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -19,12 +19,15 @@ import static android.os.VibrationEffect.EFFECT_CLICK;
import static android.os.VibrationEffect.createPredefined;
import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
+import android.animation.Animator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -32,6 +35,7 @@ import android.content.Intent;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -48,12 +52,19 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.graphics.RotationMode;
+import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
+import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
+import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
import com.android.quickstep.views.RecentsView;
@@ -369,9 +380,117 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
return TaskView.getCurveScaleForInterpolation(interpolation);
}
+ /**
+ * Creates an animation that transforms the current app window into the home app.
+ * @param startProgress The progress of {@link #mCurrentShift} to start the window from.
+ * @param homeAnimationFactory The home animation factory.
+ */
+ protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
+ HomeAnimationFactory homeAnimationFactory) {
+ final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
+ final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
+ mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
+ final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
+
+ final View floatingView = homeAnimationFactory.getFloatingView();
+ final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
+ RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext.getResources());
+ if (isFloatingIconView) {
+ FloatingIconView fiv = (FloatingIconView) floatingView;
+ anim.addAnimatorListener(fiv);
+ fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ }
+
+ AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
+
+ // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
+ // rounding at the end of the animation.
+ float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
+ float endRadius = startRect.width() / 6f;
+ // We want the window alpha to be 0 once this threshold is met, so that the
+ // FolderIconView can be seen morphing into the icon shape.
+ final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
+ anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
+ @Override
+ public void onUpdate(RectF currentRect, float progress) {
+ homeAnim.setPlayFraction(progress);
+
+ float alphaProgress = ACCEL_1_5.getInterpolation(progress);
+ float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0,
+ windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1);
+ mTransformParams.setProgress(progress)
+ .setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
+ if (isFloatingIconView) {
+ mTransformParams.setCornerRadius(endRadius * progress + startRadius
+ * (1f - progress));
+ }
+ mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
+ false /* launcherOnTop */);
+
+ if (isFloatingIconView) {
+ ((FloatingIconView) floatingView).update(currentRect, 1f, progress,
+ windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ if (isFloatingIconView) {
+ ((FloatingIconView) floatingView).fastFinish();
+ }
+ }
+ });
+ anim.addAnimatorListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ homeAnim.dispatchOnStart();
+ }
+
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ homeAnim.getAnimationPlayer().end();
+ }
+ });
+ return anim;
+ }
+
public interface Factory {
BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask,
long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask);
}
+
+ protected interface RunningWindowAnim {
+ void end();
+
+ void cancel();
+
+ static RunningWindowAnim wrap(Animator animator) {
+ return new RunningWindowAnim() {
+ @Override
+ public void end() {
+ animator.end();
+ }
+
+ @Override
+ public void cancel() {
+ animator.cancel();
+ }
+ };
+ }
+
+ static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) {
+ return new RunningWindowAnim() {
+ @Override
+ public void end() {
+ rectFSpringAnim.end();
+ }
+
+ @Override
+ public void cancel() {
+ rectFSpringAnim.cancel();
+ }
+ };
+ }
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 894edd46c..295585e00 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -151,16 +151,10 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
@NonNull
@Override
public RectF getWindowTargetRect() {
- final int halfIconSize = dp.iconSizePx / 2;
- final float targetCenterX = dp.availableWidthPx / 2f;
- final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx;
-
if (canUseWorkspaceView) {
return iconLocation;
} else {
- // Fallback to animate to center of screen.
- return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize,
- targetCenterX + halfIconSize, targetCenterY + halfIconSize);
+ return HomeAnimationFactory.getDefaultWindowTargetRect(dp);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 83e90ed19..df37759cc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -18,7 +18,6 @@ package com.android.quickstep;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
-import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
@@ -27,7 +26,6 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
-import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.HIDE;
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.PEEK;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
@@ -52,7 +50,6 @@ import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
import android.os.SystemClock;
-import android.util.Log;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
import android.view.ViewTreeObserver.OnDrawListener;
@@ -68,13 +65,11 @@ import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.RaceConditionTracker;
import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.ActivityControlHelper.AnimationFactory;
import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
@@ -83,7 +78,6 @@ import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider;
import com.android.quickstep.util.RectFSpringAnim;
-import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.views.LiveTileOverlay;
import com.android.quickstep.views.RecentsView;
@@ -968,67 +962,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
* @param homeAnimationFactory The home animation factory.
*/
- private RectFSpringAnim createWindowAnimationToHome(float startProgress,
+ @Override
+ protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
HomeAnimationFactory homeAnimationFactory) {
- final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
- final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
- mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
- final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
-
- final View floatingView = homeAnimationFactory.getFloatingView();
- final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
- RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources());
- if (isFloatingIconView) {
- FloatingIconView fiv = (FloatingIconView) floatingView;
- anim.addAnimatorListener(fiv);
- fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
- }
-
- AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
-
- // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
- // rounding at the end of the animation.
- float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
- float endRadius = startRect.width() / 6f;
- // We want the window alpha to be 0 once this threshold is met, so that the
- // FolderIconView can be seen morphing into the icon shape.
- final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
- anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
- @Override
- public void onUpdate(RectF currentRect, float progress) {
- homeAnim.setPlayFraction(progress);
-
- float alphaProgress = ACCEL_1_5.getInterpolation(progress);
- float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0,
- windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1);
- mTransformParams.setProgress(progress)
- .setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
- if (isFloatingIconView) {
- mTransformParams.setCornerRadius(endRadius * progress + startRadius
- * (1f - progress));
- }
- mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
- false /* launcherOnTop */);
-
- if (isFloatingIconView) {
- ((FloatingIconView) floatingView).update(currentRect, 1f, progress,
- windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
- }
-
- updateSysUiFlags(Math.max(progress, mCurrentShift.value));
- }
-
- @Override
- public void onCancel() {
- if (isFloatingIconView) {
- ((FloatingIconView) floatingView).fastFinish();
- }
- }
- });
+ RectFSpringAnim anim =
+ super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
+ anim.addOnUpdateListener((r, p) -> updateSysUiFlags(Math.max(p, mCurrentShift.value)));
anim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
- homeAnim.dispatchOnStart();
if (mActivity != null) {
mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
}
@@ -1036,7 +978,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
@Override
public void onAnimationSuccess(Animator animator) {
- homeAnim.getAnimationPlayer().end();
if (mRecentsView != null) {
mRecentsView.post(mRecentsView::resetTaskVisuals);
}
@@ -1270,38 +1211,4 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
return app.isNotInRecents
|| app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
}
-
- private interface RunningWindowAnim {
- void end();
-
- void cancel();
-
- static RunningWindowAnim wrap(Animator animator) {
- return new RunningWindowAnim() {
- @Override
- public void end() {
- animator.end();
- }
-
- @Override
- public void cancel() {
- animator.cancel();
- }
- };
- }
-
- static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) {
- return new RunningWindowAnim() {
- @Override
- public void end() {
- rectFSpringAnim.end();
- }
-
- @Override
- public void cancel() {
- rectFSpringAnim.cancel();
- }
- };
- }
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index 7abf62d35..631c34c22 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -18,11 +18,12 @@ package com.android.quickstep.inputconsumers;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
-import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK;
+import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK;
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS;
+import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -31,10 +32,13 @@ import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
+import android.graphics.RectF;
import android.os.Bundle;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseSwipeUpHandler;
import com.android.quickstep.MultiStateCallback;
@@ -44,6 +48,7 @@ import com.android.quickstep.RecentsModel;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.ObjectWrapper;
+import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -102,10 +107,10 @@ public class FallbackNoButtonInputConsumer extends
private final boolean mRunningOverHome;
private final boolean mSwipeUpOverHome;
-
private final RunningTaskInfo mRunningTaskInfo;
- private Animator mFinishAnimation;
+ private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f);
+ private RunningWindowAnim mFinishAnimation;
public FallbackNoButtonInputConsumer(Context context,
OverviewComponentObserver overviewComponentObserver,
@@ -226,6 +231,8 @@ public class FallbackNoButtonInputConsumer extends
@Override
public void updateFinalShift() {
mTransformParams.setProgress(mCurrentShift.value);
+ mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode
+ && (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD));
if (mRecentsAnimationWrapper.targetSet != null) {
applyTransformUnchecked();
}
@@ -240,6 +247,7 @@ public class FallbackNoButtonInputConsumer extends
@Override
public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
+ mEndVelocityPxPerMs.set(0, velocity.y / 1000);
if (mInQuickSwitchMode) {
// For now set it to non-null, it will be reset before starting the animation
mEndTarget = LAST_TASK;
@@ -288,12 +296,14 @@ public class FallbackNoButtonInputConsumer extends
}
}
-
private void onHandlerInvalidated() {
mActivityInitListener.unregister();
if (mGestureEndCallback != null) {
mGestureEndCallback.run();
}
+ if (mFinishAnimation != null) {
+ mFinishAnimation.end();
+ }
}
private void onHandlerInvalidatedWithRecents() {
@@ -364,31 +374,39 @@ public class FallbackNoButtonInputConsumer extends
}
float endProgress = mEndTarget.mEndProgress;
-
+ long duration = (long) (mEndTarget.mDurationMultiplier *
+ Math.abs(endProgress - mCurrentShift.value));
+ if (mRecentsView != null) {
+ duration = Math.max(duration, mRecentsView.getScroller().getDuration());
+ }
if (mCurrentShift.value != endProgress || mInQuickSwitchMode) {
- AnimatorSet anim = new AnimatorSet();
- anim.play(mLauncherAlpha.animateToValue(
- mLauncherAlpha.value, mEndTarget.mLauncherAlpha));
- anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
-
-
- long duration = (long) (mEndTarget.mDurationMultiplier *
- Math.abs(endProgress - mCurrentShift.value));
- if (mRecentsView != null) {
- duration = Math.max(duration, mRecentsView.getScroller().getDuration());
- }
-
- anim.setDuration(duration);
- anim.addListener(new AnimationSuccessListener() {
+ AnimationSuccessListener endListener = new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
finishAnimationTargetSetAnimationComplete();
mFinishAnimation = null;
}
- });
- anim.start();
- mFinishAnimation = anim;
+ };
+
+ if (mEndTarget == HOME && !mRunningOverHome) {
+ RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration);
+ anim.addAnimatorListener(endListener);
+ anim.start(mEndVelocityPxPerMs);
+ mFinishAnimation = RunningWindowAnim.wrap(anim);
+ } else {
+
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(mLauncherAlpha.animateToValue(
+ mLauncherAlpha.value, mEndTarget.mLauncherAlpha));
+ anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
+
+ anim.setDuration(duration);
+ anim.addListener(endListener);
+ anim.start();
+ mFinishAnimation = RunningWindowAnim.wrap(anim);
+ }
+
} else {
finishAnimationTargetSetAnimationComplete();
}
@@ -412,4 +430,26 @@ public class FallbackNoButtonInputConsumer extends
mRecentsAnimationWrapper.setController(null);
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
}
+
+ /**
+ * Creates an animation that transforms the current app window into the home app.
+ * @param startProgress The progress of {@link #mCurrentShift} to start the window from.
+ */
+ private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) {
+ HomeAnimationFactory factory = new HomeAnimationFactory() {
+ @Override
+ public RectF getWindowTargetRect() {
+ return HomeAnimationFactory.getDefaultWindowTargetRect(mDp);
+ }
+
+ @Override
+ public AnimatorPlaybackController createActivityAnimationToHome() {
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1));
+ anim.setDuration(duration);
+ return AnimatorPlaybackController.wrap(anim, duration);
+ }
+ };
+ return createWindowAnimationToHome(startProgress, factory);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index 9c5cf2042..c6eafe6a6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -237,6 +237,6 @@ public class RectFSpringAnim {
public interface OnUpdateListener {
void onUpdate(RectF currentRect, float progress);
- void onCancel();
+ default void onCancel() { }
}
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index cd2c9cb1b..5c9c7d4ca 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -152,5 +152,15 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
default void playAtomicAnimation(float velocity) {
// No-op
}
+
+ static RectF getDefaultWindowTargetRect(DeviceProfile dp) {
+ final int halfIconSize = dp.iconSizePx / 2;
+ final float targetCenterX = dp.availableWidthPx / 2f;
+ final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx;
+ // Fallback to animate to center of screen.
+ return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize,
+ targetCenterX + halfIconSize, targetCenterY + halfIconSize);
+ }
+
}
}