Don't check user dictionary, except for spelling.

We check different lists of dictionaries based on the use case.

Bug 19270992.

Change-Id: Ide69f2855978ebad32a58e9689b3a8d47e095994
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 48cca76..8fbb44a 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -135,7 +135,9 @@
             final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
             final int inputStyle, final KeyboardLayout keyboardLayout);
 
-    boolean isValidWord(final String word, final boolean ignoreCase);
+    boolean isValidSpellingWord(final String word);
+
+    boolean isValidSuggestionWord(final String word);
 
     int getFrequency(final String word);
 
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index 99f0247..2865dee 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -39,7 +39,6 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -79,13 +78,33 @@
     private final Object mLock = new Object();
     private final DistracterFilter mDistracterFilter;
 
-    private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS =
-            new String[] {
-                Dictionary.TYPE_MAIN,
-                Dictionary.TYPE_USER_HISTORY,
-                Dictionary.TYPE_USER,
-                Dictionary.TYPE_CONTACTS,
-            };
+    private static final String[] ALL_DICTIONARY_TYPES = new String[] {
+        Dictionary.TYPE_MAIN,
+        Dictionary.TYPE_USER_HISTORY,
+        Dictionary.TYPE_USER,
+        Dictionary.TYPE_CONTACTS};
+
+    private static final String[] SUB_DICTIONARY_TYPES = new String[] {
+        Dictionary.TYPE_USER_HISTORY,
+        Dictionary.TYPE_USER,
+        Dictionary.TYPE_CONTACTS};
+
+    /**
+     * {@link Dictionary#TYPE_USER} is deprecated, except for the spelling service.
+     */
+    private static final String[] DICTIONARY_TYPES_FOR_SPELLING = new String[] {
+        Dictionary.TYPE_MAIN,
+        Dictionary.TYPE_USER_HISTORY,
+        Dictionary.TYPE_USER,
+        Dictionary.TYPE_CONTACTS};
+
+    /**
+     * {@link Dictionary#TYPE_USER} is deprecated, except for the spelling service.
+     */
+    private static final String[] DICTIONARY_TYPES_FOR_SUGGESTIONS = new String[] {
+        Dictionary.TYPE_MAIN,
+        Dictionary.TYPE_USER_HISTORY,
+        Dictionary.TYPE_CONTACTS};
 
     public static final Map<String, Class<? extends ExpandableBinaryDictionary>>
             DICT_TYPE_TO_CLASS = new HashMap<>();
@@ -100,10 +119,6 @@
     private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
             new Class[] { Context.class, Locale.class, File.class, String.class, String.class };
 
-    private static final String[] SUB_DICT_TYPES =
-            Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS, 1 /* start */,
-                    DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length);
-
     /**
      * Returns whether this facilitator is exactly for this list of locales.
      *
@@ -404,7 +419,7 @@
             if (null == currentDictionaryGroupForLocale) {
                 continue;
             }
-            for (final String dictType : SUB_DICT_TYPES) {
+            for (final String dictType : SUB_DICTIONARY_TYPES) {
                 if (currentDictionaryGroupForLocale.hasDict(dictType, account)) {
                     dictTypeForLocale.add(dictType);
                 }
@@ -563,7 +578,7 @@
             mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
         }
         for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+            for (final String dictType : ALL_DICTIONARY_TYPES) {
                 dictionaryGroup.closeDict(dictType);
             }
         }
@@ -648,8 +663,7 @@
         final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
         final String secondWord;
         if (wasAutoCapitalized) {
-            if (isValidWord(word, false /* ignoreCase */)
-                    && !isValidWord(lowerCasedWord, false /* ignoreCase */)) {
+            if (isValidSuggestionWord(word) && !isValidSuggestionWord(lowerCasedWord)) {
                 // If the word was auto-capitalized and exists only as a capitalized word in the
                 // dictionary, then we must not downcase it before registering it. For example,
                 // the name of the contacts in start-of-sentence position would come here with the
@@ -711,7 +725,7 @@
         final float[] weightOfLangModelVsSpatialModel =
                 new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
         for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+            for (final String dictType : DICTIONARY_TYPES_FOR_SUGGESTIONS) {
                 final Dictionary dictionary = dictionaryGroup.getDict(dictType);
                 if (null == dictionary) continue;
                 final float weightForLocale = composer.isBatchMode()
@@ -731,7 +745,15 @@
         return suggestionResults;
     }
 
-    public boolean isValidWord(final String word, final boolean ignoreCase) {
+    public boolean isValidSpellingWord(final String word) {
+        return isValidWord(word, DICTIONARY_TYPES_FOR_SPELLING);
+    }
+
+    public boolean isValidSuggestionWord(final String word) {
+        return isValidWord(word, DICTIONARY_TYPES_FOR_SUGGESTIONS);
+    }
+
+    private boolean isValidWord(final String word, final String[] dictionariesToCheck) {
         if (TextUtils.isEmpty(word)) {
             return false;
         }
@@ -740,15 +762,13 @@
             if (dictionaryGroup.mLocale == null) {
                 continue;
             }
-            final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+            for (final String dictType : dictionariesToCheck) {
                 final Dictionary dictionary = dictionaryGroup.getDict(dictType);
                 // Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
                 // would be immutable once it's finished initializing, but concretely a null test is
                 // probably good enough for the time being.
                 if (null == dictionary) continue;
-                if (dictionary.isValidWord(word)
-                        || (ignoreCase && dictionary.isValidWord(lowerCasedWord))) {
+                if (dictionary.isValidWord(word)) {
                     return true;
                 }
             }
@@ -764,7 +784,7 @@
         int maxFreq = Dictionary.NOT_A_PROBABILITY;
         final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
         for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+            for (final String dictType : ALL_DICTIONARY_TYPES) {
                 final Dictionary dictionary = dictionaryGroup.getDict(dictType);
                 if (dictionary == null) continue;
                 final int tempFreq;
@@ -820,7 +840,7 @@
         final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
         final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
         for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
-            for (final String dictType : SUB_DICT_TYPES) {
+            for (final String dictType : SUB_DICTIONARY_TYPES) {
                 final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictType);
                 if (dictionary == null) continue;
                 statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 7851dd2..477e570 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -154,7 +154,7 @@
         try {
             DictionaryFacilitator dictionaryFacilitatorForLocale =
                     mDictionaryFacilitatorCache.get(locale);
-            return dictionaryFacilitatorForLocale.isValidWord(word, false /* igroreCase */);
+            return dictionaryFacilitatorForLocale.isValidSpellingWord(word);
         } finally {
             mSemaphore.release();
         }
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
index af99797..09bb03f 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
@@ -196,8 +196,7 @@
             mDistractersCache.put(cacheKey, Boolean.TRUE);
             return true;
         }
-        final boolean Word = dictionaryFacilitator.isValidWord(testedWord, false /* ignoreCase */);
-        if (Word) {
+        if (dictionaryFacilitator.isValidSuggestionWord(testedWord)) {
             // Valid word is not a distracter.
             if (DEBUG) {
                 Log.d(TAG, "isDistracter: false (valid word)");
@@ -291,14 +290,14 @@
             final Locale locale) {
         final DictionaryFacilitator dictionaryFacilitator =
                 mDictionaryFacilitatorLruCache.get(locale);
-        if (dictionaryFacilitator.isValidWord(testedWord, false /* ignoreCase */)) {
+        if (dictionaryFacilitator.isValidSuggestionWord(testedWord)) {
             return false;
         }
-        final String lowerCaseTargetWord = testedWord.toLowerCase(locale);
-        if (testedWord.equals(lowerCaseTargetWord)) {
+        final String lowerCaseWord = testedWord.toLowerCase(locale);
+        if (testedWord.equals(lowerCaseWord)) {
             return false;
         }
-        if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) {
+        if (dictionaryFacilitator.isValidSuggestionWord(lowerCaseWord)) {
             return true;
         }
         if (StringUtils.getCapitalizationType(testedWord) == StringUtils.CAPITALIZE_FIRST
@@ -317,10 +316,10 @@
             return HandlingType.getHandlingType(false /* shouldBeLowerCased */, false /* isOov */);
         }
         final boolean shouldBeLowerCased = shouldBeLowerCased(ngramContext, testedWord, locale);
-        final String caseModifiedWord =
-                shouldBeLowerCased ? testedWord.toLowerCase(locale) : testedWord;
-        final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidWord(
-                caseModifiedWord, false /* ignoreCase */);
+        final String caseModifiedWord = shouldBeLowerCased
+                ? testedWord.toLowerCase(locale) : testedWord;
+        final boolean isOov = !mDictionaryFacilitatorLruCache.get(locale).isValidSuggestionWord(
+                caseModifiedWord);
         return HandlingType.getHandlingType(shouldBeLowerCased, isOov);
     }
 }