Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Clean up text input configuration in clearTextInputClient #34209

Merged
merged 4 commits into from
Jun 24, 2022
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
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