Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions shell/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,12 @@ action("robolectric_tests") {
"test/io/flutter/embedding/engine/systemchannels/PlatformChannelTest.java",
"test/io/flutter/external/FlutterLaunchTests.java",
"test/io/flutter/plugin/common/StandardMessageCodecTest.java",
"test/io/flutter/plugin/editing/InputConnectionAdaptorTest.java",
"test/io/flutter/plugin/editing/TextInputPluginTest.java",
"test/io/flutter/plugin/platform/PlatformPluginTest.java",
"test/io/flutter/plugin/platform/SingleViewPresentationTest.java",
"test/io/flutter/plugins/GeneratedPluginRegistrant.java",
"test/io/flutter/util/FakeKeyEvent.java",
"test/io/flutter/util/PreconditionsTest.java",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.provider.Settings;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputType;
import android.text.Layout;
import android.text.Selection;
import android.text.TextPaint;
Expand Down Expand Up @@ -274,8 +275,11 @@ public boolean sendKeyEvent(KeyEvent event) {
int newSel = Math.min(selStart + 1, mEditable.length());
setSelection(newSel, newSel);
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
|| event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER) {
// When the enter key is pressed on a non-multiline field, consider it a
// submit instead of a newline.
} else if ((event.getKeyCode() == KeyEvent.KEYCODE_ENTER
|| event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER)
&& (InputType.TYPE_TEXT_FLAG_MULTI_LINE & mEditorInfo.inputType) == 0) {
performEditorAction(mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION);
return true;
} else {
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/android/test/io/flutter/FlutterTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.flutter.embedding.engine.systemchannels.PlatformChannelTest;
import io.flutter.external.FlutterLaunchTests;
import io.flutter.plugin.common.StandardMessageCodecTest;
import io.flutter.plugin.editing.InputConnectionAdaptorTest;
import io.flutter.plugin.editing.TextInputPluginTest;
import io.flutter.plugin.platform.PlatformPluginTest;
import io.flutter.plugin.platform.SingleViewPresentationTest;
Expand Down Expand Up @@ -44,6 +45,7 @@
FlutterShellArgsTest.class,
FlutterRendererTest.class,
FlutterViewTest.class,
InputConnectionAdaptorTest.class,
PlatformChannelTest.class,
PlatformPluginTest.class,
PluginComponentTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.flutter.plugin.editing;

import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.content.res.AssetManager;
import android.text.Editable;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.util.FakeKeyEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

@Config(manifest = Config.NONE, sdk = 27)
@RunWith(RobolectricTestRunner.class)
public class InputConnectionAdaptorTest {
@Test
public void inputConnectionAdaptor_ReceivesEnter() throws NullPointerException {
View testView = new View(RuntimeEnvironment.application);
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
int inputTargetId = 0;
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
Editable mEditable = Editable.Factory.getInstance().newEditable("");
Editable spyEditable = spy(mEditable);
EditorInfo outAttrs = new EditorInfo();
outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;

InputConnectionAdaptor inputConnectionAdaptor =
new InputConnectionAdaptor(
testView, inputTargetId, textInputChannel, spyEditable, outAttrs);

// Send an enter key and make sure the Editable received it.
FakeKeyEvent keyEvent = new FakeKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER);
inputConnectionAdaptor.sendKeyEvent(keyEvent);
verify(spyEditable, times(1)).insert(eq(0), anyString());
}
}
15 changes: 15 additions & 0 deletions shell/platform/android/test/io/flutter/util/FakeKeyEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.flutter.util;

import android.view.KeyEvent;

// In the test environment, keyEvent.getUnicodeChar throws an exception. This
// class works around the exception by hardcoding the returned value.
public class FakeKeyEvent extends KeyEvent {
public FakeKeyEvent(int action, int keyCode) {
super(action, keyCode);
}

public final int getUnicodeChar() {
return 1;
}
}