summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladislav Kaznacheev <kaznacheev@google.com>2015-06-18 17:30:57 +0300
committereray orçunus <erayorcunus@gmail.com>2015-10-10 17:16:27 -0700
commitf1b946efb7e36dbe1b7e6ac7cb28d99d2d83f566 (patch)
tree5e00902dfedb07358d18dc8d7b6b7468bcfb01a6
parent77668c73f487a38037f7d619a0f8ce5837eaaa09 (diff)
downloadandroid_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.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 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;
}