Skip to content

Commit

Permalink
Clean up text input configuration in clearTextInputClient (flutter#34209
Browse files Browse the repository at this point in the history
)
  • Loading branch information
LongCatIsLooong authored Jun 24, 2022
1 parent 54867f3 commit 98221a2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class TextInputPlugin implements ListenableEditingState.EditingStateWatch
@NonNull private final TextInputChannel textInputChannel;
@NonNull private InputTarget inputTarget = new InputTarget(InputTarget.Type.NO_TARGET, 0);
@Nullable private TextInputChannel.Configuration configuration;
@Nullable private SparseArray<TextInputChannel.Configuration> mAutofillConfigurations;
@Nullable private SparseArray<TextInputChannel.Configuration> autofillConfiguration;
@NonNull private ListenableEditingState mEditable;
private boolean mRestartInputPending;
@Nullable private InputConnection lastInputConnection;
Expand Down Expand Up @@ -556,6 +556,7 @@ void clearTextInputClient() {
}
mEditable.removeEditingStateListener(this);
notifyViewExited();
configuration = null;
updateAutofillConfigurationIfNeeded(null);
inputTarget = new InputTarget(InputTarget.Type.NO_TARGET, 0);
unlockPlatformViewInputConnection();
Expand Down Expand Up @@ -679,7 +680,7 @@ public void didChangeEditingState(
// have changed. However if the value of an unfocused EditableText is changed in the framework,
// such change will not be sent to the text input plugin until the next TextInput.attach call.
private boolean needsAutofill() {
return mAutofillConfigurations != null;
return autofillConfiguration != null;
}

private void notifyViewEntered() {
Expand Down Expand Up @@ -724,21 +725,20 @@ private void updateAutofillConfigurationIfNeeded(TextInputChannel.Configuration

if (configuration == null || configuration.autofill == null) {
// Disables autofill if the configuration doesn't have an autofill field.
mAutofillConfigurations = null;
autofillConfiguration = null;
return;
}

final TextInputChannel.Configuration[] configurations = configuration.fields;
mAutofillConfigurations = new SparseArray<>();
autofillConfiguration = new SparseArray<>();

if (configurations == null) {
mAutofillConfigurations.put(
configuration.autofill.uniqueIdentifier.hashCode(), configuration);
autofillConfiguration.put(configuration.autofill.uniqueIdentifier.hashCode(), configuration);
} else {
for (TextInputChannel.Configuration config : configurations) {
TextInputChannel.Configuration.Autofill autofill = config.autofill;
if (autofill != null) {
mAutofillConfigurations.put(autofill.uniqueIdentifier.hashCode(), config);
autofillConfiguration.put(autofill.uniqueIdentifier.hashCode(), config);
afm.notifyValueChanged(
mView,
autofill.uniqueIdentifier.hashCode(),
Expand All @@ -755,9 +755,9 @@ public void onProvideAutofillVirtualStructure(@NonNull ViewStructure structure,

final String triggerIdentifier = configuration.autofill.uniqueIdentifier;
final AutofillId parentId = structure.getAutofillId();
for (int i = 0; i < mAutofillConfigurations.size(); i++) {
final int autofillId = mAutofillConfigurations.keyAt(i);
final TextInputChannel.Configuration config = mAutofillConfigurations.valueAt(i);
for (int i = 0; i < autofillConfiguration.size(); i++) {
final int autofillId = autofillConfiguration.keyAt(i);
final TextInputChannel.Configuration config = autofillConfiguration.valueAt(i);
final TextInputChannel.Configuration.Autofill autofill = config.autofill;
if (autofill == null) {
continue;
Expand Down Expand Up @@ -801,16 +801,16 @@ public void autofill(@NonNull SparseArray<AutofillValue> values) {
return;
}

final TextInputChannel.Configuration.Autofill currentAutofill = configuration.autofill;
if (currentAutofill == null) {
if (configuration == null || autofillConfiguration == null || configuration.autofill == null) {
return;
}

final TextInputChannel.Configuration.Autofill currentAutofill = configuration.autofill;
final HashMap<String, TextInputChannel.TextEditState> editingValues = new HashMap<>();
for (int i = 0; i < values.size(); i++) {
int virtualId = values.keyAt(i);

final TextInputChannel.Configuration config = mAutofillConfigurations.get(virtualId);
final TextInputChannel.Configuration config = autofillConfiguration.get(virtualId);
if (config == null || config.autofill == null) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1781,6 +1781,53 @@ public void autofill_testAutofillUpdatesTheFramework() {
assertEquals(editState.text, "unfocused field");
}

@Test
public void autofill_doesNotCrashAfterClearClientCall() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return;
}
FlutterView testView = new FlutterView(ctx);
TextInputChannel textInputChannel = spy(new TextInputChannel(mock(DartExecutor.class)));
TextInputPlugin textInputPlugin =
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
// Set up an autofill scenario with 2 fields.
final TextInputChannel.Configuration.Autofill autofillConfig =
new TextInputChannel.Configuration.Autofill(
"1",
new String[] {"HINT1"},
"placeholder1",
new TextInputChannel.TextEditState("", 0, 0, -1, -1));
final TextInputChannel.Configuration config =
new TextInputChannel.Configuration(
false,
false,
true,
true,
false,
TextInputChannel.TextCapitalization.NONE,
null,
null,
null,
autofillConfig,
null);

textInputPlugin.setTextInputClient(0, config);
textInputPlugin.setTextInputEditingState(
testView, new TextInputChannel.TextEditState("", 0, 0, -1, -1));
textInputPlugin.clearTextInputClient();

final SparseArray<AutofillValue> autofillValues = new SparseArray();
autofillValues.append("1".hashCode(), AutofillValue.forText("focused field"));
autofillValues.append("2".hashCode(), AutofillValue.forText("unfocused field"));

// Autofill both fields.
textInputPlugin.autofill(autofillValues);

verify(textInputChannel, never()).updateEditingStateWithTag(anyInt(), any());
verify(textInputChannel, never())
.updateEditingState(anyInt(), any(), anyInt(), anyInt(), anyInt(), anyInt());
}

@Test
public void autofill_testSetTextIpnutClientUpdatesSideFields() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
Expand Down

0 comments on commit 98221a2

Please sign in to comment.