Skip to content

Commit 02aa865

Browse files
authored
Fix the newline on some keyboards (flutter#16560)
1 parent fdabcad commit 02aa865

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

shell/platform/android/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,12 @@ action("robolectric_tests") {
435435
"test/io/flutter/embedding/engine/systemchannels/PlatformChannelTest.java",
436436
"test/io/flutter/external/FlutterLaunchTests.java",
437437
"test/io/flutter/plugin/common/StandardMessageCodecTest.java",
438+
"test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java",
438439
"test/io/flutter/plugin/editing/TextInputPluginTest.java",
439440
"test/io/flutter/plugin/platform/PlatformPluginTest.java",
440441
"test/io/flutter/plugin/platform/SingleViewPresentationTest.java",
441442
"test/io/flutter/plugins/GeneratedPluginRegistrant.java",
443+
"test/io/flutter/util/FakeKeyEvent.java",
442444
"test/io/flutter/util/PreconditionsTest.java",
443445
]
444446

shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.provider.Settings;
1111
import android.text.DynamicLayout;
1212
import android.text.Editable;
13+
import android.text.InputType;
1314
import android.text.Layout;
1415
import android.text.Selection;
1516
import android.text.TextPaint;
@@ -274,8 +275,11 @@ public boolean sendKeyEvent(KeyEvent event) {
274275
int newSel = Math.min(selStart + 1, mEditable.length());
275276
setSelection(newSel, newSel);
276277
return true;
277-
} else if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
278-
|| event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER) {
278+
// When the enter key is pressed on a non-multiline field, consider it a
279+
// submit instead of a newline.
280+
} else if ((event.getKeyCode() == KeyEvent.KEYCODE_ENTER
281+
|| event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER)
282+
&& (InputType.TYPE_TEXT_FLAG_MULTI_LINE & mEditorInfo.inputType) == 0) {
279283
performEditorAction(mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION);
280284
return true;
281285
} else {

shell/platform/android/test/io/flutter/FlutterTestSuite.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.flutter.embedding.engine.systemchannels.PlatformChannelTest;
1818
import io.flutter.external.FlutterLaunchTests;
1919
import io.flutter.plugin.common.StandardMessageCodecTest;
20+
import io.flutter.plugin.editing.InputConnectionAdaptorTest;
2021
import io.flutter.plugin.editing.TextInputPluginTest;
2122
import io.flutter.plugin.platform.PlatformPluginTest;
2223
import io.flutter.plugin.platform.SingleViewPresentationTest;
@@ -44,6 +45,7 @@
4445
FlutterShellArgsTest.class,
4546
FlutterRendererTest.class,
4647
FlutterViewTest.class,
48+
InputConnectionAdaptorTest.class,
4749
PlatformChannelTest.class,
4850
PlatformPluginTest.class,
4951
PluginComponentTest.class,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.flutter.plugin.editing;
2+
3+
import static org.mockito.Mockito.anyString;
4+
import static org.mockito.Mockito.eq;
5+
import static org.mockito.Mockito.mock;
6+
import static org.mockito.Mockito.spy;
7+
import static org.mockito.Mockito.times;
8+
import static org.mockito.Mockito.verify;
9+
10+
import android.content.res.AssetManager;
11+
import android.text.Editable;
12+
import android.text.InputType;
13+
import android.view.KeyEvent;
14+
import android.view.View;
15+
import android.view.inputmethod.EditorInfo;
16+
import io.flutter.embedding.engine.FlutterJNI;
17+
import io.flutter.embedding.engine.dart.DartExecutor;
18+
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
19+
import io.flutter.util.FakeKeyEvent;
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
import org.robolectric.RobolectricTestRunner;
23+
import org.robolectric.RuntimeEnvironment;
24+
import org.robolectric.annotation.Config;
25+
26+
@Config(manifest = Config.NONE, sdk = 27)
27+
@RunWith(RobolectricTestRunner.class)
28+
public class InputConnectionAdaptorTest {
29+
@Test
30+
public void inputConnectionAdaptor_ReceivesEnter() throws NullPointerException {
31+
View testView = new View(RuntimeEnvironment.application);
32+
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
33+
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
34+
int inputTargetId = 0;
35+
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
36+
Editable mEditable = Editable.Factory.getInstance().newEditable("");
37+
Editable spyEditable = spy(mEditable);
38+
EditorInfo outAttrs = new EditorInfo();
39+
outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
40+
41+
InputConnectionAdaptor inputConnectionAdaptor =
42+
new InputConnectionAdaptor(
43+
testView, inputTargetId, textInputChannel, spyEditable, outAttrs);
44+
45+
// Send an enter key and make sure the Editable received it.
46+
FakeKeyEvent keyEvent = new FakeKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
47+
inputConnectionAdaptor.sendKeyEvent(keyEvent);
48+
verify(spyEditable, times(1)).insert(eq(0), anyString());
49+
}
50+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.flutter.util;
2+
3+
import android.view.KeyEvent;
4+
5+
// In the test environment, keyEvent.getUnicodeChar throws an exception. This
6+
// class works around the exception by hardcoding the returned value.
7+
public class FakeKeyEvent extends KeyEvent {
8+
public FakeKeyEvent(int action, int keyCode) {
9+
super(action, keyCode);
10+
}
11+
12+
public final int getUnicodeChar() {
13+
return 1;
14+
}
15+
}

0 commit comments

Comments
 (0)