Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1b946ef authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev Committed by eray orçunus
Browse files

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
parent 77668c73
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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;
            }