am a2cb2f36: Make the typed word a SuggestedWordInfo

* commit 'a2cb2f36a6b51f73602bd7e917c418657da0c973':
  Make the typed word a SuggestedWordInfo
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index db67e34..6411010 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1638,7 +1638,7 @@
         // 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 ee8d3f8..4df1d65 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -133,11 +133,12 @@
             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 @@
             }
         }
 
-        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<SuggestedWordInfo> suggestionsList;
         if (DBG && !suggestionsContainer.isEmpty()) {
-            suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestionsContainer);
+            suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWordString,
+                    suggestionsContainer);
         } else {
             suggestionsList = suggestionsContainer;
         }
@@ -230,7 +233,7 @@
             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 @@
         // (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 02b2d56..49153d2 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.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 @@
             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 @@
     // INPUT_STYLE_* constants above.
     public final int mInputStyle;
     public final int mSequenceNumber; // Sequence number for auto-commit.
+    @Nonnull
     protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
+    @Nullable
     public final ArrayList<SuggestedWordInfo> mRawSuggestions;
 
-    public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
-            final ArrayList<SuggestedWordInfo> rawSuggestions,
-            final String typedWord,
+    public SuggestedWords(@Nonnull final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
+            @Nullable final ArrayList<SuggestedWordInfo> rawSuggestions,
+            @Nullable final SuggestedWordInfo typedWordInfo,
             final boolean typedWordValid,
             final boolean willAutoCorrect,
             final boolean isObsoleteSuggestions,
@@ -83,7 +87,7 @@
         mIsObsoleteSuggestions = isObsoleteSuggestions;
         mInputStyle = inputStyle;
         mSequenceNumber = sequenceNumber;
-        mTypedWord = typedWord;
+        mTypedWordInfo = typedWordInfo;
     }
 
     public boolean isEmpty() {
@@ -199,14 +203,12 @@
     // 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<SuggestedWordInfo> getTypedWordAndPreviousSuggestions(
-            final String typedWord, final SuggestedWords previousSuggestions) {
+            @Nonnull final SuggestedWordInfo typedWordInfo,
+            @Nonnull final SuggestedWords previousSuggestions) {
         final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>();
         final HashSet<String> 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 @@
                     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 bca2464..0185a04 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 @@
             } 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 @@
                 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 @@
         final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor();
         if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return;
         final ArrayList<SuggestedWordInfo> 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 @@
         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 @@
                 }
             }
         }
-        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 @@
             // 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 @@
      * 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<SuggestedWords.SuggestedWordInfo> 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 7a7edf0..f658d72 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -89,9 +89,10 @@
 
     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<SuggestedWordInfo> 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 @@
         // 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 */,