From 8a1675379e03bd7830d35212fd987346927068a9 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 22 Oct 2013 19:22:57 +0900 Subject: 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. Bug: 11273655 Change-Id: I6ce5de2f76effc453ca691a654ab6bf17445b9e7 --- java/src/com/android/inputmethod/latin/RichInputConnection.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'java/src/com/android/inputmethod/latin/RichInputConnection.java') diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index e43cab5ca..c212f9c81 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -294,7 +294,14 @@ public final class RichInputConnection { // 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); } -- cgit v1.2.3-83-g751a From 3a9b2430a56cb2d774070bd8ecd661d0dfb82484 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 13 Nov 2013 14:20:45 +0900 Subject: Fix many small nits. ...the interaction of which results in a very bad bug. Bug: 11648854 Change-Id: I774489e384388f187e72b9ac091ab387c5e1a79a --- java/src/com/android/inputmethod/latin/LatinIME.java | 11 +++++++++-- .../com/android/inputmethod/latin/RichInputConnection.java | 8 ++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'java/src/com/android/inputmethod/latin/RichInputConnection.java') diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 91faf4802..0f883245f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -910,6 +910,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen false /* shouldFinishComposition */)) { // We try resetting the caches up to 5 times before giving up. mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */); + // mLastSelection{Start,End} are reset later in this method, don't need to do it here canReachInputConnection = false; } else { if (isDifferentTextField) { @@ -989,10 +990,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (textLength > mLastSelectionStart || (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE && mLastSelectionStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) { + // It should not be possible to have only one of those variables be + // NOT_A_CURSOR_POSITION, so if they are equal, either the selection is zero-sized + // (simple cursor, no selection) or there is no cursor/we don't know its pos + final boolean wasEqual = mLastSelectionStart == mLastSelectionEnd; mLastSelectionStart = textLength; // We can't figure out the value of mLastSelectionEnd :( - // But at least if it's smaller than mLastSelectionStart something is wrong - if (mLastSelectionStart > mLastSelectionEnd) { + // But at least if it's smaller than mLastSelectionStart something is wrong, + // and if they used to be equal we also don't want to make it look like there is a + // selection. + if (wasEqual || mLastSelectionStart > mLastSelectionEnd) { mLastSelectionEnd = mLastSelectionStart; } } diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index c212f9c81..673d1b4c2 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -61,7 +61,7 @@ public final class RichInputConnection { * cursor may end up after all the keyboard-triggered updates have passed. We keep this to * compare it to the actual cursor position to guess whether the move was caused by a * keyboard command or not. - * It's not really the cursor position: the cursor may not be there yet, and it's also expected + * It's not really the cursor position: the cursor may not be there yet, and it's also expected * there be cases where it never actually comes to be there. */ private int mExpectedCursorPosition = INVALID_CURSOR_POSITION; // in chars, not code points @@ -292,7 +292,11 @@ public final class RichInputConnection { mCommittedTextBeforeComposingText.length() + mComposingText.length(); // If we have enough characters to satisfy the request, or if we have all characters in // the text field, then we can return the cached version right away. - if (cachedLength >= n || cachedLength >= mExpectedCursorPosition) { + // However, if we don't have an expected cursor position, then we should always + // go fetch the cache again (as it happens, INVALID_CURSOR_POSITION < 0, so we need to + // test for this explicitly) + if (INVALID_CURSOR_POSITION != mExpectedCursorPosition + && (cachedLength >= n || cachedLength >= mExpectedCursorPosition)) { final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText); // We call #toString() here to create a temporary object. // In some situations, this method is called on a worker thread, and it's possible -- cgit v1.2.3-83-g751a