Merge "Merge "Unifies the finger-to-cursor distance between drag cursor and drag handle." into rvc-dev am: 45b08852ad am: 820d73a646" into rvc-d1-dev-plus-aosp am: 465881727f

Change-Id: Ie3a3ea94d5e38424842f79c9dd473e8334f134cf
This commit is contained in:
Automerger Merge Worker
2020-03-10 00:49:03 +00:00
3 changed files with 196 additions and 71 deletions

View File

@@ -4587,7 +4587,8 @@ public class Editor {
protected int mHorizontalGravity;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
// Where the touch position should be on the handle to ensure a maximum cursor visibility.
// This is the distance in pixels from the top of the handle view.
private float mIdealVerticalOffset;
// Parent's (TextView) previous position in window
private int mLastParentX, mLastParentY;
@@ -4612,6 +4613,11 @@ public class Editor {
// when magnifier is used.
private float mTextViewScaleX;
private float mTextViewScaleY;
/**
* The vertical distance in pixels from finger to the cursor Y while dragging.
* See {@link Editor.InsertionPointCursorController#getLineDuringDrag}.
*/
private final int mIdealFingerToCursorOffset;
private HandleView(Drawable drawableLtr, Drawable drawableRtl, final int id) {
super(mTextView.getContext());
@@ -4633,12 +4639,17 @@ public class Editor {
final int handleHeight = getPreferredHeight();
mTouchOffsetY = -0.3f * handleHeight;
mIdealVerticalOffset = 0.7f * handleHeight;
mIdealFingerToCursorOffset = (int)(mIdealVerticalOffset - mTouchOffsetY);
}
public float getIdealVerticalOffset() {
return mIdealVerticalOffset;
}
final int getIdealFingerToCursorOffset() {
return mIdealFingerToCursorOffset;
}
void setDrawables(final Drawable drawableLtr, final Drawable drawableRtl) {
mDrawableLtr = drawableLtr;
mDrawableRtl = drawableRtl;
@@ -6123,36 +6134,34 @@ public class Editor {
*/
private int getLineDuringDrag(MotionEvent event) {
final Layout layout = mTextView.getLayout();
if (mTouchState.isOnHandle()) {
// The drag was initiated from the handle, so no need to apply the snap logic. See
// InsertionHandleView.touchThrough().
if (mPrevLineDuringDrag == UNSET_LINE) {
return getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, event.getY());
}
// In case of touch through on handle (when isOnHandle() returns true), event.getY()
// returns the midpoint of the cursor vertical bar, while event.getRawY() returns the
// finger location on the screen. See {@link InsertionHandleView#touchThrough}.
final float fingerY = mTouchState.isOnHandle()
? event.getRawY() - mTextView.getLocationOnScreen()[1]
: event.getY();
final float cursorY = fingerY - getHandle().getIdealFingerToCursorOffset();
int line = getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, cursorY);
if (mIsTouchSnappedToHandleDuringDrag) {
float cursorY = event.getY() - getHandle().getIdealVerticalOffset();
return getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, cursorY);
}
int line = getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, event.getY());
if (mPrevLineDuringDrag == UNSET_LINE || line <= mPrevLineDuringDrag) {
// User's finger is on the same line or moving up; continue positioning the cursor
// directly at the touch location.
// Just returns the line hit by cursor Y when already snapped.
return line;
}
// User's finger is moving downwards; delay jumping to the lower line to allow the
// touch to move to the handle.
float cursorY = event.getY() - getHandle().getIdealVerticalOffset();
line = getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, cursorY);
if (line < mPrevLineDuringDrag) {
return mPrevLineDuringDrag;
// The cursor Y aims too high & not yet snapped, check the finger Y.
// If finger Y is moving downwards, don't jump to lower line (until snap).
// If finger Y is moving upwards, can jump to upper line.
return Math.min(mPrevLineDuringDrag,
getCurrentLineAdjustedForSlop(layout, mPrevLineDuringDrag, fingerY));
}
// User's finger is now over the handle, at the ideal offset from the cursor. From now
// on, position the cursor higher up from the actual touch location so that the user's
// finger stays "snapped" to the handle. This provides better visibility of the text.
// The cursor Y aims not too high, so snap!
mIsTouchSnappedToHandleDuringDrag = true;
if (TextView.DEBUG_CURSOR) {
logCursor("InsertionPointCursorController",
"snapped touch to handle: eventY=%d, cursorY=%d, mLastLine=%d, line=%d",
(int) event.getY(), (int) cursorY, mPrevLineDuringDrag, line);
"snapped touch to handle: fingerY=%d, cursorY=%d, mLastLine=%d, line=%d",
(int) fingerY, (int) cursorY, mPrevLineDuringDrag, line);
}
return line;
}
@@ -6252,7 +6261,7 @@ public class Editor {
}
}
private InsertionHandleView getHandle() {
public InsertionHandleView getHandle() {
if (mHandle == null) {
loadHandleDrawables(false /* overwrite */);
mHandle = new InsertionHandleView(mSelectHandleCenter);

View File

@@ -35,10 +35,13 @@ import static org.junit.Assert.assertTrue;
import android.app.Activity;
import android.app.Instrumentation;
import android.graphics.Rect;
import android.text.Layout;
import android.util.ArraySet;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -50,11 +53,13 @@ import com.android.frameworks.coretests.R;
import com.google.common.base.Strings;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@RunWith(AndroidJUnit4.class)
@@ -70,6 +75,7 @@ public class EditorCursorDragTest {
private Instrumentation mInstrumentation;
private Activity mActivity;
private Set<MotionEvent> mMotionEvents = new ArraySet<>();
@Before
public void before() throws Throwable {
@@ -77,6 +83,14 @@ public class EditorCursorDragTest {
mActivity = mActivityRule.getActivity();
}
@After
public void after() throws Throwable {
for (MotionEvent event : mMotionEvents) {
event.recycle();
}
mMotionEvents.clear();
}
@Test
public void testCursorDrag_horizontal_whenTextViewContentsFitOnScreen() throws Throwable {
String text = "Hello world!";
@@ -243,45 +257,45 @@ public class EditorCursorDragTest {
// Simulate a tap-and-drag gesture.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 5f, 10f);
MotionEvent event1 = downEvent(tv, event1Time, event1Time, 5f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = moveEvent(event1Time, event2Time, 50f, 10f);
MotionEvent event2 = moveEvent(tv, event1Time, event2Time, 50f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertTrue(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
MotionEvent event3 = moveEvent(event1Time, event3Time, 100f, 10f);
MotionEvent event3 = moveEvent(tv, event1Time, event3Time, 100f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertTrue(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event4Time = 2004;
MotionEvent event4 = upEvent(event1Time, event4Time, 100f, 10f);
MotionEvent event4 = upEvent(tv, event1Time, event4Time, 100f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
// Simulate a quick tap after the drag, near the location where the drag ended.
long event5Time = 2005;
MotionEvent event5 = downEvent(event5Time, event5Time, 90f, 10f);
MotionEvent event5 = downEvent(tv, event5Time, event5Time, 90f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event5));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event6Time = 2006;
MotionEvent event6 = upEvent(event5Time, event6Time, 90f, 10f);
MotionEvent event6 = upEvent(tv, event5Time, event6Time, 90f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event6));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
// Simulate another quick tap in the same location; now selection should be triggered.
long event7Time = 2007;
MotionEvent event7 = downEvent(event7Time, event7Time, 90f, 10f);
MotionEvent event7 = downEvent(tv, event7Time, event7Time, 90f, 10f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event7));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
@@ -298,19 +312,19 @@ public class EditorCursorDragTest {
// Simulate a mouse click and drag. This should NOT trigger a cursor drag.
long event1Time = 1001;
MotionEvent event1 = mouseDownEvent(event1Time, event1Time, 20f, 30f);
MotionEvent event1 = mouseDownEvent(tv, event1Time, event1Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = mouseMoveEvent(event1Time, event2Time, 120f, 30f);
MotionEvent event2 = mouseMoveEvent(tv, event1Time, event2Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
MotionEvent event3 = mouseUpEvent(event1Time, event3Time, 120f, 30f);
MotionEvent event3 = mouseUpEvent(tv, event1Time, event3Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
@@ -327,25 +341,25 @@ public class EditorCursorDragTest {
// Simulate a tap-and-drag gesture. This should trigger a cursor drag.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
MotionEvent event1 = downEvent(tv, event1Time, event1Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = moveEvent(event1Time, event2Time, 21f, 30f);
MotionEvent event2 = moveEvent(tv, event1Time, event2Time, 21f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
MotionEvent event3 = moveEvent(event1Time, event3Time, 120f, 30f);
MotionEvent event3 = moveEvent(tv, event1Time, event3Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertTrue(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event4Time = 1004;
MotionEvent event4 = upEvent(event1Time, event4Time, 120f, 30f);
MotionEvent event4 = upEvent(tv, event1Time, event4Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
@@ -362,31 +376,31 @@ public class EditorCursorDragTest {
// Simulate a double-tap followed by a drag. This should trigger a selection drag.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
MotionEvent event1 = downEvent(tv, event1Time, event1Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event2Time = 1002;
MotionEvent event2 = upEvent(event1Time, event2Time, 20f, 30f);
MotionEvent event2 = upEvent(tv, event1Time, event2Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event2));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
long event3Time = 1003;
MotionEvent event3 = downEvent(event3Time, event3Time, 20f, 30f);
MotionEvent event3 = downEvent(tv, event3Time, event3Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event3));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
long event4Time = 1004;
MotionEvent event4 = moveEvent(event3Time, event4Time, 120f, 30f);
MotionEvent event4 = moveEvent(tv, event3Time, event4Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event4));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertTrue(editor.getSelectionController().isCursorBeingModified());
long event5Time = 1005;
MotionEvent event5 = upEvent(event3Time, event5Time, 120f, 30f);
MotionEvent event5 = upEvent(tv, event3Time, event5Time, 120f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event5));
assertFalse(editor.getInsertionController().isCursorBeingModified());
assertFalse(editor.getSelectionController().isCursorBeingModified());
@@ -403,7 +417,7 @@ public class EditorCursorDragTest {
// Simulate a tap. No error should be thrown.
long event1Time = 1001;
MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f);
MotionEvent event1 = downEvent(tv, event1Time, event1Time, 20f, 30f);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1));
// Swipe left to right. No error should be thrown.
@@ -440,7 +454,8 @@ public class EditorCursorDragTest {
public void testCursorDrag_snapToHandle() throws Throwable {
String text = "line1: This is the 1st line: A\n"
+ "line2: This is the 2nd line: B\n"
+ "line3: This is the 3rd line: C\n";
+ "line3: This is the 3rd line: C\n"
+ "line4: This is the 4th line: D\n";
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
TextView tv = mActivity.findViewById(R.id.textview);
@@ -454,8 +469,8 @@ public class EditorCursorDragTest {
// Start dragging along the first line
motionEventInfo(text.indexOf("line1"), 1.0f),
motionEventInfo(text.indexOf("This is the 1st"), 1.0f),
// Move to the bottom of the third line; cursor should end up on second line
motionEventInfo(text.indexOf("he 3rd"), 0.0f, text.indexOf("he 2nd")),
// Move to the middle of the fourth line; cursor should end up on second line
motionEventInfo(text.indexOf("he 4th"), 0.5f, text.indexOf("he 2nd")),
// Move to the middle of the second line; cursor should end up on the first line
motionEventInfo(text.indexOf("he 2nd"), 0.5f, text.indexOf("he 1st"))
};
@@ -473,37 +488,137 @@ public class EditorCursorDragTest {
simulateDrag(tv, events, true);
}
private static MotionEvent downEvent(long downTime, long eventTime, float x, float y) {
return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0);
@Test
public void testCursorDrag_snapDistance() throws Throwable {
String text = "line1: This is the 1st line: A\n"
+ "line2: This is the 2nd line: B\n"
+ "line3: This is the 3rd line: C\n";
onView(withId(R.id.textview)).perform(replaceText(text));
TextView tv = mActivity.findViewById(R.id.textview);
Editor editor = tv.getEditorForTesting();
final int startIndex = text.indexOf("he 2nd");
Layout layout = tv.getLayout();
final float cursorStartX = layout.getPrimaryHorizontal(startIndex) + tv.getTotalPaddingLeft();
final float cursorStartY = layout.getLineTop(1) + tv.getTotalPaddingTop();
final float dragHandleStartX = 20;
final float dragHandleStartY = 20;
// Drag the handle from the 2nd line to the 3rd line.
tapAtPoint(tv, cursorStartX, cursorStartY);
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(startIndex));
View handleView = editor.getInsertionController().getHandle();
final int rawYOfHandleDrag = dragDownUntilLineChange(
handleView, dragHandleStartX, dragHandleStartY, tv.getSelectionStart());
// Drag the cursor from the 2nd line to the 3rd line.
tapAtPoint(tv, cursorStartX, cursorStartY);
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(startIndex));
final int rawYOfCursorDrag =
dragDownUntilLineChange(tv, cursorStartX, cursorStartY, tv.getSelectionStart());
// Drag the handle with touch through from the 2nd line to the 3rd line.
tv.getEditorForTesting().setFlagInsertionHandleGesturesEnabled(true);
tapAtPoint(tv, cursorStartX, cursorStartY);
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(startIndex));
handleView = editor.getInsertionController().getHandle();
int rawYOfHandleDragWithTouchThrough =
dragDownUntilLineChange(handleView, dragHandleStartX, dragHandleStartY, tv.getSelectionStart());
String msg = String.format(
"rawYOfHandleDrag: %d, rawYOfCursorDrag: %d, rawYOfHandleDragWithTouchThrough: %d",
rawYOfHandleDrag, rawYOfCursorDrag, rawYOfHandleDragWithTouchThrough);
final int max = Math.max(
rawYOfCursorDrag, Math.max(rawYOfHandleDrag, rawYOfHandleDragWithTouchThrough));
final int min = Math.min(
rawYOfCursorDrag, Math.min(rawYOfHandleDrag, rawYOfHandleDragWithTouchThrough));
// The drag step is 5 pixels in dragDownUntilLineChange().
// The difference among the 3 raw Y values should be no bigger than the drag step.
assertWithMessage(msg).that(max - min).isLessThan(6);
}
private static MotionEvent upEvent(long downTime, long eventTime, float x, float y) {
return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
private void dispatchTouchEvent(View view, MotionEvent event) {
mInstrumentation.runOnMainSync(() -> view.dispatchTouchEvent(event));
}
private static MotionEvent moveEvent(long downTime, long eventTime, float x, float y) {
return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
private void tapAtPoint(TextView tv, final float x, final float y) {
long downTime = sTicker.addAndGet(10_000);
dispatchTouchEvent(tv, downEvent(tv, downTime, downTime, x, y));
dispatchTouchEvent(tv, upEvent(tv, downTime, downTime + 1, x, y));
}
private static MotionEvent mouseDownEvent(long downTime, long eventTime, float x, float y) {
MotionEvent event = downEvent(downTime, eventTime, x, y);
event.setSource(InputDevice.SOURCE_MOUSE);
event.setButtonState(MotionEvent.BUTTON_PRIMARY);
private int dragDownUntilLineChange(View view, final float startX, final float startY,
final int startOffset) {
TextView tv = mActivity.findViewById(R.id.textview);
final int startLine = tv.getLayout().getLineForOffset(startOffset);
int rawY = 0;
long downTime = sTicker.addAndGet(10_000);
long eventTime = downTime;
// Move horizontally first to initiate the cursor drag.
dispatchTouchEvent(view, downEvent(view, downTime, eventTime++, startX, startY));
dispatchTouchEvent(view, moveEvent(view, downTime, eventTime++, startX + 50, startY));
dispatchTouchEvent(view, moveEvent(view, downTime, eventTime++, startX, startY));
// Move downwards 5 pixels at a time until a line change occurs.
for (int i = 0; i < 200; i++) {
MotionEvent ev = moveEvent(view, downTime, eventTime++, startX, startY + i * 5);
rawY = (int) ev.getRawY();
dispatchTouchEvent(view, ev);
if (tv.getLayout().getLineForOffset(tv.getSelectionStart()) > startLine) {
break;
}
}
String msg = String.format("The cursor didn't jump from %d!", startOffset);
assertWithMessage(msg).that(
tv.getLayout().getLineForOffset(tv.getSelectionStart())).isGreaterThan(startLine);
dispatchTouchEvent(view, upEvent(view, downTime, eventTime, startX, startY));
return rawY;
}
private MotionEvent obtainTouchEvent(
View view, int action, long downTime, long eventTime, float x, float y) {
Rect r = new Rect();
view.getBoundsOnScreen(r);
float rawX = x + r.left;
float rawY = y + r.top;
MotionEvent event =
MotionEvent.obtain(downTime, eventTime, action, rawX, rawY, 0);
view.toLocalMotionEvent(event);
mMotionEvents.add(event);
return event;
}
private static MotionEvent mouseUpEvent(long downTime, long eventTime, float x, float y) {
MotionEvent event = upEvent(downTime, eventTime, x, y);
private MotionEvent obtainMouseEvent(
View view, int action, long downTime, long eventTime, float x, float y) {
MotionEvent event = obtainTouchEvent(view, action, downTime, eventTime, x, y);
event.setSource(InputDevice.SOURCE_MOUSE);
event.setButtonState(0);
if (action != MotionEvent.ACTION_UP) {
event.setButtonState(MotionEvent.BUTTON_PRIMARY);
}
return event;
}
private static MotionEvent mouseMoveEvent(long downTime, long eventTime, float x, float y) {
MotionEvent event = moveEvent(downTime, eventTime, x, y);
event.setSource(InputDevice.SOURCE_MOUSE);
event.setButtonState(MotionEvent.BUTTON_PRIMARY);
return event;
private MotionEvent downEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainTouchEvent(view, MotionEvent.ACTION_DOWN, downTime, eventTime, x, y);
}
private MotionEvent moveEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainTouchEvent(view, MotionEvent.ACTION_MOVE, downTime, eventTime, x, y);
}
private MotionEvent upEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainTouchEvent(view, MotionEvent.ACTION_UP, downTime, eventTime, x, y);
}
private MotionEvent mouseDownEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainMouseEvent(view, MotionEvent.ACTION_DOWN, downTime, eventTime, x, y);
}
private MotionEvent mouseMoveEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainMouseEvent(view, MotionEvent.ACTION_MOVE, downTime, eventTime, x, y);
}
private MotionEvent mouseUpEvent(View view, long downTime, long eventTime, float x, float y) {
return obtainMouseEvent(view, MotionEvent.ACTION_UP, downTime, eventTime, x, y);
}
public static MotionEventInfo motionEventInfo(int index, float ratioToLineTop) {
@@ -543,14 +658,15 @@ public class EditorCursorDragTest {
float[] downCoords = events[0].getCoordinates(tv);
long downEventTime = sTicker.addAndGet(10_000);
MotionEvent downEvent = downEvent(downEventTime, downEventTime,
MotionEvent downEvent = downEvent(tv, downEventTime, downEventTime,
downCoords[0], downCoords[1]);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(downEvent));
for (int i = 1; i < events.length; i++) {
float[] moveCoords = events[i].getCoordinates(tv);
long eventTime = downEventTime + i;
MotionEvent event = moveEvent(downEventTime, eventTime, moveCoords[0], moveCoords[1]);
MotionEvent event = moveEvent(tv, downEventTime, eventTime, moveCoords[0],
moveCoords[1]);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event));
assertCursorPosition(tv, events[i].expectedCursorIndex, runAssertions);
}
@@ -558,7 +674,7 @@ public class EditorCursorDragTest {
MotionEventInfo lastEvent = events[events.length - 1];
float[] upCoords = lastEvent.getCoordinates(tv);
long upEventTime = downEventTime + events.length;
MotionEvent upEvent = upEvent(downEventTime, upEventTime, upCoords[0], upCoords[1]);
MotionEvent upEvent = upEvent(tv, downEventTime, upEventTime, upCoords[0], upCoords[1]);
mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(upEvent));
}

View File

@@ -497,7 +497,7 @@ public class TextViewActivityTest {
@Test
public void testInsertionHandle_multiLine() {
final String text = "abcd\n" + "efg\n" + "hijk\n";
final String text = "abcd\n" + "efg\n" + "hijk\n" + "lmn\n";
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
@@ -505,13 +505,13 @@ public class TextViewActivityTest {
final TextView textView = mActivity.findViewById(R.id.textview);
onHandleView(com.android.internal.R.id.insertion_handle)
.perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
onHandleView(com.android.internal.R.id.insertion_handle)
.perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
onHandleView(com.android.internal.R.id.insertion_handle)
.perform(dragHandle(textView, Handle.INSERTION, text.indexOf('i')));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("i")));
}
private void enableFlagsForInsertionHandleGestures() {