From bb3460c01fb529fd6010fece7197ed03c3b0fcdc Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 28 Apr 2021 15:17:54 -0700 Subject: [PATCH 1/3] Align home/back button from overview with tap outside Set all interpolators in QuickstepAtomicAnimationFactory instead of overriding some in OverviewToHomeAnim. This also means we can just use a normal state transition instead of OverviewToHomeAnim when tapping outside recents (i.e. startHome()). Test: in all three gesture modes, the same animation is played whether tapping outside recents, pressing home, or pressing back Bug: 185411781 Change-Id: Ibe8734e8bd7041943eb76cac30d7cac26a90c73e --- .../QuickstepAtomicAnimationFactory.java | 23 +++++++----- .../quickstep/util/OverviewToHomeAnim.java | 36 +------------------ .../quickstep/views/LauncherRecentsView.java | 12 +------ 3 files changed, 16 insertions(+), 55 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index 3ac78663f7..fd7a67ad79 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -27,12 +27,15 @@ import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; +import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.INSTANT; +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.clampToProgress; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH; +import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X; @@ -82,17 +85,19 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL); config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL); config.setInterpolator(ANIM_ALL_APPS_FADE, ACCEL); - config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f)); - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL); + config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR); - if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) { - // Scrolling in tasks, so make visible straight away - if (overview.getTaskViewCount() > 0) { - config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME); - } else { - config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7); - } + if (SysUINavigationMode.getMode(mActivity).hasGestures + && overview.getTaskViewCount() > 0) { + // Overview is going offscreen, so keep it at its current scale and opacity. + config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME); + config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, + clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f)); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME); } else { + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL); + config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f)); config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7); } diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java index 42be9bbe13..b427e5fb2c 100644 --- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java +++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java @@ -17,21 +17,10 @@ package com.android.quickstep.util; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; -import static com.android.launcher3.anim.Interpolators.DEACCEL; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; -import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; -import static com.android.launcher3.anim.Interpolators.LINEAR; -import static com.android.launcher3.anim.Interpolators.clampToProgress; -import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; -import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE; -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 android.animation.Animator; import android.animation.AnimatorSet; import android.util.Log; -import android.view.animation.Interpolator; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -101,18 +90,8 @@ public class OverviewToHomeAnim { numPagesToScroll * PER_PAGE_SCROLL_DURATION); int duration = Math.max(scrollDuration, startState.getTransitionDuration(mLauncher)); - StateAnimationConfig config = new UseFirstInterpolatorStateAnimConfig(); + StateAnimationConfig config = new StateAnimationConfig(); config.duration = duration; - boolean isLayoutNaturalToLauncher = recentsView.getPagedOrientationHandler() - .isLayoutNaturalToLauncher(); - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, isLayoutNaturalToLauncher - ? clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f) : FINAL_FRAME); - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME); - config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME); - config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR); - if (!isLayoutNaturalToLauncher) { - config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL); - } AnimatorSet stateAnim = stateManager.createAtomicAnimation( startState, NORMAL, config); stateAnim.addListener(new AnimationSuccessListener() { @@ -133,17 +112,4 @@ public class OverviewToHomeAnim { mOnReachedHome.run(); } } - - /** - * Wrapper around StateAnimationConfig that doesn't allow interpolators to be set if they are - * already set. This ensures they aren't overridden before being used. - */ - private static class UseFirstInterpolatorStateAnimConfig extends StateAnimationConfig { - @Override - public void setInterpolator(int animId, Interpolator interpolator) { - if (mInterpolators[animId] == null || interpolator == null) { - super.setInterpolator(animId, interpolator); - } - } - } } diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java index 2c5f66170b..65956d578f 100644 --- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java @@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.LauncherState.SPRING_LOADED; -import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import android.annotation.TargetApi; import android.content.Context; @@ -39,7 +38,6 @@ import com.android.launcher3.statemanager.StateManager.StateListener; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.quickstep.LauncherActivityInterface; -import com.android.quickstep.util.OverviewToHomeAnim; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.RecentsExtraCard; @@ -90,15 +88,7 @@ public class LauncherRecentsView extends RecentsView mActivity.getStateManager().goToState(NORMAL, false); - OverviewToHomeAnim overviewToHomeAnim = new OverviewToHomeAnim(mActivity, onReachedHome); - if (LIVE_TILE.get()) { - switchToScreenshot(null, - () -> finishRecentsAnimation(true /* toRecents */, - () -> overviewToHomeAnim.animateWithVelocity(0))); - } else { - overviewToHomeAnim.animateWithVelocity(0); - } + mActivity.getStateManager().goToState(NORMAL); } @Override From e8b22d5e60d2527e073e6d20af014f2b4afccacb Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 14 Apr 2021 13:50:04 -0700 Subject: [PATCH 2/3] When overview appears from motion pause, come up from bottom - Add vertical offset calculations to RecentsView (in addition to the existing horizontal offset which has been renamed accordingly). - LauncherState#getOverviewScaleAndOffset() now supports both horizontal and vertical offsets and is specified such that overview appears and disappears from the bottom of the screen rather than the side. - Quick switch still uses horizontal offset to come from the side. - No longer need to scroll to page 0 when translating offscreen. - Update interpolators for overview to home transition. - Align 2 button mode transition with 0 button mode. Test: Visually checking all of these. As appropriate, repeat in 0, 2, 3 button modes, landscape/portrait/fake landscape, and 3P launcher - Quick switch from home - Home to overview - Overview to home (swipe up) - Overview to home (tap outside) - Overview to home (back invocation) - Quick switch from app - Swipe up and hold from app - Dismiss an app - Empty recents - Split select state to home - Modal state to home Bug: 185411781 Change-Id: Ic59b877ccc0050afd7cd478778e9eeb60e2e47f7 --- .../launcher3/BaseQuickstepLauncher.java | 3 +- .../BaseRecentsViewStateController.java | 11 +- .../uioverrides/states/AllAppsState.java | 5 - .../states/BackgroundAppState.java | 2 +- .../states/OverviewModalTaskState.java | 2 +- .../uioverrides/states/OverviewState.java | 8 +- .../QuickstepAtomicAnimationFactory.java | 62 +++++---- .../NoButtonQuickSwitchTouchController.java | 8 +- .../QuickSwitchTouchController.java | 11 ++ .../quickstep/BaseActivityInterface.java | 14 +-- .../FallbackRecentsStateController.java | 7 +- .../quickstep/fallback/RecentsState.java | 4 +- .../quickstep/util/OverviewToHomeAnim.java | 20 +-- .../util/RecentsAtomicAnimationFactory.java | 12 +- .../android/quickstep/views/RecentsView.java | 118 ++++++++++++++---- .../com/android/quickstep/views/TaskView.java | 5 + src/com/android/launcher3/Launcher.java | 2 +- src/com/android/launcher3/LauncherState.java | 4 +- 18 files changed, 196 insertions(+), 102 deletions(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index cd22196686..63c1fce328 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -19,6 +19,7 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON; import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.NO_OFFSET; import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS; @@ -343,7 +344,7 @@ public abstract class BaseQuickstepLauncher extends Launcher @Override public float[] getNormalOverviewScaleAndOffset() { return SysUINavigationMode.getMode(this).hasGestures - ? new float[] {1, 1} : new float[] {1.1f, 0}; + ? new float[] {1, NO_OFFSET, 1} : new float[] {1.1f, NO_OFFSET, NO_OFFSET}; } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index b3374f33b9..e508690113 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -22,8 +22,10 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FA 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.SKIP_OVERVIEW; -import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET; import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION; @@ -62,7 +64,8 @@ public abstract class BaseRecentsViewStateController public void setState(@NonNull LauncherState state) { float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher); RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]); - ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]); + ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]); + ADJACENT_PAGE_VERTICAL_OFFSET.set(mRecentsView, scaleAndOffset[2]); TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f); getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0); @@ -92,8 +95,10 @@ public abstract class BaseRecentsViewStateController float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher); setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0], config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR)); - setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], + setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR)); + setter.setFloat(mRecentsView, ADJACENT_PAGE_VERTICAL_OFFSET, scaleAndOffset[2], + config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR)); PagedOrientationHandler orientationHandler = ((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler(); FloatProperty taskViewsFloat = orientationHandler.getSplitSelectTaskOffset( diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index a81bdd52ca..d822c8cf82 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -83,11 +83,6 @@ public class AllAppsState extends LauncherState { return ALL_APPS_CONTENT; } - @Override - public float[] getOverviewScaleAndOffset(Launcher launcher) { - return new float[] {0.9f, 1}; - } - @Override public LauncherState getHistoryForState(LauncherState previousState) { return previousState == OVERVIEW ? OVERVIEW : NORMAL; diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 77c261154b..06ffae449e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -96,6 +96,6 @@ public class BackgroundAppState extends OverviewState { BaseDraggingActivity activity) { return new float[] { ((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(), - NO_OFFSET}; + NO_OFFSET, NO_OFFSET}; } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java index 6f084a1f97..1fc288f7cf 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java @@ -78,6 +78,6 @@ public class OverviewModalTaskState extends OverviewState { float scale = Math.min((float) modalTaskSize.height() / taskSize.y, (float) modalTaskSize.width() / taskSize.x); - return new float[] {scale, NO_OFFSET}; + return new float[] {scale, NO_OFFSET, NO_OFFSET}; } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 135c47865b..c9cfad3d3f 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -17,7 +17,6 @@ package com.android.launcher3.uioverrides.states; import static com.android.launcher3.anim.Interpolators.DEACCEL_2; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW; -import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import android.content.Context; import android.graphics.Rect; @@ -60,9 +59,8 @@ public class OverviewState extends LauncherState { @Override public int getTransitionDuration(Context context) { - // In no-button mode, overview comes in all the way from the left, so give it more time. - boolean isNoButtonMode = SysUINavigationMode.INSTANCE.get(context).getMode() == NO_BUTTON; - return isNoButtonMode ? 380 : 250; + // In gesture modes, overview comes in all the way from the bottom, so give it more time. + return SysUINavigationMode.INSTANCE.get(context).getMode().hasGestures ? 380 : 250; } @Override @@ -80,7 +78,7 @@ public class OverviewState extends LauncherState { @Override public float[] getOverviewScaleAndOffset(Launcher launcher) { - return new float[] {NO_SCALE, NO_OFFSET}; + return new float[] {NO_SCALE, NO_OFFSET, NO_OFFSET}; } @Override diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index fd7a67ad79..adc6b18fed 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -23,11 +23,10 @@ import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator; import static com.android.launcher3.anim.Interpolators.ACCEL; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; +import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; import static com.android.launcher3.anim.Interpolators.DEACCEL_3; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -40,20 +39,18 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FA 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.ANIM_SCRIM_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE; -import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import android.animation.ValueAnimator; -import android.view.View; import com.android.launcher3.CellLayout; import com.android.launcher3.Hotseat; import com.android.launcher3.LauncherState; import com.android.launcher3.Workspace; -import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.quickstep.SysUINavigationMode; @@ -68,6 +65,12 @@ public class QuickstepAtomicAnimationFactory extends // Scale recents takes before animating in private static final float RECENTS_PREPARE_SCALE = 1.33f; + // Scale workspace takes before animating in + private static final float WORKSPACE_PREPARE_SCALE_GESTURES = 0.97f; + private static final float WORKSPACE_PREPARE_SCALE_BUTTONS = 0.92f; + // When the overview to home transition reaches this percentage, immediately hide overview and + // start animating away the scrim and animating in workspace. + private static final float OVERVIEW_TO_HOME_HARD_HAND_OFF = 0.4f; // Due to use of physics, duration may differ between devices so we need to calculate and // cache the value. @@ -82,23 +85,31 @@ public class QuickstepAtomicAnimationFactory extends StateAnimationConfig config) { RecentsView overview = mActivity.getOverviewPanel(); if (toState == NORMAL && fromState == OVERVIEW) { - config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL); - config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL); - config.setInterpolator(ANIM_ALL_APPS_FADE, ACCEL); - config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR); - + final float workspacePrepareScale; if (SysUINavigationMode.getMode(mActivity).hasGestures && overview.getTaskViewCount() > 0) { + workspacePrepareScale = WORKSPACE_PREPARE_SCALE_GESTURES; // Overview is going offscreen, so keep it at its current scale and opacity. config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME); - config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME); - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, - clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f)); - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME); + config.setInterpolator(ANIM_OVERVIEW_FADE, clampToProgress( + FINAL_FRAME, 0f, OVERVIEW_TO_HOME_HARD_HAND_OFF)); + config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress( + DEACCEL, 0f, OVERVIEW_TO_HOME_HARD_HAND_OFF)); + config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, AGGRESSIVE_EASE_IN_OUT); + config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress( + DEACCEL, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f)); + config.setInterpolator(ANIM_WORKSPACE_SCALE, clampToProgress( + DEACCEL, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f)); + config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress( + INSTANT, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f)); } else { - config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL); + workspacePrepareScale = WORKSPACE_PREPARE_SCALE_BUTTONS; config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f)); config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7); + config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR); + config.setInterpolator(ANIM_SCRIM_FADE, LINEAR); + config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL); + config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL); } Workspace workspace = mActivity.getWorkspace(); @@ -111,25 +122,18 @@ public class QuickstepAtomicAnimationFactory extends && currentChild.getShortcutsAndWidgets().getAlpha() > 0; } if (!isWorkspaceVisible) { - workspace.setScaleX(0.92f); - workspace.setScaleY(0.92f); + workspace.setScaleX(workspacePrepareScale); + workspace.setScaleY(workspacePrepareScale); } Hotseat hotseat = mActivity.getHotseat(); boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0; if (!isHotseatVisible) { - hotseat.setScaleX(0.92f); - hotseat.setScaleY(0.92f); - AllAppsContainerView qsbContainer = mActivity.getAppsView(); - View qsb = qsbContainer.getSearchView(); - boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0; - if (!qsbVisible) { - qsbContainer.setScaleX(0.92f); - qsbContainer.setScaleY(0.92f); - } + hotseat.setScaleX(workspacePrepareScale); + hotseat.setScaleY(workspacePrepareScale); } } else if ((fromState == NORMAL || fromState == HINT_STATE || fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) { - if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) { + if (SysUINavigationMode.getMode(mActivity).hasGestures) { config.setInterpolator(ANIM_WORKSPACE_SCALE, fromState == NORMAL ? ACCEL : OVERSHOOT_1_2); config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL); @@ -153,6 +157,10 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_ALL_APPS_FADE, OVERSHOOT_1_2); config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2); config.setInterpolator(ANIM_DEPTH, OVERSHOOT_1_2); + config.setInterpolator(ANIM_SCRIM_FADE, t -> { + // Animate at the same rate until reaching progress 1, and skip the overshoot. + return Math.min(1, OVERSHOOT_1_2.getInterpolation(t)); + }); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_2); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_1_2); } else if (fromState == HINT_STATE && toState == NORMAL) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 8278a5a660..0f64abca61 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -41,7 +41,8 @@ import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT; import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP; import static com.android.launcher3.util.DisplayController.getSingleFrameMs; import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; -import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET; import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; @@ -221,7 +222,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // Set RecentView's initial properties. RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]); - ADJACENT_PAGE_OFFSET.set(mRecentsView, 1f); + ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f); + ADJACENT_PAGE_VERTICAL_OFFSET.set(mRecentsView, 0f); mRecentsView.setContentAlpha(1); mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress()); mLauncher.getActionsView().getVisibilityAlpha().setValue( @@ -233,7 +235,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, // - OverviewScrim // - RecentsView fade (if it's empty) PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2)); - xAnim.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], LINEAR); + xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR); xAnim.setViewBackgroundColor(mLauncher.getScrimView(), toState.getWorkspaceScrimColor(mLauncher), LINEAR); if (mRecentsView.getTaskViewCount() == 0) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java index 3953e4245d..5891d5f16a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java @@ -30,6 +30,9 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PR import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE; import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET; +import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; @@ -105,6 +108,14 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll StateAnimationConfig config = new StateAnimationConfig(); setupInterpolators(config); config.duration = (long) (getShiftRange() * 2); + + // Set RecentView's initial properties for coming in from the side. + RECENTS_SCALE_PROPERTY.set(mOverviewPanel, + QUICK_SWITCH.getOverviewScaleAndOffset(mLauncher)[0] * 0.85f); + ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mOverviewPanel, 1f); + ADJACENT_PAGE_VERTICAL_OFFSET.set(mOverviewPanel, 0f); + mOverviewPanel.setContentAlpha(1); + mCurrentAnimation = mLauncher.getStateManager() .createAnimationToNewWorkspace(mToState, config); mCurrentAnimation.getTarget().addListener(mClearStateOnCancelListener); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 7aa81d4819..b60b1be24b 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -23,8 +23,8 @@ import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION; import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS; import static com.android.quickstep.SysUINavigationMode.getMode; import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM; -import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM; -import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; +import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_Y_ANIM; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_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; @@ -469,17 +469,17 @@ public abstract class BaseActivityInterface { } public float[] getOverviewScaleAndOffset(RecentsActivity activity) { - return new float[] { NO_SCALE, NO_OFFSET }; + return new float[] { NO_SCALE, NO_OFFSET, NO_OFFSET }; } /** @@ -170,7 +170,7 @@ public class RecentsState implements BaseState { @Override public float[] getOverviewScaleAndOffset(RecentsActivity activity) { - return new float[] { NO_SCALE, 1 }; + return new float[] { NO_SCALE, NO_OFFSET, 1 }; } } } diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java index b427e5fb2c..10b7662ad9 100644 --- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java +++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java @@ -27,23 +27,16 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.states.StateAnimationConfig; -import com.android.quickstep.views.RecentsView; /** * Runs an animation from overview to home. Currently, this animation is just a wrapper around the - * normal state transition, in order to keep RecentsView at the same scale and translationY that - * it started out at as it translates offscreen. It also scrolls RecentsView to page 0 and may play - * a {@link StaggeredWorkspaceAnim} if we're starting from an upward fling. + * normal state transition and may play a {@link StaggeredWorkspaceAnim} if we're starting from an + * upward fling. */ public class OverviewToHomeAnim { private static final String TAG = "OverviewToHomeAnim"; - // Constants to specify how to scroll RecentsView to the default page if it's not already there. - private static final int DEFAULT_PAGE = 0; - private static final int PER_PAGE_SCROLL_DURATION = 150; - private static final int MAX_PAGE_SCROLL_DURATION = 750; - private final Launcher mLauncher; private final Runnable mOnReachedHome; @@ -84,14 +77,8 @@ public class OverviewToHomeAnim { mIsHomeStaggeredAnimFinished = true; } - RecentsView recentsView = mLauncher.getOverviewPanel(); - int numPagesToScroll = recentsView.getNextPage() - DEFAULT_PAGE; - int scrollDuration = Math.min(MAX_PAGE_SCROLL_DURATION, - numPagesToScroll * PER_PAGE_SCROLL_DURATION); - int duration = Math.max(scrollDuration, startState.getTransitionDuration(mLauncher)); - StateAnimationConfig config = new StateAnimationConfig(); - config.duration = duration; + config.duration = startState.getTransitionDuration(mLauncher); AnimatorSet stateAnim = stateManager.createAtomicAnimation( startState, NORMAL, config); stateAnim.addListener(new AnimationSuccessListener() { @@ -104,7 +91,6 @@ public class OverviewToHomeAnim { anim.play(stateAnim); stateManager.setCurrentAnimation(anim, NORMAL); anim.start(); - recentsView.snapToPage(DEFAULT_PAGE, duration); } private void maybeOverviewToHomeAnimComplete() { diff --git a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java index ba70bf70a4..c1ca060a60 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java +++ b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java @@ -15,11 +15,13 @@ */ package com.android.quickstep.util; -import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET; +import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET; import android.animation.Animator; import android.animation.ObjectAnimator; +import androidx.dynamicanimation.animation.DynamicAnimation; + import com.android.launcher3.anim.SpringAnimationBuilder; import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory; import com.android.launcher3.statemanager.StatefulActivity; @@ -29,7 +31,7 @@ public class RecentsAtomicAnimationFactory { public static final int INDEX_RECENTS_FADE_ANIM = AtomicAnimationFactory.NEXT_INDEX + 0; - public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1; + public static final int INDEX_RECENTS_TRANSLATE_Y_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1; private static final int MY_ANIM_COUNT = 2; @@ -46,14 +48,14 @@ public class RecentsAtomicAnimationFactory ADJACENT_PAGE_OFFSET = - new FloatProperty("adjacentPageOffset") { + public static final FloatProperty ADJACENT_PAGE_HORIZONTAL_OFFSET = + new FloatProperty("adjacentPageHorizontalOffset") { @Override public void setValue(RecentsView recentsView, float v) { - if (recentsView.mAdjacentPageOffset != v) { - recentsView.mAdjacentPageOffset = v; + if (recentsView.mAdjacentPageHorizontalOffset != v) { + recentsView.mAdjacentPageHorizontalOffset = v; recentsView.updatePageOffsets(); } } @Override public Float get(RecentsView recentsView) { - return recentsView.mAdjacentPageOffset; + return recentsView.mAdjacentPageHorizontalOffset; + } + }; + + public static final FloatProperty ADJACENT_PAGE_VERTICAL_OFFSET = + new FloatProperty("adjacentPageVerticalOffset") { + @Override + public void setValue(RecentsView recentsView, float v) { + if (recentsView.mAdjacentPageVerticalOffset != v) { + recentsView.mAdjacentPageVerticalOffset = v; + recentsView.updateVerticalPageOffsets(); + } + } + + @Override + public Float get(RecentsView recentsView) { + return recentsView.mAdjacentPageVerticalOffset; } }; @@ -240,6 +256,8 @@ public abstract class RecentsView= 0 - ? -getOffsetSize(midpoint - 1, midpoint, offset) + ? -getHorizontalOffsetSize(midpoint - 1, midpoint, offset) : 0; float rightOffsetSize = midpoint + 1 < count - ? getOffsetSize(midpoint + 1, midpoint, offset) + ? getHorizontalOffsetSize(midpoint + 1, midpoint, offset) : 0; boolean showAsGrid = showAsGrid(); @@ -2677,14 +2702,14 @@ public abstract class RecentsView= 0 - ? getOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset) + ? getHorizontalOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset) : 0; modalRightOffsetSize = modalMidpoint + 1 < count - ? getOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset) + ? getHorizontalOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset) : 0; } @@ -2735,7 +2760,7 @@ public abstract class RecentsView getSecondaryTaskOffsetTranslationProperty() { + return getPagedOrientationHandler().getSecondaryValue( + TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y); + } + public FloatProperty getTaskResistanceTranslationProperty() { return getPagedOrientationHandler().getSecondaryValue( TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 09c7b7aff0..bcc3e1ff69 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2780,7 +2780,7 @@ public class Launcher extends StatefulActivity implements Launche * @see LauncherState#getOverviewScaleAndOffset(Launcher) */ public float[] getNormalOverviewScaleAndOffset() { - return new float[] {NO_SCALE, NO_OFFSET}; + return new float[] {NO_SCALE, NO_OFFSET, NO_OFFSET}; } /** diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 4c11725719..9d50edd234 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -172,10 +172,12 @@ public abstract class LauncherState implements BaseState { } /** - * Returns an array of two elements. + * Returns an array of three elements. * The first specifies the scale for the overview * The second is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview * should be shifted horizontally. + * The third is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview + * should be shifted vertically. */ public float[] getOverviewScaleAndOffset(Launcher launcher) { return launcher.getNormalOverviewScaleAndOffset(); From 48d6dc7708624740691238877368706ac9b12012 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 26 Apr 2021 15:17:04 -0700 Subject: [PATCH 3/3] Fix running task damped by overscroll when other tasks are offscreen Test: Swipe up and to the left from an app, ensure the running task scrolls freely until the adjacent task comes in from offscreen Bug: 185411781 Change-Id: I9749124a6b6f014b55e3430d1764766a232eb9dd --- .../android/quickstep/views/RecentsView.java | 58 ++++++++++++------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d2d3bc39d5..23f720041b 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -644,28 +644,9 @@ public abstract class RecentsView 0) { + // Don't dampen the scroll (due to overscroll) if the adjacent tasks are offscreen, so + // that the page can move freely given there's no visual indication why it shouldn't. + overScrollShift = (int) Utilities.mapRange(mAdjacentPageVerticalOffset, overScrollShift, + getUndampedOverScrollShift()); + } return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this) - + getOverScrollShift(); + + overScrollShift; } /**