Skip to content

Commit

Permalink
Samsung fix duplication on punctuation: Update keyboard on finish com…
Browse files Browse the repository at this point in the history
…pose. (flutter#15701)
  • Loading branch information
GaryQian authored Jan 17, 2020
1 parent 77d18d3 commit 5734ece
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.flutter.plugin.editing;

import android.content.Context;
import android.os.Build;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.Layout;
Expand All @@ -14,6 +15,7 @@
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.InputMethodManager;

Expand Down Expand Up @@ -133,6 +135,24 @@ public boolean setComposingText(CharSequence text, int newCursorPosition) {
return result;
}

@Override
public boolean finishComposingText() {
boolean result = super.finishComposingText();

if (Build.VERSION.SDK_INT >= 21) {
// 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(-1, "");
CursorAnchorInfo anchorInfo = builder.build();
mImm.updateCursorAnchorInfo(mFlutterView, anchorInfo);
}

updateEditingState();
return result;
}


@Override
public boolean setSelection(int start, int end) {
boolean result = super.setSelection(start, end);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import android.content.Context;
import android.content.res.AssetManager;
import android.os.Build;
import android.provider.Settings;
import android.util.SparseIntArray;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
Expand Down Expand Up @@ -219,10 +221,37 @@ public void inputConnection_createsActionFromEnter() throws JSONException {
verifyMethodCall(bufferCaptor.getValue(), "TextInputClient.performAction", new String[] {"0", "TextInputAction.done"});
}

@Test
public void inputConnection_finishComposingTextUpdatesIMM() throws JSONException {
TestImm testImm = Shadow.extract(RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE));
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
View testView = new View(RuntimeEnvironment.application);
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
TextInputPlugin textInputPlugin = new TextInputPlugin(testView, dartExecutor, 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));
// 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);
}
}

@Implements(InputMethodManager.class)
public static class TestImm extends ShadowInputMethodManager {
private InputMethodSubtype currentInputMethodSubtype;
private SparseIntArray restartCounter = new SparseIntArray();
private CursorAnchorInfo cursorAnchorInfo;

public TestImm() {
}
Expand All @@ -245,5 +274,14 @@ public void setCurrentInputMethodSubtype(InputMethodSubtype inputMethodSubtype)
public int getRestartCount(View view) {
return restartCounter.get(view.hashCode(), /*defaultValue=*/0);
}

@Implementation
public void updateCursorAnchorInfo(View view, CursorAnchorInfo cursorAnchorInfo) {
this.cursorAnchorInfo = cursorAnchorInfo;
}

public CursorAnchorInfo getLastCursorAnchorInfo() {
return cursorAnchorInfo;
}
}
}

0 comments on commit 5734ece

Please sign in to comment.