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

Commit ef0e9ae0 authored by Romain Guy's avatar Romain Guy
Browse files

Fixes #1972421. Prevents crash in ScrollView/HorizontalScrollView.

Add several checks to make sure there's at least one child.
parent 38645ee6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import java.io.DataInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A gesture can have a single or multiple strokes
@@ -44,7 +45,7 @@ public class Gesture implements Parcelable {
    private static final boolean BITMAP_RENDERING_ANTIALIAS = true;
    private static final boolean BITMAP_RENDERING_DITHER = true;

    private static int sGestureCount = 0;
    private static final AtomicInteger sGestureCount = new AtomicInteger(0);

    private final RectF mBoundingBox = new RectF();

@@ -54,7 +55,7 @@ public class Gesture implements Parcelable {
    private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>();

    public Gesture() {
        mGestureID = GESTURE_ID_BASE + sGestureCount++;
        mGestureID = GESTURE_ID_BASE + sGestureCount.incrementAndGet();
    }

    /**
+43 −38
Original line number Diff line number Diff line
@@ -286,6 +286,7 @@ public class HorizontalScrollView extends FrameLayout {
            return;
        }

        if (getChildCount() > 0) {
            final View child = getChildAt(0);
            int width = getMeasuredWidth();
            if (child.getMeasuredWidth() < width) {
@@ -300,6 +301,7 @@ public class HorizontalScrollView extends FrameLayout {
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
@@ -636,7 +638,7 @@ public class HorizontalScrollView extends FrameLayout {
            mTempRect.left = getScrollX() + width;
            int count = getChildCount();
            if (count > 0) {
                View view = getChildAt(count - 1);
                View view = getChildAt(0);
                if (mTempRect.left + width > view.getRight()) {
                    mTempRect.left = view.getRight() - width;
                }
@@ -674,7 +676,7 @@ public class HorizontalScrollView extends FrameLayout {
        if (right) {
            int count = getChildCount();
            if (count > 0) {
                View view = getChildAt(count - 1);
                View view = getChildAt(0);
                mTempRect.right = view.getRight();
                mTempRect.left = mTempRect.right - width;
            }
@@ -751,9 +753,9 @@ public class HorizontalScrollView extends FrameLayout {

            if (direction == View.FOCUS_LEFT && getScrollX() < scrollDelta) {
                scrollDelta = getScrollX();
            } else if (direction == View.FOCUS_RIGHT) {
            } else if (direction == View.FOCUS_RIGHT && getChildCount() > 0) {
                
                int daRight = getChildAt(getChildCount() - 1).getRight();
                int daRight = getChildAt(0).getRight();

                int screenRight = getScrollX() + getWidth();

@@ -975,6 +977,7 @@ public class HorizontalScrollView extends FrameLayout {
     * @return The scroll delta.
     */
    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
        if (getChildCount() == 0) return 0;

        int width = getWidth();
        int screenLeft = getScrollX();
@@ -1008,7 +1011,7 @@ public class HorizontalScrollView extends FrameLayout {
            }

            // make sure we aren't scrolling beyond the end of our content
            int right = getChildAt(getChildCount() - 1).getRight();
            int right = getChildAt(0).getRight();
            int distanceToRight = right - screenRight;
            scrollXDelta = Math.min(scrollXDelta, distanceToRight);

@@ -1148,6 +1151,7 @@ public class HorizontalScrollView extends FrameLayout {
     *                  which means we want to scroll towards the left.
     */
    public void fling(int velocityX) {
        if (getChildCount() > 0) {
            int width = getWidth() - mPaddingRight - mPaddingLeft;
            int right = getChildAt(0).getWidth();
    
@@ -1170,6 +1174,7 @@ public class HorizontalScrollView extends FrameLayout {
    
            invalidate();
        }
    }

    /**
     * {@inheritDoc}
+46 −54
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Config;
import android.util.Log;
import android.view.FocusFinder;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -54,7 +52,6 @@ import java.util.List;
 */
public class ScrollView extends FrameLayout {
    static final String TAG = "ScrollView";
    static final boolean localLOGV = false || Config.LOGV;
    
    static final int ANIMATED_SCROLL_GAP = 250;

@@ -287,6 +284,7 @@ public class ScrollView extends FrameLayout {
            return;
        }

        if (getChildCount() > 0) {
            final View child = getChildAt(0);
            int height = getMeasuredHeight();
            if (child.getMeasuredHeight() < height) {
@@ -296,11 +294,13 @@ public class ScrollView extends FrameLayout {
                        + mPaddingRight, lp.width);
                height -= mPaddingTop;
                height -= mPaddingBottom;
            int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                int childHeightMeasureSpec =
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
@@ -756,8 +756,8 @@ public class ScrollView extends FrameLayout {
            if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
                scrollDelta = getScrollY();
            } else if (direction == View.FOCUS_DOWN) {

                int daBottom = getChildAt(getChildCount() - 1).getBottom();
                if (getChildCount() > 0) {
                    int daBottom = getChildAt(0).getBottom();
    
                    int screenBottom = getScrollY() + getHeight();
    
@@ -765,6 +765,7 @@ public class ScrollView extends FrameLayout {
                        scrollDelta = daBottom - screenBottom;
                    }
                }
            }
            if (scrollDelta == 0) {
                return false;
            }
@@ -830,16 +831,12 @@ public class ScrollView extends FrameLayout {
    public final void smoothScrollBy(int dx, int dy) {
        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
        if (duration > ANIMATED_SCROLL_GAP) {
            if (localLOGV) Log.v(TAG, "Smooth scroll: mScrollY=" + mScrollY
                    + " dy=" + dy);
            mScroller.startScroll(mScrollX, mScrollY, dx, dy);
            invalidate();
        } else {
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
            if (localLOGV) Log.v(TAG, "Immediate scroll: mScrollY=" + mScrollY
                    + " dy=" + dy);
            scrollBy(dx, dy);
        }
        mLastScroll = AnimationUtils.currentAnimationTimeMillis();
@@ -922,9 +919,6 @@ public class ScrollView extends FrameLayout {
                View child = getChildAt(0);
                mScrollX = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
                mScrollY = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
                if (localLOGV) Log.v(TAG, "mScrollY=" + mScrollY + " y=" + y
                        + " height=" + this.getHeight()
                        + " child height=" + child.getHeight());
            } else {
                mScrollX = x;
                mScrollY = y;
@@ -986,6 +980,7 @@ public class ScrollView extends FrameLayout {
     * @return The scroll delta.
     */
    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
        if (getChildCount() == 0) return 0;

        int height = getHeight();
        int screenTop = getScrollY();
@@ -1005,9 +1000,6 @@ public class ScrollView extends FrameLayout {

        int scrollYDelta = 0;

        if (localLOGV) Log.v(TAG, "child=" + rect.toShortString()
                + " screenTop=" + screenTop + " screenBottom=" + screenBottom
                + " height=" + height);
        if (rect.bottom > screenBottom && rect.top > screenTop) {
            // need to move down to get it in view: move down just enough so
            // that the entire rectangle is in view (or at least the first
@@ -1022,10 +1014,8 @@ public class ScrollView extends FrameLayout {
            }

            // make sure we aren't scrolling beyond the end of our content
            int bottom = getChildAt(getChildCount() - 1).getBottom();
            int bottom = getChildAt(0).getBottom();
            int distanceToBottom = bottom - screenBottom;
            if (localLOGV) Log.v(TAG, "scrollYDelta=" + scrollYDelta
                    + " distanceToBottom=" + distanceToBottom);
            scrollYDelta = Math.min(scrollYDelta, distanceToBottom);

        } else if (rect.top < screenTop && rect.bottom < screenBottom) {
@@ -1164,6 +1154,7 @@ public class ScrollView extends FrameLayout {
     *                  which means we want to scroll towards the top.
     */
    public void fling(int velocityY) {
        if (getChildCount() > 0) {
            int height = getHeight() - mPaddingBottom - mPaddingTop;
            int bottom = getChildAt(0).getHeight();
    
@@ -1185,6 +1176,7 @@ public class ScrollView extends FrameLayout {
    
            invalidate();
        }
    }

    /**
     * {@inheritDoc}