diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java index f45c73f53..db877ab7a 100644 --- a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java +++ b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java @@ -16,10 +16,12 @@ package com.android.inputmethod.latin; -import java.util.Arrays; +import android.text.TextUtils; import com.android.inputmethod.latin.utils.StringUtils; +import java.util.Arrays; + /** * Class to represent information of previous words. This class is used to add n-gram entries * into binary dictionaries, to get predictions, and to get suggestions. @@ -37,8 +39,8 @@ public class PrevWordsInfo { public static final WordInfo EMPTY_WORD_INFO = new WordInfo(null); public static final WordInfo BEGINNING_OF_SENTENCE = new WordInfo(); - // This is an empty string when mIsBeginningOfSentence is true. - public final String mWord; + // This is an empty char sequence when mIsBeginningOfSentence is true. + public final CharSequence mWord; // TODO: Have sentence separator. // Whether the current context is beginning of sentence or not. This is true when composing // at the beginning of an input field or composing a word after a sentence separator. @@ -50,7 +52,7 @@ public class PrevWordsInfo { mIsBeginningOfSentence = true; } - public WordInfo(final String word) { + public WordInfo(final CharSequence word) { mWord = word; mIsBeginningOfSentence = false; } @@ -73,7 +75,7 @@ public class PrevWordsInfo { return mWord == wordInfo.mWord && mIsBeginningOfSentence == wordInfo.mIsBeginningOfSentence; } - return mWord.equals(wordInfo.mWord) + return TextUtils.equals(mWord, wordInfo.mWord) && mIsBeginningOfSentence == wordInfo.mIsBeginningOfSentence; } } diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index a98b0f156..8e027e4f9 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; +import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Constants; @@ -60,7 +61,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, final PrevWordsInfo prevWordsInfo, final String word, final boolean isValid, final int timestamp, final DistracterFilter distracterFilter) { - final String prevWord = prevWordsInfo.mPrevWordsInfo[0].mWord; + final CharSequence prevWord = prevWordsInfo.mPrevWordsInfo[0].mWord; if (word.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH || (prevWord != null && prevWord.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) { return; @@ -71,7 +72,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp, distracterFilter); // Do not insert a word as a bigram of itself - if (word.equals(prevWord)) { + if (TextUtils.equals(word, prevWord)) { return; } if (null != prevWord) { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java index 38d720664..14ab2dbbf 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java @@ -24,7 +24,9 @@ import android.view.textservice.SentenceSuggestionsInfo; import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; +import com.android.inputmethod.compat.TextInfoCompatUtils; import com.android.inputmethod.latin.PrevWordsInfo; +import com.android.inputmethod.latin.utils.StringUtils; import java.util.ArrayList; import java.util.Locale; @@ -42,15 +44,15 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti, SentenceSuggestionsInfo ssi) { - final String typedText = ti.getText(); - if (!typedText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { + final CharSequence typedText = TextInfoCompatUtils.getCharSequenceOrString(ti); + if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { return null; } final int N = ssi.getSuggestionsCount(); final ArrayList additionalOffsets = new ArrayList<>(); final ArrayList additionalLengths = new ArrayList<>(); final ArrayList additionalSuggestionsInfos = new ArrayList<>(); - String currentWord = null; + CharSequence currentWord = null; for (int i = 0; i < N; ++i) { final SuggestionsInfo si = ssi.getSuggestionsInfoAt(i); final int flags = si.getSuggestionsAttributes(); @@ -59,32 +61,33 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck } final int offset = ssi.getOffsetAt(i); final int length = ssi.getLengthAt(i); - final String subText = typedText.substring(offset, offset + length); + final CharSequence subText = typedText.subSequence(offset, offset + length); final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(new PrevWordsInfo.WordInfo(currentWord)); currentWord = subText; - if (!subText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { + if (!subText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { continue; } - final String[] splitTexts = - subText.split(AndroidSpellCheckerService.SINGLE_QUOTE, -1); + final CharSequence[] splitTexts = StringUtils.split(subText, + AndroidSpellCheckerService.SINGLE_QUOTE, + true /* preserveTrailingEmptySegments */ ); if (splitTexts == null || splitTexts.length <= 1) { continue; } final int splitNum = splitTexts.length; for (int j = 0; j < splitNum; ++j) { - final String splitText = splitTexts[j]; + final CharSequence splitText = splitTexts[j]; if (TextUtils.isEmpty(splitText)) { continue; } - if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWordsInfo) == null) { + if (mSuggestionsCache.getSuggestionsFromCache(splitText.toString(), prevWordsInfo) + == null) { continue; } final int newLength = splitText.length(); // Neither RESULT_ATTR_IN_THE_DICTIONARY nor RESULT_ATTR_LOOKS_LIKE_TYPO final int newFlags = 0; - final SuggestionsInfo newSi = - new SuggestionsInfo(newFlags, EMPTY_STRING_ARRAY); + final SuggestionsInfo newSi = new SuggestionsInfo(newFlags, EMPTY_STRING_ARRAY); newSi.setCookieAndSequence(si.getCookie(), si.getSequence()); if (DBG) { Log.d(TAG, "Override and remove old span over: " + splitText + ", " @@ -194,20 +197,22 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck final int length = textInfos.length; final SuggestionsInfo[] retval = new SuggestionsInfo[length]; for (int i = 0; i < length; ++i) { - final String prevWord; + final CharSequence prevWord; if (sequentialWords && i > 0) { - final String prevWordCandidate = textInfos[i - 1].getText(); - // Note that an empty string would be used to indicate the initial word - // in the future. - prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate; + final TextInfo prevTextInfo = textInfos[i - 1]; + final CharSequence prevWordCandidate = + TextInfoCompatUtils.getCharSequenceOrString(prevTextInfo); + // Note that an empty string would be used to indicate the initial word + // in the future. + prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate; } else { prevWord = null; } final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(new PrevWordsInfo.WordInfo(prevWord)); - retval[i] = onGetSuggestionsInternal(textInfos[i], prevWordsInfo, suggestionsLimit); - retval[i].setCookieAndSequence(textInfos[i].getCookie(), - textInfos[i].getSequence()); + final TextInfo textInfo = textInfos[i]; + retval[i] = onGetSuggestionsInternal(textInfo, prevWordsInfo, suggestionsLimit); + retval[i].setCookieAndSequence(textInfo.getCookie(), textInfo.getSequence()); } return retval; } finally { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java index 13352f39e..ae582ea25 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java @@ -21,6 +21,7 @@ import android.view.textservice.SentenceSuggestionsInfo; import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; +import com.android.inputmethod.compat.TextInfoCompatUtils; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.RunInLocale; @@ -127,7 +128,8 @@ public class SentenceLevelAdapter { public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) { final WordIterator wordIterator = mWordIterator; - final CharSequence originalText = originalTextInfo.getText(); + final CharSequence originalText = + TextInfoCompatUtils.getCharSequenceOrString(originalTextInfo); final int cookie = originalTextInfo.getCookie(); final int start = -1; final int end = originalText.length(); @@ -136,8 +138,9 @@ public class SentenceLevelAdapter { int wordEnd = wordIterator.getEndOfWord(originalText, wordStart); while (wordStart <= end && wordEnd != -1 && wordStart != -1) { if (wordEnd >= start && wordEnd > wordStart) { - final String query = originalText.subSequence(wordStart, wordEnd).toString(); - final TextInfo ti = new TextInfo(query, cookie, query.hashCode()); + CharSequence subSequence = originalText.subSequence(wordStart, wordEnd).toString(); + final TextInfo ti = TextInfoCompatUtils.newInstance(subSequence, 0, + subSequence.length(), cookie, subSequence.hashCode()); wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd)); } wordStart = wordIterator.getBeginningOfNextWord(originalText, wordEnd); diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java index 9ec19efa8..fbce3f2fd 100644 --- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java +++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java @@ -43,7 +43,7 @@ public final class LanguageModelParam { private static final int BIGRAM_PROBABILITY_FOR_VALID_WORD = 10; private static final int BIGRAM_PROBABILITY_FOR_OOV_WORD = Dictionary.NOT_A_PROBABILITY; - public final String mTargetWord; + public final CharSequence mTargetWord; public final int[] mWord0; public final int[] mWord1; // TODO: this needs to be a list of shortcuts @@ -57,13 +57,13 @@ public final class LanguageModelParam { public final int mTimestamp; // Constructor for unigram. TODO: support shortcuts - public LanguageModelParam(final String word, final int unigramProbability, + public LanguageModelParam(final CharSequence word, final int unigramProbability, final int timestamp) { this(null /* word0 */, word, unigramProbability, Dictionary.NOT_A_PROBABILITY, timestamp); } // Constructor for unigram and bigram. - public LanguageModelParam(final String word0, final String word1, + public LanguageModelParam(final CharSequence word0, final CharSequence word1, final int unigramProbability, final int bigramProbability, final int timestamp) { mTargetWord = word1;