diff options
author | Vladislav Kaznacheev <kaznacheev@google.com> | 2015-06-18 17:30:57 +0300 |
---|---|---|
committer | Vladislav Kaznacheev <kaznacheev@google.com> | 2015-06-19 11:22:59 +0300 |
commit | 160d12ee51672e1482f95a349edb49630398d335 (patch) | |
tree | 5efa6f28137df4342c6c32b8a45d84d7d891cb6a /core | |
parent | 275294dbce30eb1f9ef4847d0f9c3d6b602de06c (diff) | |
download | frameworks_base-160d12ee51672e1482f95a349edb49630398d335.zip frameworks_base-160d12ee51672e1482f95a349edb49630398d335.tar.gz frameworks_base-160d12ee51672e1482f95a349edb49630398d335.tar.bz2 |
Fix huge bounce-back in ListView when double-flinging
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
Diffstat (limited to 'core')
-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 451e493..98bfd7d 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -731,7 +731,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); @@ -797,7 +797,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)); @@ -848,12 +850,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; } |