From d5871d78dc6209353b744d2f300e8a95d55e7023 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Mon, 31 Aug 2020 16:29:48 -0700 Subject: [PATCH] Pass text input key events to the EventResponder if they do not yield characters If the InputConnectionAdaptor receives a key event that does not move the caret or produce a text character (such as the back button), then the event should be given to the EventResponder which will forward it to the view. Fixes https://github.com/flutter/flutter/issues/64864 --- .../plugin/editing/InputConnectionAdaptor.java | 17 +++++++++-------- .../editing/InputConnectionAdaptorTest.java | 11 +++++++++++ .../test/io/flutter/util/FakeKeyEvent.java | 3 +++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index ab4ed5c6b1d82..d702e2b7855ea 100644 --- a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -402,15 +402,16 @@ public boolean sendKeyEvent(KeyEvent event) { } else { // Enter a character. int character = event.getUnicodeChar(); - if (character != 0) { - int selStart = Math.max(0, Selection.getSelectionStart(mEditable)); - int selEnd = Math.max(0, Selection.getSelectionEnd(mEditable)); - int selMin = Math.min(selStart, selEnd); - int selMax = Math.max(selStart, selEnd); - if (selMin != selMax) mEditable.delete(selMin, selMax); - mEditable.insert(selMin, String.valueOf((char) character)); - setSelection(selMin + 1, selMin + 1); + if (character == 0) { + return false; } + int selStart = Math.max(0, Selection.getSelectionStart(mEditable)); + int selEnd = Math.max(0, Selection.getSelectionEnd(mEditable)); + int selMin = Math.min(selStart, selEnd); + int selMax = Math.max(selStart, selEnd); + if (selMin != selMax) mEditable.delete(selMin, selMax); + mEditable.insert(selMin, String.valueOf((char) character)); + setSelection(selMin + 1, selMin + 1); return true; } } 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 458e75b7cfb02..2052a47934c0d 100644 --- a/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java +++ b/shell/platform/android/test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java @@ -1106,6 +1106,17 @@ public void testSendKeyEvent_delKeyDeletesBackwardComplexEmojis() { assertEquals(Selection.getSelectionStart(editable), 0); } + @Test + public void testDoesNotConsumeBackButton() { + Editable editable = sampleEditable(0, 0); + InputConnectionAdaptor adaptor = sampleInputConnectionAdaptor(editable); + + FakeKeyEvent keyEvent = new FakeKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); + boolean didConsume = adaptor.sendKeyEvent(keyEvent); + + assertFalse(didConsume); + } + private static final String SAMPLE_TEXT = "Lorem ipsum dolor sit amet," + "\nconsectetur adipiscing elit."; diff --git a/shell/platform/android/test/io/flutter/util/FakeKeyEvent.java b/shell/platform/android/test/io/flutter/util/FakeKeyEvent.java index 2c9b9ceb1c3b8..75ce7b6ddb302 100644 --- a/shell/platform/android/test/io/flutter/util/FakeKeyEvent.java +++ b/shell/platform/android/test/io/flutter/util/FakeKeyEvent.java @@ -10,6 +10,9 @@ public FakeKeyEvent(int action, int keyCode) { } public final int getUnicodeChar() { + if (getKeyCode() == KeyEvent.KEYCODE_BACK) { + return 0; + } return 1; } }