Tests for RSB stretch on scrolling views
Bug: 204794759
Tests for RSB stretch overscroll for ListView,
ScrollView, and HorizontalScrollView.
Test: These are the tests
Change-Id: I72796dc0ea6ff7915e09669761177b10677ca34a
diff --git a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
index 0067a8a..3f62731 100644
--- a/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/HorizontalScrollViewTest.java
@@ -36,6 +36,8 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Xml;
+import android.view.InputDevice;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
@@ -949,6 +951,108 @@
edgeEffect.onAbsorbVelocity > 0);
}
+ @Test
+ public void scrollFromRotaryStretchesLeft() throws Throwable {
+ showOnlyStretch();
+
+ ScrollViewTest.CaptureOnReleaseEdgeEffect
+ edgeEffect = new ScrollViewTest.CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowLeft = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchLeft() throws Throwable {
+ showOnlyStretch();
+
+ ScrollViewTest.CaptureOnReleaseEdgeEffect
+ edgeEffect = new ScrollViewTest.CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowLeft = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromRotaryStretchesRight() throws Throwable {
+ showOnlyStretch();
+
+ mActivityRule.runOnUiThread(() -> {
+ // Scroll all the way to the Right
+ mScrollViewStretch.scrollTo(210, 0);
+ });
+
+ ScrollViewTest.CaptureOnReleaseEdgeEffect
+ edgeEffect = new ScrollViewTest.CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowRight = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchRight() throws Throwable {
+ showOnlyStretch();
+
+ mActivityRule.runOnUiThread(() -> {
+ // Scroll all the way to the Right
+ mScrollViewStretch.scrollTo(210, 0);
+ });
+
+ ScrollViewTest.CaptureOnReleaseEdgeEffect
+ edgeEffect = new ScrollViewTest.CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowRight = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ private MotionEvent createScrollEvent(float scrollAmount, int source) {
+ MotionEvent.PointerProperties pointerProperties = new MotionEvent.PointerProperties();
+ pointerProperties.toolType = MotionEvent.TOOL_TYPE_MOUSE;
+ MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
+ int axis = source == InputDevice.SOURCE_ROTARY_ENCODER ? MotionEvent.AXIS_SCROLL
+ : MotionEvent.AXIS_HSCROLL;
+ pointerCoords.setAxisValue(axis, scrollAmount);
+
+ return MotionEvent.obtain(
+ 0, /* downTime */
+ 0, /* eventTime */
+ MotionEvent.ACTION_SCROLL, /* action */
+ 1, /* pointerCount */
+ new MotionEvent.PointerProperties[] { pointerProperties },
+ new MotionEvent.PointerCoords[] { pointerCoords },
+ 0, /* metaState */
+ 0, /* buttonState */
+ 0f, /* xPrecision */
+ 0f, /* yPrecision */
+ 0, /* deviceId */
+ 0, /* edgeFlags */
+ source, /* source */
+ 0 /* flags */
+ );
+ }
+
private void showOnlyStretch() throws Throwable {
mActivityRule.runOnUiThread(() -> {
mScrollViewCustom.setVisibility(View.GONE);
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index 6cf81e3..9abef33 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -56,7 +56,9 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.Xml;
+import android.view.InputDevice;
import android.view.KeyEvent;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LayoutAnimationController;
@@ -65,6 +67,7 @@
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
+import android.widget.EdgeEffect;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
@@ -1413,6 +1416,102 @@
assertNotEquals(firstVisible, mListViewStretch.getFirstVisiblePosition());
}
+ @Test
+ public void scrollFromRotaryStretchesTop() throws Throwable {
+ showOnlyStretch();
+
+ CaptureOnReleaseEdgeEffect
+ edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mListViewStretch.mEdgeGlowTop = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mListViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchTop() throws Throwable {
+ showOnlyStretch();
+
+ CaptureOnReleaseEdgeEffect
+ edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mListViewStretch.mEdgeGlowTop = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mListViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromRotaryStretchesBottom() throws Throwable {
+ showOnlyStretch();
+
+ scrollToBottomOfStretch();
+
+ CaptureOnReleaseEdgeEffect
+ edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mListViewStretch.mEdgeGlowBottom = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mListViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchBottom() throws Throwable {
+ showOnlyStretch();
+
+ scrollToBottomOfStretch();
+
+ CaptureOnReleaseEdgeEffect
+ edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mListViewStretch.mEdgeGlowBottom = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mListViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ private MotionEvent createScrollEvent(float scrollAmount, int source) {
+ MotionEvent.PointerProperties pointerProperties = new MotionEvent.PointerProperties();
+ pointerProperties.toolType = MotionEvent.TOOL_TYPE_MOUSE;
+ MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
+ int axis = source == InputDevice.SOURCE_ROTARY_ENCODER ? MotionEvent.AXIS_SCROLL
+ : MotionEvent.AXIS_VSCROLL;
+ pointerCoords.setAxisValue(axis, scrollAmount);
+
+ return MotionEvent.obtain(
+ 0, /* downTime */
+ 0, /* eventTime */
+ MotionEvent.ACTION_SCROLL, /* action */
+ 1, /* pointerCount */
+ new MotionEvent.PointerProperties[] { pointerProperties },
+ new MotionEvent.PointerCoords[] { pointerCoords },
+ 0, /* metaState */
+ 0, /* buttonState */
+ 0f, /* xPrecision */
+ 0f, /* yPrecision */
+ 0, /* deviceId */
+ 0, /* edgeFlags */
+ source, /* source */
+ 0 /* flags */
+ );
+ }
+
private void executeWhileDragging(
int dragY,
Runnable duringDrag,
@@ -1711,4 +1810,18 @@
return view;
}
}
+
+ private static class CaptureOnReleaseEdgeEffect extends EdgeEffect {
+ public boolean onReleaseCalled;
+
+ CaptureOnReleaseEdgeEffect(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onRelease() {
+ onReleaseCalled = true;
+ super.onRelease();
+ }
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
index 8bebb57..8459ae0 100644
--- a/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ScrollViewTest.java
@@ -36,6 +36,8 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Xml;
+import android.view.InputDevice;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
@@ -984,6 +986,104 @@
assertTrue(edgeEffect.onAbsorbVelocity > 0);
}
+ @Test
+ public void scrollFromRotaryStretchesTop() throws Throwable {
+ showOnlyStretch();
+
+ CaptureOnReleaseEdgeEffect edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowTop = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchTop() throws Throwable {
+ showOnlyStretch();
+
+ CaptureOnReleaseEdgeEffect edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowTop = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromRotaryStretchesBottom() throws Throwable {
+ showOnlyStretch();
+
+ mActivityRule.runOnUiThread(() -> {
+ // Scroll all the way to the bottom
+ mScrollViewStretch.scrollTo(0, 210);
+ });
+
+ CaptureOnReleaseEdgeEffect edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowBottom = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertTrue(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_ROTARY_ENCODER)));
+ assertFalse(edgeEffect.isFinished());
+ assertTrue(edgeEffect.getDistance() > 0f);
+ assertTrue(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ @Test
+ public void scrollFromMouseDoesNotStretchBottom() throws Throwable {
+ showOnlyStretch();
+
+ mActivityRule.runOnUiThread(() -> {
+ // Scroll all the way to the bottom
+ mScrollViewStretch.scrollTo(0, 210);
+ });
+
+ CaptureOnReleaseEdgeEffect edgeEffect = new CaptureOnReleaseEdgeEffect(mActivity);
+ mScrollViewStretch.mEdgeGlowBottom = edgeEffect;
+
+ mActivityRule.runOnUiThread(() -> {
+ assertFalse(mScrollViewStretch.dispatchGenericMotionEvent(
+ createScrollEvent(-2f, InputDevice.SOURCE_MOUSE)));
+ assertTrue(edgeEffect.isFinished());
+ assertFalse(edgeEffect.onReleaseCalled);
+ });
+ }
+
+ private MotionEvent createScrollEvent(float scrollAmount, int source) {
+ MotionEvent.PointerProperties pointerProperties = new MotionEvent.PointerProperties();
+ pointerProperties.toolType = MotionEvent.TOOL_TYPE_MOUSE;
+ MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
+ int axis = source == InputDevice.SOURCE_ROTARY_ENCODER ? MotionEvent.AXIS_SCROLL
+ : MotionEvent.AXIS_VSCROLL;
+ pointerCoords.setAxisValue(axis, scrollAmount);
+
+ return MotionEvent.obtain(
+ 0, /* downTime */
+ 0, /* eventTime */
+ MotionEvent.ACTION_SCROLL, /* action */
+ 1, /* pointerCount */
+ new MotionEvent.PointerProperties[] { pointerProperties },
+ new MotionEvent.PointerCoords[] { pointerCoords },
+ 0, /* metaState */
+ 0, /* buttonState */
+ 0f, /* xPrecision */
+ 0f, /* yPrecision */
+ 0, /* deviceId */
+ 0, /* edgeFlags */
+ source, /* source */
+ 0 /* flags */
+ );
+ }
+
private void showOnlyStretch() throws Throwable {
mActivityRule.runOnUiThread(() -> {
mScrollViewCustom.setVisibility(View.GONE);
@@ -1147,4 +1247,18 @@
super.onAbsorb(velocity);
}
}
+
+ public static class CaptureOnReleaseEdgeEffect extends EdgeEffect {
+ public boolean onReleaseCalled;
+
+ public CaptureOnReleaseEdgeEffect(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onRelease() {
+ onReleaseCalled = true;
+ super.onRelease();
+ }
+ }
}