Remember the source dictionary for each suggestion.

Change-Id: I3c63372bd5572a479a67eaecfe8c8ea1cabc70d9
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 8d5bc15..e4ffa75 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -137,7 +137,7 @@
             if (len > 0) {
                 suggestions.add(new SuggestedWordInfo(
                         new String(mOutputChars_bigrams, start, len),
-                        mBigramScores[j], SuggestedWordInfo.KIND_CORRECTION));
+                        mBigramScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType));
             }
         }
         return suggestions;
@@ -162,7 +162,7 @@
                 // TODO: actually get the kind from native code
                 suggestions.add(new SuggestedWordInfo(
                         new String(mOutputChars, start, len),
-                        mScores[j], SuggestedWordInfo.KIND_CORRECTION));
+                        mScores[j], SuggestedWordInfo.KIND_CORRECTION, mDictType));
             }
         }
         return suggestions;
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 0a853c4..0835450 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -34,6 +34,8 @@
     public static final int NOT_A_PROBABILITY = -1;
 
     public static final String TYPE_USER_TYPED = "user_typed";
+    public static final String TYPE_APPLICATION_DEFINED = "application_defined";
+    public static final String TYPE_HARDCODED = "hardcoded"; // punctuation signs and such
     public static final String TYPE_MAIN = "main";
     public static final String TYPE_CONTACTS = "contacts";
     // User dictionary, the system-managed one.
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index e86a657..cfecc66 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -382,7 +382,7 @@
             // the respective size of the typed word and the suggestion if it matters sometime
             // in the future.
             suggestions.add(new SuggestedWordInfo(new String(word, 0, depth + 1), finalFreq,
-                    SuggestedWordInfo.KIND_CORRECTION));
+                    SuggestedWordInfo.KIND_CORRECTION, mDictType));
             if (suggestions.size() >= Suggest.MAX_SUGGESTIONS) return false;
         }
         if (null != node.mShortcutTargets) {
@@ -390,7 +390,7 @@
             for (int shortcutIndex = 0; shortcutIndex < length; ++shortcutIndex) {
                 final char[] shortcut = node.mShortcutTargets.get(shortcutIndex);
                 suggestions.add(new SuggestedWordInfo(new String(shortcut, 0, shortcut.length),
-                        finalFreq, SuggestedWordInfo.KIND_SHORTCUT));
+                        finalFreq, SuggestedWordInfo.KIND_SHORTCUT, mDictType));
                 if (suggestions.size() > Suggest.MAX_SUGGESTIONS) return false;
             }
         }
@@ -665,7 +665,7 @@
             if (freq >= 0) {
                 suggestions.add(new SuggestedWordInfo(new String(mLookedUpString, index,
                         BinaryDictionary.MAX_WORD_LENGTH - index),
-                        freq, SuggestedWordInfo.KIND_CORRECTION));
+                        freq, SuggestedWordInfo.KIND_CORRECTION, mDictType));
             }
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index ef423f1..2cc9b8c 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -179,7 +179,8 @@
         if (puncs != null) {
             for (final String puncSpec : puncs) {
                 puncList.add(new SuggestedWordInfo(KeySpecParser.getLabel(puncSpec),
-                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED));
+                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_HARDCODED,
+                        Dictionary.TYPE_HARDCODED));
             }
         }
         return new SuggestedWords(puncList,
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 9f3df05..93e6d66 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -201,7 +201,6 @@
         final String consideredWord = mTrailingSingleQuotesCount > 0
                 ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount)
                 : typedWord;
-        // Treating USER_TYPED as UNIGRAM suggestion for logging now.
         LatinImeLogger.onAddSuggestedWord(typedWord, Dictionary.TYPE_USER_TYPED);
 
         if (wordComposer.size() <= 1 && isCorrectionEnabled) {
@@ -272,16 +271,19 @@
                     sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
                 }
                 suggestionsContainer.add(0, new SuggestedWordInfo(sb.toString(),
-                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST));
+                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST,
+                        Dictionary.TYPE_WHITELIST));
             } else {
                 suggestionsContainer.add(0, new SuggestedWordInfo(whitelistedWord,
-                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST));
+                        SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST,
+                        Dictionary.TYPE_WHITELIST));
             }
         }
 
         if (!isPrediction) {
             suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
-                    SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED));
+                    SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
+                    Dictionary.TYPE_USER_TYPED));
         }
         SuggestedWordInfo.removeDups(suggestionsContainer);
 
@@ -403,7 +405,7 @@
         for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
             sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
         }
-        return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind);
+        return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind, wordInfo.mSourceDict);
     }
 
     public void close() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 9883cd6..f6926f3 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -92,7 +92,7 @@
         for (CompletionInfo info : infos) {
             if (null != info && info.getText() != null) {
                 result.add(new SuggestedWordInfo(info.getText(), SuggestedWordInfo.MAX_SCORE,
-                        SuggestedWordInfo.KIND_APP_DEFINED));
+                        SuggestedWordInfo.KIND_APP_DEFINED, Dictionary.TYPE_APPLICATION_DEFINED));
             }
         }
         return result;
@@ -105,7 +105,7 @@
         final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<SuggestedWordInfo>();
         final HashSet<String> alreadySeen = new HashSet<String>();
         suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE,
-                SuggestedWordInfo.KIND_TYPED));
+                SuggestedWordInfo.KIND_TYPED, Dictionary.TYPE_USER_TYPED));
         alreadySeen.add(typedWord.toString());
         final int previousSize = previousSuggestions.size();
         for (int pos = 1; pos < previousSize; pos++) {
@@ -135,13 +135,16 @@
         public final int mScore;
         public final int mKind; // one of the KIND_* constants above
         public final int mCodePointCount;
+        public final String mSourceDict;
         private String mDebugString = "";
 
-        public SuggestedWordInfo(final CharSequence word, final int score, final int kind) {
+        public SuggestedWordInfo(final CharSequence word, final int score, final int kind,
+                final String sourceDict) {
             mWordStr = word.toString();
             mWord = word;
             mScore = score;
             mKind = kind;
+            mSourceDict = sourceDict;
             mCodePointCount = StringUtils.codePointCount(mWordStr);
         }