Stopgap solution for a crash.

This returns the wrong string, but since it's used for getting the
previous word for bigrams, it only results in slightly worse
suggestions quality.
Cherry-pick of I6ce5de2f

Bug: 11273655
Change-Id: I17fb6d74f18fb31bd8f8518f80456d74ae30a2c3
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index e43cab5..c212f9c 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -294,7 +294,14 @@
         // the text field, then we can return the cached version right away.
         if (cachedLength >= n || cachedLength >= mExpectedCursorPosition) {
             final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText);
-            s.append(mComposingText);
+            // We call #toString() here to create a temporary object.
+            // In some situations, this method is called on a worker thread, and it's possible
+            // the main thread touches the contents of mComposingText while this worker thread
+            // is suspended, because mComposingText is a StringBuilder. This may lead to crashes,
+            // so we call #toString() on it. That will result in the return value being strictly
+            // speaking wrong, but since this is used for basing bigram probability off, and
+            // it's only going to matter for one getSuggestions call, it's fine in the practice.
+            s.append(mComposingText.toString());
             if (s.length() > n) {
                 s.delete(0, s.length() - n);
             }