diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
13 files changed, 176 insertions, 121 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 5afb62b69..9c70cad0a 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -263,7 +263,8 @@ final public class BinaryDictionaryGetter { public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale, final Context context) { - final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale); + final boolean hasDefaultWordList = DictionaryInfoUtils.isDictionaryAvailable( + context, locale); BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context, hasDefaultWordList); final File[] cachedWordLists = getCachedWordLists(locale.toString(), context); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index d0d626c54..e363661eb 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -63,6 +63,9 @@ public class DictionaryFacilitator { // HACK: This threshold is being used when adding a capitalized entry in the User History // dictionary. private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140; + // How many words we need to type in a row ({@see mConfidenceInMostProbableLanguage}) to + // declare we are confident the user is typing in the most probable language. + private static final int CONFIDENCE_THRESHOLD = 3; private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() }; private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0]; @@ -138,6 +141,10 @@ public class DictionaryFacilitator { public final Locale mLocale; private Dictionary mMainDict; + // Confidence that the most probable language is actually the language the user is + // typing in. For now, this is simply the number of times a word from this language + // has been committed in a row. + private int mConfidence = 0; public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap = @@ -260,8 +267,9 @@ public class DictionaryFacilitator { public void switchMostProbableLanguage(@Nullable final Locale locale) { if (null == locale) { // In many cases, there is no locale to a committed word. For example, a typed word - // that does not auto-correct has no locale. In this case we simply do not change - // the most probable language. + // that is in none of the currently active dictionaries but still does not + // auto-correct to anything has no locale. In this case we simply do not change + // the most probable language and do not touch confidence. return; } final DictionaryGroup newMostProbableDictionaryGroup = @@ -272,15 +280,28 @@ public class DictionaryFacilitator { // facilitator any more. In this case, just not changing things is fine. return; } - 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; + if (newMostProbableDictionaryGroup == mMostProbableDictionaryGroup) { + ++newMostProbableDictionaryGroup.mConfidence; + } else { + mMostProbableDictionaryGroup.mWeightForTypingInLocale = + DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE; + mMostProbableDictionaryGroup.mWeightForGesturingInLocale = + DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE; + mMostProbableDictionaryGroup.mConfidence = 0; + newMostProbableDictionaryGroup.mWeightForTypingInLocale = + DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; + newMostProbableDictionaryGroup.mWeightForGesturingInLocale = + DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE; + mMostProbableDictionaryGroup = newMostProbableDictionaryGroup; + } + } + + public boolean isConfidentAboutCurrentLanguageBeing(final Locale mLocale) { + final DictionaryGroup mostProbableDictionaryGroup = mMostProbableDictionaryGroup; + if (!mostProbableDictionaryGroup.mLocale.equals(mLocale)) { + return false; + } + return mostProbableDictionaryGroup.mConfidence >= CONFIDENCE_THRESHOLD; } @Nullable @@ -624,7 +645,8 @@ public class DictionaryFacilitator { final int timeStampInSeconds, final boolean blockPotentiallyOffensive) { final ExpandableBinaryDictionary userHistoryDictionary = dictionaryGroup.getSubDict(Dictionary.TYPE_USER_HISTORY); - if (userHistoryDictionary == null) { + if (userHistoryDictionary == null + || !isConfidentAboutCurrentLanguageBeing(userHistoryDictionary.mLocale)) { return; } final int maxFreq = getFrequency(word); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index a395fdeef..781ab06c5 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -19,10 +19,8 @@ package com.android.inputmethod.latin; import android.content.ContentProviderClient; import android.content.Context; import android.content.res.AssetFileDescriptor; -import android.content.res.Resources; import android.util.Log; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.utils.DictionaryInfoUtils; import java.io.File; @@ -43,11 +41,10 @@ public final class DictionaryFactory { * locale. If none is found, it falls back to the built-in dictionary - if any. * @param context application context for reading resources * @param locale the locale for which to create the dictionary - * @param useFullEditDistance whether to use the full edit distance in suggestions * @return an initialized instance of DictionaryCollection */ public static DictionaryCollection createMainDictionaryFromManager(final Context context, - final Locale locale, final boolean useFullEditDistance) { + final Locale locale) { if (null == locale) { Log.e(TAG, "No locale defined for dictionary"); return new DictionaryCollection(Dictionary.TYPE_MAIN, locale, @@ -61,7 +58,7 @@ public final class DictionaryFactory { for (final AssetFileAddress f : assetFileList) { final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength, - useFullEditDistance, locale, Dictionary.TYPE_MAIN); + false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN); if (readOnlyBinaryDictionary.isValidDictionary()) { dictList.add(readOnlyBinaryDictionary); } else { @@ -122,26 +119,12 @@ public final class DictionaryFactory { } /** - * Initializes a main dictionary collection from a dictionary pack, with default flags. - * - * This searches for a content provider providing a dictionary pack for the specified - * locale. If none is found, it falls back to the built-in dictionary, if any. - * @param context application context for reading resources - * @param locale the locale for which to create the dictionary - * @return an initialized instance of DictionaryCollection - */ - public static DictionaryCollection createMainDictionaryFromManager(final Context context, - final Locale locale) { - return createMainDictionaryFromManager(context, locale, false /* useFullEditDistance */); - } - - /** * Initializes a read-only binary dictionary from a raw resource file * @param context application context for reading resources * @param locale the locale to use for the resource * @return an initialized instance of ReadOnlyBinaryDictionary */ - protected static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context, + private static ReadOnlyBinaryDictionary createReadOnlyBinaryDictionary(final Context context, final Locale locale) { AssetFileDescriptor afd = null; try { @@ -175,36 +158,4 @@ public final class DictionaryFactory { } } } - - /** - * Create a dictionary from passed data. This is intended for unit tests only. - * @param dictionaryList the list of files to read, with their offsets and lengths - * @param useFullEditDistance whether to use the full edit distance in suggestions - * @return the created dictionary, or null. - */ - @UsedForTesting - public static Dictionary createDictionaryForTest(final AssetFileAddress[] dictionaryList, - final boolean useFullEditDistance, Locale locale) { - final DictionaryCollection dictionaryCollection = - new DictionaryCollection(Dictionary.TYPE_MAIN, locale); - for (final AssetFileAddress address : dictionaryList) { - final ReadOnlyBinaryDictionary readOnlyBinaryDictionary = new ReadOnlyBinaryDictionary( - address.mFilename, address.mOffset, address.mLength, useFullEditDistance, - locale, Dictionary.TYPE_MAIN); - dictionaryCollection.addDictionary(readOnlyBinaryDictionary); - } - return dictionaryCollection; - } - - /** - * Find out whether a dictionary is available for this locale. - * @param context the context on which to check resources. - * @param locale the locale to check for. - * @return whether a (non-placeholder) dictionary is available or not. - */ - public static boolean isDictionaryAvailable(Context context, Locale locale) { - final Resources res = context.getResources(); - return 0 != DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale( - res, locale); - } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 7b7b6d35e..66746cb6a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -708,6 +708,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.mSuggest.setAutoCorrectionThreshold( settingsValues.mAutoCorrectionThreshold); } + mInputLogic.mSuggest.setPlausibilityThreshold(settingsValues.mPlausibilityThreshold); } /** @@ -1007,6 +1008,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen suggest.setAutoCorrectionThreshold( currentSettingsValues.mAutoCorrectionThreshold); } + suggest.setPlausibilityThreshold(currentSettingsValues.mPlausibilityThreshold); switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index a1ac55a20..686c3a4b2 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -110,7 +110,7 @@ public class RichInputMethodManager { // Initialize additional subtypes. SubtypeLocaleUtils.init(context); - final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes(context); + final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes(); setAdditionalInputMethodSubtypes(additionalSubtypes); final ConnectivityManager connectivityManager = @@ -119,11 +119,10 @@ public class RichInputMethodManager { mIsNetworkConnected = (info != null && info.isConnected()); } - public InputMethodSubtype[] getAdditionalSubtypes(final Context context) { - SubtypeLocaleUtils.init(context); - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + public InputMethodSubtype[] getAdditionalSubtypes() { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes( - prefs, context.getResources()); + prefs, mContext.getResources()); return AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefAdditionalSubtypes); } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 4df1d6505..0bf0f687a 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -32,6 +32,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. @@ -62,15 +65,30 @@ public final class Suggest { } private float mAutoCorrectionThreshold; + private float mPlausibilityThreshold; public Suggest(final DictionaryFacilitator dictionaryFacilitator) { mDictionaryFacilitator = dictionaryFacilitator; } + /** + * Set the normalized-score threshold for a suggestion to be considered strong enough that we + * will auto-correct to this. + * @param threshold the threshold + */ public void setAutoCorrectionThreshold(final float threshold) { mAutoCorrectionThreshold = threshold; } + /** + * Set the normalized-score threshold for what we consider a "plausible" suggestion, in + * the same dimension as the auto-correction threshold. + * @param threshold the threshold + */ + public void setPlausibilityThreshold(final float threshold) { + mPlausibilityThreshold = threshold; + } + public interface OnGetSuggestedWordsCallback { public void onGetSuggestedWords(final SuggestedWords suggestedWords); } @@ -115,7 +133,8 @@ public final class Suggest { return suggestionsContainer; } - private static String getWhitelistedWordOrNull(final ArrayList<SuggestedWordInfo> suggestions) { + private static SuggestedWordInfo getWhitelistedWordInfoOrNull( + @Nonnull final ArrayList<SuggestedWordInfo> suggestions) { if (suggestions.isEmpty()) { return null; } @@ -123,9 +142,21 @@ public final class Suggest { if (!firstSuggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) { return null; } - return firstSuggestedWordInfo.mWord; + return firstSuggestedWordInfo; } + // Quality constants for dictionary match + // In increasing order of quality + // This source dictionary does not match the typed word. + private static final int QUALITY_NO_MATCH = 0; + // This source dictionary has a null locale, and the preferred locale is also null. + private static final int QUALITY_MATCH_NULL = 1; + // This source dictionary has a non-null locale different from the preferred locale. The + // preferred locale may be null : this is still better than MATCH_NULL. + private static final int QUALITY_MATCH_OTHER_LOCALE = 2; + // This source dictionary matches the preferred locale. + private static final int QUALITY_MATCH_PREFERRED_LOCALE = 3; + // Retrieves suggestions for non-batch input (typing, recorrection, predictions...) // and calls the callback function with the suggestions. private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer, @@ -143,22 +174,67 @@ public final class Suggest { final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(), settingsValuesForSuggestion, SESSION_ID_TYPING); + final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale(); final ArrayList<SuggestedWordInfo> suggestionsContainer = getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, 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); + mostProbableLocale); + + boolean typedWordExistsInAnotherLanguage = false; + int qualityOfFoundSourceDictionary = QUALITY_NO_MATCH; + @Nullable Dictionary sourceDictionaryOfRemovedWord = null; + for (final SuggestedWordInfo info : suggestionsContainer) { + // Search for the best dictionary, defined as the first one with the highest match + // quality we can find. + if (typedWordString.equals(info.mWord)) { + if (mostProbableLocale.equals(info.mSourceDict.mLocale)) { + if (qualityOfFoundSourceDictionary < QUALITY_MATCH_PREFERRED_LOCALE) { + // Use this source if the old match had lower quality than this match + sourceDictionaryOfRemovedWord = info.mSourceDict; + qualityOfFoundSourceDictionary = QUALITY_MATCH_PREFERRED_LOCALE; + } + } else { + final int matchQuality = (null == info.mSourceDict.mLocale) + ? QUALITY_MATCH_NULL : QUALITY_MATCH_OTHER_LOCALE; + if (qualityOfFoundSourceDictionary < matchQuality) { + // Use this source if the old match had lower quality than this match + sourceDictionaryOfRemovedWord = info.mSourceDict; + qualityOfFoundSourceDictionary = matchQuality; + } + typedWordExistsInAnotherLanguage = true; + } + } + } - final String whitelistedWord = getWhitelistedWordOrNull(suggestionsContainer); + SuggestedWordInfo.removeDups(typedWordString, suggestionsContainer); + + final SuggestedWordInfo whitelistedWordInfo = + getWhitelistedWordInfoOrNull(suggestionsContainer); + final String whitelistedWord; + if (null != whitelistedWordInfo && + (mDictionaryFacilitator.isConfidentAboutCurrentLanguageBeing( + whitelistedWordInfo.mSourceDict.mLocale) + || (!typedWordExistsInAnotherLanguage + && !hasPlausibleCandidateInAnyOtherLanguage(suggestionsContainer, + consideredWord, whitelistedWordInfo)))) { + // We'll use the whitelist candidate if we are confident the user is typing in the + // language of the dictionary it's coming from, or if there is no plausible candidate + // coming from another language. + whitelistedWord = whitelistedWordInfo.mWord; + } else { + // If on the contrary we are not confident in the current language and we have + // at least a plausible candidate in any other language, then we don't use this + // whitelist candidate. + whitelistedWord = null; + } final boolean resultsArePredictions = !wordComposer.isComposingWord(); // We allow auto-correction if we have a whitelisted word, or if the word had more than // one char and was not suggested. final boolean allowsToBeAutoCorrected = (null != whitelistedWord) - || (consideredWord.length() > 1 && !didRemoveTypedWord); + || (consideredWord.length() > 1 && (null == sourceDictionaryOfRemovedWord)); final boolean hasAutoCorrection; // If correction is not enabled, we never auto-correct. This is for example for when @@ -194,7 +270,7 @@ public final class Suggest { hasAutoCorrection = false; } else { final SuggestedWordInfo firstSuggestion = suggestionResults.first(); - if (!AutoCorrectionUtils.suggestionExceedsAutoCorrectionThreshold( + if (!AutoCorrectionUtils.suggestionExceedsThreshold( firstSuggestion, consideredWord, mAutoCorrectionThreshold)) { // Score is too low for autocorrect hasAutoCorrection = false; @@ -209,7 +285,8 @@ public final class Suggest { final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, - Dictionary.DICTIONARY_USER_TYPED, + null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED + : sourceDictionaryOfRemovedWord, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); if (!TextUtils.isEmpty(typedWordString)) { @@ -242,6 +319,20 @@ public final class Suggest { false /* isObsoleteSuggestions */, inputStyle, sequenceNumber)); } + private boolean hasPlausibleCandidateInAnyOtherLanguage( + final ArrayList<SuggestedWordInfo> suggestionsContainer, final String consideredWord, + final SuggestedWordInfo whitelistedWordInfo) { + for (final SuggestedWordInfo info : suggestionsContainer) { + if (whitelistedWordInfo.mSourceDict.mLocale.equals(info.mSourceDict.mLocale)) { + continue; + } + return AutoCorrectionUtils.suggestionExceedsThreshold(info, consideredWord, + mPlausibilityThreshold); + } + // No candidate in another language + return false; + } + // Retrieves suggestions for the batch input // and calls the callback function with the suggestions. private void getSuggestedWordsForBatchInput(final WordComposer wordComposer, diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 49153d261..30dd51aed 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -355,37 +355,30 @@ public class SuggestedWords { } // This will always remove the higher index if a duplicate is found. - public static boolean removeDups(final String typedWord, - ArrayList<SuggestedWordInfo> candidates) { + public static void removeDups(@Nullable final String typedWord, + @Nonnull ArrayList<SuggestedWordInfo> candidates) { if (candidates.isEmpty()) { - return false; + return; } - final boolean didRemoveTypedWord; if (!TextUtils.isEmpty(typedWord)) { - didRemoveTypedWord = removeSuggestedWordInfoFrom(typedWord, candidates, - -1 /* startIndexExclusive */); - } else { - didRemoveTypedWord = false; + removeSuggestedWordInfoFromList(typedWord, candidates, -1 /* startIndexExclusive */); } for (int i = 0; i < candidates.size(); ++i) { - removeSuggestedWordInfoFrom(candidates.get(i).mWord, candidates, + removeSuggestedWordInfoFromList(candidates.get(i).mWord, candidates, i /* startIndexExclusive */); } - return didRemoveTypedWord; } - private static boolean removeSuggestedWordInfoFrom(final String word, - final ArrayList<SuggestedWordInfo> candidates, final int startIndexExclusive) { - boolean didRemove = false; + private static void removeSuggestedWordInfoFromList( + @Nonnull final String word, @Nonnull final ArrayList<SuggestedWordInfo> candidates, + final int startIndexExclusive) { for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) { final SuggestedWordInfo previous = candidates.get(i); if (word.equals(previous.mWord)) { - didRemove = true; candidates.remove(i); --i; } } - return didRemove; } } diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java index 123ab208c..982d4c690 100644 --- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java +++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java @@ -69,7 +69,7 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver { // subtypes when the package is replaced. RichInputMethodManager.init(context); final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); - final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes(context); + final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes(); richImm.setAdditionalInputMethodSubtypes(additionalSubtypes); LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context); } else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) { diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java index b749aa51a..21ea8f859 100644 --- a/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java +++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStylePreference.java @@ -196,16 +196,6 @@ final class CustomInputStylePreference extends DialogPreference } } - private static int getSpinnerPosition(final Spinner spinner) { - if (spinner == null) return -1; - return spinner.getSelectedItemPosition(); - } - - private static void setSpinnerPosition(final Spinner spinner, final int position) { - if (spinner == null || position < 0) return; - spinner.setSelection(position); - } - @Override protected Parcelable onSaveInstanceState() { final Parcelable superState = super.onSaveInstanceState(); @@ -216,8 +206,6 @@ final class CustomInputStylePreference extends DialogPreference final SavedState myState = new SavedState(superState); myState.mSubtype = mSubtype; - myState.mSubtypeLocaleSelectedPos = getSpinnerPosition(mSubtypeLocaleSpinner); - myState.mKeyboardLayoutSetSelectedPos = getSpinnerPosition(mKeyboardLayoutSetSpinner); return myState; } @@ -230,15 +218,11 @@ final class CustomInputStylePreference extends DialogPreference final SavedState myState = (SavedState) state; super.onRestoreInstanceState(myState.getSuperState()); - setSpinnerPosition(mSubtypeLocaleSpinner, myState.mSubtypeLocaleSelectedPos); - setSpinnerPosition(mKeyboardLayoutSetSpinner, myState.mKeyboardLayoutSetSelectedPos); setSubtype(myState.mSubtype); } static final class SavedState extends Preference.BaseSavedState { InputMethodSubtype mSubtype; - int mSubtypeLocaleSelectedPos; - int mKeyboardLayoutSetSelectedPos; public SavedState(final Parcelable superState) { super(superState); @@ -247,15 +231,11 @@ final class CustomInputStylePreference extends DialogPreference @Override public void writeToParcel(final Parcel dest, final int flags) { super.writeToParcel(dest, flags); - dest.writeInt(mSubtypeLocaleSelectedPos); - dest.writeInt(mKeyboardLayoutSetSelectedPos); dest.writeParcelable(mSubtype, 0); } public SavedState(final Parcel source) { super(source); - mSubtypeLocaleSelectedPos = source.readInt(); - mKeyboardLayoutSetSelectedPos = source.readInt(); mSubtype = (InputMethodSubtype)source.readParcelable(null); } diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 16c053474..490fa827c 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -238,6 +238,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return !currentAutoCorrectionSetting.equals(autoCorrectionOff); } + public static float readPlausibilityThreshold(final Resources res) { + return Float.parseFloat(res.getString(R.string.plausibility_threshold)); + } + public static boolean readBlockPotentiallyOffensive(final SharedPreferences prefs, final Resources res) { return prefs.getBoolean(PREF_BLOCK_POTENTIALLY_OFFENSIVE, diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 26415e7d4..c3755792c 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -96,6 +96,7 @@ public class SettingsValues { public final int mKeyPreviewPopupDismissDelay; private final boolean mAutoCorrectEnabled; public final float mAutoCorrectionThreshold; + public final float mPlausibilityThreshold; public final boolean mAutoCorrectionEnabledPerUserSettings; private final boolean mSuggestionsEnabledPerUserSettings; private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds; @@ -172,6 +173,7 @@ public class SettingsValues { Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true); mAutoCorrectionThreshold = readAutoCorrectionThreshold(res, autoCorrectionThresholdRawValue); + mPlausibilityThreshold = Settings.readPlausibilityThreshold(res); mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res); mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true); mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java index 120cffbde..2fd257922 100644 --- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java @@ -29,9 +29,8 @@ public final class AutoCorrectionUtils { // Purely static class: can't instantiate. } - public static boolean suggestionExceedsAutoCorrectionThreshold( - final SuggestedWordInfo suggestion, final String consideredWord, - final float autoCorrectionThreshold) { + public static boolean suggestionExceedsThreshold(final SuggestedWordInfo suggestion, + final String consideredWord, final float threshold) { if (null != suggestion) { // Shortlist a whitelisted word if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) { @@ -45,11 +44,11 @@ public final class AutoCorrectionUtils { if (DBG) { Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + "," + autoCorrectionSuggestionScore + ", " + normalizedScore - + "(" + autoCorrectionThreshold + ")"); + + "(" + threshold + ")"); } - if (normalizedScore >= autoCorrectionThreshold) { + if (normalizedScore >= threshold) { if (DBG) { - Log.d(TAG, "Auto corrected by S-threshold."); + Log.d(TAG, "Exceeds threshold."); } return true; } diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java index 0bcc50dd4..fcce1ecdd 100644 --- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java @@ -246,6 +246,17 @@ public class DictionaryInfoUtils { } /** + * Find out whether a dictionary is available for this locale. + * @param context the context on which to check resources. + * @param locale the locale to check for. + * @return whether a (non-placeholder) dictionary is available or not. + */ + public static boolean isDictionaryAvailable(final Context context, final Locale locale) { + final Resources res = context.getResources(); + return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale); + } + + /** * Helper method to return a dictionary res id for a locale, or 0 if none. * @param res resources for the app * @param locale dictionary locale |