From 516b63db2866f144a00ec7e1e6c29cb0865f5ff3 Mon Sep 17 00:00:00 2001
From: Jean Chalard <jchalard@google.com>
Date: Wed, 9 Jan 2013 18:37:10 +0900
Subject: [PATCH] Fix a race condition with backspaces

And add a test to make sure it stays not-broken.

Bug: 7946604
Change-Id: I996da3d5507d591ec25a13fb57434f39843f1df5
---
 .../android/inputmethod/latin/LatinIME.java   |  5 +++++
 .../inputmethod/latin/InputLogicTests.java    | 21 +++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6eeee9c2a8..3b0112b272 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1717,6 +1717,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
                 // If there is a selection, remove it.
                 final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
                 mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd);
+                // Reset mLastSelectionEnd to mLastSelectionStart. This is what is supposed to
+                // happen, and if it's wrong, the next call to onUpdateSelection will correct it,
+                // but we want to set it right away to avoid it being used with the wrong values
+                // later (typically, in a subsequent press on backspace).
+                mLastSelectionEnd = mLastSelectionStart;
                 mConnection.deleteSurroundingText(lengthToDelete, 0);
             } else {
                 // There is no selection, just delete one character.
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 38f5305ded..6412a9db55 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -102,6 +102,27 @@ public class InputLogicTests extends InputTestsBase {
         assertEquals("delete selection", EXPECTED_RESULT, mTextView.getText().toString());
     }
 
+    public void testDeleteSelectionTwice() {
+        final String STRING_TO_TYPE = "some text delete me some text";
+        final int typedLength = STRING_TO_TYPE.length();
+        final int SELECTION_START = 10;
+        final int SELECTION_END = 19;
+        final String EXPECTED_RESULT = "some text some text";
+        type(STRING_TO_TYPE);
+        // There is no IMF to call onUpdateSelection for us so we must do it by hand.
+        // Send once to simulate the cursor actually responding to the move caused by typing.
+        // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor
+        // move with a move triggered by LatinIME inputting stuff.
+        mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
+        mInputConnection.setSelection(SELECTION_START, SELECTION_END);
+        // And now we simulate the user actually selecting some text.
+        mLatinIME.onUpdateSelection(typedLength, typedLength,
+                SELECTION_START, SELECTION_END, -1, -1);
+        type(Constants.CODE_DELETE);
+        type(Constants.CODE_DELETE);
+        assertEquals("delete selection twice", EXPECTED_RESULT, mTextView.getText().toString());
+    }
+
     public void testAutoCorrect() {
         final String STRING_TO_TYPE = "tgis ";
         final String EXPECTED_RESULT = "this ";
-- 
GitLab