[ML3] Put the locale in SuggestedWordInfo

...and remove it from SuggestionResults.

Change-Id: Iae85ec7e82e2caf18cc6d7656aa46dc150707cdd
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 693e1cd..2e10875 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -83,7 +83,6 @@
     public static final String DIR_NAME_SUFFIX_FOR_RECORD_MIGRATION = ".migrating";
 
     private long mNativeDict;
-    private final Locale mLocale;
     private final long mDictSize;
     private final String mDictFilePath;
     private final boolean mUseFullEditDistance;
@@ -117,8 +116,7 @@
     public BinaryDictionary(final String filename, final long offset, final long length,
             final boolean useFullEditDistance, final Locale locale, final String dictType,
             final boolean isUpdatable) {
-        super(dictType);
-        mLocale = locale;
+        super(dictType, locale);
         mDictSize = length;
         mDictFilePath = filename;
         mIsUpdatable = isUpdatable;
@@ -138,8 +136,7 @@
     public BinaryDictionary(final String filename, final boolean useFullEditDistance,
             final Locale locale, final String dictType, final long formatVersion,
             final Map<String, String> attributeMap) {
-        super(dictType);
-        mLocale = locale;
+        super(dictType, locale);
         mDictSize = 0;
         mDictFilePath = filename;
         // On memory dictionary is always updatable.
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 560ced9..2f79c76 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -16,12 +16,12 @@
 
 package com.android.inputmethod.latin;
 
-import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.ProximityInfo;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
 import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
 
 import java.util.ArrayList;
+import java.util.Locale;
 
 /**
  * Abstract base class for a dictionary that can do a fuzzy search for words based on a set of key
@@ -62,9 +62,12 @@
     // Contextual dictionary.
     public static final String TYPE_CONTEXTUAL = "contextual";
     public final String mDictType;
+    // The locale for this dictionary. May be null if unknown (phony dictionary for example).
+    public final Locale mLocale;
 
-    public Dictionary(final String dictType) {
+    public Dictionary(final String dictType, final Locale locale) {
         mDictType = dictType;
+        mLocale = locale;
     }
 
     /**
@@ -162,7 +165,7 @@
     private static class PhonyDictionary extends Dictionary {
         // This class is not publicly instantiable.
         private PhonyDictionary(final String type) {
-            super(type);
+            super(type, null);
         }
 
         @Override
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 2b4c54d..ca5e937 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -25,6 +25,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Locale;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -34,13 +35,14 @@
     private final String TAG = DictionaryCollection.class.getSimpleName();
     protected final CopyOnWriteArrayList<Dictionary> mDictionaries;
 
-    public DictionaryCollection(final String dictType) {
-        super(dictType);
+    public DictionaryCollection(final String dictType, final Locale locale) {
+        super(dictType, locale);
         mDictionaries = new CopyOnWriteArrayList<>();
     }
 
-    public DictionaryCollection(final String dictType, final Dictionary... dictionaries) {
-        super(dictType);
+    public DictionaryCollection(final String dictType, final Locale locale,
+            final Dictionary... dictionaries) {
+        super(dictType, locale);
         if (null == dictionaries) {
             mDictionaries = new CopyOnWriteArrayList<>();
         } else {
@@ -49,8 +51,9 @@
         }
     }
 
-    public DictionaryCollection(final String dictType, final Collection<Dictionary> dictionaries) {
-        super(dictType);
+    public DictionaryCollection(final String dictType, final Locale locale,
+            final Collection<Dictionary> dictionaries) {
+        super(dictType, locale);
         mDictionaries = new CopyOnWriteArrayList<>(dictionaries);
         mDictionaries.removeAll(Collections.singleton(null));
     }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index fe395a8..480bd1f 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -503,7 +503,7 @@
             final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
         final Dictionaries dictionaries = mDictionaries;
         final SuggestionResults suggestionResults =
-                new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS);
+                new SuggestionResults(SuggestedWords.MAX_SUGGESTIONS);
         final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT };
         for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
             final Dictionary dictionary = dictionaries.getDict(dictType);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 59de4f8..3459b42 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -50,7 +50,7 @@
             final Locale locale, final boolean useFullEditDistance) {
         if (null == locale) {
             Log.e(TAG, "No locale defined for dictionary");
-            return new DictionaryCollection(Dictionary.TYPE_MAIN,
+            return new DictionaryCollection(Dictionary.TYPE_MAIN, locale,
                     createReadOnlyBinaryDictionary(context, locale));
         }
 
@@ -75,7 +75,7 @@
         // If the list is empty, that means we should not use any dictionary (for example, the user
         // explicitly disabled the main dictionary), so the following is okay. dictList is never
         // null, but if for some reason it is, DictionaryCollection handles it gracefully.
-        return new DictionaryCollection(Dictionary.TYPE_MAIN, dictList);
+        return new DictionaryCollection(Dictionary.TYPE_MAIN, locale, dictList);
     }
 
     /**
@@ -188,7 +188,7 @@
     public static Dictionary createDictionaryForTest(final AssetFileAddress[] dictionaryList,
             final boolean useFullEditDistance, Locale locale) {
         final DictionaryCollection dictionaryCollection =
-                new DictionaryCollection(Dictionary.TYPE_MAIN);
+                new DictionaryCollection(Dictionary.TYPE_MAIN, locale);
         for (final AssetFileAddress address : dictionaryList) {
             final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(
                     address.mFilename, address.mOffset, address.mLength, useFullEditDistance,
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index de38403..a1dd67f 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -86,9 +86,6 @@
      */
     private final String mDictName;
 
-    /** Dictionary locale */
-    private final Locale mLocale;
-
     /** Dictionary file */
     private final File mDictFile;
 
@@ -137,10 +134,9 @@
      */
     public ExpandableBinaryDictionary(final Context context, final String dictName,
             final Locale locale, final String dictType, final File dictFile) {
-        super(dictType);
+        super(dictType, locale);
         mDictName = dictName;
         mContext = context;
-        mLocale = locale;
         mDictFile = getDictFile(context, dictName, dictFile);
         mBinaryDictionary = null;
         mIsReloading = new AtomicBoolean();
diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
index 5d4fc58..ecf25c2 100644
--- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
@@ -40,7 +40,7 @@
 
     public ReadOnlyBinaryDictionary(final String filename, final long offset, final long length,
             final boolean useFullEditDistance, final Locale locale, final String dictType) {
-        super(dictType);
+        super(dictType, locale);
         mBinaryDictionary = new BinaryDictionary(filename, offset, length, useFullEditDistance,
                 locale, dictType, false /* isUpdatable */);
     }
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 6779351..9e4aa40 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -84,7 +84,7 @@
 
     private static ArrayList<SuggestedWordInfo> getTransformedSuggestedWordInfoList(
             final WordComposer wordComposer, final SuggestionResults results,
-            final int trailingSingleQuotesCount) {
+            final int trailingSingleQuotesCount, final Locale defaultLocale) {
         final boolean shouldMakeSuggestionsAllUpperCase = wordComposer.isAllUpperCase()
                 && !wordComposer.isResumed();
         final boolean isOnlyFirstCharCapitalized =
@@ -96,9 +96,11 @@
                 || 0 != trailingSingleQuotesCount) {
             for (int i = 0; i < suggestionsCount; ++i) {
                 final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
+                final Locale wordLocale = wordInfo.mSourceDict.mLocale;
                 final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
-                        wordInfo, results.mLocale, shouldMakeSuggestionsAllUpperCase,
-                        isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
+                        wordInfo, null == wordLocale ? defaultLocale : wordLocale,
+                        shouldMakeSuggestionsAllUpperCase, isOnlyFirstCharCapitalized,
+                        trailingSingleQuotesCount);
                 suggestionsContainer.set(i, transformedWordInfo);
             }
         }
@@ -134,7 +136,7 @@
                 SESSION_ID_TYPING);
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
-                        trailingSingleQuotesCount);
+                        trailingSingleQuotesCount, mDictionaryFacilitator.getLocale());
         final boolean didRemoveTypedWord =
                 SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer);
 
@@ -208,6 +210,7 @@
         final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
                 wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
                 SESSION_ID_GESTURE);
+        final Locale defaultLocale = mDictionaryFacilitator.getLocale();
         final ArrayList<SuggestedWordInfo> suggestionsContainer =
                 new ArrayList<>(suggestionResults);
         final int suggestionsCount = suggestionsContainer.size();
@@ -216,9 +219,10 @@
         if (isFirstCharCapitalized || isAllUpperCase) {
             for (int i = 0; i < suggestionsCount; ++i) {
                 final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
+                final Locale wordlocale = wordInfo.mSourceDict.mLocale;
                 final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
-                        wordInfo, suggestionResults.mLocale, isAllUpperCase, isFirstCharCapitalized,
-                        0 /* trailingSingleQuotesCount */);
+                        wordInfo, null == wordlocale ? defaultLocale : wordlocale, isAllUpperCase,
+                        isFirstCharCapitalized, 0 /* trailingSingleQuotesCount */);
                 suggestionsContainer.set(i, transformedWordInfo);
             }
         }
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index 7170bd7..eaa5743 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -30,18 +30,16 @@
  * than its limit
  */
 public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
-    public final Locale mLocale;
     public final ArrayList<SuggestedWordInfo> mRawSuggestions;
     private final int mCapacity;
 
-    public SuggestionResults(final Locale locale, final int capacity) {
-        this(locale, sSuggestedWordInfoComparator, capacity);
+    public SuggestionResults(final int capacity) {
+        this(sSuggestedWordInfoComparator, capacity);
     }
 
-    public SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator,
+    public SuggestionResults(final Comparator<SuggestedWordInfo> comparator,
             final int capacity) {
         super(comparator);
-        mLocale = locale;
         mCapacity = capacity;
         if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) {
             mRawSuggestions = new ArrayList<>();