diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index db67e3412..6411010e6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1638,7 +1638,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Cache the auto-correction in accessibility code so we can speak it if the user // touches a key that will insert it. AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, - suggestedWords.mTypedWord); + suggestedWords.mTypedWordInfo.mWord); } // Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener} diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index ee8d3f8cb..4df1d6505 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -133,11 +133,12 @@ public final class Suggest { final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { - final String typedWord = wordComposer.getTypedWord(); - final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWord); + final String typedWordString = wordComposer.getTypedWord(); + final int trailingSingleQuotesCount = + StringUtils.getTrailingSingleQuotesCount(typedWordString); final String consideredWord = trailingSingleQuotesCount > 0 - ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount) - : typedWord; + ? typedWordString.substring(0, typedWordString.length() - trailingSingleQuotesCount) + : typedWordString; final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(), @@ -206,17 +207,19 @@ public final class Suggest { } } - if (!TextUtils.isEmpty(typedWord)) { - suggestionsContainer.add(0, new SuggestedWordInfo(typedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, - Dictionary.DICTIONARY_USER_TYPED, - SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, - SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); + final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, + Dictionary.DICTIONARY_USER_TYPED, + SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, + SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); + if (!TextUtils.isEmpty(typedWordString)) { + suggestionsContainer.add(0, typedWordInfo); } final ArrayList suggestionsList; if (DBG && !suggestionsContainer.isEmpty()) { - suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestionsContainer); + suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWordString, + suggestionsContainer); } else { suggestionsList = suggestionsContainer; } @@ -230,7 +233,7 @@ public final class Suggest { inputStyle = inputStyleIfNotPrediction; } callback.onGetSuggestedWords(new SuggestedWords(suggestionsList, - suggestionResults.mRawSuggestions, typedWord, + suggestionResults.mRawSuggestions, typedWordInfo, // TODO: this first argument is lying. If this is a whitelisted word which is an // actual word, it says typedWordValid = false, which looks wrong. We should either // rename the attribute or change the value. @@ -286,12 +289,12 @@ public final class Suggest { // (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false). // Note that because this method is never used to get predictions, there is no need to // modify inputType such in getSuggestedWordsForNonBatchInput. - final String pseudoTypedWord = suggestionsContainer.isEmpty() ? null - : suggestionsContainer.get(0).mWord; + final SuggestedWordInfo pseudoTypedWordInfo = suggestionsContainer.isEmpty() ? null + : suggestionsContainer.get(0); callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer, suggestionResults.mRawSuggestions, - pseudoTypedWord, + pseudoTypedWordInfo, true /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */, diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 02b2d56e7..49153d261 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.HashSet; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class SuggestedWords { public static final int INDEX_OF_TYPED_WORD = 0; @@ -54,7 +55,8 @@ public class SuggestedWords { false /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */, INPUT_STYLE_NONE, NOT_A_SEQUENCE_NUMBER); - public final String mTypedWord; + @Nullable + public final SuggestedWordInfo mTypedWordInfo; public final boolean mTypedWordValid; // Note: this INCLUDES cases where the word will auto-correct to itself. A good definition // of what this flag means would be "the top suggestion is strong enough to auto-correct", @@ -65,12 +67,14 @@ public class SuggestedWords { // INPUT_STYLE_* constants above. public final int mInputStyle; public final int mSequenceNumber; // Sequence number for auto-commit. + @Nonnull protected final ArrayList mSuggestedWordInfoList; + @Nullable public final ArrayList mRawSuggestions; - public SuggestedWords(final ArrayList suggestedWordInfoList, - final ArrayList rawSuggestions, - final String typedWord, + public SuggestedWords(@Nonnull final ArrayList suggestedWordInfoList, + @Nullable final ArrayList rawSuggestions, + @Nullable final SuggestedWordInfo typedWordInfo, final boolean typedWordValid, final boolean willAutoCorrect, final boolean isObsoleteSuggestions, @@ -83,7 +87,7 @@ public class SuggestedWords { mIsObsoleteSuggestions = isObsoleteSuggestions; mInputStyle = inputStyle; mSequenceNumber = sequenceNumber; - mTypedWord = typedWord; + mTypedWordInfo = typedWordInfo; } public boolean isEmpty() { @@ -199,14 +203,12 @@ public class SuggestedWords { // Should get rid of the first one (what the user typed previously) from suggestions // and replace it with what the user currently typed. public static ArrayList getTypedWordAndPreviousSuggestions( - final String typedWord, final SuggestedWords previousSuggestions) { + @Nonnull final SuggestedWordInfo typedWordInfo, + @Nonnull final SuggestedWords previousSuggestions) { final ArrayList suggestionsList = new ArrayList<>(); final HashSet alreadySeen = new HashSet<>(); - suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, - SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, - SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); - alreadySeen.add(typedWord.toString()); + suggestionsList.add(typedWordInfo); + alreadySeen.add(typedWordInfo.mWord); final int previousSize = previousSuggestions.size(); for (int index = 1; index < previousSize; index++) { final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(index); @@ -412,7 +414,7 @@ public class SuggestedWords { SuggestedWordInfo.NOT_A_CONFIDENCE)); } return new SuggestedWords(newSuggestions, null /* rawSuggestions */, - newSuggestions.isEmpty() ? null : newSuggestions.get(0).mWord /* typedWord */, + newSuggestions.isEmpty() ? null : newSuggestions.get(0) /* typedWordInfo */, mTypedWordValid, mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH, NOT_A_SEQUENCE_NUMBER); } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index bca2464fb..0185a04ef 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -623,11 +623,7 @@ public final class InputLogic { } else { // We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD) // because it may differ from mWordComposer.mTypedWord. - suggestedWordInfo = new SuggestedWordInfo(suggestedWords.mTypedWord, - SuggestedWordInfo.MAX_SCORE, - SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, - SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, - SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); + suggestedWordInfo = suggestedWords.mTypedWordInfo; } mWordComposer.setAutoCorrection(suggestedWordInfo); } @@ -1414,14 +1410,19 @@ public final class InputLogic { new OnGetSuggestedWordsCallback() { @Override public void onGetSuggestedWords(final SuggestedWords suggestedWords) { - final String typedWord = mWordComposer.getTypedWord(); + final String typedWordString = mWordComposer.getTypedWord(); + final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo( + typedWordString, SuggestedWordInfo.MAX_SCORE, + SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, + SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, + SuggestedWordInfo.NOT_A_CONFIDENCE); // Show new suggestions if we have at least one. Otherwise keep the old // suggestions with the new typed word. Exception: if the length of the // typed word is <= 1 (after a deletion typically) we clear old suggestions. - if (suggestedWords.size() > 1 || typedWord.length() <= 1) { + if (suggestedWords.size() > 1 || typedWordString.length() <= 1) { holder.set(suggestedWords); } else { - holder.set(retrieveOlderSuggestions(typedWord, mSuggestedWords)); + holder.set(retrieveOlderSuggestions(typedWordInfo, mSuggestedWords)); } } } @@ -1493,13 +1494,14 @@ public final class InputLogic { final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return; final ArrayList suggestions = new ArrayList<>(); - final String typedWord = range.mWord.toString(); - suggestions.add(new SuggestedWordInfo(typedWord, + final String typedWordString = range.mWord.toString(); + final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, SuggestedWords.MAX_SUGGESTIONS + 1, SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, - SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); - if (!isResumableWord(settingsValues, typedWord)) { + SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); + suggestions.add(typedWordInfo); + if (!isResumableWord(settingsValues, typedWordString)) { mSuggestionStripViewAccessor.setNeutralSuggestionStrip(); return; } @@ -1507,7 +1509,7 @@ public final class InputLogic { for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) { for (final String s : span.getSuggestions()) { ++i; - if (!TextUtils.equals(s, typedWord)) { + if (!TextUtils.equals(s, typedWordString)) { suggestions.add(new SuggestedWordInfo(s, SuggestedWords.MAX_SUGGESTIONS - i, SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED, @@ -1517,11 +1519,11 @@ public final class InputLogic { } } } - final int[] codePoints = StringUtils.toCodePointArray(typedWord); + final int[] codePoints = StringUtils.toCodePointArray(typedWordString); mWordComposer.setComposingWord(codePoints, mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); mWordComposer.setCursorPositionWithinWord( - typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor)); + typedWordString.codePointCount(0, numberOfCharsInWordBeforeCursor)); if (forStartInput) { mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug(); } @@ -1543,7 +1545,7 @@ public final class InputLogic { // color of the word in the suggestion strip changes according to this parameter, // and false gives the correct color. final SuggestedWords suggestedWords = new SuggestedWords(suggestions, - null /* rawSuggestions */, typedWord, false /* typedWordValid */, + null /* rawSuggestions */, typedWordInfo, false /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */, SuggestedWords.INPUT_STYLE_RECORRECTION, SuggestedWords.NOT_A_SEQUENCE_NUMBER); doShowSuggestionsAndClearAutoCorrectionIndicator(suggestedWords); @@ -1876,19 +1878,19 @@ public final class InputLogic { * Make a {@link com.android.inputmethod.latin.SuggestedWords} object containing a typed word * and obsolete suggestions. * See {@link com.android.inputmethod.latin.SuggestedWords#getTypedWordAndPreviousSuggestions( - * String, com.android.inputmethod.latin.SuggestedWords)}. - * @param typedWord The typed word as a string. + * SuggestedWordInfo, com.android.inputmethod.latin.SuggestedWords)}. + * @param typedWordInfo The typed word as a SuggestedWordInfo. * @param previousSuggestedWords The previously suggested words. * @return Obsolete suggestions with the newly typed word. */ - static SuggestedWords retrieveOlderSuggestions(final String typedWord, + static SuggestedWords retrieveOlderSuggestions(final SuggestedWordInfo typedWordInfo, final SuggestedWords previousSuggestedWords) { final SuggestedWords oldSuggestedWords = previousSuggestedWords.isPunctuationSuggestions() ? SuggestedWords.getEmptyInstance() : previousSuggestedWords; final ArrayList typedWordAndPreviousSuggestions = - SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords); + SuggestedWords.getTypedWordAndPreviousSuggestions(typedWordInfo, oldSuggestedWords); return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */, - typedWord, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, + typedWordInfo, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */, true /* isObsoleteSuggestions */, oldSuggestedWords.mInputStyle, SuggestedWords.NOT_A_SEQUENCE_NUMBER); } diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java index 7a7edf031..f658d726b 100644 --- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java +++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java @@ -89,9 +89,10 @@ public class SuggestedWordsTests extends AndroidTestCase { public void testGetTypedWordInfoOrNull() { final String TYPED_WORD = "typed"; + final SuggestedWordInfo TYPED_WORD_INFO = createTypedWordInfo(TYPED_WORD); final int NUMBER_OF_ADDED_SUGGESTIONS = 5; final ArrayList list = new ArrayList<>(); - list.add(createTypedWordInfo(TYPED_WORD)); + list.add(TYPED_WORD_INFO); for (int i = 0; i < NUMBER_OF_ADDED_SUGGESTIONS; ++i) { list.add(createCorrectionWordInfo(Integer.toString(i))); } @@ -99,7 +100,7 @@ public class SuggestedWordsTests extends AndroidTestCase { // Make sure getTypedWordInfoOrNull() returns non-null object. final SuggestedWords wordsWithTypedWord = new SuggestedWords( list, null /* rawSuggestions */, - TYPED_WORD, + TYPED_WORD_INFO, false /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */,