diff options
author | Vladislav Kaznacheev <kaznacheev@google.com> | 2015-06-18 17:30:57 +0300 |
---|---|---|
committer | eray orçunus <erayorcunus@gmail.com> | 2015-10-10 17:16:27 -0700 |
commit | f1b946efb7e36dbe1b7e6ac7cb28d99d2d83f566 (patch) | |
tree | 5e00902dfedb07358d18dc8d7b6b7468bcfb01a6 | |
parent | 77668c73f487a38037f7d619a0f8ce5837eaaa09 (diff) | |
download | android_frameworks_base-cm-12.0.tar.gz android_frameworks_base-cm-12.0.tar.bz2 android_frameworks_base-cm-12.0.zip |
Fix huge bounce-back in ListView when double-flingingcm-12.0
The bounce-back reliably happened when AbsListView.fling
was called with high enough velocity (>50000). Such values
caused integer overflow when squared in the course of some
ballistic calculations in OverScroller.fitOnBounceCurve.
Bug: 19056278
Change-Id: I35d5376c67bc6847955b44ee268e89bce2db81d0
-rw-r--r-- | core/java/android/widget/OverScroller.java | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index 9818bb5cb4b..91ccb55951b 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -738,7 +738,7 @@ public class OverScroller { // mStartTime has been set mFinished = false; mState = CUBIC; - mStart = start; + mCurrentPosition = mStart = start; mFinal = end; final int delta = start - end; mDeceleration = getDeceleration(delta); @@ -805,7 +805,9 @@ public class OverScroller { private void fitOnBounceCurve(int start, int end, int velocity) { // Simulate a bounce that started from edge final float durationToApex = - velocity / mDeceleration; - final float distanceToApex = velocity * velocity / 2.0f / Math.abs(mDeceleration); + // The float cast below is necessary to avoid integer overflow. + final float velocitySquared = (float) velocity * velocity; + final float distanceToApex = velocitySquared / 2.0f / Math.abs(mDeceleration); final float distanceToEdge = Math.abs(end - start); final float totalDuration = (float) Math.sqrt( 2.0 * (distanceToApex + distanceToEdge) / Math.abs(mDeceleration)); @@ -856,12 +858,14 @@ public class OverScroller { private void onEdgeReached() { // mStart, mVelocity and mStartTime were adjusted to their values when edge was reached. - float distance = mVelocity * mVelocity / (2.0f * Math.abs(mDeceleration)); + // The float cast below is necessary to avoid integer overflow. + final float velocitySquared = (float) mVelocity * mVelocity; + float distance = velocitySquared / (2.0f * Math.abs(mDeceleration)); final float sign = Math.signum(mVelocity); if (distance > mOver) { // Default deceleration is not sufficient to slow us down before boundary - mDeceleration = - sign * mVelocity * mVelocity / (2.0f * mOver); + mDeceleration = - sign * velocitySquared / (2.0f * mOver); distance = mOver; } |