summaryrefslogtreecommitdiff
path: root/core/java/android/widget/TextView.java
diff options
context:
space:
mode:
authorShu Chen <shuchen@google.com>2020-04-04 14:46:50 +0800
committerShu Chen <shuchen@google.com>2020-04-16 13:58:10 +0800
commiteb8b1ba3df0082797dfa26c45240dbf4654360ef (patch)
tree2287b0ac9b2f5dadc3bce091f15a3254937a8cb2 /core/java/android/widget/TextView.java
parent449baa2ee38a254be92f2e907fcf846003851801 (diff)
Prevents multi touch among TextView and handle reviews.
- First touch on TextView blocks secondary touches on handles. - First touch on handles blocks later touches on TextView but doesn't block secondary touches on other handles. Bug: 150995597 Test: manually tested & automation tests: atest FrameworksCoreTests:EditorCursorDragTest atest FrameworksCoreTests:TextViewActivityTest Change-Id: I7717fc061fc81514fc1dad0d3acbc73e683516cf
Diffstat (limited to 'core/java/android/widget/TextView.java')
-rw-r--r--core/java/android/widget/TextView.java46
1 files changed, 46 insertions, 0 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e1783181457f..4be9e1a2051b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -855,6 +855,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int mTextEditSuggestionContainerLayout;
int mTextEditSuggestionHighlightStyle;
+ private static final int NO_POINTER_ID = -1;
+ /**
+ * The prime (the 1st finger) pointer id which is used as a lock to prevent multi touch among
+ * TextView and the handle views which are rendered on popup windows.
+ */
+ private int mPrimePointerId = NO_POINTER_ID;
+
+ /**
+ * Whether the prime pointer is from the event delivered to selection handle or insertion
+ * handle.
+ */
+ private boolean mIsPrimePointerFromHandleView;
+
/**
* {@link EditText} specific data, created on demand when one of the Editor fields is used.
* See {@link #createEditorIfNeeded()}.
@@ -10886,6 +10899,36 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ /**
+ * Called from onTouchEvent() to prevent the touches by secondary fingers.
+ * Dragging on handles can revise cursor/selection, so can dragging on the text view.
+ * This method is a lock to avoid processing multiple fingers on both text view and handles.
+ * Note: multiple fingers on handles (e.g. 2 fingers on the 2 selection handles) should work.
+ *
+ * @param event The motion event that is being handled and carries the pointer info.
+ * @param fromHandleView true if the event is delivered to selection handle or insertion
+ * handle; false if this event is delivered to TextView.
+ * @return Returns true to indicate that onTouchEvent() can continue processing the motion
+ * event, otherwise false.
+ * - Always returns true for the first finger.
+ * - For secondary fingers, if the first or current finger is from TextView, returns false.
+ * This is to make touch mutually exclusive between the TextView and the handles, but
+ * not among the handles.
+ */
+ boolean isFromPrimePointer(MotionEvent event, boolean fromHandleView) {
+ if (mPrimePointerId == NO_POINTER_ID) {
+ mPrimePointerId = event.getPointerId(0);
+ mIsPrimePointerFromHandleView = fromHandleView;
+ } else if (mPrimePointerId != event.getPointerId(0)) {
+ return mIsPrimePointerFromHandleView && fromHandleView;
+ }
+ if (event.getActionMasked() == MotionEvent.ACTION_UP
+ || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
+ mPrimePointerId = -1;
+ }
+ return true;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
if (DEBUG_CURSOR) {
@@ -10894,6 +10937,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
MotionEvent.actionToString(event.getActionMasked()),
event.getX(), event.getY());
}
+ if (!isFromPrimePointer(event, false)) {
+ return true;
+ }
final int action = event.getActionMasked();
if (mEditor != null) {