Skip to content
Snippets Groups Projects
Commit c3ebf1a4 authored by Jean Chalard's avatar Jean Chalard
Browse files

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
parent 223b8b44
No related branches found
No related tags found
No related merge requests found
...@@ -340,13 +340,6 @@ public class RichInputConnection { ...@@ -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 * Returns the word before the cursor if the cursor is at the end of a word, null otherwise
*/ */
public CharSequence getWordBeforeCursorIfAtEndOfWord(final SettingsValues settings) { 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) : <SOL>"|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, // Bail out if the cursor is in the middle of a word (cursor must be followed by whitespace,
// separator or end of line/text) // separator or end of line/text)
// Example: "test|"<EOL> "te|st" get rejected here // Example: "test|"<EOL> "te|st" get rejected here
...@@ -363,6 +356,15 @@ public class RichInputConnection { ...@@ -363,6 +356,15 @@ public class RichInputConnection {
word = word.subSequence(1, word.length()); word = word.subSequence(1, word.length());
} }
if (TextUtils.isEmpty(word)) return null; 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) : <SOL>"|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 final char firstChar = word.charAt(0); // we just tested that word is not empty
if (word.length() == 1 && !Character.isLetter(firstChar)) return null; if (word.length() == 1 && !Character.isLetter(firstChar)) return null;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment