1package io.flutter.plugin.editing;
3import static io.flutter.Build.API_LEVELS;
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertNotNull;
6import static org.junit.Assert.assertThrows;
7import static org.junit.Assert.assertTrue;
8import static org.mockito.AdditionalMatchers.aryEq;
9import static org.mockito.AdditionalMatchers.gt;
10import static org.mockito.ArgumentMatchers.anyInt;
11import static org.mockito.Mockito.any;
12import static org.mockito.Mockito.atLeast;
13import static org.mockito.Mockito.eq;
14import static org.mockito.Mockito.isNotNull;
15import static org.mockito.Mockito.isNull;
16import static org.mockito.Mockito.mock;
17import static org.mockito.Mockito.never;
18import static org.mockito.Mockito.spy;
19import static org.mockito.Mockito.times;
20import static org.mockito.Mockito.verify;
21import static org.mockito.Mockito.when;
23import android.annotation.TargetApi;
26import android.content.res.AssetManager;
31import android.provider.Settings;
35import android.util.SparseIntArray;
38import android.view.ViewStructure;
39import android.view.WindowInsets;
40import android.view.WindowInsetsAnimation;
41import android.view.autofill.AutofillManager;
42import android.view.autofill.AutofillValue;
43import android.view.inputmethod.CursorAnchorInfo;
44import android.view.inputmethod.EditorInfo;
45import android.view.inputmethod.InputConnection;
46import android.view.inputmethod.InputMethodManager;
47import android.view.inputmethod.InputMethodSubtype;
48import androidx.test.core.app.ApplicationProvider;
49import androidx.test.ext.junit.runners.AndroidJUnit4;
50import io.flutter.embedding.android.FlutterView;
51import io.flutter.embedding.android.KeyboardManager;
52import io.flutter.embedding.engine.FlutterEngine;
53import io.flutter.embedding.engine.FlutterJNI;
54import io.flutter.embedding.engine.dart.DartExecutor;
55import io.flutter.embedding.engine.loader.FlutterLoader;
56import io.flutter.embedding.engine.renderer.FlutterRenderer;
57import io.flutter.embedding.engine.systemchannels.TextInputChannel;
58import io.flutter.embedding.engine.systemchannels.TextInputChannel.TextEditState;
59import io.flutter.plugin.common.BinaryMessenger;
60import io.flutter.plugin.common.JSONMethodCodec;
61import io.flutter.plugin.common.MethodCall;
62import io.flutter.plugin.platform.PlatformViewsController;
63import java.nio.ByteBuffer;
64import java.util.ArrayList;
65import java.util.HashMap;
67import org.json.JSONArray;
68import org.json.JSONException;
69import org.json.JSONObject;
70import org.junit.Before;
72import org.junit.runner.RunWith;
73import org.mockito.ArgumentCaptor;
74import org.mockito.Mock;
75import org.mockito.MockitoAnnotations;
76import org.robolectric.Robolectric;
77import org.robolectric.annotation.Config;
78import org.robolectric.annotation.Implementation;
79import org.robolectric.annotation.Implements;
80import org.robolectric.shadow.api.Shadow;
81import org.robolectric.shadows.ShadowAutofillManager;
82import org.robolectric.shadows.ShadowBuild;
83import org.robolectric.shadows.ShadowInputMethodManager;
87 shadows = {TextInputPluginTest.TestImm.class, TextInputPluginTest.TestAfm.class})
88@RunWith(AndroidJUnit4.class)
90 private final Context ctx = ApplicationProvider.getApplicationContext();
96 MockitoAnnotations.openMocks(
this);
97 when(mockFlutterJni.isAttached()).thenReturn(
true);
101 private void verifyMethodCall(ByteBuffer
buffer, String methodName, String[] expectedArgs)
102 throws JSONException {
105 assertEquals(methodName, methodCall.
method);
106 if (expectedArgs !=
null) {
108 assertEquals(expectedArgs.length,
args.length());
109 for (
int i = 0;
i <
args.length();
i++) {
110 assertEquals(expectedArgs[
i],
args.get(
i).toString());
115 private static void sendToBinaryMessageHandler(
116 BinaryMessenger.BinaryMessageHandler binaryMessageHandler, String method, Object
args) {
118 ByteBuffer encodedMethodCall = JSONMethodCodec.INSTANCE.encodeMethodCall(methodCall);
119 binaryMessageHandler.onMessage(
120 (ByteBuffer) encodedMethodCall.flip(), mock(BinaryMessenger.BinaryReply.class));
123 @SuppressWarnings(
"deprecation")
128 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
129 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
131 View testView =
new View(ctx);
139 ArgumentCaptor<String> channelCaptor = ArgumentCaptor.forClass(String.class);
140 ArgumentCaptor<ByteBuffer> bufferCaptor = ArgumentCaptor.forClass(ByteBuffer.class);
142 verify(dartExecutor,
times(1)).send(channelCaptor.capture(), bufferCaptor.capture(), isNull());
143 assertEquals(
"flutter/textinput", channelCaptor.getValue());
144 verifyMethodCall(bufferCaptor.getValue(),
"TextInputClient.requestExistingInputState",
null);
150 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
151 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
153 View testView =
new View(ctx);
175 assertTrue(
textInputPlugin.getEditable().toString().equals(
"initial input from framework"));
177 verify(textInputChannel,
times(0))
178 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
184 assertTrue(
textInputPlugin.getEditable().toString().equals(
"more update from the framework"));
185 verify(textInputChannel,
times(0))
186 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
192 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
193 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
195 View testView =
new View(ctx);
203 assertTrue(
textInputPlugin.getEditable().toString().equals(
"initial input from framework"));
209 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
210 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
212 View testView =
new View(ctx);
236 textInputPlugin.getEditable().toString().equals(
"receiving initial input from framework"));
238 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
243 "receiving more updates from the framework", 1, 2, -1, -1));
249 .
equals(
"receiving more updates from the framework"));
250 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
255 throws NullPointerException {
257 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
258 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
260 View testView =
new View(ctx);
261 EditorInfo outAttrs =
new EditorInfo();
262 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
266 CharSequence newText =
"I do not fear computers. I fear the lack of them.";
288 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
289 verify(textInputChannel,
times(0))
290 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
294 .extractBatchTextEditingDeltas()
297 InputConnection inputConnection =
300 inputConnection.beginBatchEdit();
301 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
302 verify(textInputChannel,
times(0))
303 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
304 inputConnection.setComposingText(newText, newText.length());
305 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
306 verify(textInputChannel,
times(0))
307 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
308 inputConnection.endBatchEdit();
313 .extractBatchTextEditingDeltas()
316 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
317 verify(textInputChannel,
times(1))
318 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
320 inputConnection.beginBatchEdit();
322 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
323 verify(textInputChannel,
times(1))
324 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
326 inputConnection.endBatchEdit();
331 .extractBatchTextEditingDeltas()
334 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
335 verify(textInputChannel,
times(1))
336 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
338 inputConnection.beginBatchEdit();
340 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
341 verify(textInputChannel,
times(1))
342 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
347 inputConnection.setSelection(3, 4);
348 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
349 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
351 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
352 verify(textInputChannel,
times(1))
353 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
355 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
356 verify(textInputChannel,
times(1))
357 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
359 inputConnection.endBatchEdit();
361 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
362 verify(textInputChannel,
times(2))
363 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
368 throws NullPointerException {
370 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
371 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
373 View testView =
new View(ctx);
374 EditorInfo outAttrs =
new EditorInfo();
375 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
379 CharSequence newText =
"I do not fear computers. I fear the lack of them.";
381 new TextEditingDelta(
"", 0, 0, newText, newText.length(), newText.length(), 0, 49);
403 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
404 verify(textInputChannel,
times(0))
405 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
409 .extractBatchTextEditingDeltas()
412 InputConnection inputConnection =
415 inputConnection.beginBatchEdit();
416 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
417 verify(textInputChannel,
times(0))
418 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
419 inputConnection.setComposingText(newText, newText.length());
420 final ArrayList<TextEditingDelta> actualDeltas =
422 assertEquals(2, actualDeltas.size());
424 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
425 verify(textInputChannel,
times(0))
426 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
427 inputConnection.endBatchEdit();
432 .extractBatchTextEditingDeltas()
445 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
446 verify(textInputChannel,
times(0))
447 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
449 inputConnection.beginBatchEdit();
451 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
452 verify(textInputChannel,
times(0))
453 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
455 inputConnection.endBatchEdit();
460 .extractBatchTextEditingDeltas()
463 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
464 verify(textInputChannel,
times(0))
465 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
467 inputConnection.beginBatchEdit();
469 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
470 verify(textInputChannel,
times(0))
471 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
476 inputConnection.setSelection(3, 4);
477 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
478 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
480 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
481 verify(textInputChannel,
times(0))
482 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
484 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
485 verify(textInputChannel,
times(0))
486 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
488 inputConnection.endBatchEdit();
490 verify(textInputChannel,
times(2)).updateEditingStateWithDeltas(anyInt(),
any());
491 verify(textInputChannel,
times(0))
492 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
497 throws NullPointerException {
499 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
500 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
502 View testView =
new View(ctx);
503 EditorInfo outAttrs =
new EditorInfo();
504 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
508 CharSequence newText =
"I do not fear computers. I fear the lack of them.";
510 new TextEditingDelta(
"", 0, 0, newText, newText.length(), newText.length(), 0, 49);
532 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
536 .extractBatchTextEditingDeltas()
539 InputConnection inputConnection =
542 inputConnection.beginBatchEdit();
543 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
544 inputConnection.setComposingText(newText, newText.length());
545 final ArrayList<TextEditingDelta> actualDeltas =
547 assertEquals(2, actualDeltas.size());
549 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
550 inputConnection.endBatchEdit();
555 .extractBatchTextEditingDeltas()
568 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
570 inputConnection.beginBatchEdit();
572 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
574 inputConnection.endBatchEdit();
579 .extractBatchTextEditingDeltas()
582 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
584 inputConnection.beginBatchEdit();
586 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
591 inputConnection.setSelection(3, 4);
592 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
593 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
595 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
597 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
599 inputConnection.endBatchEdit();
601 verify(textInputChannel,
times(2)).updateEditingStateWithDeltas(anyInt(),
any());
606 throws NullPointerException {
608 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
609 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
611 View testView =
new View(ctx);
612 EditorInfo outAttrs =
new EditorInfo();
613 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
617 CharSequence newText =
"I do not fear computers. I fear the lack of them.";
620 newText, 0, 49,
"I do not fear computers. I fear the lack of them", 48, 48, 0, 48);
642 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
646 .extractBatchTextEditingDeltas()
649 InputConnection inputConnection =
652 inputConnection.beginBatchEdit();
653 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
654 inputConnection.setComposingText(
"I do not fear computers. I fear the lack of them", 48);
655 final ArrayList<TextEditingDelta> actualDeltas =
658 System.out.println(
delta.getDeltaText());
659 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
660 inputConnection.endBatchEdit();
665 .extractBatchTextEditingDeltas()
678 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
680 inputConnection.beginBatchEdit();
682 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
684 inputConnection.endBatchEdit();
689 .extractBatchTextEditingDeltas()
692 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
694 inputConnection.beginBatchEdit();
696 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
701 inputConnection.setSelection(3, 4);
702 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
703 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
705 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
707 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
709 inputConnection.endBatchEdit();
711 verify(textInputChannel,
times(2)).updateEditingStateWithDeltas(anyInt(),
any());
716 throws NullPointerException {
718 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
719 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
721 View testView =
new View(ctx);
722 EditorInfo outAttrs =
new EditorInfo();
723 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
727 CharSequence newText =
"helfo";
750 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
754 .extractBatchTextEditingDeltas()
757 InputConnection inputConnection =
760 inputConnection.beginBatchEdit();
761 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
762 inputConnection.setComposingText(
"hello", 5);
763 final ArrayList<TextEditingDelta> actualDeltas =
766 System.out.println(
delta.getDeltaText());
767 verify(textInputChannel,
times(0)).updateEditingStateWithDeltas(anyInt(),
any());
768 inputConnection.endBatchEdit();
773 .extractBatchTextEditingDeltas()
786 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
788 inputConnection.beginBatchEdit();
790 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
792 inputConnection.endBatchEdit();
797 .extractBatchTextEditingDeltas()
800 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
802 inputConnection.beginBatchEdit();
804 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
809 inputConnection.setSelection(3, 4);
810 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
811 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
813 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
815 verify(textInputChannel,
times(1)).updateEditingStateWithDeltas(anyInt(),
any());
817 inputConnection.endBatchEdit();
819 verify(textInputChannel,
times(2)).updateEditingStateWithDeltas(anyInt(),
any());
825 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
826 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
828 View testView =
new View(ctx);
829 EditorInfo outAttrs =
new EditorInfo();
830 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE;
855 verify(textInputChannel,
times(0))
856 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
863 verify(textInputChannel,
times(0))
864 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
865 inputConnectionAdaptor.
setComposingText(
"I do not fear computers. I fear the lack of them.", 1);
866 verify(textInputChannel,
times(0))
867 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
869 verify(textInputChannel,
times(1))
872 eq(
"I do not fear computers. I fear the lack of them."),
880 verify(textInputChannel,
times(1))
881 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
885 verify(textInputChannel,
times(1))
886 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
890 verify(textInputChannel,
times(1))
891 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
894 assertEquals(Selection.getSelectionStart(
textInputPlugin.getEditable()), 3);
895 assertEquals(Selection.getSelectionEnd(
textInputPlugin.getEditable()), 4);
897 verify(textInputChannel,
times(1))
898 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
900 verify(textInputChannel,
times(1))
901 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
905 verify(textInputChannel,
times(1))
908 eq(
"I do not fear computers. I fear the lack of them."),
918 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
919 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
921 View testView =
new View(ctx);
956 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
957 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
959 View testView =
new View(ctx);
990 assertTrue(
textInputPlugin.getEditable().toString().equals(
"Shibuyawoo"));
999 @SuppressWarnings(
"deprecation")
1003 InputMethodSubtype inputMethodSubtype =
1004 new InputMethodSubtype(0, 0,
"en",
"",
"",
false,
false);
1005 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1007 View testView =
new View(ctx);
1030 InputConnection connection =
1033 connection.setComposingText(
"POWERRRRR", 1);
1040 connection.finishComposingText();
1045 connection.setComposingText(
"POWERRRRR", 1);
1059 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", 0, -9, -1, -1));
1060 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", -9, 0, -1, -1));
1061 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", 0, 1, -1, -1));
1062 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", 1, 0, -1, -1));
1063 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, 1, 5));
1064 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, 5, 1));
1065 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, 5, 5));
1068 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", -1, -2, -1, -1));
1069 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", -2, -1, -1, -1));
1070 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"", -9, -9, -1, -1));
1073 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, -9, -1));
1074 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, -1, -9));
1075 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, -9, -9));
1076 assertThrows(IndexOutOfBoundsException.class, () ->
new TextEditState(
"Text", 0, 0, 2, 1));
1081 assertEquals(
"",
state.text);
1082 assertEquals(-1,
state.selectionStart);
1083 assertEquals(-1,
state.selectionEnd);
1084 assertEquals(-1,
state.composingStart);
1085 assertEquals(-1,
state.composingEnd);
1088 assertEquals(0,
state.selectionStart);
1089 assertEquals(0,
state.selectionEnd);
1092 assertEquals(4,
state.selectionStart);
1093 assertEquals(2,
state.selectionEnd);
1096 assertEquals(
"text",
state.text);
1097 assertEquals(0,
state.selectionStart);
1098 assertEquals(0,
state.selectionEnd);
1099 assertEquals(0,
state.composingStart);
1100 assertEquals(0,
state.composingEnd);
1105 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1108 View testView =
new View(ctx);
1136 InputMethodSubtype inputMethodSubtype = mock(InputMethodSubtype.class);
1137 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1139 View testView =
new View(ctx);
1170 View testView =
new View(ctx);
1174 verify(textInputChannel,
times(1)).setTextInputMethodHandler(isNotNull());
1176 verify(textInputChannel,
times(1)).setTextInputMethodHandler(isNull());
1179 @SuppressWarnings(
"deprecation")
1181 private
void verifyInputConnection(
TextInputChannel.TextInputType textInputType)
1182 throws JSONException {
1183 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1185 View testView =
new View(ctx);
1209 ArgumentCaptor<String> channelCaptor = ArgumentCaptor.forClass(String.class);
1210 ArgumentCaptor<ByteBuffer> bufferCaptor = ArgumentCaptor.forClass(ByteBuffer.class);
1211 verify(dartExecutor,
times(1)).send(channelCaptor.capture(), bufferCaptor.capture(), isNull());
1212 assertEquals(
"flutter/textinput", channelCaptor.getValue());
1213 verifyMethodCall(bufferCaptor.getValue(),
"TextInputClient.requestExistingInputState",
null);
1219 connection.
handleKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
1220 verify(dartExecutor,
times(2)).send(channelCaptor.capture(), bufferCaptor.capture(), isNull());
1221 assertEquals(
"flutter/textinput", channelCaptor.getValue());
1223 bufferCaptor.getValue(),
1224 "TextInputClient.performAction",
1225 new String[] {
"0",
"TextInputAction.done"});
1226 connection.
handleKeyEvent(
new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER));
1228 connection.
handleKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_NUMPAD_ENTER));
1229 verify(dartExecutor,
times(3)).send(channelCaptor.capture(), bufferCaptor.capture(), isNull());
1230 assertEquals(
"flutter/textinput", channelCaptor.getValue());
1232 bufferCaptor.getValue(),
1233 "TextInputClient.performAction",
1234 new String[] {
"0",
"TextInputAction.done"});
1247 @SuppressWarnings(
"deprecation")
1250 ShadowBuild.setManufacturer(
"samsung");
1251 InputMethodSubtype inputMethodSubtype =
1252 new InputMethodSubtype(0, 0,
"en",
"",
"",
false,
false);
1253 Settings.Secure.putString(
1254 ctx.getContentResolver(),
1255 Settings.Secure.DEFAULT_INPUT_METHOD,
1256 "com.sec.android.inputmethod/.SamsungKeypad");
1257 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1260 View testView =
new View(ctx);
1283 InputConnection connection =
1287 connection.requestCursorUpdates(
1288 InputConnection.CURSOR_UPDATE_MONITOR | InputConnection.CURSOR_UPDATE_IMMEDIATE);
1290 connection.finishComposingText();
1298 View testView =
new View(ctx);
1319 InputConnection connection =
1322 assertNotNull(connection);
1327 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
1328 View testView =
new View(ctx);
1350 assertEquals(testImm.isSoftInputVisible(),
false);
1356 View testView =
new View(ctx);
1377 EditorInfo editorInfo =
new EditorInfo();
1378 InputConnection connection =
1382 editorInfo.inputType,
1383 InputType.TYPE_CLASS_TEXT
1384 | InputType.TYPE_TEXT_FLAG_MULTI_LINE
1385 | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
1386 | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
1399 final TextInputChannel.Configuration.Autofill autofill =
1403 final TextInputChannel.Configuration config =
1434 final ViewStructure viewStructure = mock(ViewStructure.class);
1435 final ViewStructure[] children = {mock(ViewStructure.class), mock(ViewStructure.class)};
1437 when(viewStructure.newChild(anyInt()))
1438 .thenAnswer(invocation -> children[(
int) invocation.getArgument(0)]);
1442 verify(viewStructure).newChild(0);
1444 verify(children[0]).setAutofillId(
any(),
eq(
"1".hashCode()));
1446 verify(children[0], never()).setAutofillHints(aryEq(
new String[] {}));
1447 verify(children[0]).setDimens(anyInt(), anyInt(), anyInt(), anyInt(), gt(0), gt(0));
1459 final TextInputChannel.Configuration.Autofill autofill =
1463 final TextInputChannel.Configuration config =
1480 final ViewStructure viewStructure = mock(ViewStructure.class);
1484 verify(viewStructure,
times(0)).newChild(anyInt());
1496 final TextInputChannel.Configuration.Autofill autofill =
1503 final TextInputChannel.Configuration config =
1520 final ViewStructure viewStructure = mock(ViewStructure.class);
1521 final ViewStructure[] children = {mock(ViewStructure.class), mock(ViewStructure.class)};
1523 when(viewStructure.newChild(anyInt()))
1524 .thenAnswer(invocation -> children[(
int) invocation.getArgument(0)]);
1527 verify(children[0]).setHint(
"placeholder");
1531 @SuppressWarnings(
"deprecation")
1541 final TextInputChannel.Configuration.Autofill autofill1 =
1544 new String[] {
"HINT1"},
1547 final TextInputChannel.Configuration.Autofill autofill2 =
1550 new String[] {
"HINT2",
"EXTRA"},
1554 final TextInputChannel.Configuration config1 =
1568 final TextInputChannel.Configuration config2 =
1599 final ViewStructure viewStructure = mock(ViewStructure.class);
1600 final ViewStructure[] children = {mock(ViewStructure.class), mock(ViewStructure.class)};
1602 when(viewStructure.newChild(anyInt()))
1603 .thenAnswer(invocation -> children[(
int) invocation.getArgument(0)]);
1607 verify(viewStructure).newChild(0);
1608 verify(viewStructure).newChild(1);
1610 verify(children[0]).setAutofillId(
any(),
eq(
"1".hashCode()));
1611 verify(children[0]).setAutofillHints(aryEq(
new String[] {
"HINT1"}));
1612 verify(children[0]).setDimens(anyInt(), anyInt(), anyInt(), anyInt(), gt(0), gt(0));
1613 verify(children[0]).setHint(
"placeholder1");
1615 verify(children[1]).setAutofillId(
any(),
eq(
"2".hashCode()));
1616 verify(children[1]).setAutofillHints(aryEq(
new String[] {
"HINT2",
"EXTRA"}));
1617 verify(children[1]).setDimens(anyInt(), anyInt(), anyInt(), anyInt(), gt(0), gt(0));
1618 verify(children[1],
times(0)).setHint(
any());
1621 @SuppressWarnings(
"deprecation")
1633 final TextInputChannel.Configuration.Autofill autofill =
1636 new String[] {
"HINT1"},
1657 final ViewStructure viewStructure = mock(ViewStructure.class);
1658 final ViewStructure[] children = {mock(ViewStructure.class)};
1660 when(viewStructure.newChild(anyInt()))
1661 .thenAnswer(invocation -> children[(
int) invocation.getArgument(0)]);
1665 verify(viewStructure).newChild(0);
1667 verify(children[0]).setAutofillId(
any(),
eq(
"1".hashCode()));
1668 verify(children[0]).setAutofillHints(aryEq(
new String[] {
"HINT1"}));
1669 verify(children[0]).setHint(
"placeholder");
1671 verify(children[0]).setDimens(anyInt(), anyInt(), anyInt(), anyInt(), gt(0), gt(0));
1681 TestAfm testAfm = Shadow.extract(ctx.getSystemService(AutofillManager.class));
1688 final TextInputChannel.Configuration.Autofill autofill1 =
1691 new String[] {
"HINT1"},
1694 final TextInputChannel.Configuration.Autofill autofill2 =
1697 new String[] {
"HINT2",
"EXTRA"},
1701 final TextInputChannel.Configuration config1 =
1715 final TextInputChannel.Configuration config2 =
1732 final TextInputChannel.Configuration autofillConfiguration =
1766 mockKeyboardManager,
1771 assertEquals(
"input from IME new text", testAfm.
changeString);
1792 assertEquals(
"1".hashCode(), testAfm.
exitId);
1799 assertEquals(
"1".hashCode(), testAfm.
exitId);
1806 assertEquals(
"1".hashCode(), testAfm.
exitId);
1810 @SuppressWarnings(
"deprecation")
1817 TestAfm testAfm = Shadow.extract(ctx.getSystemService(AutofillManager.class));
1824 final TextInputChannel.Configuration.Autofill autofill1 =
1827 new String[] {
"HINT1"},
1830 final TextInputChannel.Configuration.Autofill autofill2 =
1833 new String[] {
"HINT2",
"EXTRA"},
1837 final TextInputChannel.Configuration config1 =
1851 final TextInputChannel.Configuration config2 =
1866 final TextInputChannel.Configuration autofillConfiguration =
1885 final SparseArray<AutofillValue> autofillValues =
new SparseArray();
1886 autofillValues.append(
"1".hashCode(), AutofillValue.forText(
"focused field"));
1887 autofillValues.append(
"2".hashCode(), AutofillValue.forText(
"unfocused field"));
1893 assertTrue(
textInputPlugin.getEditable().toString().equals(
"focused field"));
1896 verify(textInputChannel,
times(1))
1897 .updateEditingState(anyInt(),
eq(
"focused field"),
eq(13),
eq(13),
eq(-1),
eq(-1));
1899 final ArgumentCaptor<HashMap> mapCaptor = ArgumentCaptor.forClass(HashMap.class);
1901 verify(textInputChannel,
times(1)).updateEditingStateWithTag(anyInt(), mapCaptor.capture());
1902 final TextInputChannel.TextEditState editState =
1904 assertEquals(editState.text,
"unfocused field");
1918 final TextInputChannel.Configuration.Autofill autofillConfig =
1921 new String[] {
"HINT1"},
1924 final TextInputChannel.Configuration config =
1944 final SparseArray<AutofillValue> autofillValues =
new SparseArray();
1945 autofillValues.append(
"1".hashCode(), AutofillValue.forText(
"focused field"));
1946 autofillValues.append(
"2".hashCode(), AutofillValue.forText(
"unfocused field"));
1951 verify(textInputChannel, never()).updateEditingStateWithTag(anyInt(),
any());
1952 verify(textInputChannel, never())
1953 .updateEditingState(anyInt(),
any(), anyInt(), anyInt(), anyInt(), anyInt());
1963 TestAfm testAfm = Shadow.extract(ctx.getSystemService(AutofillManager.class));
1970 final TextInputChannel.Configuration.Autofill autofill1 =
1973 new String[] {
"HINT1"},
1976 final TextInputChannel.Configuration.Autofill autofill2 =
1979 new String[] {
"HINT2",
"EXTRA"},
1982 "Unfocused fields need love like everything does", 0, 0, -1, -1));
1984 final TextInputChannel.Configuration config1 =
1998 final TextInputChannel.Configuration config2 =
2013 final TextInputChannel.Configuration autofillConfiguration =
2032 assertEquals(
"Unfocused fields need love like everything does", testAfm.
changeString);
2036 @SuppressWarnings(
"deprecation")
2039 return new FlutterView(Robolectric.setupActivity(Activity.class));
2042 @SuppressWarnings(
"deprecation")
2049 TextInputChannel.TextInputMethodHandler mockHandler =
2055 verify(mockBinaryMessenger,
times(1))
2056 .setMessageHandler(
any(String.class), binaryMessageHandlerCaptor.capture());
2058 BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
2059 binaryMessageHandlerCaptor.getValue();
2061 sendToBinaryMessageHandler(binaryMessageHandler,
"TextInput.requestAutofill",
null);
2062 verify(mockHandler,
times(1)).requestAutofill();
2064 sendToBinaryMessageHandler(binaryMessageHandler,
"TextInput.finishAutofillContext",
true);
2065 verify(mockHandler,
times(1)).finishAutofillContext(
true);
2067 sendToBinaryMessageHandler(binaryMessageHandler,
"TextInput.finishAutofillContext",
false);
2068 verify(mockHandler,
times(1)).finishAutofillContext(
false);
2071 @SuppressWarnings(
"deprecation")
2081 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
2084 View testView =
new View(ctx);
2088 verify(mockBinaryMessenger,
times(1))
2089 .setMessageHandler(
any(String.class), binaryMessageHandlerCaptor.capture());
2091 JSONObject arguments =
new JSONObject();
2092 arguments.put(
"action",
"actionCommand");
2093 arguments.put(
"data",
"");
2095 BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
2096 binaryMessageHandlerCaptor.getValue();
2097 sendToBinaryMessageHandler(binaryMessageHandler,
"TextInput.sendAppPrivateCommand", arguments);
2098 verify(mockEventHandler,
times(1))
2099 .sendAppPrivateCommand(
any(View.class),
eq(
"actionCommand"),
eq(
null));
2102 @SuppressWarnings(
"deprecation")
2112 TestImm testImm = Shadow.extract(ctx.getSystemService(Context.INPUT_METHOD_SERVICE));
2115 View testView =
new View(ctx);
2119 verify(mockBinaryMessenger,
times(1))
2120 .setMessageHandler(
any(String.class), binaryMessageHandlerCaptor.capture());
2122 JSONObject arguments =
new JSONObject();
2123 arguments.put(
"action",
"actionCommand");
2124 arguments.put(
"data",
"actionData");
2126 ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
2127 BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
2128 binaryMessageHandlerCaptor.getValue();
2129 sendToBinaryMessageHandler(binaryMessageHandler,
"TextInput.sendAppPrivateCommand", arguments);
2130 verify(mockEventHandler,
times(1))
2131 .sendAppPrivateCommand(
any(View.class),
eq(
"actionCommand"), bundleCaptor.capture());
2132 assertEquals(
"actionData", bundleCaptor.getValue().getCharSequence(
"data"));
2138 @SuppressWarnings(
"deprecation")
2141 public
void ime_windowInsetsSync_notLaidOutBehindNavigation_excludesNavigationBars() {
2143 when(testView.getWindowSystemUiVisibility()).thenReturn(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
2151 when(flutterEngine.
getRenderer()).thenReturn(flutterRenderer);
2154 WindowInsetsAnimation animation = mock(WindowInsetsAnimation.class);
2155 when(animation.getTypeMask()).thenReturn(WindowInsets.Type.ime());
2158 animationList.add(animation);
2163 WindowInsets.Builder
builder =
new WindowInsets.Builder();
2168 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2169 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2174 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 100));
2175 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 0));
2178 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2179 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2183 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 50));
2184 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2187 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2188 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2192 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 25));
2193 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2196 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2197 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2199 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 50));
2200 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2203 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2204 assertEquals(10, viewportMetricsCaptor.getValue().viewInsetBottom);
2210 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2211 assertEquals(100, viewportMetricsCaptor.getValue().viewInsetBottom);
2217 @SuppressWarnings(
"deprecation")
2220 public
void ime_windowInsetsSync_laidOutBehindNavigation_includesNavigationBars() {
2222 when(testView.getWindowSystemUiVisibility())
2224 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
2232 when(flutterEngine.
getRenderer()).thenReturn(flutterRenderer);
2235 WindowInsetsAnimation animation = mock(WindowInsetsAnimation.class);
2236 when(animation.getTypeMask()).thenReturn(WindowInsets.Type.ime());
2239 animationList.add(animation);
2244 WindowInsets.Builder
builder =
new WindowInsets.Builder();
2249 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2250 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2255 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 100));
2256 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 0));
2259 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2260 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2264 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 50));
2265 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2268 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2269 assertEquals(0, viewportMetricsCaptor.getValue().viewInsetBottom);
2273 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 25));
2274 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2277 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2278 assertEquals(25, viewportMetricsCaptor.getValue().viewInsetBottom);
2280 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 50));
2281 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 40));
2284 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2285 assertEquals(50, viewportMetricsCaptor.getValue().viewInsetBottom);
2291 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2292 assertEquals(100, viewportMetricsCaptor.getValue().viewInsetBottom);
2298 @SuppressWarnings(
"deprecation")
2301 public
void lastWindowInsets_updatedOnSecondOnProgressCall() {
2303 when(testView.getWindowSystemUiVisibility()).thenReturn(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
2311 when(flutterEngine.
getRenderer()).thenReturn(flutterRenderer);
2314 WindowInsetsAnimation imeAnimation = mock(WindowInsetsAnimation.class);
2315 when(imeAnimation.getTypeMask()).thenReturn(WindowInsets.Type.ime());
2316 WindowInsetsAnimation navigationBarAnimation = mock(WindowInsetsAnimation.class);
2317 when(navigationBarAnimation.getTypeMask()).thenReturn(WindowInsets.Type.navigationBars());
2320 animationList.add(imeAnimation);
2321 animationList.add(navigationBarAnimation);
2326 WindowInsets.Builder
builder =
new WindowInsets.Builder();
2329 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 1000));
2330 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 100));
2333 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2334 assertEquals(100, viewportMetricsCaptor.getValue().viewPaddingBottom);
2339 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 0));
2340 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 100));
2343 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2344 assertEquals(100, viewportMetricsCaptor.getValue().viewPaddingBottom);
2348 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 0));
2349 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 0));
2352 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2353 assertEquals(100, viewportMetricsCaptor.getValue().viewPaddingBottom);
2357 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 500));
2358 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 0));
2361 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2362 assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingBottom);
2364 builder.setInsets(WindowInsets.Type.ime(), Insets.of(0, 0, 0, 250));
2365 builder.setInsets(WindowInsets.Type.navigationBars(), Insets.of(0, 0, 0, 0));
2368 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2369 assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingBottom);
2375 verify(flutterRenderer, atLeast(1)).setViewportMetrics(viewportMetricsCaptor.capture());
2376 assertEquals(0, viewportMetricsCaptor.getValue().viewPaddingBottom);
2383 @Implements(InputMethodManager.class)
2384 public static class
TestImm extends ShadowInputMethodManager {
2385 private InputMethodSubtype currentInputMethodSubtype;
2386 private SparseIntArray restartCounter =
new SparseIntArray();
2387 private CursorAnchorInfo cursorAnchorInfo;
2388 private ArrayList<Integer> selectionUpdateValues;
2389 private boolean trackSelection =
false;
2393 selectionUpdateValues =
new ArrayList<Integer>();
2398 return currentInputMethodSubtype;
2403 int count = restartCounter.get(view.hashCode(), 0) + 1;
2404 restartCounter.put(view.hashCode(),
count);
2408 this.currentInputMethodSubtype = inputMethodSubtype;
2412 return restartCounter.get(view.hashCode(), 0);
2416 handler = eventHandler;
2426 this.cursorAnchorInfo = cursorAnchorInfo;
2432 View view,
int selStart,
int selEnd,
int candidatesStart,
int candidatesEnd) {
2433 if (trackSelection) {
2434 this.selectionUpdateValues.add(selStart);
2435 this.selectionUpdateValues.add(selEnd);
2436 this.selectionUpdateValues.add(candidatesStart);
2437 this.selectionUpdateValues.add(candidatesEnd);
2443 trackSelection = val;
2448 return selectionUpdateValues;
2452 return cursorAnchorInfo;
2456 @Implements(AutofillManager.class)
2457 public static class
TestAfm extends ShadowAutofillManager {
2469 finishState =
"cancel";
2473 finishState =
"commit";
2477 enterId = virtualId;
2488 changeVirtualId = virtualId;
2489 changeString =
value.getTextValue().toString();
2494 changeVirtualId =
empty;
2495 changeString =
null;
static SkISize times(const SkISize &size, float factor)
static bool eq(const SkM44 &a, const SkM44 &b, float tol)
bool equals(SkDrawable *a, SkDrawable *b)
void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine)
FlutterRenderer getRenderer()
void setTextInputMethodHandler(@Nullable TextInputMethodHandler textInputMethodHandler)
MethodCall decodeMethodCall(@NonNull ByteBuffer message)
static final JSONMethodCodec INSTANCE
WindowInsetsAnimation.Callback getAnimationCallback()
View.OnApplyWindowInsetsListener getInsetsListener()
CharSequence getDeltaText()
int getNewSelectionStart()
CharSequence getOldText()
int getNewComposingStart()
void notifyViewExited(View view, int virtualId)
void notifyViewEntered(View view, int virtualId, Rect absBounds)
void notifyValueChanged(View view, int virtualId, AutofillValue value)
void updateCursorAnchorInfo(View view, CursorAnchorInfo cursorAnchorInfo)
ArrayList< Integer > getSelectionUpdateValues()
void setEventHandler(EventHandler eventHandler)
void setTrackSelection(boolean val)
void updateSelection(View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd)
void restartInput(View view)
InputMethodSubtype getCurrentInputMethodSubtype()
void setCurrentInputMethodSubtype(InputMethodSubtype inputMethodSubtype)
void sendAppPrivateCommand(View view, String action, Bundle data)
CursorAnchorInfo getLastCursorAnchorInfo()
int getRestartCount(View view)
void textInputPlugin_RequestsReattachOnCreation()
void inputConnection_textInputTypeNone()
void autofill_testAutofillUpdatesTheFramework()
void inputConnection_textInputTypeMultilineAndSuggestionsDisabled()
void textEditingDelta_TestUpdateEditingValueIsNotInvokedWhenDeltaModelEnabled()
void setTextInputEditingState_doesNotInvokeUpdateEditingStateWithDeltas()
void autofill_canBeDisabled()
void autofill_doesNotCrashAfterClearClientCall()
void autofill_onProvideVirtualViewStructure_singular_textfield()
void autofill_onProvideVirtualViewStructure()
void autofill_testSetTextIpnutClientUpdatesSideFields()
void inputConnectionAdaptor_RepeatFilter()
void showTextInput_textInputTypeNone()
void textEditingDelta_TestDeltaIsCreatedWhenComposingTextSetIsDeleting()
void clearTextInputClient_alwaysRestartsImm()
void TextEditState_throwsOnInvalidStatesReceived()
void inputConnection_finishComposingTextUpdatesIMM()
void textEditingDelta_TestDeltaIsCreatedWhenComposingTextSetIsInserting()
void respondsToInputChannelMessages()
void setTextInputEditingState_alwaysSetEditableWhenDifferent()
void sendAppPrivateCommand_hasData()
void setTextInputEditingState_restartsIMEOnlyWhenFrameworkChangesComposingRegion()
void setTextInputEditingState_doesNotInvokeUpdateEditingState()
void autofill_testLifeCycle()
void sendAppPrivateCommand_dataIsEmpty()
void setTextInputEditingState_nullInputMethodSubtype()
void setTextInputEditingState_willNotThrowWithoutSetTextInputClient()
void destroy_clearTextInputMethodHandler()
void inputConnection_createsActionFromEnter()
void inputConnection_respondsToKeyEvents_textInputTypeNone()
void textEditingDelta_TestUpdateEditingValueWithDeltasIsNotInvokedWhenDeltaModelDisabled()
FlutterJNI mockFlutterJni
FlutterLoader mockFlutterLoader
void setTextInputEditingState_doesNotRestartWhenTextIsIdentical()
void autofill_enabledByDefault()
void textEditingDelta_TestDeltaIsCreatedWhenComposingTextSetIsReplacing()
EMSCRIPTEN_KEEPALIVE void empty()
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
void clearTextInputClient()
void sendAppPrivateCommand(View view, String action, Bundle data)
FlutterTextInputPlugin * textInputPlugin
def Build(configs, env, options)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
SIT bool any(const Vec< 1, T > &x)
std::shared_ptr< const fml::Mapping > data