mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Revert "Use dispatchKeyEventPreIme, and handle keys sent to InputConnection.sendKeyEvent on Android (#21163)" (flutter/engine#21513)
This reverts commit afeb9b27f0191997cc45682ab756c0be4d3e155c.
This commit is contained in:
parent
2bd5b1e59d
commit
f2669455f3
@ -66,8 +66,7 @@ public class AndroidKeyProcessor {
|
||||
@NonNull TextInputPlugin textInputPlugin) {
|
||||
this.keyEventChannel = keyEventChannel;
|
||||
this.textInputPlugin = textInputPlugin;
|
||||
textInputPlugin.setKeyEventProcessor(this);
|
||||
this.eventResponder = new EventResponder(view, textInputPlugin);
|
||||
this.eventResponder = new EventResponder(view);
|
||||
this.keyEventChannel.setEventResponseHandler(eventResponder);
|
||||
}
|
||||
|
||||
@ -81,20 +80,13 @@ public class AndroidKeyProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a key event is received by the {@link FlutterView} or the {@link
|
||||
* InputConnectionAdaptor}.
|
||||
* Called when a key up event is received by the {@link FlutterView}.
|
||||
*
|
||||
* @param keyEvent the Android key event to respond to.
|
||||
* @return true if the key event should not be propagated to other Android components. Delayed
|
||||
* synthesis events will return false, so that other components may handle them.
|
||||
*/
|
||||
public boolean onKeyEvent(@NonNull KeyEvent keyEvent) {
|
||||
int action = keyEvent.getAction();
|
||||
if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) {
|
||||
// There is theoretically a KeyEvent.ACTION_MULTIPLE, but that shouldn't
|
||||
// be sent anymore anyhow.
|
||||
return false;
|
||||
}
|
||||
public boolean onKeyUp(@NonNull KeyEvent keyEvent) {
|
||||
if (eventResponder.dispatchingKeyEvent) {
|
||||
// Don't handle it if it is from our own delayed event synthesis.
|
||||
return false;
|
||||
@ -103,11 +95,38 @@ public class AndroidKeyProcessor {
|
||||
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
|
||||
KeyEventChannel.FlutterKeyEvent flutterEvent =
|
||||
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter, eventIdSerial++);
|
||||
if (action == KeyEvent.ACTION_DOWN) {
|
||||
keyEventChannel.keyDown(flutterEvent);
|
||||
} else {
|
||||
keyEventChannel.keyUp(flutterEvent);
|
||||
keyEventChannel.keyUp(flutterEvent);
|
||||
eventResponder.addEvent(flutterEvent.eventId, keyEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a key down event is received by the {@link FlutterView}.
|
||||
*
|
||||
* @param keyEvent the Android key event to respond to.
|
||||
* @return true if the key event should not be propagated to other Android components. Delayed
|
||||
* synthesis events will return false, so that other components may handle them.
|
||||
*/
|
||||
public boolean onKeyDown(@NonNull KeyEvent keyEvent) {
|
||||
if (eventResponder.dispatchingKeyEvent) {
|
||||
// Don't handle it if it is from our own delayed event synthesis.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the textInputPlugin is still valid and accepting text, then we'll try
|
||||
// and send the key event to it, assuming that if the event can be sent,
|
||||
// that it has been handled.
|
||||
if (textInputPlugin.getLastInputConnection() != null
|
||||
&& textInputPlugin.getInputMethodManager().isAcceptingText()) {
|
||||
if (textInputPlugin.getLastInputConnection().sendKeyEvent(keyEvent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
|
||||
KeyEventChannel.FlutterKeyEvent flutterEvent =
|
||||
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter, eventIdSerial++);
|
||||
keyEventChannel.keyDown(flutterEvent);
|
||||
eventResponder.addEvent(flutterEvent.eventId, keyEvent);
|
||||
return true;
|
||||
}
|
||||
@ -177,12 +196,10 @@ public class AndroidKeyProcessor {
|
||||
private static final long MAX_PENDING_EVENTS = 1000;
|
||||
final Deque<Entry<Long, KeyEvent>> pendingEvents = new ArrayDeque<Entry<Long, KeyEvent>>();
|
||||
@NonNull private final View view;
|
||||
@NonNull private final TextInputPlugin textInputPlugin;
|
||||
boolean dispatchingKeyEvent = false;
|
||||
|
||||
public EventResponder(@NonNull View view, @NonNull TextInputPlugin textInputPlugin) {
|
||||
public EventResponder(@NonNull View view) {
|
||||
this.view = view;
|
||||
this.textInputPlugin = textInputPlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,26 +267,12 @@ public class AndroidKeyProcessor {
|
||||
* @param event the event to be dispatched to the activity.
|
||||
*/
|
||||
public void dispatchKeyEvent(KeyEvent event) {
|
||||
// If the textInputPlugin is still valid and accepting text, then we'll try
|
||||
// and send the key event to it, assuming that if the event can be sent,
|
||||
// that it has been handled.
|
||||
if (textInputPlugin.getLastInputConnection() != null
|
||||
&& textInputPlugin.getInputMethodManager().isAcceptingText()) {
|
||||
dispatchingKeyEvent = true;
|
||||
boolean handled = textInputPlugin.getLastInputConnection().sendKeyEvent(event);
|
||||
dispatchingKeyEvent = false;
|
||||
if (handled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Since the framework didn't handle it, dispatch the key again.
|
||||
if (view != null) {
|
||||
// Turn on dispatchingKeyEvent so that we don't dispatch to ourselves and
|
||||
// send it to the framework again.
|
||||
dispatchingKeyEvent = true;
|
||||
|
||||
view.getRootView().dispatchKeyEventPreIme(event);
|
||||
view.getRootView().dispatchKeyEvent(event);
|
||||
dispatchingKeyEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -721,7 +721,27 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a hardware key is pressed or released, before the IME receives the key.
|
||||
* Invoked when key is released.
|
||||
*
|
||||
* <p>This method is typically invoked in response to the release of a physical keyboard key or a
|
||||
* D-pad button. It is generally not invoked when a virtual software keyboard is used, though a
|
||||
* software keyboard may choose to invoke this method in some situations.
|
||||
*
|
||||
* <p>{@link KeyEvent}s are sent from Android to Flutter. {@link AndroidKeyProcessor} may do some
|
||||
* additional work with the given {@link KeyEvent}, e.g., combine this {@code keyCode} with the
|
||||
* previous {@code keyCode} to generate a unicode combined character.
|
||||
*/
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
|
||||
if (!isAttachedToFlutterEngine()) {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
return androidKeyProcessor.onKeyUp(event) || super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when key is pressed.
|
||||
*
|
||||
* <p>This method is typically invoked in response to the press of a physical keyboard key or a
|
||||
* D-pad button. It is generally not invoked when a virtual software keyboard is used, though a
|
||||
@ -732,13 +752,12 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
|
||||
* previous {@code keyCode} to generate a unicode combined character.
|
||||
*/
|
||||
@Override
|
||||
public boolean dispatchKeyEventPreIme(KeyEvent event) {
|
||||
// If the key processor doesn't handle it, then send it on to the
|
||||
// superclass. The key processor will typically handle all events except
|
||||
// those where it has re-dispatched the event after receiving a reply from
|
||||
// the framework that the framework did not handle it.
|
||||
return (isAttachedToFlutterEngine() && androidKeyProcessor.onKeyEvent(event))
|
||||
|| super.dispatchKeyEventPreIme(event);
|
||||
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
|
||||
if (!isAttachedToFlutterEngine()) {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
return androidKeyProcessor.onKeyDown(event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -27,7 +27,6 @@ import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
import io.flutter.Log;
|
||||
import io.flutter.embedding.android.AndroidKeyProcessor;
|
||||
import io.flutter.embedding.engine.FlutterJNI;
|
||||
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
|
||||
|
||||
@ -35,7 +34,6 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
private final View mFlutterView;
|
||||
private final int mClient;
|
||||
private final TextInputChannel textInputChannel;
|
||||
private final AndroidKeyProcessor keyProcessor;
|
||||
private final Editable mEditable;
|
||||
private final EditorInfo mEditorInfo;
|
||||
private int mBatchCount;
|
||||
@ -99,7 +97,6 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
View view,
|
||||
int client,
|
||||
TextInputChannel textInputChannel,
|
||||
AndroidKeyProcessor keyProcessor,
|
||||
Editable editable,
|
||||
EditorInfo editorInfo,
|
||||
FlutterJNI flutterJNI) {
|
||||
@ -110,7 +107,6 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
mEditable = editable;
|
||||
mEditorInfo = editorInfo;
|
||||
mBatchCount = 0;
|
||||
this.keyProcessor = keyProcessor;
|
||||
this.flutterTextUtils = new FlutterTextUtils(flutterJNI);
|
||||
// We create a dummy Layout with max width so that the selection
|
||||
// shifting acts as if all text were in one line.
|
||||
@ -132,10 +128,9 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
View view,
|
||||
int client,
|
||||
TextInputChannel textInputChannel,
|
||||
AndroidKeyProcessor keyProcessor,
|
||||
Editable editable,
|
||||
EditorInfo editorInfo) {
|
||||
this(view, client, textInputChannel, keyProcessor, editable, editorInfo, new FlutterJNI());
|
||||
this(view, client, textInputChannel, editable, editorInfo, new FlutterJNI());
|
||||
}
|
||||
|
||||
// Send the current state of the editable to Flutter.
|
||||
@ -328,14 +323,6 @@ class InputConnectionAdaptor extends BaseInputConnection {
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
// 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
|
||||
// returning false so that it can be processed here.
|
||||
if (keyProcessor != null && keyProcessor.onKeyEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
markDirty();
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
|
||||
|
||||
@ -33,7 +33,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import io.flutter.embedding.android.AndroidKeyProcessor;
|
||||
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
|
||||
import io.flutter.plugin.platform.PlatformViewsController;
|
||||
import java.util.HashMap;
|
||||
@ -55,7 +54,6 @@ public class TextInputPlugin {
|
||||
@Nullable private Rect lastClientRect;
|
||||
private final boolean restartAlwaysRequired;
|
||||
private ImeSyncDeferringInsetsCallback imeSyncCallback;
|
||||
private AndroidKeyProcessor keyProcessor;
|
||||
|
||||
// When true following calls to createInputConnection will return the cached lastInputConnection
|
||||
// if the input
|
||||
@ -329,15 +327,6 @@ public class TextInputPlugin {
|
||||
return imeSyncCallback;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public AndroidKeyProcessor getKeyEventProcessor() {
|
||||
return keyProcessor;
|
||||
}
|
||||
|
||||
public void setKeyEventProcessor(AndroidKeyProcessor processor) {
|
||||
keyProcessor = processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the current platform view input connection until unlockPlatformViewInputConnection is
|
||||
* called.
|
||||
@ -480,8 +469,7 @@ public class TextInputPlugin {
|
||||
outAttrs.imeOptions |= enterAction;
|
||||
|
||||
InputConnectionAdaptor connection =
|
||||
new InputConnectionAdaptor(
|
||||
view, inputTarget.id, textInputChannel, keyProcessor, mEditable, outAttrs);
|
||||
new InputConnectionAdaptor(view, inputTarget.id, textInputChannel, mEditable, outAttrs);
|
||||
outAttrs.initialSelStart = Selection.getSelectionStart(mEditable);
|
||||
outAttrs.initialSelEnd = Selection.getSelectionEnd(mEditable);
|
||||
|
||||
|
||||
@ -268,9 +268,19 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEventPreIme(KeyEvent event) {
|
||||
return (isAttached() && androidKeyProcessor.onKeyEvent(event))
|
||||
|| super.dispatchKeyEventPreIme(event);
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (!isAttached()) {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
return androidKeyProcessor.onKeyUp(event) || super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (!isAttached()) {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
return androidKeyProcessor.onKeyDown(event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
public FlutterNativeView getFlutterNativeView() {
|
||||
|
||||
@ -51,11 +51,11 @@ public class AndroidKeyProcessorTest {
|
||||
AndroidKeyProcessor processor =
|
||||
new AndroidKeyProcessor(fakeView, fakeKeyEventChannel, mock(TextInputPlugin.class));
|
||||
|
||||
boolean result = processor.onKeyEvent(new FakeKeyEvent(KeyEvent.ACTION_DOWN, 65));
|
||||
boolean result = processor.onKeyDown(new FakeKeyEvent(KeyEvent.ACTION_DOWN, 65));
|
||||
assertEquals(true, result);
|
||||
verify(fakeKeyEventChannel, times(1)).keyDown(any(KeyEventChannel.FlutterKeyEvent.class));
|
||||
verify(fakeKeyEventChannel, times(0)).keyUp(any(KeyEventChannel.FlutterKeyEvent.class));
|
||||
verify(fakeView, times(0)).dispatchKeyEventPreIme(any(KeyEvent.class));
|
||||
verify(fakeView, times(0)).dispatchKeyEvent(any(KeyEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -97,31 +97,31 @@ public class AndroidKeyProcessorTest {
|
||||
ArgumentCaptor.forClass(KeyEventChannel.FlutterKeyEvent.class);
|
||||
FakeKeyEvent fakeKeyEvent = new FakeKeyEvent(KeyEvent.ACTION_DOWN, 65);
|
||||
|
||||
boolean result = processor.onKeyEvent(fakeKeyEvent);
|
||||
boolean result = processor.onKeyDown(fakeKeyEvent);
|
||||
assertEquals(true, result);
|
||||
|
||||
// Capture the FlutterKeyEvent so we can find out its event ID to use when
|
||||
// faking our response.
|
||||
verify(fakeKeyEventChannel, times(1)).keyDown(eventCaptor.capture());
|
||||
boolean[] dispatchResult = {true};
|
||||
when(fakeView.dispatchKeyEventPreIme(any(KeyEvent.class)))
|
||||
when(fakeView.dispatchKeyEvent(any(KeyEvent.class)))
|
||||
.then(
|
||||
new Answer<Boolean>() {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation) throws Throwable {
|
||||
KeyEvent event = (KeyEvent) invocation.getArguments()[0];
|
||||
assertEquals(fakeKeyEvent, event);
|
||||
dispatchResult[0] = processor.onKeyEvent(event);
|
||||
dispatchResult[0] = processor.onKeyDown(event);
|
||||
return dispatchResult[0];
|
||||
}
|
||||
});
|
||||
|
||||
// Fake a response from the framework.
|
||||
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().eventId);
|
||||
verify(fakeView, times(1)).dispatchKeyEventPreIme(fakeKeyEvent);
|
||||
verify(fakeView, times(1)).dispatchKeyEvent(fakeKeyEvent);
|
||||
assertEquals(false, dispatchResult[0]);
|
||||
verify(fakeKeyEventChannel, times(0)).keyUp(any(KeyEventChannel.FlutterKeyEvent.class));
|
||||
verify(fakeRootView, times(1)).dispatchKeyEventPreIme(fakeKeyEvent);
|
||||
verify(fakeRootView, times(1)).dispatchKeyEvent(fakeKeyEvent);
|
||||
}
|
||||
|
||||
public void synthesizesEventsWhenKeyUpNotHandled() {
|
||||
@ -147,31 +147,31 @@ public class AndroidKeyProcessorTest {
|
||||
ArgumentCaptor.forClass(KeyEventChannel.FlutterKeyEvent.class);
|
||||
FakeKeyEvent fakeKeyEvent = new FakeKeyEvent(KeyEvent.ACTION_UP, 65);
|
||||
|
||||
boolean result = processor.onKeyEvent(fakeKeyEvent);
|
||||
boolean result = processor.onKeyUp(fakeKeyEvent);
|
||||
assertEquals(true, result);
|
||||
|
||||
// Capture the FlutterKeyEvent so we can find out its event ID to use when
|
||||
// faking our response.
|
||||
verify(fakeKeyEventChannel, times(1)).keyUp(eventCaptor.capture());
|
||||
boolean[] dispatchResult = {true};
|
||||
when(fakeView.dispatchKeyEventPreIme(any(KeyEvent.class)))
|
||||
when(fakeView.dispatchKeyEvent(any(KeyEvent.class)))
|
||||
.then(
|
||||
new Answer<Boolean>() {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation) throws Throwable {
|
||||
KeyEvent event = (KeyEvent) invocation.getArguments()[0];
|
||||
assertEquals(fakeKeyEvent, event);
|
||||
dispatchResult[0] = processor.onKeyEvent(event);
|
||||
dispatchResult[0] = processor.onKeyUp(event);
|
||||
return dispatchResult[0];
|
||||
}
|
||||
});
|
||||
|
||||
// Fake a response from the framework.
|
||||
handlerCaptor.getValue().onKeyEventNotHandled(eventCaptor.getValue().eventId);
|
||||
verify(fakeView, times(1)).dispatchKeyEventPreIme(fakeKeyEvent);
|
||||
verify(fakeView, times(1)).dispatchKeyEvent(fakeKeyEvent);
|
||||
assertEquals(false, dispatchResult[0]);
|
||||
verify(fakeKeyEventChannel, times(0)).keyUp(any(KeyEventChannel.FlutterKeyEvent.class));
|
||||
verify(fakeRootView, times(1)).dispatchKeyEventPreIme(fakeKeyEvent);
|
||||
verify(fakeRootView, times(1)).dispatchKeyEvent(fakeKeyEvent);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
||||
@ -25,7 +25,6 @@ import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import io.flutter.embedding.android.AndroidKeyProcessor;
|
||||
import io.flutter.embedding.engine.FlutterJNI;
|
||||
import io.flutter.embedding.engine.dart.DartExecutor;
|
||||
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
|
||||
@ -69,7 +68,6 @@ public class InputConnectionAdaptorTest {
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
|
||||
int inputTargetId = 0;
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable mEditable = Editable.Factory.getInstance().newEditable("");
|
||||
Editable spyEditable = spy(mEditable);
|
||||
EditorInfo outAttrs = new EditorInfo();
|
||||
@ -77,7 +75,7 @@ public class InputConnectionAdaptorTest {
|
||||
|
||||
InputConnectionAdaptor inputConnectionAdaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, inputTargetId, textInputChannel, mockKeyProcessor, spyEditable, outAttrs);
|
||||
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);
|
||||
@ -158,11 +156,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
adaptor.performPrivateCommand("actionCommand", null);
|
||||
|
||||
ArgumentCaptor<String> channelCaptor = ArgumentCaptor.forClass(String.class);
|
||||
@ -186,11 +183,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
byte[] buffer = new byte[] {'a', 'b', 'c', 'd'};
|
||||
@ -220,11 +216,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
byte b = 3;
|
||||
@ -252,11 +247,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
char[] buffer = new char[] {'a', 'b', 'c', 'd'};
|
||||
@ -287,11 +281,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
char b = 'a';
|
||||
@ -319,11 +312,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
CharSequence charSequence1 = new StringBuffer("abc");
|
||||
@ -355,11 +347,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
CharSequence charSequence = new StringBuffer("abc");
|
||||
@ -389,11 +380,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
float value = 0.5f;
|
||||
@ -421,11 +411,10 @@ public class InputConnectionAdaptorTest {
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJNI, mock(AssetManager.class)));
|
||||
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable editable = sampleEditable(0, 0);
|
||||
InputConnectionAdaptor adaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
float[] value = {0.5f, 0.6f};
|
||||
@ -918,7 +907,6 @@ public class InputConnectionAdaptorTest {
|
||||
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
|
||||
int inputTargetId = 0;
|
||||
TestTextInputChannel textInputChannel = new TestTextInputChannel(dartExecutor);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
Editable mEditable = Editable.Factory.getInstance().newEditable("");
|
||||
Editable spyEditable = spy(mEditable);
|
||||
EditorInfo outAttrs = new EditorInfo();
|
||||
@ -926,7 +914,7 @@ public class InputConnectionAdaptorTest {
|
||||
|
||||
InputConnectionAdaptor inputConnectionAdaptor =
|
||||
new InputConnectionAdaptor(
|
||||
testView, inputTargetId, textInputChannel, mockKeyProcessor, spyEditable, outAttrs);
|
||||
testView, inputTargetId, textInputChannel, spyEditable, outAttrs);
|
||||
|
||||
inputConnectionAdaptor.beginBatchEdit();
|
||||
assertEquals(textInputChannel.updateEditingStateInvocations, 0);
|
||||
@ -1171,7 +1159,6 @@ public class InputConnectionAdaptorTest {
|
||||
int client = 0;
|
||||
TextInputChannel textInputChannel = mock(TextInputChannel.class);
|
||||
FlutterJNI mockFlutterJNI = mock(FlutterJNI.class);
|
||||
AndroidKeyProcessor mockKeyProcessor = mock(AndroidKeyProcessor.class);
|
||||
when(mockFlutterJNI.nativeFlutterTextUtilsIsEmoji(anyInt()))
|
||||
.thenAnswer((invocation) -> Emoji.isEmoji((int) invocation.getArguments()[0]));
|
||||
when(mockFlutterJNI.nativeFlutterTextUtilsIsEmojiModifier(anyInt()))
|
||||
@ -1188,7 +1175,7 @@ public class InputConnectionAdaptorTest {
|
||||
.thenAnswer(
|
||||
(invocation) -> Emoji.isRegionalIndicatorSymbol((int) invocation.getArguments()[0]));
|
||||
return new InputConnectionAdaptor(
|
||||
testView, client, textInputChannel, mockKeyProcessor, editable, null, mockFlutterJNI);
|
||||
testView, client, textInputChannel, editable, null, mockFlutterJNI);
|
||||
}
|
||||
|
||||
private class TestTextInputChannel extends TextInputChannel {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user