diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index a990ff38610..8a50cde7b71 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -4,12 +4,9 @@ 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.provider.Settings; import android.text.DynamicLayout; import android.text.Editable; import android.text.InputType; @@ -20,12 +17,10 @@ import android.text.method.TextKeyListener; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.EditorInfo; 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.engine.systemchannels.TextInputChannel; @@ -38,8 +33,6 @@ class InputConnectionAdaptor extends BaseInputConnection { private int mBatchCount; private InputMethodManager mImm; private final Layout mLayout; - // Used to determine if Samsung-specific hacks should be applied. - private final boolean isSamsung; private boolean mRepeatCheckNeeded = false; private TextEditingValue mLastSentTextEditngValue; @@ -116,8 +109,6 @@ class InputConnectionAdaptor extends BaseInputConnection { 0.0f, false); mImm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - - isSamsung = isSamsung(); } // Send the current state of the editable to Flutter. @@ -227,21 +218,6 @@ class InputConnectionAdaptor extends BaseInputConnection { @Override public boolean finishComposingText() { boolean result = super.finishComposingText(); - - // Apply Samsung hacks. Samsung caches composing region data strangely, causing text - // duplication. - if (isSamsung) { - if (Build.VERSION.SDK_INT >= 21) { - // Samsung keyboards don't clear the composing region on finishComposingText. - // Update the keyboard with a reset/empty composing region. Critical on - // Samsung keyboards to prevent punctuation duplication. - CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder(); - builder.setComposingText(/*composingTextStart*/ -1, /*composingText*/ ""); - CursorAnchorInfo anchorInfo = builder.build(); - mImm.updateCursorAnchorInfo(mFlutterView, anchorInfo); - } - } - markDirty(); return result; } @@ -263,27 +239,6 @@ class InputConnectionAdaptor extends BaseInputConnection { return result; } - // 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; - } - 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 public boolean setSelection(int start, int end) { boolean result = super.setSelection(start, end); diff --git a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java index b515d80b430..082c43d3a08 100644 --- a/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java +++ b/engine/src/flutter/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java @@ -369,52 +369,6 @@ public class TextInputPluginTest { new String[] {"0", "TextInputAction.done"}); } - @Test - public void inputConnection_finishComposingTextUpdatesIMM() throws JSONException { - ShadowBuild.setManufacturer("samsung"); - InputMethodSubtype inputMethodSubtype = - new InputMethodSubtype(0, 0, /*locale=*/ "en", "", "", false, false); - Settings.Secure.putString( - RuntimeEnvironment.application.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, - "com.sec.android.inputmethod/.SamsungKeypad"); - TestImm testImm = - Shadow.extract( - RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE)); - testImm.setCurrentInputMethodSubtype(inputMethodSubtype); - FlutterJNI mockFlutterJni = mock(FlutterJNI.class); - View testView = new View(RuntimeEnvironment.application); - DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class))); - TextInputChannel textInputChannel = new TextInputChannel(dartExecutor); - TextInputPlugin textInputPlugin = - new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class)); - textInputPlugin.setTextInputClient( - 0, - new TextInputChannel.Configuration( - false, - false, - true, - TextInputChannel.TextCapitalization.NONE, - new TextInputChannel.InputType(TextInputChannel.TextInputType.TEXT, false, false), - null, - null, - null, - null)); - // There's a pending restart since we initialized the text input client. Flush that now. - textInputPlugin.setTextInputEditingState( - testView, new TextInputChannel.TextEditState("", 0, 0)); - InputConnection connection = textInputPlugin.createInputConnection(testView, new EditorInfo()); - - connection.finishComposingText(); - - if (Build.VERSION.SDK_INT >= 21) { - CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder(); - builder.setComposingText(-1, ""); - CursorAnchorInfo anchorInfo = builder.build(); - assertEquals(testImm.getLastCursorAnchorInfo(), anchorInfo); - } - } - @Test public void autofill_onProvideVirtualViewStructure() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;