summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorVladislav Kaznacheev <kaznacheev@google.com>2015-06-18 17:30:57 +0300
committerVladislav Kaznacheev <kaznacheev@google.com>2015-06-19 11:22:59 +0300
commit160d12ee51672e1482f95a349edb49630398d335 (patch)
tree5efa6f28137df4342c6c32b8a45d84d7d891cb6a /core
parent275294dbce30eb1f9ef4847d0f9c3d6b602de06c (diff)
downloadframeworks_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.java12
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;
}