From c3ebf1a43a6202c9992773722ff1eed7088b9a91 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Mon, 25 Jun 2012 15:58:53 +0900 Subject: Refactoring and groundwork to fix a bug with older apps This has a good, although small, impact on performance : it removes a two-way IPC call in a most frequent case, while possibly adding one in a rather unfrequent and less critical case. Also, this fixes a bug with surrogate pairs. This specific branch of code now correctly handles surrogate pairs. Aside from this, it should have no impact on behavior. However, since it does delay access to the previous character in the text view by a two-way IPC call, it actually goes a long way toward fixing bug#6668226. It is not really a fix and the race condition still exists, but this change makes it much, much harder to hit. Bug: 6668226 Change-Id: Id11cc6a0b7488d6bd392227cafdcf3a8d4c62f6c --- .../android/inputmethod/latin/RichInputConnection.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (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 0c19bed05..40d327ebb 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -340,13 +340,6 @@ public class RichInputConnection { * Returns the word before the cursor if the cursor is at the end of a word, null otherwise */ public CharSequence getWordBeforeCursorIfAtEndOfWord(final SettingsValues settings) { - // Bail out if the cursor is not at the end of a word (cursor must be preceded by - // non-whitespace, non-separator, non-start-of-text) - // Example ("|" is the cursor here) : "|a" " |a" " | " all get rejected here. - final CharSequence textBeforeCursor = getTextBeforeCursor(1, 0); - if (TextUtils.isEmpty(textBeforeCursor) - || settings.isWordSeparator(textBeforeCursor.charAt(0))) return null; - // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace, // separator or end of line/text) // Example: "test|" "te|st" get rejected here @@ -363,6 +356,15 @@ public class RichInputConnection { word = word.subSequence(1, word.length()); } if (TextUtils.isEmpty(word)) return null; + // Find the last code point of the string + final int lastCodePoint = Character.codePointBefore(word, word.length()); + // If for some reason the text field contains non-unicode binary data, or if the + // charsequence is exactly one char long and the contents is a low surrogate, return null. + if (!Character.isDefined(lastCodePoint)) return null; + // Bail out if the cursor is not at the end of a word (cursor must be preceded by + // non-whitespace, non-separator, non-start-of-text) + // Example ("|" is the cursor here) : "|a" " |a" " | " all get rejected here. + if (settings.isWordSeparator(lastCodePoint)) return null; final char firstChar = word.charAt(0); // we just tested that word is not empty if (word.length() == 1 && !Character.isLetter(firstChar)) return null; -- cgit v1.2.3-83-g751a