From 99b55fa6a5d232153ba07fc580091ec8e1e8d42e Mon Sep 17 00:00:00 2001 From: Nikita Dubrovsky Date: Sun, 12 Jan 2020 20:57:51 -0800 Subject: [PATCH] Fix NPE in InsertionPointCursorController.onTouchEvent Calls to SelectionModifierCursorController must be guarded by hasSelectionController() because it's possible to have a TextView with an Editor but no selection controller if the TextView is configured to have non-selectable text. Bug: 147366705 Bug: 145535274 Bug: 143852764 Test: Manual and unit test atest FrameworksCoreTests:EditorCursorDragTest Change-Id: I7fdec754e6fa51561b08fab024ea672c43f2c8f5 --- core/java/android/widget/Editor.java | 2 +- .../android/widget/EditorCursorDragTest.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 20af76b0d5ca7..f851e10fa4f64 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -5737,7 +5737,7 @@ public class Editor { private boolean mIsDraggingCursor; public void onTouchEvent(MotionEvent event) { - if (getSelectionController().isCursorBeingModified()) { + if (hasSelectionController() && getSelectionController().isCursorBeingModified()) { return; } switch (event.getActionMasked()) { diff --git a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java index 89c237498e5c3..8c9b4d071c2da 100644 --- a/core/tests/coretests/src/android/widget/EditorCursorDragTest.java +++ b/core/tests/coretests/src/android/widget/EditorCursorDragTest.java @@ -67,6 +67,7 @@ public class EditorCursorDragTest { mOriginalFlagValue = Editor.FLAG_ENABLE_CURSOR_DRAG; Editor.FLAG_ENABLE_CURSOR_DRAG = true; } + @After public void after() throws Throwable { Editor.FLAG_ENABLE_CURSOR_DRAG = mOriginalFlagValue; @@ -356,6 +357,23 @@ public class EditorCursorDragTest { assertFalse(editor.getSelectionController().isCursorBeingModified()); } + @Test // Reproduces b/147366705 + public void testCursorDrag_nonSelectableTextView() throws Throwable { + String text = "Hello world!"; + TextView tv = mActivity.findViewById(R.id.nonselectable_textview); + tv.setText(text); + Editor editor = tv.getEditorForTesting(); + + // Simulate a tap. No error should be thrown. + long event1Time = 1001; + MotionEvent event1 = downEvent(event1Time, event1Time, 20f, 30f); + mInstrumentation.runOnMainSync(() -> editor.onTouchEvent(event1)); + + // Swipe left to right. No error should be thrown. + onView(withId(R.id.nonselectable_textview)).perform( + dragOnText(text.indexOf("llo"), text.indexOf("!"))); + } + private static MotionEvent downEvent(long downTime, long eventTime, float x, float y) { return MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0); }