From ce8b2b51800e42fc61c14f516ec563c3561b7adb Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 1 Jul 2020 17:25:28 -0700 Subject: [PATCH] Add translation component to swipe up resistance Now recents view follows your finger all the way to the top of the screen. Specifically, your finger tracks the bottom of the window until resistance starts (when RecentsView is at 75% scale), then we add translation to compensate for the slower rate of scaling down, such that your finger slips to the top of the window by the time it reaches the top of the screen. Also reset this translation back to 0 in the state handlers. Bug: 149934536 Fixes: 158701272 Change-Id: Iaee58da758d422f0173c29d002f5c451ce0c1809 --- .../quickstep/SwipeUpAnimationLogic.java | 3 ++- .../FallbackRecentsStateController.java | 4 +++ .../quickstep/fallback/RecentsState.java | 1 - .../quickstep/util/TaskViewSimulator.java | 5 +++- .../android/quickstep/views/RecentsView.java | 25 ++++++++++++++++++- .../BaseRecentsViewStateController.java | 5 ++++ .../quickstep/BaseActivityInterface.java | 4 ++- .../AnimatorControllerWithResistance.java | 23 +++++++++++++++-- .../touch/LandscapePagedViewHandler.java | 8 ++++-- .../touch/PagedOrientationHandler.java | 3 ++- .../touch/PortraitPagedViewHandler.java | 8 ++++-- .../touch/SeascapePagedViewHandler.java | 2 +- 12 files changed, 78 insertions(+), 13 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeUpAnimationLogic.java index 137f8091ad..2963b6ce18 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -101,7 +101,8 @@ public abstract class SwipeUpAnimationLogic { AnimatorPlaybackController normalController = pa.createPlaybackController(); mWindowTransitionController = AnimatorControllerWithResistance.createForRecents( normalController, mContext, mTaskViewSimulator.getOrientationState(), - mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE); + mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE, + mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE); } @UiThread diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 163c23268b..24a761066a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -19,6 +19,7 @@ import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X; +import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y; import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK; import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; @@ -26,6 +27,7 @@ import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_MODALNESS; +import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; @@ -86,6 +88,8 @@ public class FallbackRecentsStateController implements StateHandler { return new float[] { NO_SCALE, NO_OFFSET }; } - private static class ModalState extends RecentsState { public ModalState(int id, int flags) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java index c5918fed84..db64464a61 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewSimulator.java @@ -90,6 +90,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // RecentsView properties public final AnimatedFloat recentsViewScale = new AnimatedFloat(); public final AnimatedFloat fullScreenProgress = new AnimatedFloat(); + public final AnimatedFloat recentsViewSecondaryTranslation = new AnimatedFloat(); private final ScrollState mScrollState = new ScrollState(); // Cached calculations @@ -274,8 +275,10 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { mOrientationState.getOrientationHandler().set( mMatrix, MATRIX_POST_TRANSLATE, mScrollState.scroll); - // Apply recensView matrix + // Apply RecentsView matrix mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y); + mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE, + recentsViewSecondaryTranslation.value); applyWindowToHomeRotation(mMatrix); // Crop rect is the inverse of thumbnail matrix diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 5ce6f6ba60..6ebf8ad46a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -210,6 +210,19 @@ public abstract class RecentsView extends PagedView } }; + public static final FloatProperty TASK_SECONDARY_TRANSLATION = + new FloatProperty("taskSecondaryTranslation") { + @Override + public void setValue(RecentsView recentsView, float v) { + recentsView.setTaskViewsSecondaryTranslation(v); + } + + @Override + public Float get(RecentsView recentsView) { + return recentsView.mTaskViewsSecondaryTranslation; + } + }; + /** Same as normal SCALE_PROPERTY, but also updates page offsets that depend on this scale. */ public static final FloatProperty RECENTS_SCALE_PROPERTY = new FloatProperty("recentsScale") { @@ -219,6 +232,7 @@ public abstract class RecentsView extends PagedView view.setScaleY(scale); view.mLastComputedTaskPushOutDistance = null; view.updatePageOffsets(); + view.setTaskViewsSecondaryTranslation(view.mTaskViewsSecondaryTranslation); } @Override @@ -269,6 +283,7 @@ public abstract class RecentsView extends PagedView protected boolean mFreezeViewVisibility; private float mAdjacentPageOffset = 0; + private float mTaskViewsSecondaryTranslation = 0; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. @@ -1391,7 +1406,7 @@ public abstract class RecentsView extends PagedView FloatProperty secondaryViewTranslate = mOrientationHandler.getSecondaryViewTranslate(); int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); - int verticalFactor = mOrientationHandler.getTaskDismissDirectionFactor(); + int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor(); ResourceProvider rp = DynamicResource.provider(mActivity); SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START) @@ -1908,6 +1923,14 @@ public abstract class RecentsView extends PagedView return distanceToOffscreen * offsetProgress; } + private void setTaskViewsSecondaryTranslation(float translation) { + mTaskViewsSecondaryTranslation = translation; + for (int i = 0; i < getTaskViewCount(); i++) { + TaskView task = getTaskViewAt(i); + mOrientationHandler.getSecondaryViewTranslate().set(task, translation / getScaleY()); + } + } + /** * TODO: Do not assume motion across X axis for adjacent page */ diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index 6e120e8bd8..1b8e244ac1 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -24,11 +24,13 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MO import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X; +import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y; import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK; import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; +import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; import android.util.FloatProperty; @@ -63,6 +65,7 @@ public abstract class BaseRecentsViewStateController float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher); RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]); ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]); + TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f); getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0); OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim(); @@ -97,6 +100,8 @@ public abstract class BaseRecentsViewStateController config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR)); setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR)); + setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f, + config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR)); setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0, config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT)); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 31630ff1bc..bdf525dcd0 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -28,6 +28,7 @@ import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_REC import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; +import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; import android.animation.Animator; import android.annotation.TargetApi; @@ -357,7 +358,8 @@ public abstract class BaseActivityInterface AnimatorControllerWithResistance createForRecents( + public static AnimatorControllerWithResistance createForRecents( AnimatorPlaybackController normalController, Context context, RecentsOrientedState recentsOrientedState, DeviceProfile dp, SCALE scaleTarget, - FloatProperty scaleProperty) { + FloatProperty scaleProperty, TRANSLATION translationTarget, + FloatProperty translationProperty) { Rect startRect = new Rect(); LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, startRect, recentsOrientedState.getOrientationHandler()); @@ -150,6 +156,19 @@ public class AnimatorControllerWithResistance { resistAnim.addFloat(scaleTarget, scaleProperty, startScale, endScale, scaleInterpolator); + if (!isTwoButtonMode) { + // Compute where the task view would be based on the end scale, if we didn't translate. + RectF endRectF = new RectF(startRect); + Matrix temp = new Matrix(); + temp.setScale(RECENTS_SCALE_MAX_RESIST, RECENTS_SCALE_MAX_RESIST, pivot.x, pivot.y); + temp.mapRect(endRectF); + // Translate such that the task view touches the top of the screen when drag does. + float endTranslation = endRectF.top * recentsOrientedState.getOrientationHandler() + .getSecondaryTranslationDirectionFactor(); + resistAnim.addFloat(translationTarget, translationProperty, 0, endTranslation, + RECENTS_TRANSLATE_RESIST_INTERPOLATOR); + } + AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController(); return new AnimatorControllerWithResistance(normalController, resistanceController); } diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index b2740fab3e..4fd163360b 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -107,6 +107,11 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { action.call(target, 0, param); } + @Override + public void setSecondary(T target, Float2DAction action, float param) { + action.call(target, param, 0); + } + @Override public float getPrimaryDirection(MotionEvent event, int pointerIndex) { return event.getY(pointerIndex); @@ -219,8 +224,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { return -1; } - @Override - public int getTaskDismissDirectionFactor() { + public int getSecondaryTranslationDirectionFactor() { return 1; } diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index 4b17c79a33..c0d488bb45 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -57,6 +57,7 @@ public interface PagedOrientationHandler { void set(T target, Int2DAction action, int param); void set(T target, Float2DAction action, float param); + void setSecondary(T target, Float2DAction action, float param); float getPrimaryDirection(MotionEvent event, int pointerIndex); float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId); int getMeasuredSize(View view); @@ -75,7 +76,7 @@ public interface PagedOrientationHandler { int getScrollOffsetEnd(View view, Rect insets); SingleAxisSwipeDetector.Direction getOppositeSwipeDirection(); int getPrimaryTranslationDirectionFactor(); - int getTaskDismissDirectionFactor(); + int getSecondaryTranslationDirectionFactor(); int getTaskDragDisplacementFactor(boolean isRtl); ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild); void setMaxScroll(AccessibilityEvent event, int maxScroll); diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 8f1c487f8a..9e53e5f8ec 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -104,6 +104,11 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { action.call(target, param, 0); } + @Override + public void setSecondary(T target, Float2DAction action, float param) { + action.call(target, 0, param); + } + @Override public float getPrimaryDirection(MotionEvent event, int pointerIndex) { return event.getX(pointerIndex); @@ -216,8 +221,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { return 1; } - @Override - public int getTaskDismissDirectionFactor() { + public int getSecondaryTranslationDirectionFactor() { return -1; } diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index e91f16d71a..7153452f23 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -28,7 +28,7 @@ import com.android.launcher3.Utilities; public class SeascapePagedViewHandler extends LandscapePagedViewHandler { @Override - public int getTaskDismissDirectionFactor() { + public int getSecondaryTranslationDirectionFactor() { return -1; }