Annotate the typed word with its source dictionary

...when applicable of course. This will allow for informing the
language switching authorities that the typed word was a
specific language, instead of leaving them in the dark.

Bug: 18063142
Bug: 18130489
Bug: 18132240
Bug: 18136721
Bug: 18200415
Change-Id: Ice3e7026a68c3018f54d730ec84f6762bf55899b
main
Jean Chalard 2014-11-05 11:57:39 +09:00
parent a94733cbca
commit a7efe06208
2 changed files with 44 additions and 21 deletions

View File

@ -32,6 +32,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import javax.annotation.Nullable;
/** /**
* This class loads a dictionary and provides a list of suggestions for a given sequence of * This class loads a dictionary and provides a list of suggestions for a given sequence of
* characters. This includes corrections and completions. * characters. This includes corrections and completions.
@ -143,14 +145,16 @@ public final class Suggest {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(), wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
settingsValuesForSuggestion, SESSION_ID_TYPING); settingsValuesForSuggestion, SESSION_ID_TYPING);
final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer = final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults, getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount, trailingSingleQuotesCount,
// For transforming suggestions that don't come for any dictionary, we // For transforming suggestions that don't come for any dictionary, we
// use the currently most probable locale as it's our best bet. // use the currently most probable locale as it's our best bet.
mDictionaryFacilitator.getMostProbableLocale()); mostProbableLocale);
final boolean didRemoveTypedWord = @Nullable final Dictionary sourceDictionaryOfRemovedWord =
SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer); SuggestedWordInfo.removeDupsAndReturnSourceOfTypedWord(wordComposer.getTypedWord(),
mostProbableLocale /* preferredLocale */, suggestionsContainer);
final String whitelistedWord = getWhitelistedWordOrNull(suggestionsContainer); final String whitelistedWord = getWhitelistedWordOrNull(suggestionsContainer);
final boolean resultsArePredictions = !wordComposer.isComposingWord(); final boolean resultsArePredictions = !wordComposer.isComposingWord();
@ -158,7 +162,7 @@ public final class Suggest {
// We allow auto-correction if we have a whitelisted word, or if the word had more than // We allow auto-correction if we have a whitelisted word, or if the word had more than
// one char and was not suggested. // one char and was not suggested.
final boolean allowsToBeAutoCorrected = (null != whitelistedWord) final boolean allowsToBeAutoCorrected = (null != whitelistedWord)
|| (consideredWord.length() > 1 && !didRemoveTypedWord); || (consideredWord.length() > 1 && (null == sourceDictionaryOfRemovedWord));
final boolean hasAutoCorrection; final boolean hasAutoCorrection;
// If correction is not enabled, we never auto-correct. This is for example for when // If correction is not enabled, we never auto-correct. This is for example for when
@ -209,7 +213,8 @@ public final class Suggest {
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString, final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED, SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
Dictionary.DICTIONARY_USER_TYPED, null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED
: sourceDictionaryOfRemovedWord,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
if (!TextUtils.isEmpty(typedWordString)) { if (!TextUtils.isEmpty(typedWordString)) {
@ -275,7 +280,8 @@ public final class Suggest {
final SuggestedWordInfo rejected = suggestionsContainer.remove(0); final SuggestedWordInfo rejected = suggestionsContainer.remove(0);
suggestionsContainer.add(1, rejected); suggestionsContainer.add(1, rejected);
} }
SuggestedWordInfo.removeDups(null /* typedWord */, suggestionsContainer); SuggestedWordInfo.removeDupsAndReturnSourceOfTypedWord(null /* typedWord */,
null /* preferredLocale */, suggestionsContainer);
// For some reason some suggestions with MIN_VALUE are making their way here. // For some reason some suggestions with MIN_VALUE are making their way here.
// TODO: Find a more robust way to detect distracters. // TODO: Find a more robust way to detect distracters.

View File

@ -27,6 +27,7 @@ import com.android.inputmethod.latin.define.DebugFlags;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -355,37 +356,53 @@ public class SuggestedWords {
} }
// This will always remove the higher index if a duplicate is found. // This will always remove the higher index if a duplicate is found.
public static boolean removeDups(final String typedWord, // Returns null if the typed word is not found. Always return the dictionary for the
ArrayList<SuggestedWordInfo> candidates) { // highest suggestion matching the locale if found, otherwise return the dictionary for
// the highest suggestion.
@Nullable
public static Dictionary removeDupsAndReturnSourceOfTypedWord(
@Nullable final String typedWord,
@Nullable final Locale preferredLocale,
@Nonnull ArrayList<SuggestedWordInfo> candidates) {
if (candidates.isEmpty()) { if (candidates.isEmpty()) {
return false; return null;
} }
final boolean didRemoveTypedWord; final Dictionary sourceDictionaryOfTypedWord;
if (!TextUtils.isEmpty(typedWord)) { if (!TextUtils.isEmpty(typedWord)) {
didRemoveTypedWord = removeSuggestedWordInfoFrom(typedWord, candidates, sourceDictionaryOfTypedWord =
-1 /* startIndexExclusive */); removeSuggestedWordInfoFromListAndReturnSourceDictionary(typedWord,
preferredLocale, candidates, -1 /* startIndexExclusive */);
} else { } else {
didRemoveTypedWord = false; sourceDictionaryOfTypedWord = null;
} }
for (int i = 0; i < candidates.size(); ++i) { for (int i = 0; i < candidates.size(); ++i) {
removeSuggestedWordInfoFrom(candidates.get(i).mWord, candidates, removeSuggestedWordInfoFromListAndReturnSourceDictionary(candidates.get(i).mWord,
i /* startIndexExclusive */); null /* preferredLocale */, candidates, i /* startIndexExclusive */);
} }
return didRemoveTypedWord; return sourceDictionaryOfTypedWord;
} }
private static boolean removeSuggestedWordInfoFrom(final String word, @Nullable
final ArrayList<SuggestedWordInfo> candidates, final int startIndexExclusive) { private static Dictionary removeSuggestedWordInfoFromListAndReturnSourceDictionary(
boolean didRemove = false; @Nonnull final String word, @Nullable final Locale preferredLocale,
@Nonnull final ArrayList<SuggestedWordInfo> candidates,
final int startIndexExclusive) {
Dictionary sourceDictionaryOfTypedWord = null;
for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) { for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) {
final SuggestedWordInfo previous = candidates.get(i); final SuggestedWordInfo previous = candidates.get(i);
if (word.equals(previous.mWord)) { if (word.equals(previous.mWord)) {
didRemove = true; if (null == sourceDictionaryOfTypedWord
|| (null != preferredLocale
&& preferredLocale.equals(previous.mSourceDict.mLocale))) {
if (Dictionary.TYPE_USER_HISTORY != previous.mSourceDict.mDictType) {
sourceDictionaryOfTypedWord = previous.mSourceDict;
}
}
candidates.remove(i); candidates.remove(i);
--i; --i;
} }
} }
return didRemove; return sourceDictionaryOfTypedWord;
} }
} }