diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
38 files changed, 306 insertions, 1363 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index b0eae0832..7e4d66583 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -27,6 +27,7 @@ import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.FileUtils; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.common.StringUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; @@ -319,9 +320,9 @@ public final class BinaryDictionary extends Dictionary { final int count = session.mOutputSuggestionCount[0]; final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>(); for (int j = 0; j < count; ++j) { - final int start = j * Constants.DICTIONARY_MAX_WORD_LENGTH; + final int start = j * DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; int len = 0; - while (len < Constants.DICTIONARY_MAX_WORD_LENGTH + while (len < DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH && session.mOutputCodePoints[start + len] != 0) { ++len; } @@ -390,7 +391,7 @@ public final class BinaryDictionary extends Dictionary { return null; } final int[] codePoints = StringUtils.toCodePointArray(word); - final int[] outCodePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH]; + final int[] outCodePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH]; final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT]; final int[] outProbabilityInfo = new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT]; @@ -431,7 +432,7 @@ public final class BinaryDictionary extends Dictionary { * If token is 0, this method newly starts iterating the dictionary. */ public GetNextWordPropertyResult getNextWordProperty(final int token) { - final int[] codePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH]; + final int[] codePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH]; final boolean[] isBeginningOfSentence = new boolean[1]; final int nextToken = getNextWordNative(mNativeDict, token, codePoints, isBeginningOfSentence); diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java index e7fd99ee8..6816f129a 100644 --- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java +++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java @@ -16,8 +16,8 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.NativeSuggestOptions; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.utils.JniUtils; import java.util.Locale; @@ -28,14 +28,15 @@ public final class DicTraverseSession { } // Must be equal to MAX_RESULTS in native/jni/src/defines.h private static final int MAX_RESULTS = 18; - public final int[] mInputCodePoints = new int[Constants.DICTIONARY_MAX_WORD_LENGTH]; + public final int[] mInputCodePoints = + new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH]; public final int[][] mPrevWordCodePointArrays = - new int[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][]; + new int[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][]; public final boolean[] mIsBeginningOfSentenceArray = - new boolean[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; + new boolean[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; public final int[] mOutputSuggestionCount = new int[1]; public final int[] mOutputCodePoints = - new int[Constants.DICTIONARY_MAX_WORD_LENGTH * MAX_RESULTS]; + new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH * MAX_RESULTS]; public final int[] mSpaceIndices = new int[MAX_RESULTS]; public final int[] mOutputScores = new int[MAX_RESULTS]; public final int[] mOutputTypes = new int[MAX_RESULTS]; diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 7d7ed77e7..16dcb3208 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -49,8 +49,7 @@ public abstract class Dictionary { // Spawned by resuming suggestions. Comes from a span that was in the TextView. public static final String TYPE_RESUMED = "resumed"; - public static final PhonyDictionary DICTIONARY_RESUMED = - new PhonyDictionary(TYPE_RESUMED); + public static final PhonyDictionary DICTIONARY_RESUMED = new PhonyDictionary(TYPE_RESUMED); // The following types of dictionary have actual functional instances. We don't need final // phony dictionary instances for them. @@ -60,10 +59,6 @@ public abstract class Dictionary { public static final String TYPE_USER = "user"; // User history dictionary internal to LatinIME. public static final String TYPE_USER_HISTORY = "history"; - // Personalization dictionary. - public static final String TYPE_PERSONALIZATION = "personalization"; - // 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; @@ -76,9 +71,7 @@ public abstract class Dictionary { TYPE_USER_TYPED, TYPE_USER, TYPE_CONTACTS, - TYPE_USER_HISTORY, - TYPE_PERSONALIZATION, - TYPE_CONTEXTUAL)); + TYPE_USER_HISTORY)); public Dictionary(final String dictType, final Locale locale) { mDictType = dictType; diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index a0a1d939e..3e4cda47a 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -17,21 +17,19 @@ package com.android.inputmethod.latin; import android.content.Context; -import android.view.inputmethod.InputMethodSubtype; import android.util.Pair; +import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback; -import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; -import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.SuggestionResults; import java.io.File; import java.util.ArrayList; import java.util.HashMap; -import java.util.Locale; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -45,6 +43,35 @@ import javax.annotation.Nullable; * DictionaryFacilitator as a client for interacting with dictionaries. */ public interface DictionaryFacilitator { + + public static final String[] ALL_DICTIONARY_TYPES = new String[] { + Dictionary.TYPE_MAIN, + Dictionary.TYPE_USER_HISTORY, + Dictionary.TYPE_USER, + Dictionary.TYPE_CONTACTS}; + + public static final String[] DYNAMIC_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. + */ + public 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. + */ + public static final String[] DICTIONARY_TYPES_FOR_SUGGESTIONS = new String[] { + Dictionary.TYPE_MAIN, + Dictionary.TYPE_USER_HISTORY, + Dictionary.TYPE_CONTACTS}; + /** * Returns whether this facilitator is exactly for this list of locales. * @@ -86,24 +113,22 @@ public interface DictionaryFacilitator { boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale); - void resetDictionaries(final Context context, final Locale[] newLocales, - final boolean useContactsDict, final boolean usePersonalizedDicts, - final boolean forceReloadMainDictionary, - @Nullable final String account, - final DictionaryInitializationListener listener); - - void resetDictionariesWithDictNamePrefix(final Context context, + void resetDictionaries( + final Context context, final Locale[] newLocales, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, - @Nullable final DictionaryInitializationListener listener, + @Nullable final String account, final String dictNamePrefix, - @Nullable final String account); + @Nullable final DictionaryInitializationListener listener); @UsedForTesting - void resetDictionariesForTesting(final Context context, final Locale[] locales, - final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, + void resetDictionariesForTesting( + final Context context, + final Locale[] locales, + final ArrayList<String> dictionaryTypes, + final HashMap<String, File> dictionaryFiles, final Map<String, Map<String, String>> additionalDictAttributes, @Nullable final String account); @@ -118,10 +143,6 @@ public interface DictionaryFacilitator { boolean hasAtLeastOneUninitializedMainDictionary(); - boolean hasPersonalizationDictionary(); - - void flushPersonalizationDictionary(); - void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit) throws InterruptedException; @@ -129,10 +150,6 @@ public interface DictionaryFacilitator { void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit) throws InterruptedException; - boolean isUserDictionaryEnabled(); - - void addWordToUserDictionary(final Context context, final String word); - void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive); @@ -142,9 +159,12 @@ public interface DictionaryFacilitator { // TODO: Revise the way to fusion suggestion results. SuggestionResults getSuggestionResults(final WordComposer composer, final NgramContext ngramContext, final long proximityInfoHandle, - final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId); + final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId, + final int inputStyle, final KeyboardLayout keyboardLayout); + + boolean isValidSpellingWord(final String word); - boolean isValidWord(final String word, final boolean ignoreCase); + boolean isValidSuggestionWord(final String word); int getFrequency(final String word); @@ -152,21 +172,6 @@ public interface DictionaryFacilitator { void clearUserHistoryDictionary(); - // This method gets called only when the IME receives a notification to remove the - // personalization dictionary. - void clearPersonalizationDictionary(); - - void clearContextualDictionary(); - - void addEntriesToPersonalizationDictionary( - final PersonalizationDataChunk personalizationDataChunk, - final SpacingAndPunctuations spacingAndPunctuations, - final UpdateEntriesForInputEventsCallback callback); - - @UsedForTesting - void addPhraseToContextualDictionary(final String[] phrase, final int probability, - final int bigramProbabilityForWords, final int bigramProbabilityForPhrases); - void dumpDictionaryForDebug(final String dictName); ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java index 167501118..dd34faef8 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -23,16 +23,12 @@ import android.util.Pair; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.latin.NgramContext.WordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.common.Constants; -import com.android.inputmethod.latin.personalization.ContextualDictionary; -import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; -import com.android.inputmethod.latin.personalization.PersonalizationDictionary; import com.android.inputmethod.latin.personalization.UserHistoryDictionary; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; -import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.DistracterFilter; import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions; import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary; @@ -43,7 +39,6 @@ import java.io.File; 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; @@ -78,42 +73,24 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() }; private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0]; - private boolean mIsUserDictEnabled = false; private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0); // To synchronize assigning mDictionaryGroup to ensure closing dictionaries. private final Object mLock = new Object(); private final DistracterFilter mDistracterFilter; - private final PersonalizationHelperForDictionaryFacilitator mPersonalizationHelper; - - private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS = - new String[] { - Dictionary.TYPE_MAIN, - Dictionary.TYPE_USER_HISTORY, - Dictionary.TYPE_PERSONALIZATION, - Dictionary.TYPE_USER, - Dictionary.TYPE_CONTACTS, - Dictionary.TYPE_CONTEXTUAL - }; public static final Map<String, Class<? extends ExpandableBinaryDictionary>> DICT_TYPE_TO_CLASS = new HashMap<>(); static { DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class); - DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_PERSONALIZATION, PersonalizationDictionary.class); DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER, UserBinaryDictionary.class); DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTACTS, ContactsBinaryDictionary.class); - DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTEXTUAL, ContextualDictionary.class); } private static final String DICT_FACTORY_METHOD_NAME = "getDictionary"; 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. * @@ -257,23 +234,18 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public DictionaryFacilitatorImpl() { mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER; - mPersonalizationHelper = null; } public DictionaryFacilitatorImpl(final Context context) { mDistracterFilter = new DistracterFilterCheckingExactMatchesAndSuggestions(context); - mPersonalizationHelper = - new PersonalizationHelperForDictionaryFacilitator(context, mDistracterFilter); } public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) { mDistracterFilter.updateEnabledSubtypes(enabledSubtypes); - mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes); } // TODO: remove this, it's confusing with seamless multiple language switching public void setIsMonolingualUser(final boolean isMonolingualUser) { - mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser); } public boolean isActive() { @@ -370,16 +342,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } - public void resetDictionaries(final Context context, final Locale[] newLocales, - final boolean useContactsDict, final boolean usePersonalizedDicts, - final boolean forceReloadMainDictionary, - @Nullable final String account, - final DictionaryInitializationListener listener) { - resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict, - usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */, - account); - } - @Nullable static DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups, final Locale locale) { @@ -391,14 +353,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { return null; } - public void resetDictionariesWithDictNamePrefix(final Context context, + public void resetDictionaries( + final Context context, final Locale[] newLocales, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, - @Nullable final DictionaryInitializationListener listener, + @Nullable final String account, final String dictNamePrefix, - @Nullable final String account) { + @Nullable final DictionaryInitializationListener listener) { final HashMap<Locale, ArrayList<String>> existingDictionariesToCleanup = new HashMap<>(); // TODO: Make subDictTypesToUse configurable by resource or a static final list. final HashSet<String> subDictTypesToUse = new HashSet<>(); @@ -408,8 +371,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } if (usePersonalizedDicts) { subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY); - subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION); - subDictTypesToUse.add(Dictionary.TYPE_CONTEXTUAL); } // Gather all dictionaries. We'll remove them from the list to clean up later. @@ -421,7 +382,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { if (null == currentDictionaryGroupForLocale) { continue; } - for (final String dictType : SUB_DICT_TYPES) { + for (final String dictType : DYNAMIC_DICTIONARY_TYPES) { if (currentDictionaryGroupForLocale.hasDict(dictType, account)) { dictTypeForLocale.add(dictType); } @@ -473,7 +434,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { oldDictionaryGroups = mDictionaryGroups; mDictionaryGroups = newDictionaryGroups; mMostProbableDictionaryGroup = newDictionaryGroups[0]; - mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context); if (hasAtLeastOneUninitializedMainDictionary()) { asyncReloadUninitializedMainDictionaries(context, newLocales, listener); } @@ -581,14 +541,11 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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); } } mDistracterFilter.close(); - if (mPersonalizationHelper != null) { - mPersonalizationHelper.close(); - } } @UsedForTesting @@ -620,30 +577,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { return false; } - public boolean hasPersonalizationDictionary() { - final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; - for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { - if (dictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION, null /* account */)) { - return true; - } - } - return false; - } - - public void flushPersonalizationDictionary() { - final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion = - new HashSet<>(); - final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; - for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { - final ExpandableBinaryDictionary personalizationDictUsedForSuggestion = - dictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION); - personalizationDictsUsedForSuggestion.add(personalizationDictUsedForSuggestion); - } - mPersonalizationHelper.flushPersonalizationDictionariesToUpdate( - personalizationDictsUsedForSuggestion); - mDistracterFilter.close(); - } - public void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit) throws InterruptedException { mLatchForWaitingLoadingMainDictionaries.await(timeout, unit); @@ -661,19 +594,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } - public boolean isUserDictionaryEnabled() { - return mIsUserDictEnabled; - } - - public void addWordToUserDictionary(final Context context, final String word) { - final Locale locale = getMostProbableLocale(); - if (locale == null) { - return; - } - // TODO: add a toast telling what language this is being added to? - UserBinaryDictionary.addWordToUserDictionary(context, locale, word); - } - public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { @@ -706,8 +626,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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 @@ -755,21 +674,21 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { public void removeWordFromPersonalizedDicts(final String word) { removeWord(Dictionary.TYPE_USER_HISTORY, word); - removeWord(Dictionary.TYPE_PERSONALIZATION, word); - removeWord(Dictionary.TYPE_CONTEXTUAL, word); } // TODO: Revise the way to fusion suggestion results. - public SuggestionResults getSuggestionResults(final WordComposer composer, - final NgramContext ngramContext, final long proximityInfoHandle, - final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) { + @Override + public SuggestionResults getSuggestionResults(WordComposer composer, + NgramContext ngramContext, long proximityInfoHandle, + SettingsValuesForSuggestion settingsValuesForSuggestion, int sessionId, + int inputStyle, KeyboardLayout keyboardLayout) { final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; final SuggestionResults suggestionResults = new SuggestionResults( SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext()); 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() @@ -789,7 +708,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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; } @@ -798,15 +725,13 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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; } } @@ -822,7 +747,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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; @@ -861,64 +786,6 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { clearSubDictionary(Dictionary.TYPE_USER_HISTORY); } - // This method gets called only when the IME receives a notification to remove the - // personalization dictionary. - public void clearPersonalizationDictionary() { - clearSubDictionary(Dictionary.TYPE_PERSONALIZATION); - mPersonalizationHelper.clearDictionariesToUpdate(); - } - - public void clearContextualDictionary() { - clearSubDictionary(Dictionary.TYPE_CONTEXTUAL); - } - - public void addEntriesToPersonalizationDictionary( - final PersonalizationDataChunk personalizationDataChunk, - final SpacingAndPunctuations spacingAndPunctuations, - final UpdateEntriesForInputEventsCallback callback) { - mPersonalizationHelper.updateEntriesOfPersonalizationDictionaries( - getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations, - callback); - } - - @UsedForTesting - public void addPhraseToContextualDictionary(final String[] phrase, final int probability, - final int bigramProbabilityForWords, final int bigramProbabilityForPhrases) { - // TODO: we're inserting the phrase into the dictionary for the active language. Rethink - // this a bit from a theoretical point of view. - final ExpandableBinaryDictionary contextualDict = - getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL); - if (contextualDict == null) { - return; - } - NgramContext ngramContext = NgramContext.BEGINNING_OF_SENTENCE; - for (int i = 0; i < phrase.length; i++) { - final String[] subPhrase = Arrays.copyOfRange(phrase, i /* start */, phrase.length); - final String subPhraseStr = TextUtils.join(Constants.WORD_SEPARATOR, subPhrase); - contextualDict.addUnigramEntryWithCheckingDistracter( - subPhraseStr, probability, null /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY /* shortcutFreq */, - false /* isNotAWord */, false /* isPossiblyOffensive */, - BinaryDictionary.NOT_A_VALID_TIMESTAMP, - DistracterFilter.EMPTY_DISTRACTER_FILTER); - contextualDict.addNgramEntry(ngramContext, subPhraseStr, - bigramProbabilityForPhrases, BinaryDictionary.NOT_A_VALID_TIMESTAMP); - - if (i < phrase.length - 1) { - contextualDict.addUnigramEntryWithCheckingDistracter( - phrase[i], probability, null /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY /* shortcutFreq */, - false /* isNotAWord */, false /* isPossiblyOffensive */, - BinaryDictionary.NOT_A_VALID_TIMESTAMP, - DistracterFilter.EMPTY_DISTRACTER_FILTER); - contextualDict.addNgramEntry(ngramContext, phrase[i], - bigramProbabilityForWords, BinaryDictionary.NOT_A_VALID_TIMESTAMP); - } - ngramContext = - ngramContext.getNextNgramContext(new NgramContext.WordInfo(phrase[i])); - } - } - public void dumpDictionaryForDebug(final String dictName) { final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { @@ -936,7 +803,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { 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 : DYNAMIC_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/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java index 13bd15101..85ecf93f3 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java @@ -28,10 +28,11 @@ import android.util.LruCache; /** * Cache for dictionary facilitators of multiple locales. - * This class automatically creates and releases facilitator instances using LRU policy. + * This class automatically creates and releases up to 3 facilitator instances using LRU policy. */ public class DictionaryFacilitatorLruCache { - static final String TAG = DictionaryFacilitatorLruCache.class.getSimpleName(); + private static final String TAG = "DictionaryFacilitatorLruCache"; + private static final int MAX_DICTIONARY_FACILITATOR_COUNT = 3; private static final int WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS = 1000; private static final int MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT = 5; @@ -74,10 +75,10 @@ public class DictionaryFacilitatorLruCache { private final Object mLock = new Object(); private boolean mUseContactsDictionary = false; - public DictionaryFacilitatorLruCache(final Context context, final int maxSize, - final String dictionaryNamePrefix) { + public DictionaryFacilitatorLruCache(final Context context, final String dictionaryNamePrefix) { mContext = context; - mLruCache = new DictionaryFacilitatorLruCacheInner(mCachedLocales, maxSize); + mLruCache = new DictionaryFacilitatorLruCacheInner( + mCachedLocales, MAX_DICTIONARY_FACILITATOR_COUNT); mDictionaryNamePrefix = dictionaryNamePrefix; } @@ -103,11 +104,10 @@ public class DictionaryFacilitatorLruCache { private void resetDictionariesForLocaleLocked(final DictionaryFacilitator dictionaryFacilitator, final Locale locale) { // Note: Given that personalized dictionaries are not used here; we can pass null account. - dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, new Locale[] { locale }, + dictionaryFacilitator.resetDictionaries(mContext, new Locale[]{locale}, mUseContactsDictionary, false /* usePersonalizedDicts */, - false /* forceReloadMainDictionary */, null /* listener */, - mDictionaryNamePrefix, - null /* account */); + false /* forceReloadMainDictionary */, null /* account */, + mDictionaryNamePrefix, null /* listener */); } public void setUseContactsDictionary(final boolean useContectsDictionary) { @@ -128,7 +128,7 @@ public class DictionaryFacilitatorLruCache { public DictionaryFacilitator get(final Locale locale) { DictionaryFacilitator dictionaryFacilitator = mLruCache.get(locale); if (dictionaryFacilitator != null) { - // dictionary falicitator for the locale is in the cache. + // dictionary facilitator for the locale is in the cache. return dictionaryFacilitator; } synchronized (mLock) { diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 1c54a20e7..87d46e226 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -22,8 +22,8 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.common.ComposedData; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.FileUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.UnsupportedFormatException; @@ -73,7 +73,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** * The maximum length of a word in this dictionary. */ - protected static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH; + protected static final int MAX_WORD_LENGTH = + DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4; diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java index 9fcdb2229..426d33e6d 100644 --- a/java/src/com/android/inputmethod/latin/LastComposedWord.java +++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java @@ -19,8 +19,8 @@ package com.android.inputmethod.latin; import android.text.TextUtils; import com.android.inputmethod.event.Event; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.InputPointers; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import java.util.ArrayList; @@ -53,7 +53,7 @@ public final class LastComposedWord { public final NgramContext mNgramContext; public final int mCapitalizedMode; public final InputPointers mInputPointers = - new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH); + new InputPointers(DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH); private boolean mActive; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 622cdb0a6..74ef6481a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -20,7 +20,6 @@ import static com.android.inputmethod.latin.common.Constants.ImeOption.FORCE_ASC import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE; import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT; -import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -32,13 +31,11 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; -import android.os.Build; import android.os.Debug; import android.os.IBinder; import android.os.Message; import android.preference.PreferenceManager; import android.text.InputType; -import android.text.TextUtils; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; @@ -47,18 +44,14 @@ import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup.LayoutParams; -import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; -import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; -import android.widget.TextView; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils; import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater; @@ -72,7 +65,6 @@ import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.MainKeyboardView; -import com.android.inputmethod.keyboard.TextDecoratorUi; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.common.Constants; @@ -81,9 +73,7 @@ import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.define.DebugFlags; import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.inputlogic.InputLogic; -import com.android.inputmethod.latin.personalization.ContextualDictionaryUpdater; import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever; -import com.android.inputmethod.latin.personalization.PersonalizationDictionaryUpdater; import com.android.inputmethod.latin.personalization.PersonalizationHelper; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsActivity; @@ -92,8 +82,6 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripView; import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; import com.android.inputmethod.latin.touchinputconsumer.GestureConsumer; import com.android.inputmethod.latin.utils.ApplicationUtils; -import com.android.inputmethod.latin.utils.CapsModeUtils; -import com.android.inputmethod.latin.utils.CursorAnchorInfoUtils; import com.android.inputmethod.latin.utils.DialogUtils; import com.android.inputmethod.latin.utils.ImportantNoticeUtils; import com.android.inputmethod.latin.utils.IntentUtils; @@ -139,19 +127,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final String SCHEME_PACKAGE = "package"; final Settings mSettings; - private final DictionaryFacilitator mDictionaryFacilitator = - DictionaryFacilitatorProvider.newDictionaryFacilitator(this /* context */); - // TODO: Move from LatinIME. - private final PersonalizationDictionaryUpdater mPersonalizationDictionaryUpdater = - new PersonalizationDictionaryUpdater(this /* context */, mDictionaryFacilitator); - private final ContextualDictionaryUpdater mContextualDictionaryUpdater = - new ContextualDictionaryUpdater(this /* context */, mDictionaryFacilitator, - new Runnable() { - @Override - public void run() { - mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE); - } - }); + private final DictionaryFacilitator mDictionaryFacilitator = + DictionaryFacilitatorProvider.newDictionaryFacilitator(this /* context */); final InputLogic mInputLogic = new InputLogic(this /* LatinIME */, this /* SuggestionStripViewAccessor */, mDictionaryFacilitator); // We expect to have only one decoder in almost all cases, hence the default capacity of 1. @@ -162,7 +139,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private View mInputView; private InsetsUpdater mInsetsUpdater; private SuggestionStripView mSuggestionStripView; - private TextView mExtractEditText; private RichInputMethodManager mRichImm; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; @@ -642,11 +618,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void refreshPersonalizationDictionarySession( final SettingsValues currentSettingsValues) { + // TODO: Remove all existing personalized dictionaries. mDictionaryFacilitator.setIsMonolingualUser( mRichImm.isSystemLocaleSameAsLocaleOfAllEnabledSubtypesOfEnabledImes()); - mPersonalizationDictionaryUpdater.onLoadSettings( - currentSettingsValues.mUsePersonalizedDicts); - mContextualDictionaryUpdater.onLoadSettings(currentSettingsValues.mUsePersonalizedDicts); final boolean shouldKeepUserHistoryDictionaries; if (currentSettingsValues.mUsePersonalizedDicts) { shouldKeepUserHistoryDictionaries = true; @@ -705,7 +679,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mDictionaryFacilitator.resetDictionaries(this /* context */, locales, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, - settingsValues.mAccount, + settingsValues.mAccount, "" /* dictNamePrefix */, this /* DictionaryInitializationListener */); if (settingsValues.mAutoCorrectionEnabledPerUserSettings) { mInputLogic.mSuggest.setAutoCorrectionThreshold( @@ -723,15 +697,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mDictionaryFacilitator.getLocales(), settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, true /* forceReloadMainDictionary */, - settingsValues.mAccount, + settingsValues.mAccount, "" /* dictNamePrefix */, this /* DictionaryInitializationListener */); } @Override public void onDestroy() { mDictionaryFacilitator.closeDictionaries(); - mPersonalizationDictionaryUpdater.onDestroy(); - mContextualDictionaryUpdater.onDestroy(); mSettings.onDestroy(); NetworkConnectivityUtils.onDestroy(this /* context */); unregisterReceiver(mRingerModeChangeReceiver); @@ -793,57 +765,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (hasSuggestionStripView()) { mSuggestionStripView.setListener(this, view); } - mInputLogic.setTextDecoratorUi(new TextDecoratorUi(this, view)); } @Override - public void setExtractView(final View view) { - final TextView prevExtractEditText = mExtractEditText; - super.setExtractView(view); - TextView nextExtractEditText = null; - if (view != null) { - final View extractEditText = view.findViewById(android.R.id.inputExtractEditText); - if (extractEditText instanceof TextView) { - nextExtractEditText = (TextView)extractEditText; - } - } - if (prevExtractEditText == nextExtractEditText) { - return; - } - if (prevExtractEditText != null) { - prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener( - mExtractTextViewPreDrawListener); - } - mExtractEditText = nextExtractEditText; - if (mExtractEditText != null) { - mExtractEditText.getViewTreeObserver().addOnPreDrawListener( - mExtractTextViewPreDrawListener); - } - } - - void updateCursorAnchorInfo() { - // CursorAnchorInfo is used on L and later. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (isFullscreenMode() && mExtractEditText != null) { - mInputLogic.onUpdateCursorAnchorInfo( - CursorAnchorInfoUtils.extractFromTextView(mExtractEditText)); - } - } - } - - private final ViewTreeObserver.OnPreDrawListener mExtractTextViewPreDrawListener = - new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - updateCursorAnchorInfo(); - return true; - } - }; - - @Override public void setCandidatesView(final View view) { // To ensure that CandidatesView will never be set. - return; } @Override @@ -1050,8 +976,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen currentSettingsValues.mGestureTrailEnabled, currentSettingsValues.mGestureFloatingPreviewTextEnabled); - // Contextual dictionary should be updated for the current application. - mContextualDictionaryUpdater.onStartInputView(editorInfo.packageName); if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } @@ -1114,15 +1038,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) { - if (isFullscreenMode()) { - return; - } - mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.wrap(info)); - } - /** * This is called when the user has clicked on the extracted text view, * when running in fullscreen mode. The default implementation hides @@ -1303,7 +1218,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void updateFullscreenMode() { super.updateFullscreenMode(); - mInputLogic.onUpdateFullscreenMode(isFullscreenMode()); updateSoftInputWindowLayoutParameters(); } @@ -1351,18 +1265,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return keyboard.getCoordinates(codePoints); } - // Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is - // pressed. - @Override - public void addWordToUserDictionary(final String word) { - if (TextUtils.isEmpty(word)) { - // Probably never supposed to happen, but just in case. - return; - } - mDictionaryFacilitator.addWordToUserDictionary(this /* context */, word); - mInputLogic.onAddWordToUserDictionary(); - } - // Callback for the {@link SuggestionStripView}, to call when the important notice strip is // pressed. @Override @@ -1557,19 +1459,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return null != mSuggestionStripView; } - @Override - public boolean isShowingAddToDictionaryHint() { - return hasSuggestionStripView() && mSuggestionStripView.isShowingAddToDictionaryHint(); - } - - @Override - public void dismissAddToDictionaryHint() { - if (!hasSuggestionStripView()) { - return; - } - mSuggestionStripView.dismissAddToDictionaryHint(); - } - private void setSuggestedWords(final SuggestedWords suggestedWords) { final SettingsValues currentSettingsValues = mSettings.getCurrent(); mInputLogic.setSuggestedWords(suggestedWords); @@ -1631,7 +1520,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return; } mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard.getProximityInfo(), - mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback); + mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback, + keyboard.getKeyboardLayout()); } @Override @@ -1658,21 +1548,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen updateStateAfterInputTransaction(completeInputTransaction); } - @Override - public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip) { - if (!hasSuggestionStripView()) { - return; - } - final String wordToShow; - if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) { - wordToShow = word.toLowerCase(mDictionaryFacilitator.getMostProbableLocale()); - } else { - wordToShow = word; - } - mSuggestionStripView.showAddToDictionaryHint(wordToShow, - isFromSuggestionStrip /* shouldShowWordToSave */); - } - // This will show either an empty suggestion strip (if prediction is enabled) or // punctuation suggestions (if it's disabled). @Override @@ -1935,7 +1810,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mDictionaryFacilitator.resetDictionaries(this, new Locale[] { locale }, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, - settingsValues.mAccount, + settingsValues.mAccount, "", /* dictionaryNamePrefix */ this /* DictionaryInitializationListener */); } @@ -1943,7 +1818,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @UsedForTesting /* package for test */ void clearPersonalizedDictionariesForTest() { mDictionaryFacilitator.clearUserHistoryDictionary(); - mDictionaryFacilitator.clearPersonalizationDictionary(); } @UsedForTesting diff --git a/java/src/com/android/inputmethod/latin/NgramContext.java b/java/src/com/android/inputmethod/latin/NgramContext.java index b47731229..86155e0be 100644 --- a/java/src/com/android/inputmethod/latin/NgramContext.java +++ b/java/src/com/android/inputmethod/latin/NgramContext.java @@ -19,9 +19,10 @@ package com.android.inputmethod.latin; import android.text.TextUtils; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.StringUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; +import java.util.ArrayList; import java.util.Arrays; import javax.annotation.Nonnull; @@ -38,6 +39,10 @@ public class NgramContext { public static final NgramContext BEGINNING_OF_SENTENCE = new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + public static final String BEGINNING_OF_SENTENCE_TAG = "<S>"; + + public static final String CONTEXT_SEPARATOR = " "; + /** * Word information used to represent previous words information. */ @@ -106,14 +111,39 @@ public class NgramContext { // Create next prevWordsInfo using current prevWordsInfo. @Nonnull public NgramContext getNextNgramContext(final WordInfo wordInfo) { - final int nextPrevWordCount = Math.min(Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, - mPrevWordsCount + 1); + final int nextPrevWordCount = Math.min( + DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, mPrevWordsCount + 1); final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount]; prevWordsInfo[0] = wordInfo; System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1); return new NgramContext(prevWordsInfo); } + + /** + * Extracts the previous words context. + * + * @return a String with the previous words separated by white space. + */ + public String extractPrevWordsContext() { + final ArrayList<String> terms = new ArrayList<>(); + for (int i = mPrevWordsInfo.length - 1; i >= 0; --i) { + if (mPrevWordsInfo[i] != null && mPrevWordsInfo[i].isValid()) { + final NgramContext.WordInfo wordInfo = mPrevWordsInfo[i]; + if (wordInfo.mIsBeginningOfSentence) { + terms.add(BEGINNING_OF_SENTENCE_TAG); + } else { + final String term = wordInfo.mWord.toString(); + if (!term.isEmpty()) { + terms.add(term); + } + } + } + } + return terms.size() == 0 ? BEGINNING_OF_SENTENCE_TAG + : TextUtils.join(CONTEXT_SEPARATOR, terms); + } + public boolean isValid() { return mPrevWordsCount > 0 && mPrevWordsInfo[0].isValid(); } diff --git a/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java deleted file mode 100644 index 8926c06b1..000000000 --- a/java/src/com/android/inputmethod/latin/PersonalizationHelperForDictionaryFacilitator.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicInteger; - -import android.content.Context; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.ExpandableBinaryDictionary.UpdateEntriesForInputEventsCallback; -import com.android.inputmethod.latin.personalization.PersonalizationDataChunk; -import com.android.inputmethod.latin.personalization.PersonalizationDictionary; -import com.android.inputmethod.latin.settings.SpacingAndPunctuations; -import com.android.inputmethod.latin.utils.DistracterFilter; -import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary; -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; -import com.android.inputmethod.latin.utils.WordInputEventForPersonalization; - -/** - * Class for managing and updating personalization dictionaries. - */ -public class PersonalizationHelperForDictionaryFacilitator { - private final Context mContext; - private final DistracterFilter mDistracterFilter; - private final HashMap<String, HashSet<Locale>> mLangToLocalesMap = new HashMap<>(); - private final HashMap<Locale, ExpandableBinaryDictionary> mPersonalizationDictsToUpdate = - new HashMap<>(); - private boolean mIsMonolingualUser = false; - - PersonalizationHelperForDictionaryFacilitator(final Context context, - final DistracterFilter distracterFilter) { - mContext = context; - mDistracterFilter = distracterFilter; - } - - public void close() { - mLangToLocalesMap.clear(); - for (final ExpandableBinaryDictionary dict : mPersonalizationDictsToUpdate.values()) { - dict.close(); - } - mPersonalizationDictsToUpdate.clear(); - } - - public void clearDictionariesToUpdate() { - for (final ExpandableBinaryDictionary dict : mPersonalizationDictsToUpdate.values()) { - dict.clear(); - } - mPersonalizationDictsToUpdate.clear(); - } - - public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) { - for (final InputMethodSubtype subtype : enabledSubtypes) { - final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype); - final String language = locale.getLanguage(); - final HashSet<Locale> locales = mLangToLocalesMap.get(language); - if (locales != null) { - locales.add(locale); - } else { - final HashSet<Locale> localeSet = new HashSet<>(); - localeSet.add(locale); - mLangToLocalesMap.put(language, localeSet); - } - } - } - - public void setIsMonolingualUser(final boolean isMonolingualUser) { - mIsMonolingualUser = isMonolingualUser; - } - - /** - * Flush personalization dictionaries to dictionary files. Close dictionaries after writing - * files except the dictionaries that is used for generating suggestions. - * - * @param personalizationDictsUsedForSuggestion the personalization dictionaries used for - * generating suggestions that won't be closed. - */ - public void flushPersonalizationDictionariesToUpdate( - final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion) { - for (final ExpandableBinaryDictionary personalizationDict : - mPersonalizationDictsToUpdate.values()) { - personalizationDict.asyncFlushBinaryDictionary(); - if (!personalizationDictsUsedForSuggestion.contains(personalizationDict)) { - // Close if the dictionary is not being used for suggestion. - personalizationDict.close(); - } - } - mDistracterFilter.close(); - mPersonalizationDictsToUpdate.clear(); - } - - private ExpandableBinaryDictionary getPersonalizationDictToUpdate(final Context context, - final Locale locale) { - ExpandableBinaryDictionary personalizationDict = mPersonalizationDictsToUpdate.get(locale); - if (personalizationDict != null) { - return personalizationDict; - } - personalizationDict = PersonalizationDictionary.getDictionary(context, locale, - null /* dictFile */, "" /* dictNamePrefix */, null /* account */); - mPersonalizationDictsToUpdate.put(locale, personalizationDict); - return personalizationDict; - } - - private void updateEntriesOfPersonalizationDictionariesForLocale(final Locale locale, - final PersonalizationDataChunk personalizationDataChunk, - final SpacingAndPunctuations spacingAndPunctuations, - final UpdateEntriesForInputEventsCallback callback) { - final ExpandableBinaryDictionary personalizationDict = - getPersonalizationDictToUpdate(mContext, locale); - if (personalizationDict == null) { - if (callback != null) { - callback.onFinished(); - } - return; - } - final ArrayList<WordInputEventForPersonalization> inputEvents = - WordInputEventForPersonalization.createInputEventFrom( - personalizationDataChunk.mTokens, - personalizationDataChunk.mTimestampInSeconds, spacingAndPunctuations, - locale, new DistracterFilterCheckingIsInDictionary( - mDistracterFilter, personalizationDict)); - if (inputEvents == null || inputEvents.isEmpty()) { - if (callback != null) { - callback.onFinished(); - } - return; - } - personalizationDict.updateEntriesForInputEvents(inputEvents, callback); - } - - public void updateEntriesOfPersonalizationDictionaries(final Locale defaultLocale, - final PersonalizationDataChunk personalizationDataChunk, - final SpacingAndPunctuations spacingAndPunctuations, - final UpdateEntriesForInputEventsCallback callback) { - final String language = personalizationDataChunk.mDetectedLanguage; - final HashSet<Locale> locales; - if (mIsMonolingualUser && PersonalizationDataChunk.LANGUAGE_UNKNOWN.equals(language) - && mLangToLocalesMap.size() == 1) { - locales = mLangToLocalesMap.get(defaultLocale.getLanguage()); - } else { - locales = mLangToLocalesMap.get(language); - } - if (locales == null || locales.isEmpty()) { - if (callback != null) { - callback.onFinished(); - } - return; - } - final AtomicInteger remainingTaskCount = new AtomicInteger(locales.size()); - final UpdateEntriesForInputEventsCallback callbackForLocales = - new UpdateEntriesForInputEventsCallback() { - @Override - public void onFinished() { - if (remainingTaskCount.decrementAndGet() == 0) { - // Update tasks for all locales have been finished. - if (callback != null) { - callback.onFinished(); - } - } - } - }; - for (final Locale locale : locales) { - updateEntriesOfPersonalizationDictionariesForLocale(locale, personalizationDataChunk, - spacingAndPunctuations, callbackForLocales); - } - } -} diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 834f747d9..0210d7e18 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -16,14 +16,14 @@ package com.android.inputmethod.latin; -import android.graphics.Color; +import static com.android.inputmethod.latin.define.DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; + import android.inputmethodservice.InputMethodService; import android.os.Build; import android.os.Bundle; import android.text.SpannableStringBuilder; -import android.text.Spanned; import android.text.TextUtils; -import android.text.style.BackgroundColorSpan; +import android.text.style.CharacterStyle; import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; @@ -35,7 +35,9 @@ import android.view.inputmethod.InputMethodManager; import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.UnicodeSurrogate; import com.android.inputmethod.latin.common.StringUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.CapsModeUtils; @@ -61,9 +63,9 @@ public final class RichInputConnection implements PrivateCommandPerformer { private static final boolean DEBUG_PREVIOUS_TEXT = false; private static final boolean DEBUG_BATCH_NESTING = false; // Provision for long words and separators between the words. - private static final int LOOKBACK_CHARACTER_NUM = Constants.DICTIONARY_MAX_WORD_LENGTH - * (Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1) /* words */ - + Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM /* separators */; + private static final int LOOKBACK_CHARACTER_NUM = DICTIONARY_MAX_WORD_LENGTH + * (DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM + 1) /* words */ + + DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM /* separators */; private static final int INVALID_CURSOR_POSITION = -1; /** @@ -91,16 +93,10 @@ public final class RichInputConnection implements PrivateCommandPerformer { private final StringBuilder mComposingText = new StringBuilder(); /** - * This variable is a temporary object used in - * {@link #commitTextWithBackgroundColor(CharSequence,int,int,int)} to avoid object creation. + * This variable is a temporary object used in {@link #commitText(CharSequence,int)} + * to avoid object creation. */ private SpannableStringBuilder mTempObjectForCommitText = new SpannableStringBuilder(); - /** - * This variable is used to track whether the last committed text had the background color or - * not. - * TODO: Omit this flag if possible. - */ - private boolean mLastCommittedTextHasBackgroundColor = false; private final InputMethodService mParent; InputConnection mIC; @@ -239,39 +235,18 @@ public final class RichInputConnection implements PrivateCommandPerformer { // it works, but it's wrong and should be fixed. mCommittedTextBeforeComposingText.append(mComposingText); mComposingText.setLength(0); - // TODO: Clear this flag in setComposingRegion() and setComposingText() as well if needed. - mLastCommittedTextHasBackgroundColor = false; if (null != mIC) { mIC.finishComposingText(); } } /** - * Synonym of {@code commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT}. + * Calls {@link InputConnection#commitText(CharSequence, int)}. + * * @param text The text to commit. This may include styles. - * See {@link InputConnection#commitText(CharSequence, int)}. * @param newCursorPosition The new cursor position around the text. - * See {@link InputConnection#commitText(CharSequence, int)}. */ public void commitText(final CharSequence text, final int newCursorPosition) { - commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT, text.length()); - } - - /** - * Calls {@link InputConnection#commitText(CharSequence, int)} with the given background color. - * @param text The text to commit. This may include styles. - * See {@link InputConnection#commitText(CharSequence, int)}. - * @param newCursorPosition The new cursor position around the text. - * See {@link InputConnection#commitText(CharSequence, int)}. - * @param color The background color to be attached. Set {@link Color#TRANSPARENT} to disable - * the background color. Note that this method specifies {@link BackgroundColorSpan} with - * {@link Spanned#SPAN_COMPOSING} flag, meaning that the background color persists until - * {@link #finishComposingText()} is called. - * @param coloredTextLength the length of text, in Java chars, which should be rendered with - * the given background color. - */ - public void commitTextWithBackgroundColor(final CharSequence text, final int newCursorPosition, - final int color, final int coloredTextLength) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); mCommittedTextBeforeComposingText.append(text); @@ -281,44 +256,32 @@ public final class RichInputConnection implements PrivateCommandPerformer { mExpectedSelStart += text.length() - mComposingText.length(); mExpectedSelEnd = mExpectedSelStart; mComposingText.setLength(0); - mLastCommittedTextHasBackgroundColor = false; if (null != mIC) { - if (color == Color.TRANSPARENT) { - mIC.commitText(text, newCursorPosition); - } else { - mTempObjectForCommitText.clear(); - mTempObjectForCommitText.append(text); - final BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(color); - final int spanLength = Math.min(coloredTextLength, text.length()); - mTempObjectForCommitText.setSpan(backgroundColorSpan, 0, spanLength, - Spanned.SPAN_COMPOSING | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - mIC.commitText(mTempObjectForCommitText, newCursorPosition); - mLastCommittedTextHasBackgroundColor = true; + mTempObjectForCommitText.clear(); + mTempObjectForCommitText.append(text); + final CharacterStyle[] spans = mTempObjectForCommitText.getSpans( + 0, text.length(), CharacterStyle.class); + for (final CharacterStyle span : spans) { + final int spanStart = mTempObjectForCommitText.getSpanStart(span); + final int spanEnd = mTempObjectForCommitText.getSpanEnd(span); + final int spanFlags = mTempObjectForCommitText.getSpanFlags(span); + // We have to adjust the end of the span to include an additional character. + // This is to avoid splitting a unicode surrogate pair. + // See com.android.inputmethod.latin.common.Constants.UnicodeSurrogate + // See https://b.corp.google.com/issues/19255233 + if (0 < spanEnd && spanEnd < mTempObjectForCommitText.length()) { + final char spanEndChar = mTempObjectForCommitText.charAt(spanEnd - 1); + final char nextChar = mTempObjectForCommitText.charAt(spanEnd); + if (UnicodeSurrogate.isLowSurrogate(spanEndChar) + && UnicodeSurrogate.isHighSurrogate(nextChar)) { + mTempObjectForCommitText.setSpan(span, spanStart, spanEnd + 1, spanFlags); + } + } } + mIC.commitText(mTempObjectForCommitText, newCursorPosition); } } - /** - * Removes the background color from the highlighted text if necessary. Should be called while - * there is no on-going composing text. - * - * <p>CAVEAT: This method internally calls {@link InputConnection#finishComposingText()}. - * Be careful of any unexpected side effects.</p> - */ - public void removeBackgroundColorFromHighlightedTextIfNecessary() { - // TODO: We haven't yet full tested if we really need to check this flag or not. Omit this - // flag if everything works fine without this condition. - if (!mLastCommittedTextHasBackgroundColor) { - return; - } - if (mComposingText.length() > 0) { - Log.e(TAG, "clearSpansWithComposingFlags should be called when composing text is " + - "empty. mComposingText=" + mComposingText); - return; - } - finishComposingText(); - } - public CharSequence getSelectedText(final int flags) { return (null == mIC) ? null : mIC.getSelectedText(flags); } @@ -946,8 +909,6 @@ public final class RichInputConnection implements PrivateCommandPerformer { } } - private boolean mCursorAnchorInfoMonitorEnabled = false; - /** * Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}. * @param enableMonitor {@code true} to request the editor to call back the method whenever the @@ -962,23 +923,10 @@ public final class RichInputConnection implements PrivateCommandPerformer { public boolean requestCursorUpdates(final boolean enableMonitor, final boolean requestImmediateCallback) { mIC = mParent.getCurrentInputConnection(); - final boolean scheduled; - if (null != mIC) { - scheduled = InputConnectionCompatUtils.requestCursorUpdates(mIC, enableMonitor, - requestImmediateCallback); - } else { - scheduled = false; + if (mIC == null) { + return false; } - mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor); - return scheduled; - } - - /** - * @return {@code true} if the application reported that the monitor mode of - * {@link InputMethodService#onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo)} - * is currently enabled. - */ - public boolean isCursorAnchorInfoMonitorEnabled() { - return mCursorAnchorInfoMonitorEnabled; + return InputConnectionCompatUtils.requestCursorUpdates( + mIC, enableMonitor, requestImmediateCallback); } } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 0bf0f687a..ddb2b5358 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.text.TextUtils; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.common.Constants; @@ -97,14 +98,16 @@ public final class Suggest { final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber, - final OnGetSuggestedWordsCallback callback) { + final OnGetSuggestedWordsCallback callback, + final KeyboardLayout keyboardLayout) { if (wordComposer.isBatchMode()) { getSuggestedWordsForBatchInput(wordComposer, ngramContext, proximityInfo, - settingsValuesForSuggestion, inputStyle, sequenceNumber, callback); + settingsValuesForSuggestion, inputStyle, sequenceNumber, callback, + keyboardLayout); } else { getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, inputStyle, isCorrectionEnabled, - sequenceNumber, callback); + sequenceNumber, callback, keyboardLayout); } } @@ -163,7 +166,8 @@ public final class Suggest { final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled, - final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { + final int sequenceNumber, final OnGetSuggestedWordsCallback callback, + final KeyboardLayout keyboardLayout) { final String typedWordString = wordComposer.getTypedWord(); final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWordString); @@ -173,7 +177,8 @@ public final class Suggest { final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(), - settingsValuesForSuggestion, SESSION_ID_TYPING); + settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction, + keyboardLayout); final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale(); final ArrayList<SuggestedWordInfo> suggestionsContainer = getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, @@ -270,7 +275,9 @@ public final class Suggest { hasAutoCorrection = false; } else { final SuggestedWordInfo firstSuggestion = suggestionResults.first(); - if (!AutoCorrectionUtils.suggestionExceedsThreshold( + if (suggestionResults.mAutocorrectRecommendation) { + hasAutoCorrection = true; + } else if (!AutoCorrectionUtils.suggestionExceedsThreshold( firstSuggestion, consideredWord, mAutoCorrectionThreshold)) { // Score is too low for autocorrect hasAutoCorrection = false; @@ -339,10 +346,11 @@ public final class Suggest { final NgramContext ngramContext, final ProximityInfo proximityInfo, final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyle, final int sequenceNumber, - final OnGetSuggestedWordsCallback callback) { + final OnGetSuggestedWordsCallback callback, + final KeyboardLayout keyboardLayout) { final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(), - settingsValuesForSuggestion, SESSION_ID_GESTURE); + settingsValuesForSuggestion, SESSION_ID_GESTURE, inputStyle, keyboardLayout); // For transforming words that don't come from a dictionary, because it's our best bet final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale(); final ArrayList<SuggestedWordInfo> suggestionsContainer = diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index df8db0cd2..913b63a61 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -112,6 +112,14 @@ public class SuggestedWords { } /** + * Get {@link SuggestedWordInfo} object for the typed word. + * @return The {@link SuggestedWordInfo} object for the typed word. + */ + public SuggestedWordInfo getTypedWordInfo() { + return mTypedWordInfo; + } + + /** * Get suggested word at <code>index</code>. * @param index The index of the suggested word. * @return The suggested word. @@ -347,6 +355,14 @@ public class SuggestedWords { return mDebugString; } + public String getWord() { + return mWord; + } + + public Dictionary getSourceDictionary() { + return mSourceDict; + } + public int codePointAt(int i) { return mWord.codePointAt(i); } diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index 2d2b3d0a6..1ed210377 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -16,7 +16,6 @@ package com.android.inputmethod.latin; -import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; @@ -29,7 +28,6 @@ import android.text.TextUtils; import android.util.Log; import com.android.inputmethod.annotations.ExternallyReferenced; -import com.android.inputmethod.compat.UserDictionaryCompatUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.io.File; @@ -54,13 +52,13 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { private static final int USER_DICT_SHORTCUT_FREQUENCY = 14; private static final String[] PROJECTION_QUERY_WITH_SHORTCUT = new String[] { - Words.WORD, - Words.SHORTCUT, - Words.FREQUENCY, + Words.WORD, + Words.SHORTCUT, + Words.FREQUENCY, }; private static final String[] PROJECTION_QUERY_WITHOUT_SHORTCUT = new String[] { - Words.WORD, - Words.FREQUENCY, + Words.WORD, + Words.FREQUENCY, }; private static final String NAME = "userunigram"; @@ -70,7 +68,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { final private boolean mAlsoUseMoreRestrictiveLocales; protected UserBinaryDictionary(final Context context, final Locale locale, - final boolean alsoUseMoreRestrictiveLocales, final File dictFile, final String name) { + final boolean alsoUseMoreRestrictiveLocales, + final File dictFile, final String name) { super(context, getDictName(name, locale, dictFile), locale, Dictionary.TYPE_USER, dictFile); if (null == locale) throw new NullPointerException(); // Catch the error earlier final String localeStr = locale.toString(); @@ -105,9 +104,11 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { // Note: This method is called by {@link DictionaryFacilitator} using Java reflection. @ExternallyReferenced - public static UserBinaryDictionary getDictionary(final Context context, final Locale locale, - final File dictFile, final String dictNamePrefix, @Nullable final String account) { - return new UserBinaryDictionary(context, locale, false /* alsoUseMoreRestrictiveLocales */, + public static UserBinaryDictionary getDictionary( + final Context context, final Locale locale, final File dictFile, + final String dictNamePrefix, @Nullable final String account) { + return new UserBinaryDictionary( + context, locale, false /* alsoUseMoreRestrictiveLocales */, dictFile, dictNamePrefix + NAME); } @@ -187,7 +188,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { } private void addWordsFromProjectionLocked(final String[] query, String request, - final String[] requestArguments) throws IllegalArgumentException { + final String[] requestArguments) + throws IllegalArgumentException { Cursor cursor = null; try { cursor = mContext.getContentResolver().query( @@ -204,31 +206,6 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { } } - public static boolean isEnabled(final Context context) { - final ContentResolver cr = context.getContentResolver(); - final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI); - if (client != null) { - client.release(); - return true; - } - return false; - } - - /** - * Adds a word to the user dictionary and makes it persistent. - * - * @param context the context - * @param locale the locale - * @param word the word to add. If the word is capitalized, then the dictionary will - * recognize it as a capitalized word when searched. - */ - public static void addWordToUserDictionary(final Context context, final Locale locale, - final String word) { - // Update the user dictionary provider - UserDictionaryCompatUtils.addWord(context, word, - HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY, null, locale); - } - private static int scaleFrequencyFromDefaultToLatinIme(final int defaultFrequency) { // The default frequency for the user dictionary is 250 for historical reasons. // Latin IME considers a good value for the default user dictionary frequency diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index e80e3628f..32ef1021d 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.event.CombinerChain; import com.android.inputmethod.event.Event; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -25,6 +26,7 @@ import com.android.inputmethod.latin.common.CoordinateUtils; import com.android.inputmethod.latin.common.InputPointers; import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.define.DebugFlags; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import java.util.ArrayList; import java.util.Collections; @@ -35,7 +37,7 @@ import javax.annotation.Nonnull; * A place to store the currently composing word with information such as adjacent key codes as well */ public final class WordComposer { - private static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH; + private static final int MAX_WORD_LENGTH = DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; private static final boolean DBG = DebugFlags.DEBUG_ENABLED; public static final int CAPS_MODE_OFF = 0; @@ -464,4 +466,14 @@ public final class WordComposer { public String getRejectedBatchModeSuggestion() { return mRejectedBatchModeSuggestion; } + + @UsedForTesting + void addInputPointerForTest(int index, int keyX, int keyY) { + mInputPointers.addPointerAt(index, keyX, keyY, 0, 0); + } + + @UsedForTesting + void setTypedWordCacheForTests(String typedWordCacheForTests) { + mTypedWordCache = typedWordCacheForTests; + } } diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 4842438c8..9154cc35a 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -17,7 +17,6 @@ package com.android.inputmethod.latin.inputlogic; import android.graphics.Color; -import android.inputmethodservice.InputMethodService; import android.os.SystemClock; import android.text.SpannableString; import android.text.Spanned; @@ -28,17 +27,14 @@ import android.util.Log; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.inputmethod.CorrectionInfo; -import android.view.inputmethod.CursorAnchorInfo; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.event.Event; import com.android.inputmethod.event.InputTransaction; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.ProximityInfo; -import com.android.inputmethod.keyboard.TextDecorator; -import com.android.inputmethod.keyboard.TextDecoratorUiOperator; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.LastComposedWord; @@ -91,14 +87,6 @@ public final class InputLogic { public final Suggest mSuggest; private final DictionaryFacilitator mDictionaryFacilitator; - private final TextDecorator mTextDecorator = new TextDecorator(new TextDecorator.Listener() { - @Override - public void onClickComposingTextToAddToDictionary(final String word) { - mLatinIME.addWordToUserDictionary(word); - mLatinIME.dismissAddToDictionaryHint(); - } - }); - public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; // This has package visibility so it can be accessed from InputLogicHandler. /* package */ final WordComposer mWordComposer; @@ -174,7 +162,6 @@ public final class InputLogic { mConnection.requestCursorUpdates(true /* enableMonitor */, true /* requestImmediateCallback */); } - mTextDecorator.reset(); } /** @@ -269,20 +256,6 @@ public final class InputLogic { } /** - * Determines whether "Touch again to save" should be shown or not. - * @param suggestionInfo the suggested word chosen by the user. - * @return {@code true} if we should show the "Touch again to save" hint. - */ - private boolean shouldShowAddToDictionaryHint(final SuggestedWordInfo suggestionInfo) { - // We should show the "Touch again to save" hint if the user pressed the first entry - // AND it's in none of our current dictionaries (main, user or otherwise). - return (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_TYPED) - || suggestionInfo.isKindOf(SuggestedWordInfo.KIND_OOV_CORRECTION)) - && !mDictionaryFacilitator.isValidWord(suggestionInfo.mWord, true /* ignoreCase */) - && mDictionaryFacilitator.isUserDictionaryEnabled(); - } - - /** * A suggestion was picked from the suggestion strip. * @param settingsValues the current values of the settings. * @param suggestionInfo the suggestion info. @@ -340,7 +313,6 @@ public final class InputLogic { return inputTransaction; } - final boolean shouldShowAddToDictionaryHint = shouldShowAddToDictionaryHint(suggestionInfo); commitChosenWord(settingsValues, suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR); mConnection.endBatchEdit(); @@ -350,14 +322,9 @@ public final class InputLogic { mSpaceState = SpaceState.PHANTOM; inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); - if (shouldShowAddToDictionaryHint) { - mSuggestionStripViewAccessor.suggestAddingToDictionary(suggestion, - true /* isFromSuggestionStrip */); - } else { - // If we're not showing the "Touch again to save", then update the suggestion strip. - // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE. - handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE); - } + // If we're not showing the "Touch again to save", then update the suggestion strip. + // That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE. + handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE); StatsUtils.onPickSuggestionManually(mSuggestedWords, suggestionInfo); StatsUtils.onWordCommitSuggestionPickedManually( @@ -431,11 +398,6 @@ public final class InputLogic { // The cursor has been moved : we now accept to perform recapitalization mRecapitalizeStatus.enable(); - // We moved the cursor and need to invalidate the indicator right now. - mTextDecorator.reset(); - // Remaining background color that was used for the add-to-dictionary indicator should be - // removed. - mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); // We moved the cursor. If we are touching a word, we need to resume suggestion. mLatinIME.mHandler.postResumeSuggestions(true /* shouldDelay */); // Stop the last recapitalization, if started. @@ -513,9 +475,7 @@ public final class InputLogic { handler.cancelUpdateSuggestionStrip(); ++mAutoCommitSequenceNumber; mConnection.beginBatchEdit(); - if (!mWordComposer.isComposingWord()) { - mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); - } else { + if (mWordComposer.isComposingWord()) { if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) { // If we are in the middle of a recorrection, we need to commit the recorrection // first so that we can insert the batch input at the current cursor position. @@ -806,16 +766,6 @@ public final class InputLogic { final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { - if (!mWordComposer.isComposingWord()) { - mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); - // In case the "add to dictionary" hint was still displayed. - // TODO: Do we really need to check if we have composing text here? - if (mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) { - mSuggestionStripViewAccessor.dismissAddToDictionaryHint(); - mTextDecorator.reset(); - } - } - final int codePoint = event.mCodePoint; mSpaceState = SpaceState.NONE; if (inputTransaction.mSettingsValues.isWordSeparator(codePoint) @@ -1639,20 +1589,8 @@ public final class InputLogic { 0 /* start */, lastCharIndex /* end */, 0 /* flags */); } - final boolean shouldShowAddToDictionaryForTypedWord = - shouldShowAddToDictionaryForTypedWord(mLastComposedWord, settingsValues); - if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) { - // For languages with spaces, we revert to the typed string, but the cursor is still - // after the separator so we don't resume suggestions. If the user wants to correct - // the word, they have to press backspace again. - if (shouldShowAddToDictionaryForTypedWord) { - mConnection.commitTextWithBackgroundColor(textToCommit, 1, - settingsValues.mTextHighlightColorForAddToDictionaryIndicator, - originallyTypedWordString.length()); - } else { - mConnection.commitText(textToCommit, 1); - } + mConnection.commitText(textToCommit, 1); if (usePhantomSpace) { mSpaceState = SpaceState.PHANTOM; } @@ -1662,33 +1600,13 @@ public final class InputLogic { final int[] codePoints = StringUtils.toCodePointArray(stringToCommit); mWordComposer.setComposingWord(codePoints, mLatinIME.getCoordinatesForCurrentKeyboard(codePoints)); - if (shouldShowAddToDictionaryForTypedWord) { - setComposingTextInternalWithBackgroundColor(textToCommit, 1, - settingsValues.mTextHighlightColorForAddToDictionaryIndicator, - originallyTypedWordString.length()); - } else { - setComposingTextInternal(textToCommit, 1); - } + setComposingTextInternal(textToCommit, 1); } // Don't restart suggestion yet. We'll restart if the user deletes the separator. mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; - if (shouldShowAddToDictionaryForTypedWord) { - // Due to the API limitation as of L, we cannot reliably retrieve the reverted text - // when the separator causes line breaking. Until this API limitation is addressed in - // the framework, show the indicator only when the separator doesn't contain - // line-breaking characters. - if (!StringUtils.hasLineBreakCharacter(separatorString)) { - mTextDecorator.showAddToDictionaryIndicator(originallyTypedWordString, - mConnection.getExpectedSelectionStart(), - mConnection.getExpectedSelectionEnd()); - } - mSuggestionStripViewAccessor.suggestAddingToDictionary(originallyTypedWordString, - false /* isFromSuggestionStrip */); - } else { - // We have a separator between the word and the cursor: we should show predictions. - inputTransaction.setRequiresUpdateSuggestions(); - } + // We have a separator between the word and the cursor: we should show predictions. + inputTransaction.setRequiresUpdateSuggestions(); } /** @@ -2192,7 +2110,8 @@ public final class InputLogic { public void getSuggestedWords(final SettingsValues settingsValues, final ProximityInfo proximityInfo, final int keyboardShiftMode, final int inputStyle, - final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { + final int sequenceNumber, final OnGetSuggestedWordsCallback callback, + final KeyboardLayout keyboardLayout) { mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions( getActualCapsMode(settingsValues, keyboardShiftMode)); mSuggest.getSuggestedWords(mWordComposer, @@ -2206,7 +2125,7 @@ public final class InputLogic { new SettingsValuesForSuggestion(settingsValues.mBlockPotentiallyOffensive, settingsValues.mPhraseGestureEnabled), settingsValues.mAutoCorrectionEnabledPerUserSettings, - inputStyle, sequenceNumber, callback); + inputStyle, sequenceNumber, callback, keyboardLayout); } /** @@ -2215,7 +2134,7 @@ public final class InputLogic { * * <p>Currently using this method is optional and you can still directly call * {@link RichInputConnection#setComposingText(CharSequence, int)}, but it is recommended to - * use this method whenever possible to optimize the behavior of {@link TextDecorator}.<p> + * use this method whenever possible.<p> * <p>TODO: Should we move this mechanism to {@link RichInputConnection}?</p> * * @param newComposingText the composing text to be set @@ -2300,71 +2219,4 @@ public final class InputLogic { public int getComposingLength() { return mWordComposer.size(); } - - ////////////////////////////////////////////////////////////////////////////////////////////// - // Following methods are tentatively placed in this class for the integration with - // TextDecorator. - // TODO: Decouple things that are not related to the input logic. - ////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Sets the UI operator for {@link TextDecorator}. - * @param uiOperator the UI operator which should be associated with {@link TextDecorator}. - */ - public void setTextDecoratorUi(@Nonnull final TextDecoratorUiOperator uiOperator) { - mTextDecorator.setUiOperator(uiOperator); - } - - /** - * Must be called from {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} is - * called. - * @param info The wrapper object with which we can access cursor/anchor info. - */ - public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) { - mTextDecorator.onUpdateCursorAnchorInfo(info); - } - - /** - * Must be called when {@link InputMethodService#updateFullscreenMode} is called. - * @param isFullscreen {@code true} if the input method is in full-screen mode. - */ - public void onUpdateFullscreenMode(final boolean isFullscreen) { - mTextDecorator.notifyFullScreenMode(isFullscreen); - } - - /** - * Must be called from {@link LatinIME#addWordToUserDictionary(String)}. - */ - public void onAddWordToUserDictionary() { - mConnection.removeBackgroundColorFromHighlightedTextIfNecessary(); - mTextDecorator.reset(); - } - - /** - * Returns whether the add to dictionary indicator should be shown or not. - * @param lastComposedWord the last composed word information. - * @param settingsValues the current settings value. - * @return {@code true} if the commit indicator should be shown. - */ - private boolean shouldShowAddToDictionaryForTypedWord(final LastComposedWord lastComposedWord, - final SettingsValues settingsValues) { - if (!mConnection.isCursorAnchorInfoMonitorEnabled()) { - // We cannot help in this case because we are heavily relying on this new API. - return false; - } - if (!settingsValues.mShouldShowLxxSuggestionUi) { - return false; - } - if (TextUtils.isEmpty(lastComposedWord.mTypedWord)) { - return false; - } - if (TextUtils.equals(lastComposedWord.mTypedWord, lastComposedWord.mCommittedWord)) { - return false; - } - if (!mDictionaryFacilitator.isUserDictionaryEnabled()) { - return false; - } - return !mDictionaryFacilitator.isValidWord(lastComposedWord.mTypedWord, - true /* ignoreCase */); - } } diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java index eba9654a5..3348a3767 100644 --- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java +++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java @@ -17,7 +17,7 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import java.util.Date; import java.util.HashMap; @@ -186,7 +186,7 @@ public final class FormatSpec { // TODO: Make this value adaptative to content data, store it in the header, and // use it in the reading code. - static final int MAX_WORD_LENGTH = Constants.DICTIONARY_MAX_WORD_LENGTH; + static final int MAX_WORD_LENGTH = DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; // These flags are used only in the static dictionary. static final int MASK_CHILDREN_ADDRESS_TYPE = 0xC0; diff --git a/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java b/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java deleted file mode 100644 index f663fe96a..000000000 --- a/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin.personalization; - -import android.content.Context; - -import com.android.inputmethod.annotations.ExternallyReferenced; -import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.ExpandableBinaryDictionary; - -import java.io.File; -import java.util.Locale; - -import javax.annotation.Nullable; - -public class ContextualDictionary extends ExpandableBinaryDictionary { - /* package */ static final String NAME = ContextualDictionary.class.getSimpleName(); - - private ContextualDictionary(final Context context, final Locale locale, - final File dictFile) { - super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_CONTEXTUAL, - dictFile); - // Always reset the contents. - clear(); - } - - // Note: This method is called by {@link DictionaryFacilitator} using Java reflection. - @SuppressWarnings("unused") - @ExternallyReferenced - public static ContextualDictionary getDictionary(final Context context, final Locale locale, - final File dictFile, final String dictNamePrefix, @Nullable final String account) { - return new ContextualDictionary(context, locale, dictFile); - } - - @Override - public boolean isValidWord(final String word) { - // Strings out of this dictionary should not be considered existing words. - return false; - } - - @Override - protected void loadInitialContentsLocked() { - } -} diff --git a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java index e974f3320..0c5e5d010 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java +++ b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java @@ -84,7 +84,6 @@ public class DictionaryDecayBroadcastReciever extends BroadcastReceiver { final String action = intent.getAction(); if (action.equals(DICTIONARY_DECAY_INTENT_ACTION)) { PersonalizationHelper.runGCOnAllOpenedUserHistoryDictionaries(); - PersonalizationHelper.runGCOnAllOpenedPersonalizationDictionaries(); } } } diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java deleted file mode 100644 index 734ed5583..000000000 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin.personalization; - -import java.util.Collections; -import java.util.List; - -public class PersonalizationDataChunk { - public static final String LANGUAGE_UNKNOWN = ""; - - public final boolean mInputByUser; - public final List<String> mTokens; - public final int mTimestampInSeconds; - public final String mPackageName; - public final String mDetectedLanguage; - - public PersonalizationDataChunk(boolean inputByUser, final List<String> tokens, - final int timestampInSeconds, final String packageName, final String detectedLanguage) { - mInputByUser = inputByUser; - mTokens = Collections.unmodifiableList(tokens); - mTimestampInSeconds = timestampInSeconds; - mPackageName = packageName; - mDetectedLanguage = detectedLanguage; - } -} diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java deleted file mode 100644 index 76451cc6b..000000000 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin.personalization; - -import android.content.Context; - -import com.android.inputmethod.annotations.ExternallyReferenced; -import com.android.inputmethod.latin.Dictionary; - -import java.io.File; -import java.util.Locale; - -import javax.annotation.Nullable; - -public class PersonalizationDictionary extends DecayingExpandableBinaryDictionaryBase { - /* package */ static final String NAME = PersonalizationDictionary.class.getSimpleName(); - - // TODO: Make this constructor private - /* package */ PersonalizationDictionary(final Context context, final Locale locale) { - super(context, getDictName(NAME, locale, null /* dictFile */), locale, - Dictionary.TYPE_PERSONALIZATION, null /* dictFile */); - } - - // Note: This method is called by {@link DictionaryFacilitator} using Java reflection. - @SuppressWarnings("unused") - @ExternallyReferenced - public static PersonalizationDictionary getDictionary(final Context context, - final Locale locale, final File dictFile, final String dictNamePrefix, - @Nullable final String account) { - return PersonalizationHelper.getPersonalizationDictionary(context, locale); - } -} diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java index 4231450c1..1c1cb4f95 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java @@ -32,8 +32,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; /** - * Helps handle and manage personalized dictionaries such as {@link UserHistoryDictionary} and - * {@link PersonalizationDictionary}. + * Helps handle and manage personalized dictionaries such as {@link UserHistoryDictionary}. */ public class PersonalizationHelper { private static final String TAG = PersonalizationHelper.class.getSimpleName(); @@ -41,8 +40,6 @@ public class PersonalizationHelper { private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>> sLangUserHistoryDictCache = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>> - sLangPersonalizationDictCache = new ConcurrentHashMap<>(); @Nonnull public static UserHistoryDictionary getUserHistoryDictionary( @@ -77,7 +74,6 @@ public class PersonalizationHelper { DictionaryDecayBroadcastReciever.DICTIONARY_DECAY_INTERVAL_IN_MILLIS) < currentTimestamp - sCurrentTimestampForTesting) { runGCOnAllOpenedUserHistoryDictionaries(); - runGCOnAllOpenedPersonalizationDictionaries(); } } @@ -85,10 +81,6 @@ public class PersonalizationHelper { runGCOnAllDictionariesIfRequired(sLangUserHistoryDictCache); } - public static void runGCOnAllOpenedPersonalizationDictionaries() { - runGCOnAllDictionariesIfRequired(sLangPersonalizationDictCache); - } - private static <T extends DecayingExpandableBinaryDictionaryBase> void runGCOnAllDictionariesIfRequired( final ConcurrentHashMap<String, SoftReference<T>> dictionaryMap) { @@ -103,32 +95,6 @@ public class PersonalizationHelper { } } - public static PersonalizationDictionary getPersonalizationDictionary( - final Context context, final Locale locale) { - final String localeStr = locale.toString(); - synchronized (sLangPersonalizationDictCache) { - if (sLangPersonalizationDictCache.containsKey(localeStr)) { - final SoftReference<PersonalizationDictionary> ref = - sLangPersonalizationDictCache.get(localeStr); - final PersonalizationDictionary dict = ref == null ? null : ref.get(); - if (dict != null) { - if (DEBUG) { - Log.w(TAG, "Use cached PersonalizationDictionary for " + locale); - } - return dict; - } - } - final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale); - sLangPersonalizationDictCache.put(localeStr, new SoftReference<>(dict)); - return dict; - } - } - - public static void removeAllPersonalizationDictionaries(final Context context) { - removeAllDictionaries(context, sLangPersonalizationDictCache, - PersonalizationDictionary.NAME); - } - public static void removeAllUserHistoryDictionaries(final Context context) { removeAllDictionaries(context, sLangUserHistoryDictCache, UserHistoryDictionary.NAME); diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java index 2e41027a4..1d75a3098 100644 --- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java @@ -17,17 +17,14 @@ package com.android.inputmethod.latin.personalization; import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; import com.android.inputmethod.annotations.ExternallyReferenced; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.ExpandableBinaryDictionary; import com.android.inputmethod.latin.NgramContext; -import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.define.ProductionFlags; -import com.android.inputmethod.latin.settings.LocalSettingsConstants; import com.android.inputmethod.latin.utils.DistracterFilter; import java.io.File; @@ -102,7 +99,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary, @Nonnull final NgramContext ngramContext, final String word, final boolean isValid, final int timestamp, @Nonnull final DistracterFilter distracterFilter) { - if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) { + if (word.length() > DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) { return; } userHistoryDictionary.updateEntriesForWordWithCheckingDistracter(ngramContext, word, diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index a080515dd..9a1bb7784 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -102,9 +102,6 @@ public class SettingsValues { private final boolean mSuggestionsEnabledPerUserSettings; private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds; - // TextDecorator - public final int mTextHighlightColorForAddToDictionaryIndicator; - // Debug settings public final boolean mIsInternal; public final boolean mHasCustomKeyPreviewAnimationParams; @@ -183,8 +180,6 @@ public class SettingsValues { mAutoCorrectionEnabledPerUserSettings = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect; mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs); - mTextHighlightColorForAddToDictionaryIndicator = res.getColor( - R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color); mIsInternal = Settings.isInternal(prefs); mHasCustomKeyPreviewAnimationParams = prefs.getBoolean( DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false); @@ -431,8 +426,6 @@ public class SettingsValues { sb.append("\n mAppWorkarounds = "); final AppWorkaroundsUtils awu = mAppWorkarounds.get(null, 0); sb.append("" + (null == awu ? "null" : awu.toString())); - sb.append("\n mTextHighlightColorForAddToDictionaryIndicator = "); - sb.append("" + mTextHighlightColorForAddToDictionaryIndicator); sb.append("\n mIsInternal = "); sb.append("" + mIsInternal); sb.append("\n mKeyPreviewShowUpDuration = "); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 8744020b1..02151522d 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -27,6 +27,7 @@ import android.view.textservice.SuggestionsInfo; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.DictionaryFacilitator; @@ -34,6 +35,7 @@ import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodSubtype; +import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.ScriptUtils; @@ -65,10 +67,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService // TODO: Make each spell checker session has its own session id. private final ConcurrentLinkedQueue<Integer> mSessionIdPool = new ConcurrentLinkedQueue<>(); - private static final int MAX_DICTIONARY_FACILITATOR_COUNT = 3; private final DictionaryFacilitatorLruCache mDictionaryFacilitatorCache = - new DictionaryFacilitatorLruCache(this /* context */, MAX_DICTIONARY_FACILITATOR_COUNT, - DICTIONARY_NAME_PREFIX); + new DictionaryFacilitatorLruCache(this /* context */, DICTIONARY_NAME_PREFIX); private final ConcurrentHashMap<Locale, Keyboard> mKeyboardCache = new ConcurrentHashMap<>(); // The threshold for a suggestion to be considered "recommended". @@ -152,14 +152,15 @@ public final class AndroidSpellCheckerService extends SpellCheckerService try { DictionaryFacilitator dictionaryFacilitatorForLocale = mDictionaryFacilitatorCache.get(locale); - return dictionaryFacilitatorForLocale.isValidWord(word, false /* igroreCase */); + return dictionaryFacilitatorForLocale.isValidSpellingWord(word); } finally { mSemaphore.release(); } } public SuggestionResults getSuggestionResults(final Locale locale, final WordComposer composer, - final NgramContext ngramContext, final ProximityInfo proximityInfo) { + final NgramContext ngramContext, final ProximityInfo proximityInfo, + final KeyboardLayout keyboardLayout) { Integer sessionId = null; mSemaphore.acquireUninterruptibly(); try { @@ -168,7 +169,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService mDictionaryFacilitatorCache.get(locale); return dictionaryFacilitatorForLocale.getSuggestionResults(composer, ngramContext, proximityInfo.getNativeProximityInfo(), mSettingsValuesForSuggestion, - sessionId); + sessionId, SuggestedWords.INPUT_STYLE_TYPING, keyboardLayout); } finally { if (sessionId != null) { mSessionIdPool.add(sessionId); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index 832bfd066..0b5e12f03 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -29,6 +29,7 @@ import android.view.textservice.TextInfo; import com.android.inputmethod.compat.SuggestionsInfoCompatUtils; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardLayout; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; @@ -271,18 +272,21 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { final int[] codePoints = StringUtils.toCodePointArray(text); final int[] coordinates; final ProximityInfo proximityInfo; + final KeyboardLayout keyboardLayout; if (null == keyboard) { coordinates = CoordinateUtils.newCoordinateArray(codePoints.length, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); proximityInfo = null; + keyboardLayout = null; } else { coordinates = keyboard.getCoordinates(codePoints); proximityInfo = keyboard.getProximityInfo(); + keyboardLayout = keyboard.getKeyboardLayout(); } composer.setComposingWord(codePoints, coordinates); // TODO: Don't gather suggestions if the limit is <= 0 unless necessary final SuggestionResults suggestionResults = mService.getSuggestionResults( - mLocale, composer, ngramContext, proximityInfo); + mLocale, composer, ngramContext, proximityInfo, keyboardLayout); final Result result = getResult(capitalizeType, mLocale, suggestionsLimit, mService.getRecommendedThreshold(), text, suggestionResults); isInDict = isInDictForAnyCapitalization(text, capitalizeType); diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index 7991a2473..a9d1207f1 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -28,7 +28,6 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.support.v4.view.ViewCompat; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; @@ -50,7 +49,6 @@ import com.android.inputmethod.latin.PunctuationSuggestions; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.common.LocaleUtils; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.utils.ResourceUtils; @@ -95,8 +93,6 @@ final class SuggestionStripLayoutHelper { private final int mTypedWordPositionWhenAutocorrect; private final Drawable mMoreSuggestionsHint; private static final String MORE_SUGGESTIONS_HINT = "\u2026"; - private static final String LEFTWARDS_ARROW = "\u2190"; - private static final String RIGHTWARDS_ARROW = "\u2192"; private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD); private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan(); @@ -540,55 +536,6 @@ final class SuggestionStripLayoutHelper { return countInStrip; } - public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip, - final boolean shouldShowWordToSave) { - final boolean showsHintWithWord = shouldShowWordToSave - || !Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi; - final int stripWidth = addToDictionaryStrip.getWidth(); - final int width = stripWidth - (showsHintWithWord ? mDividerWidth + mPadding * 2 : 0); - - final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save); - wordView.setTextColor(mColorTypedWord); - final int wordWidth = (int)(width * mCenterSuggestionWeight); - final CharSequence wordToSave = getEllipsizedTextWithSettingScaleX( - word, wordWidth, wordView.getPaint()); - final float wordScaleX = wordView.getTextScaleX(); - wordView.setText(wordToSave); - wordView.setTextScaleX(wordScaleX); - setLayoutWeight(wordView, mCenterSuggestionWeight, ViewGroup.LayoutParams.MATCH_PARENT); - final int wordVisibility = showsHintWithWord ? View.VISIBLE : View.GONE; - wordView.setVisibility(wordVisibility); - addToDictionaryStrip.findViewById(R.id.word_to_save_divider).setVisibility(wordVisibility); - - final Resources res = addToDictionaryStrip.getResources(); - final CharSequence hintText; - final int hintWidth; - final float hintWeight; - final TextView hintView = (TextView)addToDictionaryStrip.findViewById( - R.id.hint_add_to_dictionary); - if (showsHintWithWord) { - final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip) - == ViewCompat.LAYOUT_DIRECTION_RTL); - final String arrow = isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW; - final boolean isRtlSystem = LocaleUtils.isRtlLanguage(res.getConfiguration().locale); - final CharSequence hint = res.getText(R.string.hint_add_to_dictionary); - hintText = (isRtlLanguage == isRtlSystem) ? (arrow + hint) : (hint + arrow); - hintWidth = width - wordWidth; - hintWeight = 1.0f - mCenterSuggestionWeight; - hintView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START); - } else { - hintText = res.getText(R.string.hint_add_to_dictionary_without_word); - hintWidth = width; - hintWeight = 1.0f; - hintView.setGravity(Gravity.CENTER); - } - hintView.setTextColor(mColorAutoCorrect); - final float hintScaleX = getTextScaleX(hintText, hintWidth, hintView.getPaint()); - hintView.setText(hintText); // TextView.setText() resets text scale x to 1.0. - hintView.setTextScaleX(hintScaleX); - setLayoutWeight(hintView, hintWeight, ViewGroup.LayoutParams.MATCH_PARENT); - } - public void layoutImportantNotice(final View importantNoticeStrip, final String importantNoticeTitle) { final TextView titleView = (TextView)importantNoticeStrip.findViewById( diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index b71bd1f50..4b849496c 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -58,7 +58,6 @@ import java.util.ArrayList; public final class SuggestionStripView extends RelativeLayout implements OnClickListener, OnLongClickListener { public interface Listener { - public void addWordToUserDictionary(String word); public void showImportantNoticeContents(); public void pickSuggestionManually(SuggestedWordInfo word); public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); @@ -69,7 +68,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private final ViewGroup mSuggestionsStrip; private final ImageButton mVoiceKey; - private final ViewGroup mAddToDictionaryStrip; private final View mImportantNoticeStrip; MainKeyboardView mMainKeyboardView; @@ -91,15 +89,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick private static class StripVisibilityGroup { private final View mSuggestionStripView; private final View mSuggestionsStrip; - private final View mAddToDictionaryStrip; private final View mImportantNoticeStrip; public StripVisibilityGroup(final View suggestionStripView, - final ViewGroup suggestionsStrip, final ViewGroup addToDictionaryStrip, - final View importantNoticeStrip) { + final ViewGroup suggestionsStrip, final View importantNoticeStrip) { mSuggestionStripView = suggestionStripView; mSuggestionsStrip = suggestionsStrip; - mAddToDictionaryStrip = addToDictionaryStrip; mImportantNoticeStrip = importantNoticeStrip; showSuggestionsStrip(); } @@ -109,35 +104,22 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick : ViewCompat.LAYOUT_DIRECTION_LTR; ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection); ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); - ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection); ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection); } public void showSuggestionsStrip() { mSuggestionsStrip.setVisibility(VISIBLE); - mAddToDictionaryStrip.setVisibility(INVISIBLE); - mImportantNoticeStrip.setVisibility(INVISIBLE); - } - - public void showAddToDictionaryStrip() { - mSuggestionsStrip.setVisibility(INVISIBLE); - mAddToDictionaryStrip.setVisibility(VISIBLE); mImportantNoticeStrip.setVisibility(INVISIBLE); } public void showImportantNoticeStrip() { mSuggestionsStrip.setVisibility(INVISIBLE); - mAddToDictionaryStrip.setVisibility(INVISIBLE); mImportantNoticeStrip.setVisibility(VISIBLE); } public boolean isShowingImportantNoticeStrip() { return mImportantNoticeStrip.getVisibility() == VISIBLE; } - - public boolean isShowingAddToDictionaryStrip() { - return mAddToDictionaryStrip.getVisibility() == VISIBLE; - } } /** @@ -158,10 +140,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip); mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key); - mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip); mImportantNoticeStrip = findViewById(R.id.important_notice_strip); mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip, - mAddToDictionaryStrip, mImportantNoticeStrip); + mImportantNoticeStrip); for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) { final TextView word = new TextView(context, null, R.attr.suggestionWordStyle); @@ -227,27 +208,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick mLayoutHelper.setMoreSuggestionsHeight(remainingHeight); } - public boolean isShowingAddToDictionaryHint() { - return mStripVisibilityGroup.isShowingAddToDictionaryStrip(); - } - - public void showAddToDictionaryHint(final String word, final boolean shouldShowWordToSave) { - mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip, shouldShowWordToSave); - // {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word - // will be extracted at {@link #onClick(View)}. - mAddToDictionaryStrip.setTag(word); - mAddToDictionaryStrip.setOnClickListener(this); - mStripVisibilityGroup.showAddToDictionaryStrip(); - } - - public boolean dismissAddToDictionaryHint() { - if (isShowingAddToDictionaryHint()) { - clear(); - return true; - } - return false; - } - // This method checks if we should show the important notice (checks on permanent storage if // it has been shown once already or not, and if in the setup wizard). If applicable, it shows // the notice. In all cases, it returns true if it was shown, false otherwise. @@ -494,15 +454,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick false /* isKeyRepeat */); return; } - final Object tag = view.getTag(); - // {@link String} tag is set at {@link #suggestAddingToDictionary(String,CharSequence)}. - if (tag instanceof String) { - final String wordToSave = (String)tag; - mListener.addWordToUserDictionary(wordToSave); - clear(); - return; - } + final Object tag = view.getTag(); // {@link Integer} tag is set at // {@link SuggestionStripLayoutHelper#setupWordViewsTextAndColor(SuggestedWords,int)} and // {@link SuggestionStripLayoutHelper#layoutPunctuationSuggestions(SuggestedWords,ViewGroup} diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java index 5c86a02af..68f417e84 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripViewAccessor.java @@ -22,9 +22,6 @@ import com.android.inputmethod.latin.SuggestedWords; * An object that gives basic control of a suggestion strip and some info on it. */ public interface SuggestionStripViewAccessor { - public void suggestAddingToDictionary(final String word, final boolean isFromSuggestionStrip); - public boolean isShowingAddToDictionaryHint(); - public void dismissAddToDictionaryHint(); public void setNeutralSuggestionStrip(); public void showSuggestionStrip(final SuggestedWords suggestedWords); } diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java deleted file mode 100644 index 163443036..000000000 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin.userdictionary; - -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordContents.LocaleRenderer; -import com.android.inputmethod.latin.userdictionary.UserDictionaryLocalePicker.LocationChangedListener; - -import android.app.Fragment; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Spinner; - -import java.util.ArrayList; -import java.util.Locale; - -// Caveat: This class is basically taken from -// packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryAddWordFragment.java -// in order to deal with some devices that have issues with the user dictionary handling - -/** - * Fragment to add a word/shortcut to the user dictionary. - * - * As opposed to the UserDictionaryActivity, this is only invoked within Settings - * from the UserDictionarySettings. - */ -public class UserDictionaryAddWordFragment extends Fragment - implements AdapterView.OnItemSelectedListener, LocationChangedListener { - - private static final int OPTIONS_MENU_ADD = Menu.FIRST; - private static final int OPTIONS_MENU_DELETE = Menu.FIRST + 1; - - private UserDictionaryAddWordContents mContents; - private View mRootView; - private boolean mIsDeleting = false; - - @Override - public void onActivityCreated(final Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - setHasOptionsMenu(true); - getActivity().getActionBar().setTitle(R.string.edit_personal_dictionary); - // Keep the instance so that we remember mContents when configuration changes (eg rotation) - setRetainInstance(true); - } - - @Override - public View onCreateView(final LayoutInflater inflater, final ViewGroup container, - final Bundle savedState) { - mRootView = inflater.inflate(R.layout.user_dictionary_add_word_fullscreen, null); - mIsDeleting = false; - // If we have a non-null mContents object, it's the old value before a configuration - // change (eg rotation) so we need to use its values. Otherwise, read from the arguments. - if (null == mContents) { - mContents = new UserDictionaryAddWordContents(mRootView, getArguments()); - } else { - // We create a new mContents object to account for the new situation : a word has - // been added to the user dictionary when we started rotating, and we are now editing - // it. That means in particular if the word undergoes any change, the old version should - // be updated, so the mContents object needs to switch to EDIT mode if it was in - // INSERT mode. - mContents = new UserDictionaryAddWordContents(mRootView, - mContents /* oldInstanceToBeEdited */); - } - getActivity().getActionBar().setSubtitle(UserDictionarySettingsUtils.getLocaleDisplayName( - getActivity(), mContents.getCurrentUserDictionaryLocale())); - return mRootView; - } - - @Override - public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { - final MenuItem actionItemAdd = menu.add(0, OPTIONS_MENU_ADD, 0, - R.string.user_dict_settings_add_menu_title).setIcon(R.drawable.ic_menu_add); - actionItemAdd.setShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - final MenuItem actionItemDelete = menu.add(0, OPTIONS_MENU_DELETE, 0, - R.string.user_dict_settings_delete).setIcon(android.R.drawable.ic_menu_delete); - actionItemDelete.setShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - } - - /** - * Callback for the framework when a menu option is pressed. - * - * @param item the item that was pressed - * @return false to allow normal menu processing to proceed, true to consume it here - */ - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == OPTIONS_MENU_ADD) { - // added the entry in "onPause" - getActivity().onBackPressed(); - return true; - } - if (item.getItemId() == OPTIONS_MENU_DELETE) { - mContents.delete(getActivity()); - mIsDeleting = true; - getActivity().onBackPressed(); - return true; - } - return false; - } - - @Override - public void onResume() { - super.onResume(); - // We are being shown: display the word - updateSpinner(); - } - - private void updateSpinner() { - final ArrayList<LocaleRenderer> localesList = mContents.getLocalesList(getActivity()); - - final Spinner localeSpinner = - (Spinner)mRootView.findViewById(R.id.user_dictionary_add_locale); - final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<>( - getActivity(), android.R.layout.simple_spinner_item, localesList); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - localeSpinner.setAdapter(adapter); - localeSpinner.setOnItemSelectedListener(this); - } - - @Override - public void onPause() { - super.onPause(); - // We are being hidden: commit changes to the user dictionary, unless we were deleting it - if (!mIsDeleting) { - mContents.apply(getActivity(), null); - } - } - - @Override - public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, - final long id) { - final LocaleRenderer locale = (LocaleRenderer)parent.getItemAtPosition(pos); - if (locale.isMoreLanguages()) { - PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity(); - preferenceActivity.startPreferenceFragment(new UserDictionaryLocalePicker(), true); - } else { - mContents.updateLocale(locale.getLocaleString()); - } - } - - @Override - public void onNothingSelected(final AdapterView<?> parent) { - // I'm not sure we can come here, but if we do, that's the right thing to do. - final Bundle args = getArguments(); - mContents.updateLocale(args.getString(UserDictionaryAddWordContents.EXTRA_LOCALE)); - } - - // Called by the locale picker - @Override - public void onLocaleSelected(final Locale locale) { - mContents.updateLocale(locale.toString()); - getActivity().onBackPressed(); - } -} diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java index 1d7e7d683..fabd49f46 100644 --- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java +++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionarySettings.java @@ -240,8 +240,6 @@ public class UserDictionarySettings extends ListFragment { args.putString(UserDictionaryAddWordContents.EXTRA_LOCALE, mLocale); android.preference.PreferenceActivity pa = (android.preference.PreferenceActivity)getActivity(); - pa.startPreferencePanel(UserDictionaryAddWordFragment.class.getName(), - args, R.string.user_dict_settings_add_dialog_title, null, null, 0); } private String getWord(final int position) { diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java index fcce1ecdd..e355b7e1f 100644 --- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java @@ -27,8 +27,8 @@ import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.AssetFileAddress; import com.android.inputmethod.latin.BinaryDictionaryGetter; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.LocaleUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; @@ -450,7 +450,7 @@ public class DictionaryInfoUtils { return false; } final int length = text.length(); - if (length > Constants.DICTIONARY_MAX_WORD_LENGTH) { + if (length > DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) { return false; } int i = 0; diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java index 56a04a856..becf13fd9 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java @@ -38,6 +38,7 @@ import com.android.inputmethod.latin.DictionaryFacilitator; import com.android.inputmethod.latin.DictionaryFacilitatorLruCache; import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.RichInputMethodSubtype; +import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.common.StringUtils; @@ -52,7 +53,6 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr DistracterFilterCheckingExactMatchesAndSuggestions.class.getSimpleName(); private static final boolean DEBUG = false; - private static final int MAX_DICTIONARY_FACILITATOR_CACHE_SIZE = 3; private static final int MAX_DISTRACTERS_CACHE_SIZE = 1024; private final Context mContext; @@ -80,8 +80,8 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr mContext = context; mLocaleToSubtypeCache = new ConcurrentHashMap<>(); mLocaleToKeyboardCache = new ConcurrentHashMap<>(); - mDictionaryFacilitatorLruCache = new DictionaryFacilitatorLruCache(context, - MAX_DICTIONARY_FACILITATOR_CACHE_SIZE, "" /* dictionaryNamePrefix */); + mDictionaryFacilitatorLruCache = new DictionaryFacilitatorLruCache( + context, "" /* dictionaryNamePrefix */); mDistractersCache = new LruCache<>(MAX_DISTRACTERS_CACHE_SIZE); } @@ -195,8 +195,7 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr 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)"); @@ -252,7 +251,9 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr suggestionResults = dictionaryFacilitator.getSuggestionResults(composer, NgramContext.EMPTY_PREV_WORDS_INFO, keyboard.getProximityInfo().getNativeProximityInfo(), - settingsValuesForSuggestion, 0 /* sessionId */); + settingsValuesForSuggestion, 0 /* sessionId */, + SuggestedWords.INPUT_STYLE_TYPING, + keyboard.getKeyboardLayout()); } if (suggestionResults.isEmpty()) { return false; @@ -288,14 +289,14 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr 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 @@ -314,10 +315,10 @@ public class DistracterFilterCheckingExactMatchesAndSuggestions implements Distr 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); } } diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java index 147e57b13..c87a7c05c 100644 --- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java @@ -29,7 +29,6 @@ import com.android.inputmethod.latin.settings.PreferencesSettingsFragment; import com.android.inputmethod.latin.settings.SettingsFragment; import com.android.inputmethod.latin.settings.ThemeSettingsFragment; import com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment; -import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordFragment; import com.android.inputmethod.latin.userdictionary.UserDictionaryList; import com.android.inputmethod.latin.userdictionary.UserDictionaryLocalePicker; import com.android.inputmethod.latin.userdictionary.UserDictionarySettings; @@ -52,7 +51,6 @@ public class FragmentUtils { sLatinImeFragments.add(DebugSettingsFragment.class.getName()); sLatinImeFragments.add(SettingsFragment.class.getName()); sLatinImeFragments.add(SpellCheckerSettingsFragment.class.getName()); - sLatinImeFragments.add(UserDictionaryAddWordFragment.class.getName()); sLatinImeFragments.add(UserDictionaryList.class.getName()); sLatinImeFragments.add(UserDictionaryLocalePicker.class.getName()); sLatinImeFragments.add(UserDictionarySettings.class.getName()); diff --git a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java index 7d2ddd268..727df1a93 100644 --- a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java @@ -18,7 +18,7 @@ package com.android.inputmethod.latin.utils; import com.android.inputmethod.latin.NgramContext; import com.android.inputmethod.latin.NgramContext.WordInfo; -import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import java.util.Arrays; @@ -59,7 +59,8 @@ public final class NgramContextUtils { final SpacingAndPunctuations spacingAndPunctuations, final int n) { if (prev == null) return NgramContext.EMPTY_PREV_WORDS_INFO; final String[] w = SPACE_REGEX.split(prev); - final WordInfo[] prevWordsInfo = new WordInfo[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; + final WordInfo[] prevWordsInfo = + new WordInfo[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO); for (int i = 0; i < prevWordsInfo.length; i++) { final int focusedWordIndex = w.length - n - i; diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java index b319aeb8a..10e3994b6 100644 --- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java +++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java @@ -33,14 +33,21 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { // TODO: Instead of a boolean , we may want to include the context of this suggestion results, // such as {@link NgramContext}. public final boolean mIsBeginningOfSentence; + public final boolean mAutocorrectRecommendation; private final int mCapacity; public SuggestionResults(final int capacity, final boolean isBeginningOfSentence) { - this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence); + this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence, false); } - private SuggestionResults(final Comparator<SuggestedWordInfo> comparator, - final int capacity, final boolean isBeginningOfSentence) { + public SuggestionResults(final int capacity, final boolean isBeginningOfSentence, + final boolean autocorrectRecommendation) { + this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence, + autocorrectRecommendation); + } + + private SuggestionResults(final Comparator<SuggestedWordInfo> comparator, final int capacity, + final boolean isBeginningOfSentence, final boolean autocorrectRecommendation) { super(comparator); mCapacity = capacity; if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) { @@ -49,6 +56,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> { mRawSuggestions = null; } mIsBeginningOfSentence = isBeginningOfSentence; + mAutocorrectRecommendation = autocorrectRecommendation; } @Override diff --git a/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java b/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java index 86a5b19ec..e9a0e7a61 100644 --- a/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java +++ b/java/src/com/android/inputmethod/latin/utils/WordInputEventForPersonalization.java @@ -20,8 +20,8 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.NgramContext; -import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.common.StringUtils; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.utils.DistracterFilter.HandlingType; @@ -37,9 +37,10 @@ public final class WordInputEventForPersonalization { public final int[] mTargetWord; public final int mPrevWordsCount; - public final int[][] mPrevWordArray = new int[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][]; + public final int[][] mPrevWordArray = + new int[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][]; public final boolean[] mIsPrevWordBeginningOfSentenceArray = - new boolean[Constants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; + new boolean[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; public final boolean mIsValid; // Time stamp in seconds. public final int mTimestamp; |