From 15217bbcaa19b2a42cb8c5427ad4efee25d94ee4 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 19 Nov 2020 18:23:46 -0800 Subject: [PATCH 1/4] Remove engine-side delete key handling. --- .../editing/InputConnectionAdaptor.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index 7615126b135e2..6094fca4c78f3 100644 --- a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -287,6 +287,7 @@ private static int clampIndexToEditable(int index, Editable editable) { @Override public boolean sendKeyEvent(KeyEvent event) { + Log.w(TAG, "Received " + (event.getAction() == KeyEvent.ACTION_DOWN ? "down" : "up") + " event for " + Character.getName(event.getUnicodeChar())); // Give the key processor a chance to process this event. It will send it // to the framework to be handled and return true. If the framework ends up // not handling it, the processor will re-send the event, this time @@ -296,21 +297,22 @@ public boolean sendKeyEvent(KeyEvent event) { } if (event.getAction() == KeyEvent.ACTION_DOWN) { - if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { - int selStart = clampIndexToEditable(Selection.getSelectionStart(mEditable), mEditable); - int selEnd = clampIndexToEditable(Selection.getSelectionEnd(mEditable), mEditable); - if (selStart == selEnd && selStart > 0) { - // Extend selection to left of the last character - selStart = flutterTextUtils.getOffsetBefore(mEditable, selStart); - } - if (selEnd > selStart) { - // Delete the selection. - Selection.setSelection(mEditable, selStart); - mEditable.delete(selStart, selEnd); - return true; - } - return false; - } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) { + // if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { + // int selStart = clampIndexToEditable(Selection.getSelectionStart(mEditable), mEditable); + // int selEnd = clampIndexToEditable(Selection.getSelectionEnd(mEditable), mEditable); + // if (selStart == selEnd && selStart > 0) { + // // Extend selection to left of the last character + // selStart = flutterTextUtils.getOffsetBefore(mEditable, selStart); + // } + // if (selEnd > selStart) { + // // Delete the selection. + // Selection.setSelection(mEditable, selStart); + // mEditable.delete(selStart, selEnd); + // return true; + // } + // return false; + // } else + if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) { int selStart = Selection.getSelectionStart(mEditable); int selEnd = Selection.getSelectionEnd(mEditable); if (selStart == selEnd && !event.isShiftPressed()) { From cf43e9ee70af04cccfd62695fdb7f9b5e1e8df6c Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 19 Nov 2020 18:24:18 -0800 Subject: [PATCH 2/4] Remove engine-side delete key handling. --- .../plugin/editing/InputConnectionAdaptor.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index 6094fca4c78f3..eceadf91dc837 100644 --- a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -287,7 +287,6 @@ private static int clampIndexToEditable(int index, Editable editable) { @Override public boolean sendKeyEvent(KeyEvent event) { - Log.w(TAG, "Received " + (event.getAction() == KeyEvent.ACTION_DOWN ? "down" : "up") + " event for " + Character.getName(event.getUnicodeChar())); // Give the key processor a chance to process this event. It will send it // to the framework to be handled and return true. If the framework ends up // not handling it, the processor will re-send the event, this time @@ -297,21 +296,6 @@ public boolean sendKeyEvent(KeyEvent event) { } if (event.getAction() == KeyEvent.ACTION_DOWN) { - // if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { - // int selStart = clampIndexToEditable(Selection.getSelectionStart(mEditable), mEditable); - // int selEnd = clampIndexToEditable(Selection.getSelectionEnd(mEditable), mEditable); - // if (selStart == selEnd && selStart > 0) { - // // Extend selection to left of the last character - // selStart = flutterTextUtils.getOffsetBefore(mEditable, selStart); - // } - // if (selEnd > selStart) { - // // Delete the selection. - // Selection.setSelection(mEditable, selStart); - // mEditable.delete(selStart, selEnd); - // return true; - // } - // return false; - // } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) { int selStart = Selection.getSelectionStart(mEditable); int selEnd = Selection.getSelectionEnd(mEditable); From 51462245f755bbef69f84521d985ca60e7e799a9 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 19 Nov 2020 18:39:50 -0800 Subject: [PATCH 3/4] Remove unneeded tests --- .../editing/InputConnectionAdaptorTest.java | 163 ------------------ 1 file changed, 163 deletions(-) diff --git a/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java b/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java index feec49b017e75..08b9b29b0decd 100644 --- a/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java +++ b/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java @@ -1028,169 +1028,6 @@ public void testCursorAnchorInfo() { assertNull(testImm.lastCursorAnchorInfo); } - @Test - public void testSendKeyEvent_delKeyDeletesBackward() { - int selStart = 29; - ListenableEditingState editable = sampleEditable(selStart, selStart, SAMPLE_RTL_TEXT); - InputConnectionAdaptor adaptor = sampleInputConnectionAdaptor(editable); - - KeyEvent downKeyDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL); - - for (int i = 0; i < 9; i++) { - boolean didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - } - assertEquals(Selection.getSelectionStart(editable), 19); - - for (int i = 0; i < 9; i++) { - boolean didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - } - assertEquals(Selection.getSelectionStart(editable), 10); - } - - @Test - public void testSendKeyEvent_delKeyDeletesBackwardComplexEmojis() { - int selStart = 75; - ListenableEditingState editable = sampleEditable(selStart, selStart, SAMPLE_EMOJI_TEXT); - InputConnectionAdaptor adaptor = sampleInputConnectionAdaptor(editable); - - KeyEvent downKeyDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL); - boolean didConsume; - - // Normal Character - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 74); - - // Non-Spacing Mark - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 73); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 72); - - // Keycap - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 69); - - // Keycap with invalid base - adaptor.setSelection(68, 68); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 66); - adaptor.setSelection(67, 67); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 66); - - // Zero Width Joiner - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 55); - - // Zero Width Joiner with invalid base - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 53); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 52); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 51); - - // ----- Start Emoji Tag Sequence with invalid base testing ---- - // Delete base tag - adaptor.setSelection(39, 39); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 37); - - // Delete the sequence - adaptor.setSelection(49, 49); - for (int i = 0; i < 6; i++) { - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - } - assertEquals(Selection.getSelectionStart(editable), 37); - // ----- End Emoji Tag Sequence with invalid base testing ---- - - // Emoji Tag Sequence - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 23); - - // Variation Selector with invalid base - adaptor.setSelection(22, 22); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 21); - adaptor.setSelection(22, 22); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 21); - - // Variation Selector - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 19); - - // Emoji Modifier - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 16); - - // Emoji Modifier with invalid base - adaptor.setSelection(14, 14); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 13); - adaptor.setSelection(14, 14); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 13); - - // Line Feed - adaptor.setSelection(12, 12); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 11); - - // Carriage Return - adaptor.setSelection(12, 12); - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 11); - - // Carriage Return and Line Feed - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 9); - - // Regional Indicator Symbol odd - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 7); - - // Regional Indicator Symbol even - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 3); - - // Simple Emoji - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 1); - - // First CodePoint - didConsume = adaptor.sendKeyEvent(downKeyDown); - assertTrue(didConsume); - assertEquals(Selection.getSelectionStart(editable), 0); - } - @Test public void testDoesNotConsumeBackButton() { ListenableEditingState editable = sampleEditable(0, 0); From b323cf3ca8dbb42682caa3a6e124842432545447 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Fri, 20 Nov 2020 09:30:03 -0800 Subject: [PATCH 4/4] Add test to assure del key not consumed --- .../editing/InputConnectionAdaptorTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java b/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java index 08b9b29b0decd..dfab9ecbe0db3 100644 --- a/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java +++ b/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java @@ -1028,6 +1028,21 @@ public void testCursorAnchorInfo() { assertNull(testImm.lastCursorAnchorInfo); } + @Test + public void testSendKeyEvent_delKeyNotConsumed() { + int selStart = 29; + ListenableEditingState editable = sampleEditable(selStart, selStart, SAMPLE_RTL_TEXT); + InputConnectionAdaptor adaptor = sampleInputConnectionAdaptor(editable); + + KeyEvent downKeyDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL); + + for (int i = 0; i < 10; i++) { + boolean didConsume = adaptor.sendKeyEvent(downKeyDown); + assertFalse(didConsume); + } + assertEquals(29, Selection.getSelectionStart(editable)); + } + @Test public void testDoesNotConsumeBackButton() { ListenableEditingState editable = sampleEditable(0, 0);