Loading core/java/android/view/View.java +1 −1 Original line number Diff line number Diff line Loading @@ -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. * core/java/android/view/ViewGroup.java +8 −13 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); Loading @@ -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(); Loading @@ -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); } } } Loading core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java +82 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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. Loading Loading
core/java/android/view/View.java +1 −1 Original line number Diff line number Diff line Loading @@ -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. *
core/java/android/view/ViewGroup.java +8 −13 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); Loading @@ -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(); Loading @@ -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); } } } Loading
core/tests/coretests/src/android/view/ViewGroupScrollCaptureTest.java +82 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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. Loading