aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/Suggest.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/Suggest.java')
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java125
1 files changed, 83 insertions, 42 deletions
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 2879e2e32..6c18c948f 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -17,13 +17,17 @@
package com.android.inputmethod.latin;
import android.content.Context;
+import android.preference.PreferenceManager;
import android.text.TextUtils;
+import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationPredictionDictionary;
import com.android.inputmethod.latin.personalization.UserHistoryPredictionDictionary;
+import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.BoundedTreeSet;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -44,8 +48,9 @@ public final class Suggest {
// Session id for
// {@link #getSuggestedWords(WordComposer,String,ProximityInfo,boolean,int)}.
+ // We are sharing the same ID between typing and gesture to save RAM footprint.
public static final int SESSION_TYPING = 0;
- public static final int SESSION_GESTURE = 1;
+ public static final int SESSION_GESTURE = 0;
// TODO: rename this to CORRECTION_OFF
public static final int CORRECTION_NONE = 0;
@@ -55,21 +60,22 @@ public final class Suggest {
// Close to -2**31
private static final int SUPPRESS_SUGGEST_THRESHOLD = -2000000000;
+ public static final int MAX_SUGGESTIONS = 18;
+
public interface SuggestInitializationListener {
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
}
private static final boolean DBG = LatinImeLogger.sDBG;
- private Dictionary mMainDictionary;
- private ContactsBinaryDictionary mContactsDict;
private final ConcurrentHashMap<String, Dictionary> mDictionaries =
CollectionUtils.newConcurrentHashMap();
+ private HashSet<String> mOnlyDictionarySetForDebug = null;
+ private Dictionary mMainDictionary;
+ private ContactsBinaryDictionary mContactsDict;
@UsedForTesting
private boolean mIsCurrentlyWaitingForMainDictionary = false;
- public static final int MAX_SUGGESTIONS = 18;
-
private float mAutoCorrectionThreshold;
// Locale used for upper- and title-casing words
@@ -79,6 +85,13 @@ public final class Suggest {
final SuggestInitializationListener listener) {
initAsynchronously(context, locale, listener);
mLocale = locale;
+ // initialize a debug flag for the personalization
+ if (Settings.readUseOnlyPersonalizationDictionaryForDebug(
+ PreferenceManager.getDefaultSharedPreferences(context))) {
+ mOnlyDictionarySetForDebug = new HashSet<String>();
+ mOnlyDictionarySetForDebug.add(Dictionary.TYPE_PERSONALIZATION);
+ mOnlyDictionarySetForDebug.add(Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA);
+ }
}
@UsedForTesting
@@ -87,7 +100,7 @@ public final class Suggest {
false /* useFullEditDistance */, locale);
mLocale = locale;
mMainDictionary = mainDict;
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, mainDict);
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, mainDict);
}
private void initAsynchronously(final Context context, final Locale locale,
@@ -95,6 +108,14 @@ public final class Suggest {
resetMainDict(context, locale, listener);
}
+ private void addOrReplaceDictionaryInternal(final String key, final Dictionary dict) {
+ if (mOnlyDictionarySetForDebug != null && !mOnlyDictionarySetForDebug.contains(key)) {
+ Log.w(TAG, "Ignore add " + key + " dictionary for debug.");
+ return;
+ }
+ addOrReplaceDictionary(mDictionaries, key, dict);
+ }
+
private static void addOrReplaceDictionary(
final ConcurrentHashMap<String, Dictionary> dictionaries,
final String key, final Dictionary dict) {
@@ -118,7 +139,7 @@ public final class Suggest {
public void run() {
final DictionaryCollection newMainDict =
DictionaryFactory.createMainDictionaryFromManager(context, locale);
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_MAIN, newMainDict);
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, newMainDict);
mMainDictionary = newMainDict;
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
@@ -156,7 +177,7 @@ public final class Suggest {
* before the main dictionary, if set. This refers to the system-managed user dictionary.
*/
public void setUserDictionary(final UserBinaryDictionary userDictionary) {
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER, userDictionary);
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_USER, userDictionary);
}
/**
@@ -166,43 +187,56 @@ public final class Suggest {
*/
public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) {
mContactsDict = contactsDictionary;
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary);
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary);
}
public void setUserHistoryPredictionDictionary(
final UserHistoryPredictionDictionary userHistoryPredictionDictionary) {
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY,
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY,
userHistoryPredictionDictionary);
}
public void setPersonalizationPredictionDictionary(
final PersonalizationPredictionDictionary personalizationPredictionDictionary) {
- addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA,
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION_PREDICTION_IN_JAVA,
personalizationPredictionDictionary);
}
+ public void setPersonalizationDictionary(
+ final PersonalizationDictionary personalizationDictionary) {
+ addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION,
+ personalizationDictionary);
+ }
+
public void setAutoCorrectionThreshold(float threshold) {
mAutoCorrectionThreshold = threshold;
}
- public SuggestedWords getSuggestedWords(final WordComposer wordComposer,
+ public interface OnGetSuggestedWordsCallback {
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords);
+ }
+
+ public void getSuggestedWords(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
- final int sessionId) {
+ final int[] additionalFeaturesOptions, final int sessionId,
+ final OnGetSuggestedWordsCallback callback) {
LatinImeLogger.onStartSuggestion(prevWordForBigram);
if (wordComposer.isBatchMode()) {
- return getSuggestedWordsForBatchInput(
- wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId);
+ getSuggestedWordsForBatchInput(wordComposer, prevWordForBigram, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId, callback);
} else {
- return getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
- blockOffensiveWords, isCorrectionEnabled);
+ getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
+ blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions, callback);
}
}
- // Retrieves suggestions for the typing input.
- private SuggestedWords getSuggestedWordsForTypingInput(final WordComposer wordComposer,
+ // Retrieves suggestions for the typing input
+ // and calls the callback function with the suggestions.
+ private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final boolean isCorrectionEnabled) {
+ final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
+ final int[] additionalFeaturesOptions, final OnGetSuggestedWordsCallback callback) {
final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
@@ -225,8 +259,9 @@ public final class Suggest {
for (final String key : mDictionaries.keySet()) {
final Dictionary dictionary = mDictionaries.get(key);
- suggestionsSet.addAll(dictionary.getSuggestions(
- wordComposerForLookup, prevWordForBigram, proximityInfo, blockOffensiveWords));
+ suggestionsSet.addAll(dictionary.getSuggestions(wordComposerForLookup,
+ prevWordForBigram, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions));
}
final String whitelistedWord;
@@ -284,13 +319,16 @@ public final class Suggest {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(), wordInfo.mSourceDict);
+ LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(),
+ wordInfo.mSourceDict.mDictType);
}
if (!TextUtils.isEmpty(typedWord)) {
suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
- Dictionary.TYPE_USER_TYPED));
+ Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
}
SuggestedWordInfo.removeDups(suggestionsContainer);
@@ -301,7 +339,7 @@ public final class Suggest {
suggestionsList = suggestionsContainer;
}
- return new SuggestedWords(suggestionsList,
+ callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
// TODO: this first argument is lying. If this is a whitelisted word which is an
// actual word, it says typedWordValid = false, which looks wrong. We should either
// rename the attribute or change the value.
@@ -309,31 +347,28 @@ public final class Suggest {
hasAutoCorrection, /* willAutoCorrect */
false /* isPunctuationSuggestions */,
false /* isObsoleteSuggestions */,
- !wordComposer.isComposingWord() /* isPrediction */);
+ !wordComposer.isComposingWord() /* isPrediction */));
}
- // Retrieves suggestions for the batch input.
- private SuggestedWords getSuggestedWordsForBatchInput(final WordComposer wordComposer,
+ // Retrieves suggestions for the batch input
+ // and calls the callback function with the suggestions.
+ private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int sessionId) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final int sessionId, final OnGetSuggestedWordsCallback callback) {
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
// At second character typed, search the unigrams (scores being affected by bigrams)
for (final String key : mDictionaries.keySet()) {
- // Skip User history dictionary for lookup
- // TODO: The user history dictionary should just override getSuggestionsWithSessionId
- // to make sure it doesn't return anything and we should remove this test
- if (key.equals(Dictionary.TYPE_USER_HISTORY)) {
- continue;
- }
final Dictionary dictionary = mDictionaries.get(key);
suggestionsSet.addAll(dictionary.getSuggestionsWithSessionId(wordComposer,
- prevWordForBigram, proximityInfo, blockOffensiveWords, sessionId));
+ prevWordForBigram, proximityInfo, blockOffensiveWords,
+ additionalFeaturesOptions, sessionId));
}
for (SuggestedWordInfo wordInfo : suggestionsSet) {
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict);
+ LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType);
}
final ArrayList<SuggestedWordInfo> suggestionsContainer =
@@ -368,12 +403,12 @@ public final class Suggest {
// In the batch input mode, the most relevant suggested word should act as a "typed word"
// (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false).
- return new SuggestedWords(suggestionsContainer,
+ callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer,
true /* typedWordValid */,
false /* willAutoCorrect */,
false /* isPunctuationSuggestions */,
false /* isObsoleteSuggestions */,
- false /* isPrediction */);
+ false /* isPrediction */));
}
private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(
@@ -419,7 +454,7 @@ public final class Suggest {
private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator =
new SuggestedWordInfoComparator();
- private static SuggestedWordInfo getTransformedSuggestedWordInfo(
+ /* package for test */ static SuggestedWordInfo getTransformedSuggestedWordInfo(
final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase,
final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) {
final StringBuilder sb = new StringBuilder(wordInfo.mWord.length());
@@ -430,11 +465,17 @@ public final class Suggest {
} else {
sb.append(wordInfo.mWord);
}
- for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
+ // Appending quotes is here to help people quote words. However, it's not helpful
+ // when they type words with quotes toward the end like "it's" or "didn't", where
+ // it's more likely the user missed the last character (or didn't type it yet).
+ final int quotesToAppend = trailingSingleQuotesCount
+ - (-1 == wordInfo.mWord.indexOf(Constants.CODE_SINGLE_QUOTE) ? 0 : 1);
+ for (int i = quotesToAppend - 1; i >= 0; --i) {
sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
- wordInfo.mSourceDict);
+ wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
}
public void close() {