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

Commit 4b45c360 authored by Mark Renouf's avatar Mark Renouf Committed by Android (Google) Code Review
Browse files

Merge "Account for padding in dispatchScrollCaptureSearch" into sc-dev

parents e7f4889b c14734d8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1494,7 +1494,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    public static final int SCROLL_CAPTURE_HINT_AUTO = 0;
    /**
     * Explicitly exclcude this view as a potential scroll capture target. The system will not
     * Explicitly exclude this view as a potential scroll capture target. The system will not
     * consider it. Mutually exclusive with {@link #SCROLL_CAPTURE_HINT_INCLUDE}, which this flag
     * takes precedence over.
     *
+8 −13
Original line number Diff line number Diff line
@@ -7490,12 +7490,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            @NonNull Rect localVisibleRect, @NonNull Point windowOffset,
            @NonNull Consumer<ScrollCaptureTarget> targets) {

        // copy local visible rect for modification and dispatch
        final Rect rect = getTempRect();
        rect.set(localVisibleRect);

        if (getClipToPadding()) {
            rect.inset(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
        if (getClipToPadding() && !localVisibleRect.intersect(mPaddingLeft, mPaddingTop,
                    (mRight - mLeft)  - mPaddingRight, (mBottom - mTop) - mPaddingBottom)) {
            return;
        }

        // Dispatch to self first.
@@ -7506,6 +7503,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            return;
        }

        final Rect tmpRect = getTempRect();
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
@@ -7518,8 +7516,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            // If the resulting rectangle is not empty, the request is forwarded to the child.

            // copy local visible rect for modification and dispatch
            final Rect childVisibleRect = getTempRect();
            childVisibleRect.set(localVisibleRect);
            tmpRect.set(localVisibleRect);

            // transform to child coords
            final Point childWindowOffset = getTempPoint();
@@ -7528,20 +7525,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            final int dx = child.mLeft - mScrollX;
            final int dy = child.mTop - mScrollY;

            childVisibleRect.offset(-dx, -dy);
            tmpRect.offset(-dx, -dy);
            childWindowOffset.offset(dx, dy);

            boolean rectIsVisible = true;

            // Clip to child bounds
            if (getClipChildren()) {
                rectIsVisible = childVisibleRect.intersect(0, 0, child.getWidth(),
                        child.getHeight());
                rectIsVisible = tmpRect.intersect(0, 0, child.getWidth(), child.getHeight());
            }

            // Clip to child padding.
            if (rectIsVisible) {
                child.dispatchScrollCaptureSearch(childVisibleRect, childWindowOffset, targets);
                child.dispatchScrollCaptureSearch(tmpRect, childWindowOffset, targets);
            }
        }
    }
+82 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.os.CancellationSignal;
import android.platform.test.annotations.Presubmit;

import androidx.annotation.NonNull;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;

@@ -355,6 +354,54 @@ public class ViewGroupScrollCaptureTest {
                target.getContainingView().getScrollCaptureHint());
    }

    /**
     * Tests the effect of padding on scroll capture search dispatch.
     * <p>
     * Verifies computation of child visible bounds with padding.
     */
    @MediumTest
    @Test
    public void testOnScrollCaptureSearch_withPadding() {
        final Context context = getInstrumentation().getContext();

        Rect windowBounds = new Rect(0, 0, 200, 200);
        Point windowOffset = new Point(0, 0);

        final MockViewGroup parent = new MockViewGroup(context, 0, 0, 200, 200);
        parent.setPadding(25, 50, 25, 50);
        parent.setClipToPadding(true); // (default)

        final MockView view1 = new MockView(context, 0, -100, 200, 100);
        parent.addView(view1);

        final MockView view2 = new MockView(context, 0, 0, 200, 200);
        parent.addView(view2);

        final MockViewGroup view3 = new MockViewGroup(context, 0, 100, 200, 300);
        parent.addView(view3);
        view3.setPadding(25, 25, 25, 25);
        view3.setClipToPadding(true);

        // Where targets are added
        final ScrollCaptureSearchResults results = new ScrollCaptureSearchResults(DIRECT_EXECUTOR);

        // Dispatch to the ViewGroup
        parent.dispatchScrollCaptureSearch(windowBounds, windowOffset, results::addTarget);

        // Verify padding (with clipToPadding) is subtracted from visibleBounds
        parent.assertOnScrollCaptureSearchLastArgs(new Rect(25, 50, 175, 150), new Point(0, 0));

        view1.assertOnScrollCaptureSearchLastArgs(
                new Rect(25, 150, 175, 200), new Point(0, -100));

        view2.assertOnScrollCaptureSearchLastArgs(
                new Rect(25, 50, 175, 150), new Point(0, 0));

        // Account for padding on view3 as well (top == 25px)
        view3.assertOnScrollCaptureSearchLastArgs(
                new Rect(25, 25, 175, 50), new Point(0, 100));
    }

    public static final class MockView extends View {
        private ScrollCaptureCallback mInternalCallback;

@@ -362,6 +409,8 @@ public class ViewGroupScrollCaptureTest {
        private Rect mDispatchScrollCaptureSearchLastLocalVisibleRect;
        private Point mDispatchScrollCaptureSearchLastWindowOffset;
        private int mCreateScrollCaptureCallbackInternalCount;
        private Rect mOnScrollCaptureSearchLastLocalVisibleRect;
        private Point mOnScrollCaptureSearchLastWindowOffset;

        MockView(Context context) {
            this(context, /* left */ 0, /* top */0, /* right */ 0, /* bottom */0);
@@ -406,6 +455,21 @@ public class ViewGroupScrollCaptureTest {

        }

        @Override
        public void onScrollCaptureSearch(Rect localVisibleRect, Point windowOffset,
                Consumer<ScrollCaptureTarget> targets) {
            super.onScrollCaptureSearch(localVisibleRect, windowOffset, targets);
            mOnScrollCaptureSearchLastLocalVisibleRect = new Rect(localVisibleRect);
            mOnScrollCaptureSearchLastWindowOffset = new Point(windowOffset);
        }

        void assertOnScrollCaptureSearchLastArgs(Rect localVisibleRect, Point windowOffset) {
            assertEquals("arg localVisibleRect was incorrect.",
                    localVisibleRect, mOnScrollCaptureSearchLastLocalVisibleRect);
            assertEquals("arg windowOffset was incorrect.",
                    windowOffset, mOnScrollCaptureSearchLastWindowOffset);
        }

        @Override
        public void dispatchScrollCaptureSearch(Rect localVisibleRect, Point windowOffset,
                Consumer<ScrollCaptureTarget> results) {
@@ -449,6 +513,8 @@ public class ViewGroupScrollCaptureTest {

    public static final class MockViewGroup extends ViewGroup {
        private ScrollCaptureCallback mInternalCallback;
        private Rect mOnScrollCaptureSearchLastLocalVisibleRect;
        private Point mOnScrollCaptureSearchLastWindowOffset;

        MockViewGroup(Context context) {
            this(context, /* left */ 0, /* top */0, /* right */ 0, /* bottom */0);
@@ -476,6 +542,21 @@ public class ViewGroupScrollCaptureTest {
            return mInternalCallback;
        }

        @Override
        public void onScrollCaptureSearch(Rect localVisibleRect, Point windowOffset,
                Consumer<ScrollCaptureTarget> targets) {
            super.onScrollCaptureSearch(localVisibleRect, windowOffset, targets);
            mOnScrollCaptureSearchLastLocalVisibleRect = new Rect(localVisibleRect);
            mOnScrollCaptureSearchLastWindowOffset = new Point(windowOffset);
        }

        void assertOnScrollCaptureSearchLastArgs(Rect localVisibleRect, Point windowOffset) {
            assertEquals("arg localVisibleRect was incorrect.",
                    localVisibleRect, mOnScrollCaptureSearchLastLocalVisibleRect);
            assertEquals("arg windowOffset was incorrect.",
                    windowOffset, mOnScrollCaptureSearchLastWindowOffset);
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            // We don't layout this view.