Tests for requestDisallowInterceptTouchEvents
Bug: 185906621
When overscrolling, there is no need to call
disallowInterceptTouchEvents(). A test was added to ensure that
it isn't called during the touch down while the animation
is progressing.
Test: new test
Change-Id: Ia9ac6d81a5b60222f489ea87f31ecba0c1d48cea
(cherry picked from commit 044c71b8fab8ea16400dbbb01604ce0cc894c6f8)
diff --git a/tests/tests/widget/res/layout/horizontal_scrollview.xml b/tests/tests/widget/res/layout/horizontal_scrollview.xml
index 2acd77f..c535722 100644
--- a/tests/tests/widget/res/layout/horizontal_scrollview.xml
+++ b/tests/tests/widget/res/layout/horizontal_scrollview.xml
@@ -121,40 +121,46 @@
android:layout_width="100px"
android:layout_height="100px" />
- <HorizontalScrollView
- android:id="@+id/horizontal_scroll_view_stretch"
- android:layout_width="90px"
- android:layout_height="90px"
- android:edgeEffectType="stretch"
- android:background="#FFF">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <View
- android:background="#00F"
- android:layout_width="50px"
- android:layout_height="90px"/>
- <View
- android:background="#0FF"
- android:layout_width="50px"
- android:layout_height="90px"/>
- <View
- android:background="#0F0"
- android:layout_width="50px"
- android:layout_height="90px"/>
- <View
- android:background="#FF0"
- android:layout_width="50px"
- android:layout_height="90px"/>
- <View
- android:background="#F00"
- android:layout_width="50px"
- android:layout_height="90px"/>
- <View
- android:background="#F0F"
- android:layout_width="50px"
- android:layout_height="90px"/>
- </LinearLayout>
- </HorizontalScrollView>
+ <view
+ class="android.widget.cts.HorizontalScrollViewTest$InterceptView"
+ android:id="@+id/wrapped_stretch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <HorizontalScrollView
+ android:id="@+id/horizontal_scroll_view_stretch"
+ android:layout_width="90px"
+ android:layout_height="90px"
+ android:edgeEffectType="stretch"
+ android:background="#FFF">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <View
+ android:background="#00F"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ <View
+ android:background="#0FF"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ <View
+ android:background="#0F0"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ <View
+ android:background="#FF0"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ <View
+ android:background="#F00"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ <View
+ android:background="#F0F"
+ android:layout_width="50px"
+ android:layout_height="90px"/>
+ </LinearLayout>
+ </HorizontalScrollView>
+ </view>
</LinearLayout>
diff --git a/tests/tests/widget/res/layout/scrollview_layout.xml b/tests/tests/widget/res/layout/scrollview_layout.xml
index 47cf600..8ff83f8 100644
--- a/tests/tests/widget/res/layout/scrollview_layout.xml
+++ b/tests/tests/widget/res/layout/scrollview_layout.xml
@@ -120,43 +120,49 @@
class="android.widget.cts.ScrollViewTest$MyScrollView"
android:id="@+id/scroll_view_custom_empty"
android:layout_width="100dip"
- android:layout_height="100dip" />
+ android:layout_height="100dip"/>
- <ScrollView
- android:id="@+id/scroll_view_stretch"
- android:layout_width="90px"
- android:layout_height="90px"
- android:edgeEffectType="stretch"
- android:background="#FFF">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <View
- android:background="#00F"
- android:layout_width="90px"
- android:layout_height="50px"/>
- <View
- android:background="#0FF"
- android:layout_width="90px"
- android:layout_height="50px"/>
- <View
- android:background="#0F0"
- android:layout_width="90px"
- android:layout_height="50px"/>
- <View
- android:background="#FF0"
- android:layout_width="90px"
- android:layout_height="50px"/>
- <View
- android:background="#F00"
- android:layout_width="90px"
- android:layout_height="50px"/>
- <View
- android:background="#F0F"
- android:layout_width="90px"
- android:layout_height="50px"/>
- </LinearLayout>
- </ScrollView>
+ <view
+ class="android.widget.cts.ScrollViewTest$InterceptView"
+ android:id="@+id/wrapped_stretch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <ScrollView
+ android:id="@+id/scroll_view_stretch"
+ android:layout_width="90px"
+ android:layout_height="90px"
+ android:edgeEffectType="stretch"
+ android:background="#FFF">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <View
+ android:background="#00F"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ <View
+ android:background="#0FF"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ <View
+ android:background="#0F0"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ <View
+ android:background="#FF0"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ <View
+ android:background="#F00"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ <View
+ android:background="#F0F"
+ android:layout_width="90px"
+ android:layout_height="50px"/>
+ </LinearLayout>
+ </ScrollView>
+ </view>
</LinearLayout>
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index a93d864..2b35073 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -16,6 +16,8 @@
package android.widget.cts;
+import static android.widget.cts.util.StretchEdgeUtil.dragHoldAndRun;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
@@ -60,6 +62,8 @@
import java.util.ArrayList;
+import kotlin.Unit;
+
/**
* Test {@link HorizontalScrollView}.
*/
@@ -868,6 +872,32 @@
assertTrue(StretchEdgeUtil.dragLeftTapAndHoldStretches(mActivityRule, mScrollViewStretch));
}
+ @LargeTest
+ @Test
+ public void testRequestDisallowInterceptTouchEventNotCalled() throws Throwable {
+ // Make sure that the scroll view we care about is on screen and at the top:
+ showOnlyStretch();
+
+ InterceptView interceptView = mActivity.findViewById(R.id.wrapped_stretch);
+ dragHoldAndRun(
+ mActivityRule,
+ mScrollViewStretch,
+ mScrollViewStretch.getWidth() / 2,
+ mScrollViewStretch.getHeight() / 2,
+ 300,
+ 0,
+ () -> {
+ interceptView.requestDisallowInterceptCalled = false;
+ return Unit.INSTANCE;
+ },
+ () -> Unit.INSTANCE
+ );
+
+ mActivityRule.runOnUiThread(
+ () -> assertFalse(interceptView.requestDisallowInterceptCalled)
+ );
+ }
+
private void showOnlyStretch() throws Throwable {
mActivityRule.runOnUiThread(() -> {
mScrollViewCustom.setVisibility(View.GONE);
@@ -1015,4 +1045,26 @@
return super.computeVerticalScrollExtent();
}
}
+
+ public static class InterceptView extends FrameLayout {
+ public boolean requestDisallowInterceptCalled = false;
+
+ public InterceptView(Context context) {
+ super(context);
+ }
+
+ public InterceptView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public InterceptView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ requestDisallowInterceptCalled = true;
+ super.requestDisallowInterceptTouchEvent(disallowIntercept);
+ }
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
index 1d75886..d94b491 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
@@ -16,6 +16,8 @@
package android.widget.cts;
+import static android.widget.cts.util.StretchEdgeUtil.dragHoldAndRun;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
@@ -58,6 +60,8 @@
import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
+import kotlin.Unit;
+
/**
* Test {@link ScrollView}.
*/
@@ -882,6 +886,32 @@
assertTrue(StretchEdgeUtil.dragDownTapAndHoldStretches(mActivityRule, mScrollViewStretch));
}
+ @LargeTest
+ @Test
+ public void testRequestDisallowInterceptTouchEventNotCalled() throws Throwable {
+ // Make sure that the scroll view we care about is on screen and at the top:
+ showOnlyStretch();
+
+ InterceptView interceptView = mActivity.findViewById(R.id.wrapped_stretch);
+ Unit result = dragHoldAndRun(
+ mActivityRule,
+ mScrollViewStretch,
+ mScrollViewStretch.getWidth() / 2,
+ mScrollViewStretch.getHeight() / 2,
+ 0,
+ 300,
+ () -> {
+ interceptView.requestDisallowInterceptCalled = false;
+ return Unit.INSTANCE;
+ },
+ () -> Unit.INSTANCE
+ );
+
+ mActivityRule.runOnUiThread(
+ () -> assertFalse(interceptView.requestDisallowInterceptCalled)
+ );
+ }
+
@Test
public void testStretchAtBottom() throws Throwable {
// Make sure that the scroll view we care about is on screen and at the top:
@@ -1038,4 +1068,26 @@
parentHeightMeasureSpec, heightUsed);
}
}
+
+ public static class InterceptView extends FrameLayout {
+ public boolean requestDisallowInterceptCalled = false;
+
+ public InterceptView(Context context) {
+ super(context);
+ }
+
+ public InterceptView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public InterceptView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ requestDisallowInterceptCalled = true;
+ super.requestDisallowInterceptTouchEvent(disallowIntercept);
+ }
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/util/StretchEdgeUtil.kt b/tests/tests/widget/src/android/widget/cts/util/StretchEdgeUtil.kt
index 8aa68ee..ff744b0 100644
--- a/tests/tests/widget/src/android/widget/cts/util/StretchEdgeUtil.kt
+++ b/tests/tests/widget/src/android/widget/cts/util/StretchEdgeUtil.kt
@@ -84,7 +84,7 @@
* Drags an area of the screen and executes [onFinalMove] after sending the final drag
* motion and [onUp] after the drag up event has been sent.
*/
-private fun dragAndExecute(
+public fun dragAndExecute(
activityRule: ActivityTestRule<*>,
screenX: Int,
screenY: Int,
@@ -162,7 +162,7 @@
/**
* Drags in [view], starting at coordinates ([viewX], [viewY]) relative to [view] and moving
* ([deltaX], [deltaY]) pixels before lifting. Immediately after the up event, a down event
- * is sent. If it happens within 400 milliseconds of the last motion event, the Bitmap is captured
+ * is sent. If it happens within 50 milliseconds of the last motion event, the Bitmap is captured
* after 600ms more. If an animation was going to run, this allows that animation to finish before
* capturing the Bitmap. This is attempted up to 5 times.
*
@@ -185,12 +185,59 @@
val screenX = locationOnScreen[0]
val screenY = locationOnScreen[1]
+ return dragHoldAndRun(
+ activityRule,
+ view,
+ viewX,
+ viewY,
+ deltaX,
+ deltaY
+ ) {
+ takeScreenshot(
+ activityRule.activity.window,
+ screenX,
+ screenY,
+ view.width,
+ view.height
+ )
+ }
+}
+
+/**
+ * Drags in [view], starting at coordinates ([viewX], [viewY]) relative to [view] and moving
+ * ([deltaX], [deltaY]) pixels before lifting. Immediately after the up event,
+ * [runBeforeTapDown] is called and then a down event is sent. If it happens within 50 milliseconds
+ * of the last motion event, [runAfterTapDown] is run after 600ms more. If an animation was going
+ * to run, this allows that animation to finish before [runAfterTapDown] is executed.
+ * This is attempted up to 5 times.
+ *
+ * @return The return value from [runAfterTapDown] or `null` if the device did not respond quickly
+ * enough.
+ */
+fun <T> dragHoldAndRun(
+ activityRule: ActivityTestRule<*>,
+ view: View,
+ viewX: Int,
+ viewY: Int,
+ deltaX: Int,
+ deltaY: Int,
+ runBeforeTapDown: () -> Unit = {},
+ runAfterTapDown: () -> T
+): T? {
+ val locationOnScreen = IntArray(2)
+ activityRule.runOnUiThread {
+ view.getLocationOnScreen(locationOnScreen)
+ }
+
+ val screenX = locationOnScreen[0]
+ val screenY = locationOnScreen[1]
+
val instrumentation = InstrumentationRegistry.getInstrumentation()
// Try 5 times at most. If it fails, just return the null bitmap
repeat(5) {
var lastMotion = 0L
- var bitmap: Bitmap? = null
+ var returnValue: T? = null
dragAndExecute(
activityRule = activityRule,
screenX = screenX + viewX,
@@ -202,6 +249,7 @@
},
onUp = {
// Now press
+ runBeforeTapDown()
CtsTouchUtils.injectDownEvent(instrumentation.getUiAutomation(),
SystemClock.uptimeMillis(), screenX + viewX,
screenY + viewY, null)
@@ -215,13 +263,7 @@
// Now make sure that we wait until the release should normally have finished:
sleepAnimationTime(600)
- bitmap = takeScreenshot(
- activityRule.activity.window,
- screenX,
- screenY,
- view.width,
- view.height
- )
+ returnValue = runAfterTapDown()
}
}
)
@@ -230,8 +272,8 @@
SystemClock.uptimeMillis(), false,
screenX + viewX, screenY + viewY, null)
- if (bitmap != null) {
- return bitmap // success!
+ if (returnValue != null) {
+ return returnValue // success!
}
}
return null // timing didn't allow for success this time, so return a null