diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/Suggest.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/Suggest.java | 177 |
1 files changed, 45 insertions, 132 deletions
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index bde3a8403..f4f82f9c5 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -26,9 +26,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.io.File; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; @@ -47,35 +45,6 @@ public class Suggest { // TODO: rename this to CORRECTION_ON public static final int CORRECTION_FULL = 1; - // It seems the following values are only used for logging. - public static final int DIC_USER_TYPED = 0; - public static final int DIC_MAIN = 1; - public static final int DIC_USER = 2; - public static final int DIC_USER_HISTORY = 3; - public static final int DIC_CONTACTS = 4; - public static final int DIC_WHITELIST = 6; - // If you add a type of dictionary, increment DIC_TYPE_LAST_ID - // TODO: this value seems unused. Remove it? - public static final int DIC_TYPE_LAST_ID = 6; - public static final String DICT_KEY_MAIN = "main"; - public static final String DICT_KEY_CONTACTS = "contacts"; - // User dictionary, the system-managed one. - public static final String DICT_KEY_USER = "user"; - // User history dictionary internal to LatinIME - public static final String DICT_KEY_USER_HISTORY = "history"; - public static final String DICT_KEY_WHITELIST ="whitelist"; - // TODO: remove this map. This only serves as backward compatibility with a feature - // that has never been used and has been broken for a while. - private static final HashMap<String, Integer> sDictKeyToDictIndex - = new HashMap<String, Integer>(); - static { - sDictKeyToDictIndex.put(DICT_KEY_MAIN, DIC_MAIN); - sDictKeyToDictIndex.put(DICT_KEY_USER, DIC_USER); - sDictKeyToDictIndex.put(DICT_KEY_USER_HISTORY, DIC_USER_HISTORY); - sDictKeyToDictIndex.put(DICT_KEY_CONTACTS, DIC_CONTACTS); - sDictKeyToDictIndex.put(DICT_KEY_WHITELIST, DIC_WHITELIST); - } - private static final boolean DBG = LatinImeLogger.sDBG; private Dictionary mMainDictionary; @@ -88,11 +57,6 @@ public class Suggest { private float mAutoCorrectionThreshold; - // TODO: Remove these member variables by passing more context to addWord() callback method - private boolean mIsFirstCharCapitalized; - private boolean mIsAllUpperCase; - private int mTrailingSingleQuotesCount; - // Locale used for upper- and title-casing words final private Locale mLocale; @@ -109,13 +73,13 @@ public class Suggest { startOffset, length /* useFullEditDistance */, false, locale); mLocale = locale; mMainDictionary = mainDict; - addOrReplaceDictionary(mDictionaries, DICT_KEY_MAIN, mainDict); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict); initWhitelistAndAutocorrectAndPool(context, locale); } private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) { mWhiteListDictionary = new WhitelistDictionary(context, locale); - addOrReplaceDictionary(mDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_WHITELIST, mWhiteListDictionary); } private void initAsynchronously(final Context context, final Locale locale) { @@ -144,7 +108,7 @@ public class Suggest { public void run() { final DictionaryCollection newMainDict = DictionaryFactory.createMainDictionaryFromManager(context, locale); - addOrReplaceDictionary(mDictionaries, DICT_KEY_MAIN, newMainDict); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict); mMainDictionary = newMainDict; } }.start(); @@ -177,7 +141,7 @@ public class Suggest { * before the main dictionary, if set. This refers to the system-managed user dictionary. */ public void setUserDictionary(UserBinaryDictionary userDictionary) { - addOrReplaceDictionary(mDictionaries, DICT_KEY_USER, userDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER, userDictionary); } /** @@ -187,52 +151,35 @@ public class Suggest { */ public void setContactsDictionary(ContactsBinaryDictionary contactsDictionary) { mContactsDict = contactsDictionary; - addOrReplaceDictionary(mDictionaries, DICT_KEY_CONTACTS, contactsDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary); } public void setUserHistoryDictionary(UserHistoryDictionary userHistoryDictionary) { - addOrReplaceDictionary(mDictionaries, DICT_KEY_USER_HISTORY, userHistoryDictionary); + addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); } public void setAutoCorrectionThreshold(float threshold) { mAutoCorrectionThreshold = threshold; } - private static CharSequence capitalizeWord(final boolean all, final boolean first, - final CharSequence word) { - if (TextUtils.isEmpty(word) || !(all || first)) return word; - final int wordLength = word.length(); - final StringBuilder sb = new StringBuilder(getApproxMaxWordLength()); - // TODO: Must pay attention to locale when changing case. - if (all) { - sb.append(word.toString().toUpperCase()); - } else if (first) { - sb.append(Character.toUpperCase(word.charAt(0))); - if (wordLength > 1) { - sb.append(word.subSequence(1, wordLength)); - } - } - return sb; - } - // TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder public SuggestedWords getSuggestedWords( final WordComposer wordComposer, CharSequence prevWordForBigram, final ProximityInfo proximityInfo, final boolean isCorrectionEnabled, final boolean isPrediction) { LatinImeLogger.onStartSuggestion(prevWordForBigram); - mIsFirstCharCapitalized = !isPrediction && wordComposer.isFirstCharCapitalized(); - mIsAllUpperCase = !isPrediction && wordComposer.isAllUpperCase(); - mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); - final ArrayList<SuggestedWordInfo> suggestionsContainer = - new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); + final boolean isFirstCharCapitalized = + !isPrediction && wordComposer.isFirstCharCapitalized(); + final boolean isAllUpperCase = !isPrediction && wordComposer.isAllUpperCase(); + final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); + final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator, + MAX_SUGGESTIONS); final String typedWord = wordComposer.getTypedWord(); - final String consideredWord = mTrailingSingleQuotesCount > 0 - ? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount) + final String consideredWord = trailingSingleQuotesCount > 0 + ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount) : typedWord; - // Treating USER_TYPED as UNIGRAM suggestion for logging now. - LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); + LatinImeLogger.onAddSuggestedWord(typedWord, Dictionary.TYPE_USER_TYPED); if (wordComposer.size() <= 1 && isCorrectionEnabled) { // At first character typed, search only the bigrams @@ -245,24 +192,18 @@ public class Suggest { lowerPrevWord = null; } for (final String key : mDictionaries.keySet()) { - final int dicTypeId = sDictKeyToDictIndex.get(key); final Dictionary dictionary = mDictionaries.get(key); - final ArrayList<SuggestedWordInfo> localSuggestions = - dictionary.getBigrams(wordComposer, prevWordForBigram); + suggestionsSet.addAll(dictionary.getBigrams(wordComposer, prevWordForBigram)); if (null != lowerPrevWord) { - localSuggestions.addAll(dictionary.getBigrams(wordComposer, lowerPrevWord)); - } - for (final SuggestedWordInfo localSuggestion : localSuggestions) { - addWord(localSuggestion, dicTypeId, Dictionary.BIGRAM, - suggestionsContainer, consideredWord); + suggestionsSet.addAll(dictionary.getBigrams(wordComposer, lowerPrevWord)); } } } } else if (wordComposer.size() > 1) { final WordComposer wordComposerForLookup; - if (mTrailingSingleQuotesCount > 0) { + if (trailingSingleQuotesCount > 0) { wordComposerForLookup = new WordComposer(wordComposer); - for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { + for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { wordComposerForLookup.deleteLast(); } } else { @@ -271,27 +212,25 @@ public class Suggest { // At second character typed, search the unigrams (scores being affected by bigrams) for (final String key : mDictionaries.keySet()) { // Skip UserUnigramDictionary and WhitelistDictionary to lookup - if (key.equals(DICT_KEY_USER_HISTORY) || key.equals(DICT_KEY_WHITELIST)) + if (key.equals(Dictionary.TYPE_USER_HISTORY) + || key.equals(Dictionary.TYPE_WHITELIST)) continue; - final int dicTypeId = sDictKeyToDictIndex.get(key); final Dictionary dictionary = mDictionaries.get(key); - final ArrayList<SuggestedWordInfo> localSuggestions = dictionary.getWords( - wordComposerForLookup, prevWordForBigram, proximityInfo); - for (final SuggestedWordInfo suggestion : localSuggestions) { - addWord(suggestion, dicTypeId, Dictionary.UNIGRAM, - suggestionsContainer, consideredWord); - } + suggestionsSet.addAll(dictionary.getWords( + wordComposerForLookup, prevWordForBigram, proximityInfo)); } } - final CharSequence whitelistedWord = capitalizeWord(mIsAllUpperCase, - mIsFirstCharCapitalized, mWhiteListDictionary.getWhitelistedWord(consideredWord)); + final CharSequence whitelistedWord = + mWhiteListDictionary.getWhitelistedWord(consideredWord); final boolean hasAutoCorrection; if (isCorrectionEnabled) { + final SuggestedWordInfo bestSuggestion = suggestionsSet.isEmpty() + ? null : suggestionsSet.first(); final CharSequence autoCorrection = AutoCorrection.computeAutoCorrectionWord(mDictionaries, wordComposer, - suggestionsContainer, consideredWord, mAutoCorrectionThreshold, + bestSuggestion, consideredWord, mAutoCorrectionThreshold, whitelistedWord); hasAutoCorrection = (null != autoCorrection); } else { @@ -299,22 +238,26 @@ public class Suggest { } if (whitelistedWord != null) { - if (mTrailingSingleQuotesCount > 0) { - final StringBuilder sb = new StringBuilder(whitelistedWord); - for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { - sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); - } - suggestionsContainer.add(0, new SuggestedWordInfo(sb.toString(), - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); - } else { - suggestionsContainer.add(0, new SuggestedWordInfo(whitelistedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); - } + suggestionsSet.add(new SuggestedWordInfo(whitelistedWord, + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST, + Dictionary.TYPE_WHITELIST)); + } + + final ArrayList<SuggestedWordInfo> suggestionsContainer = + new ArrayList<SuggestedWordInfo>(suggestionsSet); + for (int i = 0; i < suggestionsContainer.size(); ++i) { + final SuggestedWordInfo wordInfo = suggestionsContainer.get(i); + final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(wordInfo, + mLocale, isAllUpperCase, isFirstCharCapitalized, trailingSingleQuotesCount); + suggestionsContainer.set(i, transformedWordInfo); + LatinImeLogger.onAddSuggestedWord(transformedWordInfo.mWord.toString(), + transformedWordInfo.mSourceDict); } if (!isPrediction) { suggestionsContainer.add(0, new SuggestedWordInfo(typedWord, - SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED)); + SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, + Dictionary.TYPE_USER_TYPED)); } SuggestedWordInfo.removeDups(suggestionsContainer); @@ -401,36 +344,6 @@ public class Suggest { private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator = new SuggestedWordInfoComparator(); - public boolean addWord(final SuggestedWordInfo wordInfo, - final int dicTypeId, final int dataType, - final ArrayList<SuggestedWordInfo> suggestions, final String consideredWord) { - int dataTypeForLog = dataType; - final int prefMaxSuggestions = MAX_SUGGESTIONS; - - final CharSequence word = wordInfo.mWord; - final int score = wordInfo.mScore; - int pos = 0; - - final int index = - Collections.binarySearch(suggestions, wordInfo, sSuggestedWordInfoComparator); - // binarySearch returns the index of an equal word info if found. If not found - // it returns -insertionPoint - 1. We want the insertion point, so: - pos = index >= 0 ? index : -index - 1; - if (pos >= prefMaxSuggestions) { - return true; - } - - final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(wordInfo, - mLocale, mIsAllUpperCase, mIsFirstCharCapitalized, mTrailingSingleQuotesCount); - suggestions.add(pos, transformedWordInfo); - if (suggestions.size() > prefMaxSuggestions) { - suggestions.remove(prefMaxSuggestions); - } - LatinImeLogger.onAddSuggestedWord(transformedWordInfo.mWord.toString(), dicTypeId, - dataTypeForLog); - return true; - } - private static SuggestedWordInfo getTransformedSuggestedWordInfo( final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase, final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) { @@ -448,7 +361,7 @@ public class Suggest { for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) { sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); } - return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind); + return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind, wordInfo.mSourceDict); } public void close() { |