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

Commit c5ce225f authored by Adrian Roos's avatar Adrian Roos
Browse files

AbsSeekBar: Fix growRect computation

Fixes an issue with the growRectTo computation where if the
difference between the current and target size wasn't an even
number, the resulting rect would not actually have the correct
size.

Also, asserts using the thumb bounds, rather than the view
bounds in case the thumb is not perfectly centered within the
view due to rounding errors on odd densities.

Fixes: 173872859
Test: atest AbsSeekBarTest
Change-Id: Ib2b81a91ba8feeb6743a4e4a588d6116d231eb8d
parent 361e0a91
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inspector.InspectableProperty;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;

import java.util.ArrayList;
@@ -776,17 +777,23 @@ public abstract class AbsSeekBar extends ProgressBar {

    /**
     * Grows {@code r} from its center such that each dimension is at least {@code minimumSize}.
     *
     * The result will still have the same {@link Rect#centerX()} and {@link Rect#centerY()} as the
     * input.
     *
     * @hide
     */
    private void growRectTo(Rect r, int minimumSize) {
        int dy = (minimumSize - r.height()) / 2;
    @VisibleForTesting
    public void growRectTo(Rect r, int minimumSize) {
        int dy = minimumSize - r.height();
        if (dy > 0) {
            r.top -= dy;
            r.bottom += dy;
            r.top -= (dy + 1) / 2;
            r.bottom += dy / 2;
        }
        int dx = (minimumSize - r.width()) / 2;
        int dx = minimumSize - r.width();
        if (dx > 0) {
            r.left -= dx;
            r.right += dx;
            r.left -= (dx + 1) / 2;
            r.right += dx / 2;
        }
    }

+41 −8
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.platform.test.annotations.Presubmit;
import android.view.View;

import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -48,6 +47,7 @@ import java.util.List;
@Presubmit
public class AbsSeekBarTest {

    public static final int PADDING = 10;
    private Context mContext;
    private AbsSeekBar mBar;

@@ -59,34 +59,42 @@ public class AbsSeekBarTest {

    @Test
    public void testExclusionForThumb_limitedTo48dp() {
        mBar.setPadding(10, 10, 10, 10);
        mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
        mBar.setThumb(newThumb(dpToPxSize(20)));
        mBar.setMin(0);
        mBar.setMax(100);
        mBar.setProgress(50);

        final int thumbOffset = mBar.getThumbOffset();

        measureAndLayout(dpToPxSize(200), dpToPxSize(100));
        List<Rect> exclusions = mBar.getSystemGestureExclusionRects();

        assertEquals("exclusions should be size 1, but was " + exclusions, 1, exclusions.size());
        assertEquals("exclusion should be centered on thumb",
                center(mBar), center(exclusions.get(0)));
                center(offset(mBar.getThumb().getBounds(), PADDING - thumbOffset, PADDING)),
                center(exclusions.get(0)));
        assertEquals("exclusion should be 48dp high", dpToPxSize(48), exclusions.get(0).height());
        assertEquals("exclusion should be 48dp wide", dpToPxSize(48), exclusions.get(0).width());
    }

    @Test
    public void testExclusionForThumb_limitedToHeight() {
        mBar.setPadding(10, 10, 10, 10);
        mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
        mBar.setThumb(newThumb(dpToPxSize(20)));
        mBar.setMin(0);
        mBar.setMax(100);
        mBar.setProgress(50);

        final int thumbOffset = mBar.getThumbOffset();

        measureAndLayout(dpToPxSize(200), dpToPxSize(32));
        List<Rect> exclusions = mBar.getSystemGestureExclusionRects();

        assertEquals("exclusions should be size 1, but was " + exclusions, 1, exclusions.size());
        assertEquals("exclusion should be centered on thumb",
                center(mBar), center(exclusions.get(0)));
                center(offset(mBar.getThumb().getBounds(), PADDING - thumbOffset, PADDING)),
                center(exclusions.get(0)));
        assertEquals("exclusion should be 32dp high", dpToPxSize(32), exclusions.get(0).height());
        assertEquals("exclusion should be 32dp wide", dpToPxSize(32), exclusions.get(0).width());
    }
@@ -95,7 +103,7 @@ public class AbsSeekBarTest {
    public void testExclusionForThumb_passesThroughUserExclusions() {
        mBar.setSystemGestureExclusionRects(Arrays.asList(new Rect(1, 2, 3, 4)));

        mBar.setPadding(10, 10, 10, 10);
        mBar.setPadding(PADDING, PADDING, PADDING, PADDING);
        mBar.setThumb(newThumb(dpToPxSize(20)));
        mBar.setMin(0);
        mBar.setMax(100);
@@ -110,12 +118,37 @@ public class AbsSeekBarTest {
        assertThat(mBar.getSystemGestureExclusionRects(), hasSize(2));
    }

    @Test
    public void testGrowRectTo_evenInitialDifference() {
        doGrowRectTest(new Rect(0, 0, 0, 0), 10, new Rect(-5, -5, 5, 5));
    }

    @Test
    public void testGrowRectTo_unevenInitialDifference() {
        doGrowRectTest(new Rect(0, 0, 1, 1), 10, new Rect(-5, -5, 5, 5));
    }

    @Test
    public void testGrowRectTo_unevenInitialDifference_unevenSize() {
        doGrowRectTest(new Rect(0, 0, 0, 0), 9, new Rect(-5, -5, 4, 4));
    }

    public void doGrowRectTest(Rect in, int minimumSize, Rect expected) {
        Rect result = new Rect(in);
        mBar.growRectTo(result, minimumSize);

        assertEquals("grown rect", expected, result);
        assertEquals("grown rect center point", center(expected), center(result));
    }

    private Point center(Rect rect) {
        return new Point(rect.centerX(), rect.centerY());
    }

    private Point center(View view) {
        return center(new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
    private Rect offset(Rect rect, int dx, int dy) {
        Rect result = new Rect(rect);
        result.offset(dx, dy);
        return result;
    }

    private ShapeDrawable newThumb(int size) {