diff options
Diffstat (limited to 'java')
4 files changed, 74 insertions, 40 deletions
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 4a218d550..6a63bfda7 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -62,6 +62,7 @@ public class DictionaryFacilitator { private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140; 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. @@ -126,9 +127,16 @@ public class DictionaryFacilitator { * A group of dictionaries that work together for a single language. */ private static class DictionaryGroup { + // TODO: Run evaluation to determine a reasonable value for these constants. The current + // values are ad-hoc and chosen without any particular care or methodology. + public static final float WEIGHT_FOR_MOST_PROBABLE_LANGUAGE = 1.0f; + public static final float WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.95f; + public static final float WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.6f; + public final Locale mLocale; private Dictionary mMainDict; - public float mWeightForLocale = 1.0f; + public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; + public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap = new ConcurrentHashMap<>(); @@ -214,25 +222,52 @@ public class DictionaryFacilitator { mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes); } + // TODO: remove this, it's confusing with seamless multiple language switching public void setIsMonolingualUser(final boolean isMonolingualUser) { mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser); } - // TODO: remove this, replace with version returning multiple locales - public Locale getLocale() { - return mDictionaryGroups[0].mLocale; + public boolean isActive() { + return null != mDictionaryGroups[0].mLocale; } /** - * Returns the primary locale among all currently active locales. BE CAREFUL using this. + * Returns the most probable locale among all currently active locales. BE CAREFUL using this. * * DO NOT USE THIS just because it's convenient. Use it when it's correct, for example when * choosing what dictionary to put a word in, or when changing the capitalization of a typed * string. - * @return the primary active locale + * @return the most probable locale */ - public Locale getPrimaryLocale() { - return mDictionaryGroups[0].mLocale; + public Locale getMostProbableLocale() { + return getDictionaryGroupForMostProbableLanguage().mLocale; + } + + public Locale[] getLocales() { + final DictionaryGroup[] dictionaryGroups = mDictionaryGroups; + final Locale[] locales = new Locale[dictionaryGroups.length]; + for (int i = 0; i < dictionaryGroups.length; ++i) { + locales[i] = dictionaryGroups[i].mLocale; + } + return locales; + } + + private DictionaryGroup getDictionaryGroupForMostProbableLanguage() { + return mMostProbableDictionaryGroup; + } + + public void switchMostProbableLanguage(final Locale locale) { + final DictionaryGroup newMostProbableDictionaryGroup = + findDictionaryGroupWithLocale(mDictionaryGroups, locale); + mMostProbableDictionaryGroup.mWeightForTypingInLocale = + DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE; + mMostProbableDictionaryGroup.mWeightForGesturingInLocale = + DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE; + newMostProbableDictionaryGroup.mWeightForTypingInLocale = + DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; + newMostProbableDictionaryGroup.mWeightForGesturingInLocale = + DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; + mMostProbableDictionaryGroup = newMostProbableDictionaryGroup; } private static ExpandableBinaryDictionary getSubDict(final String dictType, @@ -256,11 +291,11 @@ public class DictionaryFacilitator { } } - public void resetDictionaries(final Context context, final Locale newLocale, + public void resetDictionaries(final Context context, final Locale[] newLocales, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, final DictionaryInitializationListener listener) { - resetDictionariesWithDictNamePrefix(context, newLocale, useContactsDict, + resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict, usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */); } @@ -274,20 +309,13 @@ public class DictionaryFacilitator { return null; } - private DictionaryGroup getDictionaryGroupForActiveLanguage() { - // TODO: implement this - return mDictionaryGroups[0]; - } - public void resetDictionariesWithDictNamePrefix(final Context context, - final Locale newLocaleToUse, + final Locale[] newLocales, final boolean useContactsDict, final boolean usePersonalizedDicts, final boolean forceReloadMainDictionary, final DictionaryInitializationListener listener, final String dictNamePrefix) { final HashMap<Locale, ArrayList<String>> existingDictsToCleanup = new HashMap<>(); - // TODO: use several locales - final Locale[] newLocales = new Locale[] { newLocaleToUse }; // TODO: Make subDictTypesToUse configurable by resource or a static final list. final HashSet<String> subDictTypesToUse = new HashSet<>(); subDictTypesToUse.add(Dictionary.TYPE_USER); @@ -359,6 +387,7 @@ public class DictionaryFacilitator { synchronized (mLock) { oldDictionaryGroups = mDictionaryGroups; mDictionaryGroups = newDictionaryGroups; + mMostProbableDictionaryGroup = newDictionaryGroups[0]; mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context); if (hasAtLeastOneUninitializedMainDictionary()) { asyncReloadUninitializedMainDictionaries(context, newLocales, listener); @@ -448,13 +477,15 @@ public class DictionaryFacilitator { dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, subDicts); } mDictionaryGroups = dictionaryGroups; + mMostProbableDictionaryGroup = dictionaryGroups[0]; } public void closeDictionaries() { final DictionaryGroup[] dictionaryGroups; synchronized (mLock) { dictionaryGroups = mDictionaryGroups; - mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() }; + mMostProbableDictionaryGroup = new DictionaryGroup(); + mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup }; } for (final DictionaryGroup dictionaryGroup : dictionaryGroups) { for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) { @@ -469,7 +500,7 @@ public class DictionaryFacilitator { @UsedForTesting public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) { - return mDictionaryGroups[0].getSubDict(dictName); + return mMostProbableDictionaryGroup.getSubDict(dictName); } // The main dictionaries are loaded asynchronously. Don't cache the return value @@ -542,17 +573,18 @@ public class DictionaryFacilitator { } public void addWordToUserDictionary(final Context context, final String word) { - final Locale locale = getLocale(); + 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, final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { - final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage(); + final DictionaryGroup dictionaryGroup = getDictionaryGroupForMostProbableLanguage(); final String[] words = suggestion.split(Constants.WORD_SEPARATOR); NgramContext ngramContextForCurrentWord = ngramContext; for (int i = 0; i < words.length; i++) { @@ -620,7 +652,7 @@ public class DictionaryFacilitator { private void removeWord(final String dictName, final String word) { final ExpandableBinaryDictionary dictionary = - getDictionaryGroupForActiveLanguage().getSubDict(dictName); + getDictionaryGroupForMostProbableLanguage().getSubDict(dictName); if (dictionary != null) { dictionary.removeUnigramEntryDynamically(word); } @@ -645,10 +677,13 @@ public class DictionaryFacilitator { for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) { final Dictionary dictionary = dictionaryGroup.getDict(dictType); if (null == dictionary) continue; + final float weightForLocale = composer.isBatchMode() + ? dictionaryGroup.mWeightForGesturingInLocale + : dictionaryGroup.mWeightForTypingInLocale; final ArrayList<SuggestedWordInfo> dictionarySuggestions = dictionary.getSuggestions(composer, ngramContext, proximityInfo, settingsValuesForSuggestion, sessionId, - dictionaryGroup.mWeightForLocale, weightOfLangModelVsSpatialModel); + weightForLocale, weightOfLangModelVsSpatialModel); if (null == dictionarySuggestions) continue; suggestionResults.addAll(dictionarySuggestions); if (null != suggestionResults.mRawSuggestions) { @@ -747,7 +782,8 @@ public class DictionaryFacilitator { final SpacingAndPunctuations spacingAndPunctuations, final AddMultipleDictionaryEntriesCallback callback) { mPersonalizationHelper.addEntriesToPersonalizationDictionariesToUpdate( - getLocale(), personalizationDataChunk, spacingAndPunctuations, callback); + getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations, + callback); } @UsedForTesting @@ -756,7 +792,7 @@ public class DictionaryFacilitator { // 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 = - getDictionaryGroupForActiveLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL); + getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL); if (contextualDict == null) { return; } diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java index ff4a6bde1..1b33d9129 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java @@ -101,7 +101,7 @@ public class DictionaryFacilitatorLruCache { private void resetDictionariesForLocaleLocked(final DictionaryFacilitator dictionaryFacilitator, final Locale locale) { - dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, locale, + dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, new Locale[] { locale }, mUseContactsDictionary, false /* usePersonalizedDicts */, false /* forceReloadMainDictionary */, null /* listener */, mDictionaryNamePrefix); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index b168cc912..2be99a90f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -675,9 +675,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // TODO: make sure the current settings always have the right locales, and read from them private void resetDictionaryFacilitatorForLocale(final Locale[] locales) { final SettingsValues settingsValues = mSettings.getCurrent(); - // TODO: pass the array instead - final Locale locale = locales[0]; - mDictionaryFacilitator.resetDictionaries(this /* context */, locale, + mDictionaryFacilitator.resetDictionaries(this /* context */, locales, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, this); if (settingsValues.mAutoCorrectionEnabledPerUserSettings) { @@ -692,7 +690,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen /* package private */ void resetSuggestMainDict() { final SettingsValues settingsValues = mSettings.getCurrent(); mDictionaryFacilitator.resetDictionaries(this /* context */, - mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict, + mDictionaryFacilitator.getLocales(), settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, true /* forceReloadMainDictionary */, this); } @@ -1632,7 +1630,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } final String wordToShow; if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) { - wordToShow = word.toLowerCase(mDictionaryFacilitator.getPrimaryLocale()); + wordToShow = word.toLowerCase(mDictionaryFacilitator.getMostProbableLocale()); } else { wordToShow = word; } @@ -1898,7 +1896,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @UsedForTesting /* package for test */ void replaceDictionariesForTest(final Locale locale) { final SettingsValues settingsValues = mSettings.getCurrent(); - mDictionaryFacilitator.resetDictionaries(this, locale, + mDictionaryFacilitator.resetDictionaries(this, new Locale[] { locale }, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, this /* listener */); } @@ -1917,7 +1915,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } public void dumpDictionaryForDebug(final String dictName) { - if (mDictionaryFacilitator.getLocale() == null) { + if (!mDictionaryFacilitator.isActive()) { resetDictionaryFacilitatorIfNecessary(); } mDictionaryFacilitator.dumpDictionaryForDebug(dictName); diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index d2d9b9b1e..e181237a6 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -55,10 +55,6 @@ public final class Suggest { mDictionaryFacilitator = dictionaryFacilitator; } - public Locale getLocale() { - return mDictionaryFacilitator.getLocale(); - } - public void setAutoCorrectionThreshold(final float threshold) { mAutoCorrectionThreshold = threshold; } @@ -136,7 +132,10 @@ public final class Suggest { SESSION_ID_TYPING); final ArrayList<SuggestedWordInfo> suggestionsContainer = getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, - trailingSingleQuotesCount, mDictionaryFacilitator.getLocale()); + trailingSingleQuotesCount, + // For transforming suggestions that don't come for any dictionary, we + // use the currently most probable locale as it's our best bet. + mDictionaryFacilitator.getMostProbableLocale()); final boolean didRemoveTypedWord = SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer); @@ -216,7 +215,8 @@ public final class Suggest { final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion, SESSION_ID_GESTURE); - final Locale defaultLocale = mDictionaryFacilitator.getLocale(); + // 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 = new ArrayList<>(suggestionResults); final int suggestionsCount = suggestionsContainer.size(); |