diff --git a/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java b/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java index 79c8191079980..d5236c4ff75fb 100644 --- a/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java +++ b/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java @@ -424,6 +424,7 @@ public static Configuration fromJson(@NonNull JSONObject json) json.optBoolean("obscureText"), json.optBoolean("autocorrect", true), json.optBoolean("enableSuggestions"), + json.optBoolean("enableIMEPersonalizedLearning"), TextCapitalization.fromValue(json.getString("textCapitalization")), InputType.fromJson(json.getJSONObject("inputType")), inputAction, @@ -573,6 +574,7 @@ public Autofill( public final boolean obscureText; public final boolean autocorrect; public final boolean enableSuggestions; + public final boolean enableIMEPersonalizedLearning; @NonNull public final TextCapitalization textCapitalization; @NonNull public final InputType inputType; @Nullable public final Integer inputAction; @@ -584,6 +586,7 @@ public Configuration( boolean obscureText, boolean autocorrect, boolean enableSuggestions, + boolean enableIMEPersonalizedLearning, @NonNull TextCapitalization textCapitalization, @NonNull InputType inputType, @Nullable Integer inputAction, @@ -593,6 +596,7 @@ public Configuration( this.obscureText = obscureText; this.autocorrect = autocorrect; this.enableSuggestions = enableSuggestions; + this.enableIMEPersonalizedLearning = enableIMEPersonalizedLearning; this.textCapitalization = textCapitalization; this.inputType = inputType; this.inputAction = inputAction; diff --git a/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java b/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java index cd1e385d1b5bd..b466728a0b8cd 100644 --- a/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java +++ b/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java @@ -230,6 +230,7 @@ private static int inputTypeFromTextInputType( boolean obscureText, boolean autocorrect, boolean enableSuggestions, + boolean enableIMEPersonalizedLearning, TextInputChannel.TextCapitalization textCapitalization) { if (type.type == TextInputChannel.TextInputType.DATETIME) { return InputType.TYPE_CLASS_DATETIME; @@ -311,8 +312,15 @@ public InputConnection createInputConnection( configuration.obscureText, configuration.autocorrect, configuration.enableSuggestions, + configuration.enableIMEPersonalizedLearning, configuration.textCapitalization); outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && !configuration.enableIMEPersonalizedLearning) { + outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING; + } + int enterAction; if (configuration.inputAction == null) { // If an explicit input action isn't set, then default to none for multi-line fields diff --git a/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java b/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java index acf1d4fe7c790..2c928d8d6dff3 100644 --- a/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java @@ -151,6 +151,7 @@ public void setTextInputEditingState_doesNotInvokeUpdateEditingState() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -196,6 +197,7 @@ public void inputConnectionAdaptor_RepeatFilter() throws NullPointerException { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.TEXT, false, false), null, @@ -284,6 +286,7 @@ public void setTextInputEditingState_doesNotRestartWhenTextIsIdentical() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -321,6 +324,7 @@ public void setTextInputEditingState_alwaysSetEditableWhenDifferent() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -367,6 +371,7 @@ public void setTextInputEditingState_restartsIMEOnlyWhenFrameworkChangesComposin false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.TEXT, false, false), null, @@ -462,6 +467,7 @@ public void setTextInputEditingState_nullInputMethodSubtype() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -504,6 +510,7 @@ public void inputConnection_createsActionFromEnter() throws JSONException { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.TEXT, false, false), null, @@ -582,6 +589,7 @@ public void inputConnection_finishComposingTextUpdatesIMM() throws JSONException false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.TEXT, false, false), null, @@ -617,6 +625,7 @@ public void inputConnection_textInputTypeNone() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.NONE, false, false), null, @@ -646,6 +655,7 @@ public void showTextInput_textInputTypeNone() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, new TextInputChannel.InputType(TextInputChannel.TextInputType.NONE, false, false), null, @@ -682,6 +692,7 @@ public void autofill_onProvideVirtualViewStructure() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -693,6 +704,7 @@ public void autofill_onProvideVirtualViewStructure() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -706,6 +718,7 @@ public void autofill_onProvideVirtualViewStructure() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -754,6 +767,7 @@ public void autofill_onProvideVirtualViewStructure_single() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -805,6 +819,7 @@ public void autofill_testLifeCycle() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -816,6 +831,7 @@ public void autofill_testLifeCycle() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -830,6 +846,7 @@ public void autofill_testLifeCycle() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -872,6 +889,7 @@ public void autofill_testLifeCycle() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -926,6 +944,7 @@ public void autofill_testAutofillUpdatesTheFramework() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -937,6 +956,7 @@ public void autofill_testAutofillUpdatesTheFramework() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -949,6 +969,7 @@ public void autofill_testAutofillUpdatesTheFramework() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -1011,6 +1032,7 @@ public void autofill_testSetTextIpnutClientUpdatesSideFields() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -1022,6 +1044,7 @@ public void autofill_testSetTextIpnutClientUpdatesSideFields() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null, @@ -1034,6 +1057,7 @@ public void autofill_testSetTextIpnutClientUpdatesSideFields() { false, false, true, + true, TextInputChannel.TextCapitalization.NONE, null, null,