From 5554d79f82b76595c7c107a7e92694555b191677 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Fri, 12 Mar 2021 20:19:23 -0800 Subject: [PATCH] Fixed crash in EdgeEffect after fling gesture Fixed issue where mDistance and mVelocity fields would be infinite/NaN in situations where onAbsorb is called before setSize leading to division by zero issues. Updated constants to be less significant stretch Fixes: 182567334 Test: Updated EdgeEffectTests Change-Id: I4007b03271c6b5e79e95d5fe6c7c44e8c0869cd1 --- core/java/android/widget/EdgeEffect.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java index 45352e4d5ba2c..c203c7903256a 100644 --- a/core/java/android/widget/EdgeEffect.java +++ b/core/java/android/widget/EdgeEffect.java @@ -130,7 +130,7 @@ public class EdgeEffect { public @interface EdgeEffectType { } - private static final float DEFAULT_MAX_STRETCH_INTENSITY = 1.5f; + private static final float DEFAULT_MAX_STRETCH_INTENSITY = 0.08f; @SuppressWarnings("UnusedDeclaration") private static final String TAG = "EdgeEffect"; @@ -177,6 +177,7 @@ public class EdgeEffect { private long mStartTime; private float mDuration; private float mStretchIntensity = DEFAULT_MAX_STRETCH_INTENSITY; + private float mStretchDistanceFraction = 0.1f; private float mStretchDistance = -1f; private final Interpolator mInterpolator = new DecelerateInterpolator(); @@ -467,7 +468,7 @@ public class EdgeEffect { public void onAbsorb(int velocity) { if (mEdgeEffectType == TYPE_STRETCH) { mState = STATE_RECEDE; - mVelocity = velocity / mHeight; + mVelocity = velocity; mDistance = 0; mStartTime = AnimationUtils.currentAnimationTimeMillis(); } else { @@ -655,7 +656,7 @@ public class EdgeEffect { // for now leverage placeholder logic if no stretch distance is provided to // consume the displacement ratio times the minimum of the width or height mStretchDistance > 0 ? mStretchDistance : - (mDisplacement * Math.min(mWidth, mHeight)) + (mStretchDistanceFraction * Math.min(mWidth, mHeight)) ); } @@ -745,9 +746,9 @@ public class EdgeEffect { final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO); // We're always underdamped, so we can use only those equations: - double cosCoeff = mDistance; + double cosCoeff = mDistance * mHeight; double sinCoeff = (1 / mDampedFreq) * (DAMPING_RATIO * NATURAL_FREQUENCY - * mDistance + mVelocity); + * mDistance * mHeight + mVelocity); double distance = Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT) * (cosCoeff * Math.cos(mDampedFreq * deltaT) + sinCoeff * Math.sin(mDampedFreq * deltaT)); @@ -755,7 +756,7 @@ public class EdgeEffect { + Math.pow(Math.E, -DAMPING_RATIO * NATURAL_FREQUENCY * deltaT) * (-mDampedFreq * cosCoeff * Math.sin(mDampedFreq * deltaT) + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT)); - mDistance = (float) distance; + mDistance = (float) distance / mHeight; mVelocity = (float) velocity; mStartTime = time; if (isAtEquilibrium()) { @@ -786,9 +787,8 @@ public class EdgeEffect { * considered at rest or false if it is still animating. */ private boolean isAtEquilibrium() { - double velocity = mVelocity * mHeight; // in pixels/second double displacement = mDistance * mHeight; // in pixels - return Math.abs(velocity) < VELOCITY_THRESHOLD + return Math.abs(mVelocity) < VELOCITY_THRESHOLD && Math.abs(displacement) < VALUE_THRESHOLD; } }