From b5669efa36e34a3ade936fc6ae1185715e99f5f0 Mon Sep 17 00:00:00 2001 From: Matthew Ng Date: Tue, 19 Jun 2018 11:04:00 -0700 Subject: [PATCH 01/14] Touching outside the task in overview goes home There is also a deadzone area around the clear all button to tap easier. Test: start overview click anywhere that is not the shelf or task Change-Id: I187ff264444da542aca111b57d94c8199f5a0384 Fixes: 110232233 --- quickstep/res/values/dimens.xml | 1 + .../fallback/FallbackRecentsView.java | 2 +- .../quickstep/views/LauncherRecentsView.java | 2 +- .../android/quickstep/views/RecentsView.java | 75 ++++++++++++++++++- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index afaad385d8..49c4492b60 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -21,6 +21,7 @@ 48dp 2dp 10dp + 70dp 20dp 50dp - -70dp + -100dp + 6.25dp 115dp 16sp diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 252e3eaeee..b9ff28456e 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -125,13 +125,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down. public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f; - private static final int APP_CLOSE_ROW_START_DELAY_MS = 8; + private static final int APP_CLOSE_ROW_START_DELAY_MS = 9; - // The sum of [slide, oscillate, and settle] should be <= LAUNCHER_RESUME_TOTAL_DURATION. - private static final int LAUNCHER_RESUME_TOTAL_DURATION = 346; - private static final int SPRING_SLIDE_DURATION = 166; - private static final int SPRING_OSCILLATE_DURATION = 130; - private static final int SPRING_SETTLE_DURATION = 50; + private static final int SPRING_SLIDE_DURATION = 170; + private static final int SPRING_OSCILLATE_DURATION = 550; + private static final int SPRING_SETTLE_DURATION = 25; + + private static final int SPRING_ALPHA_DURATION = 100; private final Launcher mLauncher; private final DragLayer mDragLayer; @@ -173,8 +173,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Resources res = mLauncher.getResources(); mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); - mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_trans_y); - mEndSlideTransY = -mStartSlideTransY * 0.1f; + mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_start_slide_trans_y); + mEndSlideTransY = res.getDimensionPixelSize(R.dimen.springs_end_slide_trans_y); mLauncher.addOnDeviceProfileChangeListener(this); registerRemoteAnimations(); @@ -837,7 +837,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag v.setAlpha(0); ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f); alpha.setInterpolator(LINEAR); - alpha.setDuration(SPRING_SLIDE_DURATION + SPRING_OSCILLATE_DURATION); + alpha.setDuration(SPRING_ALPHA_DURATION); alpha.setStartDelay(startDelay); outAnimator.play(alpha); diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 8a1abf412d..389da48074 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -119,18 +119,20 @@ public class Interpolators { public static final Interpolator OSCILLATE = new Interpolator() { // Used to scale the oscillations horizontally - private final float horizontalScale = 1f; + private final float horizontalScale = 4f; // Used to shift the oscillations horizontally - private final float horizontalShift = 0.5f; + private final float horizontalShift = 0.22f; // Used to scale the oscillations vertically private final float verticalScale = 1f; // Used to shift the oscillations vertically private final float verticalShift = 1f; + // Amplitude of oscillation + private final float amplitude = 0.9f; @Override public float getInterpolation(float t) { t = horizontalScale * (t + horizontalShift); - return (float) ((verticalScale * (Math.exp(-t) * Math.cos(2 * Math.PI * t))) + return (float) ((verticalScale * (Math.exp(-t) * Math.cos(amplitude * Math.PI * t))) + verticalShift); } }; From 5023771e05f0a64177dfeb2a545394ed4c63e9d1 Mon Sep 17 00:00:00 2001 From: Jonathan Miranda Date: Tue, 26 Jun 2018 20:21:07 +0000 Subject: [PATCH 04/14] Revert "Tune app closing/launcher resume animation "spring" values." This reverts commit c9a7c50fac2552b96c4f80587494afcb0da78aab. Reason for revert: Change-Id: I7ed4270b742803265ed4e3e13b63688842e0b48c --- quickstep/res/values/dimens.xml | 3 +-- .../LauncherAppTransitionManagerImpl.java | 18 +++++++++--------- .../android/launcher3/anim/Interpolators.java | 8 +++----- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 675b26112f..17d5c60baf 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -33,8 +33,7 @@ 50dp - -100dp - 6.25dp + -70dp 115dp 16sp diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index b9ff28456e..252e3eaeee 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -125,13 +125,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down. public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f; - private static final int APP_CLOSE_ROW_START_DELAY_MS = 9; + private static final int APP_CLOSE_ROW_START_DELAY_MS = 8; - private static final int SPRING_SLIDE_DURATION = 170; - private static final int SPRING_OSCILLATE_DURATION = 550; - private static final int SPRING_SETTLE_DURATION = 25; - - private static final int SPRING_ALPHA_DURATION = 100; + // The sum of [slide, oscillate, and settle] should be <= LAUNCHER_RESUME_TOTAL_DURATION. + private static final int LAUNCHER_RESUME_TOTAL_DURATION = 346; + private static final int SPRING_SLIDE_DURATION = 166; + private static final int SPRING_OSCILLATE_DURATION = 130; + private static final int SPRING_SETTLE_DURATION = 50; private final Launcher mLauncher; private final DragLayer mDragLayer; @@ -173,8 +173,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Resources res = mLauncher.getResources(); mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); - mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_start_slide_trans_y); - mEndSlideTransY = res.getDimensionPixelSize(R.dimen.springs_end_slide_trans_y); + mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_trans_y); + mEndSlideTransY = -mStartSlideTransY * 0.1f; mLauncher.addOnDeviceProfileChangeListener(this); registerRemoteAnimations(); @@ -837,7 +837,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag v.setAlpha(0); ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f); alpha.setInterpolator(LINEAR); - alpha.setDuration(SPRING_ALPHA_DURATION); + alpha.setDuration(SPRING_SLIDE_DURATION + SPRING_OSCILLATE_DURATION); alpha.setStartDelay(startDelay); outAnimator.play(alpha); diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 389da48074..8a1abf412d 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -119,20 +119,18 @@ public class Interpolators { public static final Interpolator OSCILLATE = new Interpolator() { // Used to scale the oscillations horizontally - private final float horizontalScale = 4f; + private final float horizontalScale = 1f; // Used to shift the oscillations horizontally - private final float horizontalShift = 0.22f; + private final float horizontalShift = 0.5f; // Used to scale the oscillations vertically private final float verticalScale = 1f; // Used to shift the oscillations vertically private final float verticalShift = 1f; - // Amplitude of oscillation - private final float amplitude = 0.9f; @Override public float getInterpolation(float t) { t = horizontalScale * (t + horizontalShift); - return (float) ((verticalScale * (Math.exp(-t) * Math.cos(amplitude * Math.PI * t))) + return (float) ((verticalScale * (Math.exp(-t) * Math.cos(2 * Math.PI * t))) + verticalShift); } }; From 626467130f739fd3742c969be461b869a5368f10 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Tue, 26 Jun 2018 14:19:02 -0700 Subject: [PATCH 05/14] Add additional call to onStop() to stablize PIP position. Bug: 110799409 Test: Manual Change-Id: I361eeadbf298bb239d8e373f3c6fa49d1f2410a6 --- src/com/android/launcher3/Launcher.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3a8679e21b..c3c4f5e5ed 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -741,6 +741,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, NotificationListener.removeNotificationsChangedListener(); getStateManager().moveToRestState(); + UiFactory.onLauncherStateOrResumeChanged(this); + // Workaround for b/78520668, explicitly trim memory once UI is hidden onTrimMemory(TRIM_MEMORY_UI_HIDDEN); } From 33cbe61e97012d7832c3940eb8a4888f81bff6e0 Mon Sep 17 00:00:00 2001 From: Jonathan Miranda Date: Tue, 26 Jun 2018 20:21:26 +0000 Subject: [PATCH 06/14] Revert "Fix typo in horizontalShift" This reverts commit e45b3e21a95e40168a35c4bcd0f425ba2e56bc11. Reason for revert: Change-Id: I4d2956d3f8d23e8f9579fd61418bc84e7226ef60 --- src/com/android/launcher3/anim/Interpolators.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 8a1abf412d..efb08a11a5 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -121,7 +121,7 @@ public class Interpolators { // Used to scale the oscillations horizontally private final float horizontalScale = 1f; // Used to shift the oscillations horizontally - private final float horizontalShift = 0.5f; + private final float horizontalShift = 05f; // Used to scale the oscillations vertically private final float verticalScale = 1f; // Used to shift the oscillations vertically From 6a2a1a91a01b58af68b378612a4a33ca94d3363b Mon Sep 17 00:00:00 2001 From: Jonathan Miranda Date: Tue, 26 Jun 2018 20:22:18 +0000 Subject: [PATCH 07/14] Revert "Refactor "spring" code into one method." This reverts commit b83c71aa24983e1a8b7910cad32cb49133891e55. Reason for revert: Change-Id: I747dfc2ed63709f5f4032b4d4bd2cf3cd5d9e8ce --- .../LauncherAppTransitionManagerImpl.java | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 252e3eaeee..4108cd290f 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -57,7 +57,6 @@ import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.util.Pair; -import android.util.Property; import android.view.View; import android.view.ViewGroup; @@ -805,9 +804,25 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag float shiftRange = allAppsController.getShiftRange(); float slideStart = shiftRange / (shiftRange - mStartSlideTransY); float oscillateStart = shiftRange / (shiftRange - mEndSlideTransY); + // Ensures a clean hand-off between slide and oscillate. + float slideEnd = Utilities.mapToRange(0, 0, 1f, oscillateStart, 1, OSCILLATE); - buildSpringAnimation(workspaceAnimator, allAppsController, ALL_APPS_PROGRESS, - 0 /* startDelay */, slideStart, oscillateStart, 1f /* finalPosition */); + allAppsController.setProgress(slideStart); + Animator slideIn = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, + slideStart, slideEnd); + slideIn.setDuration(SPRING_SLIDE_DURATION); + slideIn.setInterpolator(DEACCEL); + + Animator oscillate = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, + oscillateStart, 1f); + oscillate.setDuration(SPRING_OSCILLATE_DURATION); + oscillate.setInterpolator(OSCILLATE); + + Animator settle = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, 1f); + settle.setDuration(SPRING_SETTLE_DURATION); + settle.setInterpolator(LINEAR); + + workspaceAnimator.playSequentially(slideIn, oscillate, settle); } mDragLayer.getScrim().hideSysUiScrim(true); @@ -837,13 +852,28 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag v.setAlpha(0); ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f); alpha.setInterpolator(LINEAR); - alpha.setDuration(SPRING_SLIDE_DURATION + SPRING_OSCILLATE_DURATION); + alpha.setDuration(SPRING_SLIDE_DURATION); alpha.setStartDelay(startDelay); outAnimator.play(alpha); - buildSpringAnimation(outAnimator, v, TRANSLATION_Y, startDelay, mStartSlideTransY, - mEndSlideTransY, 0f /* finalPosition */); + // Ensures a clean hand-off between slide and oscillate. + float slideEnd = Utilities.mapToRange(0, 0, 1f, mEndSlideTransY, 0, OSCILLATE); + v.setTranslationY(mStartSlideTransY); + ObjectAnimator slideIn = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mStartSlideTransY, + slideEnd); + slideIn.setInterpolator(DEACCEL); + slideIn.setStartDelay(startDelay); + slideIn.setDuration(SPRING_SLIDE_DURATION); + ObjectAnimator oscillate = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mEndSlideTransY, 0); + oscillate.setInterpolator(OSCILLATE); + oscillate.setDuration(SPRING_OSCILLATE_DURATION); + + ObjectAnimator settle = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0); + settle.setInterpolator(LINEAR); + settle.setDuration(SPRING_SETTLE_DURATION); + + outAnimator.playSequentially(slideIn, oscillate, settle); outAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -853,36 +883,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag }); } - /** - * Spring animations consists of three sequential animators: a slide, an oscillation, and - * a settle. - */ - private void buildSpringAnimation(AnimatorSet outAnimator, T objectToSpring, - Property property, long startDelay, float slideStart, float oscillateStart, - float finalPosition) { - // Ensures a clean hand-off between slide and oscillate. - float slideEnd = Utilities.mapToRange(0, 0, 1f, oscillateStart, finalPosition, OSCILLATE); - - property.set(objectToSpring, slideStart); - - ObjectAnimator slideIn = ObjectAnimator.ofFloat(objectToSpring, property, slideStart, - slideEnd); - slideIn.setInterpolator(DEACCEL); - slideIn.setStartDelay(startDelay); - slideIn.setDuration(SPRING_SLIDE_DURATION); - - ObjectAnimator oscillate = ObjectAnimator.ofFloat(objectToSpring, property, oscillateStart, - finalPosition); - oscillate.setInterpolator(OSCILLATE); - oscillate.setDuration(SPRING_OSCILLATE_DURATION); - - ObjectAnimator settle = ObjectAnimator.ofFloat(objectToSpring, property, finalPosition); - settle.setInterpolator(LINEAR); - settle.setDuration(SPRING_SETTLE_DURATION); - - outAnimator.playSequentially(slideIn, oscillate, settle); - } - private void resetContentView() { mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd(); mDragLayerAlpha.setValue(1f); From f274996ef3c3cdfafd43047ece976f25e273bb70 Mon Sep 17 00:00:00 2001 From: Jonathan Miranda Date: Tue, 26 Jun 2018 23:01:05 +0000 Subject: [PATCH 08/14] Revert "Add stagger and "springs" to app closing transition." This reverts commit cd57901ca460975205af9ba6cd5cd96a7225fc15. Reason for revert: Change-Id: I13e9d2db8f6d6118a1448ba04b67c81b4e485447 --- quickstep/res/values/dimens.xml | 2 +- .../LauncherAppTransitionManagerImpl.java | 116 +++--------------- .../android/launcher3/anim/Interpolators.java | 23 ---- 3 files changed, 18 insertions(+), 123 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 17d5c60baf..49c4492b60 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -33,7 +33,7 @@ 50dp - -70dp + 50dp 115dp 16sp diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index 4108cd290f..14633afa52 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -16,7 +16,6 @@ package com.android.launcher3; -import static android.view.View.TRANSLATION_Y; import static com.android.launcher3.BaseActivity.INVISIBLE_ALL; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS; @@ -28,10 +27,8 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS; import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE; -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.LINEAR; -import static com.android.launcher3.anim.Interpolators.OSCILLATE; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS; import static com.android.quickstep.TaskUtils.findTaskViewToLaunch; import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator; @@ -118,20 +115,12 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag public static final int RECENTS_LAUNCH_DURATION = 336; public static final int RECENTS_QUICKSCRUB_LAUNCH_DURATION = 300; - private static final int LAUNCHER_RESUME_START_DELAY = 40; + private static final int LAUNCHER_RESUME_START_DELAY = 100; private static final int CLOSING_TRANSITION_DURATION_MS = 250; // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down. public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f; - private static final int APP_CLOSE_ROW_START_DELAY_MS = 8; - - // The sum of [slide, oscillate, and settle] should be <= LAUNCHER_RESUME_TOTAL_DURATION. - private static final int LAUNCHER_RESUME_TOTAL_DURATION = 346; - private static final int SPRING_SLIDE_DURATION = 166; - private static final int SPRING_OSCILLATE_DURATION = 130; - private static final int SPRING_SETTLE_DURATION = 50; - private final Launcher mLauncher; private final DragLayer mDragLayer; private final AlphaProperty mDragLayerAlpha; @@ -140,8 +129,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag private final boolean mIsRtl; private final float mContentTransY; - private final float mStartSlideTransY; - private final float mEndSlideTransY; + private final float mWorkspaceTransY; private final float mClosingWindowTransY; private DeviceProfile mDeviceProfile; @@ -171,9 +159,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag Resources res = mLauncher.getResources(); mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); + mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y); mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); - mStartSlideTransY = res.getDimensionPixelSize(R.dimen.springs_trans_y); - mEndSlideTransY = -mStartSlideTransY * 0.1f; mLauncher.addOnDeviceProfileChangeListener(this); registerRemoteAnimations(); @@ -785,49 +772,25 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag }); } else { AnimatorSet workspaceAnimator = new AnimatorSet(); + + mDragLayer.setTranslationY(-mWorkspaceTransY);; + workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, + -mWorkspaceTransY, 0)); + + mDragLayerAlpha.setValue(0); + workspaceAnimator.play(ObjectAnimator.ofFloat( + mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f)); + workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY); - - ShortcutAndWidgetContainer currentPage = ((CellLayout) mLauncher.getWorkspace() - .getChildAt(mLauncher.getWorkspace().getCurrentPage())) - .getShortcutsAndWidgets(); - - // Set up springs on workspace items. - for (int i = currentPage.getChildCount() - 1; i >= 0; i--) { - View child = currentPage.getChildAt(i); - CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams()); - addStaggeredAnimationForView(child, workspaceAnimator, lp.cellY + lp.cellVSpan); - } - - // Set up a spring for the shelf. - if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) { - AllAppsTransitionController allAppsController = mLauncher.getAllAppsController(); - float shiftRange = allAppsController.getShiftRange(); - float slideStart = shiftRange / (shiftRange - mStartSlideTransY); - float oscillateStart = shiftRange / (shiftRange - mEndSlideTransY); - // Ensures a clean hand-off between slide and oscillate. - float slideEnd = Utilities.mapToRange(0, 0, 1f, oscillateStart, 1, OSCILLATE); - - allAppsController.setProgress(slideStart); - Animator slideIn = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, - slideStart, slideEnd); - slideIn.setDuration(SPRING_SLIDE_DURATION); - slideIn.setInterpolator(DEACCEL); - - Animator oscillate = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, - oscillateStart, 1f); - oscillate.setDuration(SPRING_OSCILLATE_DURATION); - oscillate.setInterpolator(OSCILLATE); - - Animator settle = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, 1f); - settle.setDuration(SPRING_SETTLE_DURATION); - settle.setInterpolator(LINEAR); - - workspaceAnimator.playSequentially(slideIn, oscillate, settle); - } + workspaceAnimator.setDuration(333); + workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7); mDragLayer.getScrim().hideSysUiScrim(true); + // Pause page indicator animations as they lead to layer trashing. mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); + mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null); + workspaceAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -838,51 +801,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag } } - /** - * Adds an alpha/trans animator for {@param v}, with a start delay based on the view's row. - * - * @param v View in a ShortcutAndWidgetContainer. - * @param row The bottom-most row that contains the view. - */ - private void addStaggeredAnimationForView(View v, AnimatorSet outAnimator, int row) { - // Invert the rows, because we stagger starting from the bottom of the screen. - int invertedRow = LauncherAppState.getIDP(mLauncher).numRows - row + 1; - long startDelay = (long) (invertedRow * APP_CLOSE_ROW_START_DELAY_MS); - - v.setAlpha(0); - ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 1f); - alpha.setInterpolator(LINEAR); - alpha.setDuration(SPRING_SLIDE_DURATION); - alpha.setStartDelay(startDelay); - outAnimator.play(alpha); - - // Ensures a clean hand-off between slide and oscillate. - float slideEnd = Utilities.mapToRange(0, 0, 1f, mEndSlideTransY, 0, OSCILLATE); - v.setTranslationY(mStartSlideTransY); - ObjectAnimator slideIn = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mStartSlideTransY, - slideEnd); - slideIn.setInterpolator(DEACCEL); - slideIn.setStartDelay(startDelay); - slideIn.setDuration(SPRING_SLIDE_DURATION); - - ObjectAnimator oscillate = ObjectAnimator.ofFloat(v, TRANSLATION_Y, mEndSlideTransY, 0); - oscillate.setInterpolator(OSCILLATE); - oscillate.setDuration(SPRING_OSCILLATE_DURATION); - - ObjectAnimator settle = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0); - settle.setInterpolator(LINEAR); - settle.setDuration(SPRING_SETTLE_DURATION); - - outAnimator.playSequentially(slideIn, oscillate, settle); - outAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - v.setAlpha(1f); - v.setTranslationY(0); - } - }); - } - private void resetContentView() { mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd(); mDragLayerAlpha.setValue(1f); diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index efb08a11a5..a4cba4f62e 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -112,29 +112,6 @@ public class Interpolators { } }; - /** - * Interpolates using a particular section of the damped oscillation function. - * The section is selected by scaling and shifting the function. - */ - public static final Interpolator OSCILLATE = new Interpolator() { - - // Used to scale the oscillations horizontally - private final float horizontalScale = 1f; - // Used to shift the oscillations horizontally - private final float horizontalShift = 05f; - // Used to scale the oscillations vertically - private final float verticalScale = 1f; - // Used to shift the oscillations vertically - private final float verticalShift = 1f; - - @Override - public float getInterpolation(float t) { - t = horizontalScale * (t + horizontalShift); - return (float) ((verticalScale * (Math.exp(-t) * Math.cos(2 * Math.PI * t))) - + verticalShift); - } - }; - private static final float FAST_FLING_PX_MS = 10; public static Interpolator scrollInterpolatorForVelocity(float velocity) { From cc3755da6e9c7b389fbf44dc6cf0a7faeb8012a7 Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 24 Jun 2018 22:47:04 -0700 Subject: [PATCH 09/14] Swipe up overshoot always plays Instead of using an OvershootInterpolator, we adjust the end progress to > 1 and add a second interpolator to settle back to 1. That way, even if the animation runs starting very late, e.g. 1.0, it still has room to overshoot. We use this same OvershootParams class to calculate an overshoot for a blocked long fling as well. Bug: 109709720 Change-Id: I43152237e4350f93e7c462c22e68d09d05c1dd57 --- .../android/quickstep/LongSwipeHelper.java | 26 ++++-- .../WindowTransformSwipeHandler.java | 61 ++++++++------ .../android/launcher3/anim/Interpolators.java | 82 +++++++++++++++++-- 3 files changed, 133 insertions(+), 36 deletions(-) diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java index 0785093302..491cbb3d26 100644 --- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java +++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java @@ -20,17 +20,22 @@ import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION; +import static com.android.quickstep.WindowTransformSwipeHandler.MIN_OVERSHOOT_DURATION; import android.animation.ValueAnimator; +import android.view.animation.Interpolator; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherStateManager; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; +import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.anim.Interpolators.OvershootParams; import com.android.launcher3.uioverrides.PortraitStatesTouchController; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; @@ -89,7 +94,9 @@ public class LongSwipeHelper { } public void end(float velocity, boolean isFling, Runnable callback) { + float velocityPxPerMs = velocity / 1000; long duration = MAX_SWIPE_DURATION; + Interpolator interpolator = DEACCEL; final float currentFraction = mAnimator.getProgressFraction(); final boolean toAllApps; @@ -107,6 +114,17 @@ public class LongSwipeHelper { long expectedDuration = Math.abs(Math.round((endProgress - currentFraction) * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER)); duration = Math.min(MAX_SWIPE_DURATION, expectedDuration); + + if (blockedFling && !toAllApps) { + Interpolators.OvershootParams overshoot = new OvershootParams(currentFraction, + currentFraction, endProgress, velocityPxPerMs, (int) mMaxSwipeDistance); + duration = (overshoot.duration + duration) + * LauncherAnimUtils.blockedFlingDurationFactor(0); + duration = Utilities.boundToRange(duration, MIN_OVERSHOOT_DURATION, + MAX_SWIPE_DURATION); + interpolator = overshoot.interpolator; + endProgress = overshoot.end; + } } else { toAllApps = velocity < 0; endProgress = toAllApps ? 1 : 0; @@ -119,18 +137,16 @@ public class LongSwipeHelper { // we want the page's snap velocity to approximately match the velocity at // which the user flings, so we scale the duration by a value near to the // derivative of the scroll interpolator at zero, ie. 2. - long baseDuration = Math.round(1000 * Math.abs(distanceToTravel / velocity)); + long baseDuration = Math.round(Math.abs(distanceToTravel / velocityPxPerMs)); duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration); } } - if (blockedFling && !toAllApps) { - duration *= LauncherAnimUtils.blockedFlingDurationFactor(0); - } final boolean finalIsFling = isFling; mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, finalIsFling, callback)); + ValueAnimator animator = mAnimator.getAnimationPlayer(); - animator.setDuration(duration).setInterpolator(DEACCEL); + animator.setDuration(duration).setInterpolator(interpolator); animator.setFloatValues(currentFraction, endProgress); animator.start(); } diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index ff3137d441..15ff19e260 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -21,6 +21,7 @@ import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION; import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL; import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB; @@ -163,6 +164,7 @@ public class WindowTransformSwipeHandler { public static final long MAX_SWIPE_DURATION = 350; public static final long MIN_SWIPE_DURATION = 80; + public static final long MIN_OVERSHOOT_DURATION = 120; public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f; private static final float SWIPE_DURATION_MULTIPLIER = @@ -498,7 +500,8 @@ public class WindowTransformSwipeHandler { setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED); // Start the window animation without waiting for launcher. - animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR); + animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR, + true /* goingToHome */); } private void shiftAnimationDestinationForQuickscrub() { @@ -699,36 +702,46 @@ public class WindowTransformSwipeHandler { private void handleNormalGestureEnd(float endVelocity, boolean isFling) { float velocityPxPerMs = endVelocity / 1000; long duration = MAX_SWIPE_DURATION; - final float endShift; + float currentShift = mCurrentShift.value; + final boolean goingToHome; + float endShift; final float startShift; - final Interpolator interpolator; + Interpolator interpolator = DEACCEL; if (!isFling) { - endShift = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted ? 1 : 0; - long expectedDuration = Math.abs(Math.round((endShift - mCurrentShift.value) + goingToHome = currentShift >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted; + endShift = goingToHome ? 1 : 0; + long expectedDuration = Math.abs(Math.round((endShift - currentShift) * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER)); duration = Math.min(MAX_SWIPE_DURATION, expectedDuration); - startShift = mCurrentShift.value; - interpolator = DEACCEL; + startShift = currentShift; + interpolator = goingToHome ? OVERSHOOT_1_2 : DEACCEL; } else { - endShift = endVelocity < 0 ? 1 : 0; - interpolator = endVelocity < 0 - ? Interpolators.overshootInterpolatorForVelocity(velocityPxPerMs, 2f) - : DEACCEL; + goingToHome = endVelocity < 0; + endShift = goingToHome ? 1 : 0; + startShift = Utilities.boundToRange(currentShift - velocityPxPerMs + * SINGLE_FRAME_MS / mTransitionDragLength, 0, 1); float minFlingVelocity = mContext.getResources() .getDimension(R.dimen.quickstep_fling_min_velocity); if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) { - float distanceToTravel = (endShift - mCurrentShift.value) * mTransitionDragLength; + if (goingToHome) { + Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams( + startShift, endShift, endShift, velocityPxPerMs, mTransitionDragLength); + endShift = overshoot.end; + interpolator = overshoot.interpolator; + duration = Utilities.boundToRange(overshoot.duration, MIN_OVERSHOOT_DURATION, + MAX_SWIPE_DURATION); + } else { + float distanceToTravel = (endShift - currentShift) * mTransitionDragLength; - // we want the page's snap velocity to approximately match the velocity at - // which the user flings, so we scale the duration by a value near to the - // derivative of the scroll interpolator at zero, ie. 2. - long baseDuration = Math.round(Math.abs(distanceToTravel / velocityPxPerMs)); - duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration); + // we want the page's snap velocity to approximately match the velocity at + // which the user flings, so we scale the duration by a value near to the + // derivative of the scroll interpolator at zero, ie. 2. + long baseDuration = Math.round(Math.abs(distanceToTravel / velocityPxPerMs)); + duration = Math.min(MAX_SWIPE_DURATION, 2 * baseDuration); + } } - startShift = Utilities.boundToRange(mCurrentShift.value - velocityPxPerMs - * SINGLE_FRAME_MS / (mTransitionDragLength), 0, 1); } - animateToProgress(startShift, endShift, duration, interpolator); + animateToProgress(startShift, endShift, duration, interpolator, goingToHome); } private void doLogGesture(boolean toLauncher) { @@ -754,14 +767,14 @@ public class WindowTransformSwipeHandler { /** Animates to the given progress, where 0 is the current app and 1 is overview. */ private void animateToProgress(float start, float end, long duration, - Interpolator interpolator) { + Interpolator interpolator, boolean goingToHome) { mRecentsAnimationWrapper.runOnInit(() -> animateToProgressInternal(start, end, duration, - interpolator)); + interpolator, goingToHome)); } private void animateToProgressInternal(float start, float end, long duration, - Interpolator interpolator) { - mIsGoingToHome = Float.compare(end, 1) == 0; + Interpolator interpolator, boolean goingToHome) { + mIsGoingToHome = goingToHome; ObjectAnimator anim = mCurrentShift.animateToValue(start, end).setDuration(duration); anim.setInterpolator(interpolator); anim.addListener(new AnimationSuccessListener() { diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 8a1abf412d..1d71c605e6 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -16,7 +16,10 @@ package com.android.launcher3.anim; +import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; + import android.graphics.Path; +import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; @@ -45,6 +48,8 @@ public class Interpolators { public static final Interpolator DEACCEL_2_5 = new DecelerateInterpolator(2.5f); public static final Interpolator DEACCEL_3 = new DecelerateInterpolator(3f); + public static final Interpolator ACCEL_DEACCEL = new AccelerateDecelerateInterpolator(); + public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f); public static final Interpolator AGGRESSIVE_EASE = new PathInterpolator(0.2f, 0f, 0f, 1f); @@ -141,17 +146,12 @@ public class Interpolators { return Math.abs(velocity) > FAST_FLING_PX_MS ? SCROLL : SCROLL_CUBIC; } - public static Interpolator overshootInterpolatorForVelocity(float velocity) { - return overshootInterpolatorForVelocity(velocity, 1f); - } - /** * Create an OvershootInterpolator with tension directly related to the velocity (in px/ms). * @param velocity The start velocity of the animation we want to overshoot. - * @param dampFactor An optional factor to reduce the amount of tension (how far we overshoot). */ - public static Interpolator overshootInterpolatorForVelocity(float velocity, float dampFactor) { - return new OvershootInterpolator(Math.min(Math.abs(velocity), 3f) / dampFactor); + public static Interpolator overshootInterpolatorForVelocity(float velocity) { + return new OvershootInterpolator(Math.min(Math.abs(velocity), 3f)); } /** @@ -183,4 +183,72 @@ public class Interpolators { float upperBound) { return t -> Utilities.mapRange(interpolator.getInterpolation(t), lowerBound, upperBound); } + + /** + * Computes parameters necessary for an overshoot effect. + */ + public static class OvershootParams { + public Interpolator interpolator; + public float start; + public float end; + public long duration; + + /** + * Given the input params, sets OvershootParams variables to be used by the caller. + * @param startProgress The progress from 0 to 1 that the overshoot starts from. + * @param overshootPastProgress The progress from 0 to 1 where we overshoot past (should + * either be equal to startProgress or endProgress, depending on if we want to + * overshoot immediately or only once we reach the end). + * @param endProgress The final progress from 0 to 1 that we will settle to. + * @param velocityPxPerMs The initial velocity that causes this overshoot. + * @param totalDistancePx The distance against which progress is calculated. + */ + public OvershootParams(float startProgress, float overshootPastProgress, + float endProgress, float velocityPxPerMs, int totalDistancePx) { + velocityPxPerMs = Math.abs(velocityPxPerMs); + start = startProgress; + int startPx = (int) (start * totalDistancePx); + // Overshoot by about half a frame. + float overshootBy = velocityPxPerMs * SINGLE_FRAME_MS / totalDistancePx / 2; + overshootBy = Utilities.boundToRange(overshootBy, 0.02f, 0.15f); + end = overshootPastProgress + overshootBy; + int endPx = (int) (end * totalDistancePx); + int overshootDistance = endPx - startPx; + // Calculate deceleration necessary to reach overshoot distance. + // Formula: velocityFinal^2 = velocityInitial^2 + 2 * acceleration * distance + // 0 = v^2 + 2ad (velocityFinal == 0) + // a = v^2 / -2d + float decelerationPxPerMs = velocityPxPerMs * velocityPxPerMs / (2 * overshootDistance); + // Calculate time necessary to reach peak of overshoot. + // Formula: acceleration = velocity / time + // time = velocity / acceleration + duration = (long) (velocityPxPerMs / decelerationPxPerMs); + + // Now that we're at the top of the overshoot, need to settle back to endProgress. + float settleDistance = end - endProgress; + int settleDistancePx = (int) (settleDistance * totalDistancePx); + // Calculate time necessary for the settle. + // Formula: distance = velocityInitial * time + 1/2 * acceleration * time^2 + // d = 1/2at^2 (velocityInitial = 0, since we just stopped at the top) + // t = sqrt(2d/a) + // Above formula assumes constant acceleration. Since we use ACCEL_DEACCEL, we actually + // have acceleration to halfway then deceleration the rest. So the formula becomes: + // t = sqrt(d/a) * 2 (half the distance for accel, half for deaccel) + long settleDuration = (long) Math.sqrt(settleDistancePx / decelerationPxPerMs) * 2; + // How much of the animation to devote to playing the overshoot (the rest is for settle). + float overshootFraction = (float) duration / (duration + settleDuration); + duration += settleDuration; + // Finally, create the interpolator, composed of two interpolators: an overshoot, which + // reaches end > 1, and then a settle to endProgress. + Interpolator overshoot = Interpolators.clampToProgress(DEACCEL, 0, overshootFraction); + // The settle starts at 1, where 1 is the top of the overshoot, and maps to a fraction + // such that final progress is endProgress. For example, if we overshot to 1.1 but want + // to end at 1, we need to map to 1/1.1. + Interpolator settle = Interpolators.clampToProgress(Interpolators.mapToProgress( + ACCEL_DEACCEL, 1, (endProgress - start) / (end - start)), overshootFraction, 1); + interpolator = t -> t <= overshootFraction + ? overshoot.getInterpolation(t) + : settle.getInterpolation(t); + } + } } \ No newline at end of file From d63e6dff2888686b075547ded2c3ad7b236a45e3 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Wed, 27 Jun 2018 15:42:33 -0700 Subject: [PATCH 10/14] Last minute swipe up overshoot tweaks b/109709720 Change-Id: Ie3831289a9af2ba4b03fcbb4f2cbb3f4c2431aec --- .../src/com/android/quickstep/LongSwipeHelper.java | 3 +-- src/com/android/launcher3/anim/Interpolators.java | 12 +++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java index 491cbb3d26..6b66ec8db5 100644 --- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java +++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java @@ -118,8 +118,7 @@ public class LongSwipeHelper { if (blockedFling && !toAllApps) { Interpolators.OvershootParams overshoot = new OvershootParams(currentFraction, currentFraction, endProgress, velocityPxPerMs, (int) mMaxSwipeDistance); - duration = (overshoot.duration + duration) - * LauncherAnimUtils.blockedFlingDurationFactor(0); + duration = (overshoot.duration + duration); duration = Utilities.boundToRange(duration, MIN_OVERSHOOT_DURATION, MAX_SWIPE_DURATION); interpolator = overshoot.interpolator; diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 3e01f7262e..675e26de05 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -57,6 +57,9 @@ public class Interpolators { public static final Interpolator EXAGGERATED_EASE; + private static final int MIN_SETTLE_DURATION = 200; + private static final float OVERSHOOT_FACTOR = 0.9f; + static { Path exaggeratedEase = new Path(); exaggeratedEase.moveTo(0, 0); @@ -186,7 +189,8 @@ public class Interpolators { start = startProgress; int startPx = (int) (start * totalDistancePx); // Overshoot by about half a frame. - float overshootBy = velocityPxPerMs * SINGLE_FRAME_MS / totalDistancePx / 2; + float overshootBy = OVERSHOOT_FACTOR * velocityPxPerMs * + SINGLE_FRAME_MS / totalDistancePx / 2; overshootBy = Utilities.boundToRange(overshootBy, 0.02f, 0.15f); end = overshootPastProgress + overshootBy; int endPx = (int) (end * totalDistancePx); @@ -211,7 +215,9 @@ public class Interpolators { // Above formula assumes constant acceleration. Since we use ACCEL_DEACCEL, we actually // have acceleration to halfway then deceleration the rest. So the formula becomes: // t = sqrt(d/a) * 2 (half the distance for accel, half for deaccel) - long settleDuration = (long) Math.sqrt(settleDistancePx / decelerationPxPerMs) * 2; + long settleDuration = (long) Math.sqrt(settleDistancePx / decelerationPxPerMs) * 4; + + settleDuration = Math.max(MIN_SETTLE_DURATION, settleDuration); // How much of the animation to devote to playing the overshoot (the rest is for settle). float overshootFraction = (float) duration / (duration + settleDuration); duration += settleDuration; @@ -228,4 +234,4 @@ public class Interpolators { : settle.getInterpolation(t); } } -} \ No newline at end of file +} From 7d4ef41cb4fdebeec7b009c7997c5e7e9be0b00f Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 28 Jun 2018 11:33:23 -0700 Subject: [PATCH 11/14] Fix clipping issue on adaptive icons Bug: 62372639 Change-Id: Ie9dcf18f61c45225823dfbbf85578edcbffd86b9 --- src/com/android/launcher3/IconCache.java | 2 +- src/com/android/launcher3/graphics/LauncherIcons.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index 9dc3129fd8..c5ca183f7d 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -801,7 +801,7 @@ public class IconCache { } private static final class IconDB extends SQLiteCacheHelper { - private final static int RELEASE_VERSION = 23; + private final static int RELEASE_VERSION = 24; private final static String TABLE_NAME = "icons"; private final static String COLUMN_ROWID = "rowid"; diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java index 09ea1ad41a..ece6c58407 100644 --- a/src/com/android/launcher3/graphics/LauncherIcons.java +++ b/src/com/android/launcher3/graphics/LauncherIcons.java @@ -337,15 +337,16 @@ public class LauncherIcons implements AutoCloseable { final int top = (textureHeight-height) / 2; mOldBounds.set(icon.getBounds()); + int offset = 0; if (Utilities.ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) { - int offset = Math.max((int) Math.ceil(BLUR_FACTOR * textureWidth), Math.max(left, top)); + offset = Math.max((int) Math.ceil(BLUR_FACTOR * textureWidth), Math.max(left, top)); int size = Math.max(width, height); icon.setBounds(offset, offset, offset + size, offset + size); } else { icon.setBounds(left, top, left+width, top+height); } mCanvas.save(); - mCanvas.scale(scale, scale, textureWidth / 2, textureHeight / 2); + mCanvas.scale(scale, scale, textureWidth / 2 + offset, textureHeight / 2 + offset); icon.draw(mCanvas); mCanvas.restore(); icon.setBounds(mOldBounds); From d7a20ce619e214ee0f1454aba28fa0a8f0754986 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 28 Jun 2018 12:07:24 -0700 Subject: [PATCH 12/14] Import translations. DO NOT MERGE Change-Id: Ieabec06db1791c1b2887c37aa600f2178906d761 Auto-generated-cl: translation import --- res/values-zh-rHK/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 5a8c6caec6..2677b21295 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -41,7 +41,7 @@ "搜尋更多應用程式" "通知" "按住捷徑即可選取。" - "撳兩下之後撳住,就可以揀選捷徑或者用自訂嘅操作。" + "連㩒兩下之後繼續㩒住,就可以揀選捷徑或者用自訂嘅操作。" "主畫面已無空間。" "我的收藏寄存區沒有足夠空間" "應用程式清單" From 82d0835fa53962b149256deeb66509c0cccd5906 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Thu, 28 Jun 2018 15:17:51 -0700 Subject: [PATCH 13/14] Fix clipping issue on adaptive icons Bug: 62372639 Verified the one last device, b***line. Change-Id: I1d97d0cbe0afe76ee21de5964abf639fb4c0fceb --- src/com/android/launcher3/graphics/LauncherIcons.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java index ece6c58407..333fe5907c 100644 --- a/src/com/android/launcher3/graphics/LauncherIcons.java +++ b/src/com/android/launcher3/graphics/LauncherIcons.java @@ -337,16 +337,15 @@ public class LauncherIcons implements AutoCloseable { final int top = (textureHeight-height) / 2; mOldBounds.set(icon.getBounds()); - int offset = 0; if (Utilities.ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) { - offset = Math.max((int) Math.ceil(BLUR_FACTOR * textureWidth), Math.max(left, top)); + int offset = Math.max((int) Math.ceil(BLUR_FACTOR * textureWidth), Math.max(left, top)); int size = Math.max(width, height); - icon.setBounds(offset, offset, offset + size, offset + size); + icon.setBounds(offset, offset, size - offset, size - offset); } else { icon.setBounds(left, top, left+width, top+height); } mCanvas.save(); - mCanvas.scale(scale, scale, textureWidth / 2 + offset, textureHeight / 2 + offset); + mCanvas.scale(scale, scale, textureWidth / 2, textureHeight / 2); icon.draw(mCanvas); mCanvas.restore(); icon.setBounds(mOldBounds); From 35a6848fa813b6b3d5c41b2b6792f7b7effa195b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 11 Jul 2018 10:56:48 -0700 Subject: [PATCH 14/14] Workaround for flicker between handoff from app to task view - Defer finishing the recents animation for a couple frames until the frame has likely been pushed to sf and drawn, otherwise the reparenting of the app surface may happen before the task view is visible in Launcher. Bug: 111299394 Test: Swipe up repeatedly from an app Change-Id: I627dc085a5e376436b2b8eb5841c45fd36deff42 --- .../quickstep/WindowTransformSwipeHandler.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java index 15ff19e260..902eb950de 100644 --- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -882,8 +882,21 @@ public class WindowTransformSwipeHandler { // new thumbnail finishTransitionPosted = new WindowCallbacksCompat(taskView) { + // The number of frames to defer until we actually finish the animation + private int mDeferFrameCount = 2; + @Override public void onPostDraw(Canvas canvas) { + if (mDeferFrameCount > 0) { + mDeferFrameCount--; + // Workaround, detach and reattach to invalidate the root node for + // another draw + detach(); + attach(); + taskView.invalidate(); + return; + } + setStateOnUiThread(STATE_SCREENSHOT_CAPTURED); detach(); }