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

This commit is contained in:
Mark Renouf
2021-04-20 16:09:14 +00:00
committed by Android (Google) Code Review
3 changed files with 91 additions and 15 deletions

View File

@@ -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.
*

View File

@@ -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);
}
}
}

View File

@@ -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.