Skip to content

Commit

Permalink
[Android TextInput] clean up nested batch edits in closeConnection() (f…
Browse files Browse the repository at this point in the history
  • Loading branch information
LongCatIsLooong authored Jun 10, 2021
1 parent e0c16f0 commit 27ddef5
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

package io.flutter.plugin.editing;

import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputType;
Expand All @@ -25,7 +23,6 @@
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import io.flutter.Log;
import io.flutter.embedding.android.KeyboardManager;
import io.flutter.embedding.engine.FlutterJNI;
Expand All @@ -48,6 +45,7 @@ class InputConnectionAdaptor extends BaseInputConnection
private final Layout mLayout;
private FlutterTextUtils flutterTextUtils;
private final KeyboardManager keyboardManager;
private int batchEditNestDepth = 0;

@SuppressWarnings("deprecation")
public InputConnectionAdaptor(
Expand Down Expand Up @@ -135,12 +133,14 @@ public Editable getEditable() {
@Override
public boolean beginBatchEdit() {
mEditable.beginBatchEdit();
batchEditNestDepth += 1;
return super.beginBatchEdit();
}

@Override
public boolean endBatchEdit() {
boolean result = super.endBatchEdit();
batchEditNestDepth -= 1;
mEditable.endBatchEdit();
return result;
}
Expand Down Expand Up @@ -238,27 +238,9 @@ public boolean clearMetaKeyStates(int states) {
public void closeConnection() {
super.closeConnection();
mEditable.removeEditingStateListener(this);
}

// Detect if the keyboard is a Samsung keyboard, where we apply Samsung-specific hacks to
// fix critical bugs that make the keyboard otherwise unusable. See finishComposingText() for
// more details.
@SuppressLint("NewApi") // New API guard is inline, the linter can't see it.
@SuppressWarnings("deprecation")
private boolean isSamsung() {
InputMethodSubtype subtype = mImm.getCurrentInputMethodSubtype();
// Impacted devices all shipped with Android Lollipop or newer.
if (subtype == null
|| Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
|| !Build.MANUFACTURER.equals("samsung")) {
return false;
for (; batchEditNestDepth > 0; batchEditNestDepth--) {
endBatchEdit();
}
String keyboardName =
Settings.Secure.getString(
mFlutterView.getContext().getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
// The Samsung keyboard is called "com.sec.android.inputmethod/.SamsungKeypad" but look
// for "Samsung" just in case Samsung changes the name of the keyboard.
return keyboardName.contains("Samsung");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,7 @@ void setTextInputEditingState(View view, TextInputChannel.TextEditState state) {
// to reset their internal states.
mRestartInputPending = composingChanged(mLastKnownFrameworkTextEditingState, state);
if (mRestartInputPending) {
Log.w(
TAG,
"Changing the content within the the composing region may cause the input method to behave strangely, and is therefore discouraged. See https://github.com/flutter/flutter/issues/78827 for more details");
Log.i(TAG, "Composing region changed by the framework. Restarting the input method.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,19 @@ public void testDoesNotConsumeBackButton() {
assertFalse(didConsume);
}

@Test
public void testCleanUpBatchEndsOnCloseConnection() {
final ListenableEditingState editable = sampleEditable(0, 0);
InputConnectionAdaptor adaptor = spy(sampleInputConnectionAdaptor(editable));
for (int i = 0; i < 5; i++) {
adaptor.beginBatchEdit();
}
adaptor.endBatchEdit();
verify(adaptor, times(1)).endBatchEdit();
adaptor.closeConnection();
verify(adaptor, times(4)).endBatchEdit();
}

private static final String SAMPLE_TEXT =
"Lorem ipsum dolor sit amet," + "\nconsectetur adipiscing elit.";

Expand Down

0 comments on commit 27ddef5

Please sign in to comment.