Merge "Rewrite long swipe resistance ("pullback") logic" into ub-launcher3-rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ffc06198ff
+2
-2
@@ -79,8 +79,8 @@ final class AppToOverviewAnimationProvider<T extends StatefulActivity<?>> extend
|
|||||||
BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
|
BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
|
||||||
mDeviceState,
|
mDeviceState,
|
||||||
wasVisible, (controller) -> {
|
wasVisible, (controller) -> {
|
||||||
controller.dispatchOnStart();
|
controller.getNormalController().dispatchOnStart();
|
||||||
controller.getAnimationPlayer().end();
|
controller.getNormalController().getAnimationPlayer().end();
|
||||||
});
|
});
|
||||||
factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
|
factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
|
||||||
factory.setRecentsAttachedToAppWindow(true, false);
|
factory.setRecentsAttachedToAppWindow(true, false);
|
||||||
|
|||||||
@@ -365,8 +365,7 @@ public abstract class BaseSwipeUpHandler<T extends StatefulActivity<?>, Q extend
|
|||||||
*/
|
*/
|
||||||
protected void applyWindowTransform() {
|
protected void applyWindowTransform() {
|
||||||
if (mWindowTransitionController != null) {
|
if (mWindowTransitionController != null) {
|
||||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||||
mWindowTransitionController.setPlayFraction(progress);
|
|
||||||
}
|
}
|
||||||
if (mRecentsAnimationTargets != null) {
|
if (mRecentsAnimationTargets != null) {
|
||||||
if (mRecentsViewScrollLinked) {
|
if (mRecentsViewScrollLinked) {
|
||||||
|
|||||||
+11
-44
@@ -21,7 +21,6 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
|||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
||||||
@@ -45,7 +44,6 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
|
|||||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.TimeInterpolator;
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
@@ -67,7 +65,6 @@ import com.android.launcher3.DeviceProfile;
|
|||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.logging.StatsLogManager;
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.logging.UserEventDispatcher;
|
import com.android.launcher3.logging.UserEventDispatcher;
|
||||||
@@ -80,6 +77,7 @@ import com.android.quickstep.BaseActivityInterface.AnimationFactory;
|
|||||||
import com.android.quickstep.GestureState.GestureEndTarget;
|
import com.android.quickstep.GestureState.GestureEndTarget;
|
||||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim;
|
import com.android.quickstep.util.ShelfPeekAnim;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||||
@@ -181,8 +179,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
private ThumbnailData mTaskSnapshot;
|
private ThumbnailData mTaskSnapshot;
|
||||||
|
|
||||||
// Used to control launcher components throughout the swipe gesture.
|
// Used to control launcher components throughout the swipe gesture.
|
||||||
private AnimatorPlaybackController mLauncherTransitionController;
|
private AnimatorControllerWithResistance mLauncherTransitionController;
|
||||||
private boolean mHasLauncherTransitionControllerStarted;
|
|
||||||
|
|
||||||
private AnimationFactory mAnimationFactory = (t) -> { };
|
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||||
|
|
||||||
@@ -528,11 +525,11 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
||||||
* (it has its own animation) or if we're already animating the current controller.
|
* (it has its own animation).
|
||||||
* @return Whether we can create the launcher controller or update its progress.
|
* @return Whether we can create the launcher controller or update its progress.
|
||||||
*/
|
*/
|
||||||
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
|
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
|
||||||
return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted;
|
return mGestureState.getEndTarget() != HOME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -542,10 +539,9 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
|
private void onAnimatorPlaybackControllerCreated(AnimatorControllerWithResistance anim) {
|
||||||
mLauncherTransitionController = anim;
|
mLauncherTransitionController = anim;
|
||||||
mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
|
mLauncherTransitionController.getNormalController().dispatchOnStart();
|
||||||
mLauncherTransitionController.dispatchOnStart();
|
|
||||||
updateLauncherTransitionProgress();
|
updateLauncherTransitionProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,10 +578,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
|| !canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
|| !canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Normalize the progress to 0 to 1, as the animation controller will clamp it to that
|
mLauncherTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||||
// anyway. The controller mimics the drag length factor by applying it to its interpolators.
|
|
||||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
|
||||||
mLauncherTransitionController.setPlayFraction(progress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1028,31 +1021,6 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
windowAnim.start();
|
windowAnim.start();
|
||||||
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
|
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
|
||||||
}
|
}
|
||||||
// Always play the entire launcher animation when going home, since it is separate from
|
|
||||||
// the animation that has been controlled thus far.
|
|
||||||
if (mGestureState.getEndTarget() == HOME) {
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to use the same interpolator as the window, but need to adjust it to
|
|
||||||
// interpolate over the remaining progress (end - start).
|
|
||||||
TimeInterpolator adjustedInterpolator = Interpolators.mapToProgress(
|
|
||||||
interpolator, start, end);
|
|
||||||
if (mLauncherTransitionController == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (start == end || duration <= 0) {
|
|
||||||
mLauncherTransitionController.dispatchSetInterpolator(t -> end);
|
|
||||||
} else {
|
|
||||||
mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
|
|
||||||
}
|
|
||||||
mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));
|
|
||||||
|
|
||||||
if (UNSTABLE_SPRINGS.get()) {
|
|
||||||
mLauncherTransitionController.dispatchOnStart();
|
|
||||||
}
|
|
||||||
mLauncherTransitionController.getAnimationPlayer().start();
|
|
||||||
mHasLauncherTransitionControllerStarted = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeRecentsScrollIfInvisible() {
|
private void computeRecentsScrollIfInvisible() {
|
||||||
@@ -1173,10 +1141,6 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
private void cancelCurrentAnimation() {
|
private void cancelCurrentAnimation() {
|
||||||
mCanceled = true;
|
mCanceled = true;
|
||||||
mCurrentShift.cancelAnimation();
|
mCurrentShift.cancelAnimation();
|
||||||
if (mLauncherTransitionController != null && mLauncherTransitionController
|
|
||||||
.getAnimationPlayer().isStarted()) {
|
|
||||||
mLauncherTransitionController.getAnimationPlayer().cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invalidateHandler() {
|
private void invalidateHandler() {
|
||||||
@@ -1202,7 +1166,10 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
private void endLauncherTransitionController() {
|
private void endLauncherTransitionController() {
|
||||||
setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
||||||
if (mLauncherTransitionController != null) {
|
if (mLauncherTransitionController != null) {
|
||||||
mLauncherTransitionController.getAnimationPlayer().end();
|
// End the animation, but stay at the same visual progress.
|
||||||
|
mLauncherTransitionController.getNormalController().dispatchSetInterpolator(
|
||||||
|
t -> Utilities.boundToRange(mCurrentShift.value, 0, 1));
|
||||||
|
mLauncherTransitionController.getNormalController().getAnimationPlayer().end();
|
||||||
mLauncherTransitionController = null;
|
mLauncherTransitionController = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -27,11 +27,11 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.quickstep.fallback.RecentsState;
|
import com.android.quickstep.fallback.RecentsState;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ public final class FallbackActivityInterface extends
|
|||||||
/** 6 */
|
/** 6 */
|
||||||
@Override
|
@Override
|
||||||
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
|
||||||
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
|
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
|
||||||
factory.initUI();
|
factory.initUI();
|
||||||
return factory;
|
return factory;
|
||||||
|
|||||||
+2
-2
@@ -39,7 +39,6 @@ import com.android.launcher3.LauncherInitListener;
|
|||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
import com.android.launcher3.appprediction.PredictionUiStateManager;
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
@@ -50,6 +49,7 @@ import com.android.launcher3.touch.PagedOrientationHandler;
|
|||||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.LayoutUtils;
|
import com.android.quickstep.util.LayoutUtils;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
@@ -119,7 +119,7 @@ public final class LauncherActivityInterface extends
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
|
||||||
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
|
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
|
||||||
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
|
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+10
-25
@@ -16,7 +16,7 @@
|
|||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
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 android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -24,7 +24,6 @@ import android.graphics.Matrix;
|
|||||||
import android.graphics.Matrix.ScaleToFit;
|
import android.graphics.Matrix.ScaleToFit;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.view.animation.Interpolator;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
@@ -35,6 +34,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
|||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.util.TaskViewSimulator;
|
import com.android.quickstep.util.TaskViewSimulator;
|
||||||
import com.android.quickstep.util.TransformParams;
|
import com.android.quickstep.util.TransformParams;
|
||||||
@@ -45,7 +45,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
|
|||||||
public abstract class SwipeUpAnimationLogic {
|
public abstract class SwipeUpAnimationLogic {
|
||||||
|
|
||||||
protected static final Rect TEMP_RECT = new Rect();
|
protected static final Rect TEMP_RECT = new Rect();
|
||||||
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
|
|
||||||
|
|
||||||
protected DeviceProfile mDp;
|
protected DeviceProfile mDp;
|
||||||
|
|
||||||
@@ -66,12 +65,8 @@ public abstract class SwipeUpAnimationLogic {
|
|||||||
protected int mTransitionDragLength;
|
protected int mTransitionDragLength;
|
||||||
// How much further we can drag past recents, as a factor of mTransitionDragLength.
|
// How much further we can drag past recents, as a factor of mTransitionDragLength.
|
||||||
protected float mDragLengthFactor = 1;
|
protected float mDragLengthFactor = 1;
|
||||||
// Start resisting when swiping past this factor of mTransitionDragLength.
|
|
||||||
private float mDragLengthFactorStartPullback = 1f;
|
|
||||||
// This is how far down we can scale down, where 0f is full screen and 1f is recents.
|
|
||||||
private float mDragLengthFactorMaxPullback = 1f;
|
|
||||||
|
|
||||||
protected AnimatorPlaybackController mWindowTransitionController;
|
protected AnimatorControllerWithResistance mWindowTransitionController;
|
||||||
|
|
||||||
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
|
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
|
||||||
GestureState gestureState, TransformParams transformParams) {
|
GestureState gestureState, TransformParams transformParams) {
|
||||||
@@ -97,19 +92,16 @@ public abstract class SwipeUpAnimationLogic {
|
|||||||
if (mDeviceState.isFullyGesturalNavMode()) {
|
if (mDeviceState.isFullyGesturalNavMode()) {
|
||||||
// We can drag all the way to the top of the screen.
|
// We can drag all the way to the top of the screen.
|
||||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||||
|
|
||||||
float startScale = mTaskViewSimulator.getFullScreenScale();
|
|
||||||
// Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
|
|
||||||
mDragLengthFactorStartPullback = (0.75f - startScale) / (1 - startScale);
|
|
||||||
mDragLengthFactorMaxPullback = (0.5f - startScale) / (1 - startScale);
|
|
||||||
} else {
|
} else {
|
||||||
mDragLengthFactor = 1;
|
mDragLengthFactor = 1 + AnimatorControllerWithResistance.TWO_BUTTON_EXTRA_DRAG_FACTOR;
|
||||||
mDragLengthFactorStartPullback = mDragLengthFactorMaxPullback = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
|
PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
|
||||||
mTaskViewSimulator.addAppToOverviewAnim(pa, t -> t * mDragLengthFactor);
|
mTaskViewSimulator.addAppToOverviewAnim(pa, LINEAR);
|
||||||
mWindowTransitionController = pa.createPlaybackController();
|
AnimatorPlaybackController normalController = pa.createPlaybackController();
|
||||||
|
mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
|
||||||
|
normalController, mContext, mTaskViewSimulator.getOrientationState(),
|
||||||
|
mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@@ -122,13 +114,6 @@ public abstract class SwipeUpAnimationLogic {
|
|||||||
} else {
|
} else {
|
||||||
float translation = Math.max(displacement, 0);
|
float translation = Math.max(displacement, 0);
|
||||||
shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
|
shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
|
||||||
if (shift > mDragLengthFactorStartPullback) {
|
|
||||||
float pullbackProgress = Utilities.getProgress(shift,
|
|
||||||
mDragLengthFactorStartPullback, mDragLengthFactor);
|
|
||||||
pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress);
|
|
||||||
shift = mDragLengthFactorStartPullback + pullbackProgress
|
|
||||||
* (mDragLengthFactorMaxPullback - mDragLengthFactorStartPullback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentShift.updateValue(shift);
|
mCurrentShift.updateValue(shift);
|
||||||
@@ -183,7 +168,7 @@ public abstract class SwipeUpAnimationLogic {
|
|||||||
HomeAnimationFactory homeAnimationFactory) {
|
HomeAnimationFactory homeAnimationFactory) {
|
||||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||||
|
|
||||||
mWindowTransitionController.setPlayFraction(startProgress / mDragLengthFactor);
|
mCurrentShift.updateValue(startProgress);
|
||||||
mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
|
mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
|
||||||
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import com.android.launcher3.touch.PagedOrientationHandler;
|
|||||||
import com.android.launcher3.util.WindowBounds;
|
import com.android.launcher3.util.WindowBounds;
|
||||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
import com.android.quickstep.util.ActivityInitListener;
|
import com.android.quickstep.util.ActivityInitListener;
|
||||||
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.ShelfPeekAnim;
|
import com.android.quickstep.util.ShelfPeekAnim;
|
||||||
import com.android.quickstep.util.SplitScreenBounds;
|
import com.android.quickstep.util.SplitScreenBounds;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
@@ -106,7 +107,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
|||||||
public abstract void onAssistantVisibilityChanged(float visibility);
|
public abstract void onAssistantVisibilityChanged(float visibility);
|
||||||
|
|
||||||
public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback);
|
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
|
||||||
|
|
||||||
public abstract ActivityInitListener createActivityInitListener(
|
public abstract ActivityInitListener createActivityInitListener(
|
||||||
Predicate<Boolean> onInitListener);
|
Predicate<Boolean> onInitListener);
|
||||||
@@ -319,11 +320,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
|||||||
|
|
||||||
protected final ACTIVITY_TYPE mActivity;
|
protected final ACTIVITY_TYPE mActivity;
|
||||||
private final STATE_TYPE mStartState;
|
private final STATE_TYPE mStartState;
|
||||||
private final Consumer<AnimatorPlaybackController> mCallback;
|
private final Consumer<AnimatorControllerWithResistance> mCallback;
|
||||||
|
|
||||||
private boolean mIsAttachedToWindow;
|
private boolean mIsAttachedToWindow;
|
||||||
|
|
||||||
DefaultAnimationFactory(Consumer<AnimatorPlaybackController> callback) {
|
DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
|
|
||||||
mActivity = getCreatedActivity();
|
mActivity = getCreatedActivity();
|
||||||
@@ -351,7 +352,13 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
|||||||
controller.setEndAction(() -> mActivity.getStateManager().goToState(
|
controller.setEndAction(() -> mActivity.getStateManager().goToState(
|
||||||
controller.getInterpolatedProgress() > 0.5 ? mOverviewState : mBackgroundState,
|
controller.getInterpolatedProgress() > 0.5 ? mOverviewState : mBackgroundState,
|
||||||
false));
|
false));
|
||||||
mCallback.accept(controller);
|
|
||||||
|
RecentsView recentsView = mActivity.getOverviewPanel();
|
||||||
|
AnimatorControllerWithResistance controllerWithResistance =
|
||||||
|
AnimatorControllerWithResistance.createForRecents(controller, mActivity,
|
||||||
|
recentsView.getPagedViewOrientedState(), mActivity.getDeviceProfile(),
|
||||||
|
recentsView, RECENTS_SCALE_PROPERTY);
|
||||||
|
mCallback.accept(controllerWithResistance);
|
||||||
|
|
||||||
// Creating the activity controller animation sometimes reapplies the launcher state
|
// Creating the activity controller animation sometimes reapplies the launcher state
|
||||||
// (because we set the animation as the current state animation), so we reapply the
|
// (because we set the animation as the current state animation), so we reapply the
|
||||||
|
|||||||
+1
-2
@@ -184,8 +184,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFinalShift() {
|
public void updateFinalShift() {
|
||||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||||
mWindowTransitionController.setPlayFraction(progress);
|
|
||||||
mTaskViewSimulator.apply(mTransformParams);
|
mTaskViewSimulator.apply(mTransformParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.quickstep.util;
|
||||||
|
|
||||||
|
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||||
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
|
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||||
|
|
||||||
|
import android.animation.TimeInterpolator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.PointF;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.util.FloatProperty;
|
||||||
|
|
||||||
|
import com.android.launcher3.DeviceProfile;
|
||||||
|
import com.android.launcher3.Utilities;
|
||||||
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
|
import com.android.quickstep.LauncherActivityInterface;
|
||||||
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls an animation that can go beyond progress = 1, at which point resistance should be
|
||||||
|
* applied. Internally, this is a wrapper around 2 {@link AnimatorPlaybackController}s, one that
|
||||||
|
* runs from progress 0 to 1 like normal, then one that seamlessly continues that animation but
|
||||||
|
* starts applying resistance as well.
|
||||||
|
*/
|
||||||
|
public class AnimatorControllerWithResistance {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How much farther we can drag past overview in 2-button mode, as a factor of the distance
|
||||||
|
* it takes to drag from an app to overview.
|
||||||
|
*/
|
||||||
|
public static final float TWO_BUTTON_EXTRA_DRAG_FACTOR = 0.25f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start slowing down the rate of scaling down when recents view is smaller than this scale.
|
||||||
|
*/
|
||||||
|
private static final float RECENTS_SCALE_START_RESIST = 0.75f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recents view will reach this scale at the very end of the drag.
|
||||||
|
*/
|
||||||
|
private static final float RECENTS_SCALE_MAX_RESIST = 0.5f;
|
||||||
|
|
||||||
|
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
|
||||||
|
|
||||||
|
private final AnimatorPlaybackController mNormalController;
|
||||||
|
private final AnimatorPlaybackController mResistanceController;
|
||||||
|
|
||||||
|
// Initialize to -1 so the first 0 gets applied.
|
||||||
|
private float mLastNormalProgress = -1;
|
||||||
|
private float mLastResistProgress;
|
||||||
|
|
||||||
|
public AnimatorControllerWithResistance(AnimatorPlaybackController normalController,
|
||||||
|
AnimatorPlaybackController resistanceController) {
|
||||||
|
mNormalController = normalController;
|
||||||
|
mResistanceController = resistanceController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimatorPlaybackController getNormalController() {
|
||||||
|
return mNormalController;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the current progress of the animation.
|
||||||
|
* @param progress From 0 to maxProgress, where 1 is the target we are animating towards.
|
||||||
|
* @param maxProgress > 1, this is where the resistance will be applied.
|
||||||
|
*/
|
||||||
|
public void setProgress(float progress, float maxProgress) {
|
||||||
|
float normalProgress = Utilities.boundToRange(progress, 0, 1);
|
||||||
|
if (normalProgress != mLastNormalProgress) {
|
||||||
|
mLastNormalProgress = normalProgress;
|
||||||
|
mNormalController.setPlayFraction(normalProgress);
|
||||||
|
}
|
||||||
|
if (maxProgress <= 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float resistProgress = progress <= 1 ? 0 : Utilities.getProgress(progress, 1, maxProgress);
|
||||||
|
if (resistProgress != mLastResistProgress) {
|
||||||
|
mLastResistProgress = resistProgress;
|
||||||
|
mResistanceController.setPlayFraction(resistProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies resistance to recents when swiping up past its target position.
|
||||||
|
* @param normalController The controller to run from 0 to 1 before this resistance applies.
|
||||||
|
* @param context Used to compute start and end values.
|
||||||
|
* @param recentsOrientedState Used to compute start and end values.
|
||||||
|
* @param dp Used to compute start and end values.
|
||||||
|
* @param scaleTarget The target for the scaleProperty.
|
||||||
|
* @param scaleProperty Animate the value to change the scale of the window/recents view.
|
||||||
|
*/
|
||||||
|
public static <SCALE> AnimatorControllerWithResistance createForRecents(
|
||||||
|
AnimatorPlaybackController normalController, Context context,
|
||||||
|
RecentsOrientedState recentsOrientedState, DeviceProfile dp, SCALE scaleTarget,
|
||||||
|
FloatProperty<SCALE> scaleProperty) {
|
||||||
|
Rect startRect = new Rect();
|
||||||
|
LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, startRect,
|
||||||
|
recentsOrientedState.getOrientationHandler());
|
||||||
|
long distanceToCover = startRect.bottom;
|
||||||
|
boolean isTwoButtonMode = SysUINavigationMode.getMode(context) == TWO_BUTTONS;
|
||||||
|
if (isTwoButtonMode) {
|
||||||
|
// We can only drag a small distance past overview, not to the top of the screen.
|
||||||
|
distanceToCover = (long)
|
||||||
|
((dp.heightPx - startRect.bottom) * TWO_BUTTON_EXTRA_DRAG_FACTOR);
|
||||||
|
}
|
||||||
|
PendingAnimation resistAnim = new PendingAnimation(distanceToCover * 2);
|
||||||
|
|
||||||
|
PointF pivot = new PointF();
|
||||||
|
float fullscreenScale = recentsOrientedState.getFullScreenScaleAndPivot(
|
||||||
|
startRect, dp, pivot);
|
||||||
|
float startScale = 1;
|
||||||
|
float prevScaleRate = (fullscreenScale - startScale) / (dp.heightPx - startRect.bottom);
|
||||||
|
// This is what the scale would be at the end of the drag if we didn't apply resistance.
|
||||||
|
float endScale = startScale - prevScaleRate * distanceToCover;
|
||||||
|
final TimeInterpolator scaleInterpolator;
|
||||||
|
if (isTwoButtonMode) {
|
||||||
|
// We are bounded by the distance of the drag, so we don't need to apply resistance.
|
||||||
|
scaleInterpolator = LINEAR;
|
||||||
|
} else {
|
||||||
|
// Create an interpolator that resists the scale so the scale doesn't get smaller than
|
||||||
|
// RECENTS_SCALE_MAX_RESIST.
|
||||||
|
float startResist = Utilities.getProgress(RECENTS_SCALE_START_RESIST, startScale,
|
||||||
|
endScale);
|
||||||
|
float maxResist = Utilities.getProgress(RECENTS_SCALE_MAX_RESIST, startScale, endScale);
|
||||||
|
scaleInterpolator = t -> {
|
||||||
|
if (t < startResist) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
float resistProgress = Utilities.getProgress(t, startResist, 1);
|
||||||
|
resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
|
||||||
|
return startResist + resistProgress * (maxResist - startResist);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
resistAnim.addFloat(scaleTarget, scaleProperty, startScale, endScale,
|
||||||
|
scaleInterpolator);
|
||||||
|
|
||||||
|
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
|
||||||
|
return new AnimatorControllerWithResistance(normalController, resistanceController);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -198,6 +198,7 @@ public class Interpolators {
|
|||||||
public OvershootParams(float startProgress, float overshootPastProgress,
|
public OvershootParams(float startProgress, float overshootPastProgress,
|
||||||
float endProgress, float velocityPxPerMs, int totalDistancePx, Context context) {
|
float endProgress, float velocityPxPerMs, int totalDistancePx, Context context) {
|
||||||
velocityPxPerMs = Math.abs(velocityPxPerMs);
|
velocityPxPerMs = Math.abs(velocityPxPerMs);
|
||||||
|
overshootPastProgress = Math.max(overshootPastProgress, startProgress);
|
||||||
start = startProgress;
|
start = startProgress;
|
||||||
int startPx = (int) (start * totalDistancePx);
|
int startPx = (int) (start * totalDistancePx);
|
||||||
// Overshoot by about half a frame.
|
// Overshoot by about half a frame.
|
||||||
|
|||||||
Reference in New Issue
Block a user