diff options
Diffstat (limited to 'java/src')
12 files changed, 123 insertions, 188 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 042a1c0d8..7714ba892 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -758,15 +758,18 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final PointerTracker tracker = PointerTracker.getPointerTracker( pointerId, this); final int px, py; + final MotionEvent motionEvent; if (mMoreKeysPanel != null && tracker.mPointerId == mMoreKeysPanelPointerTrackerId) { px = mMoreKeysPanel.translateX((int)me.getX(i)); py = mMoreKeysPanel.translateY((int)me.getY(i)); + motionEvent = null; } else { px = (int)me.getX(i); py = (int)me.getY(i); + motionEvent = me; } - tracker.onMoveEvent(px, py, eventTime); + tracker.onMoveEvent(px, py, eventTime, motionEvent); if (ENABLE_USABILITY_STUDY_LOG) { final float pointerSize = me.getSize(i); final float pointerPressure = me.getPressure(i); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 7ab68d931..32ef408b4 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -469,7 +469,7 @@ public class PointerTracker { onUpEvent(x, y, eventTime); break; case MotionEvent.ACTION_MOVE: - onMoveEvent(x, y, eventTime); + onMoveEvent(x, y, eventTime, null); break; case MotionEvent.ACTION_CANCEL: onCancelEvent(x, y, eventTime); @@ -548,7 +548,7 @@ public class PointerTracker { mIsInSlidingKeyInput = true; } - public void onMoveEvent(int x, int y, long eventTime) { + public void onMoveEvent(int x, int y, long eventTime, MotionEvent me) { if (DEBUG_MOVE_EVENT) printTouchEvent("onMoveEvent:", x, y, eventTime); if (mKeyAlreadyProcessed) @@ -760,14 +760,10 @@ public class PointerTracker { callListenerOnRelease(key, code, false); } - private long mPreviousEventTime; - private void printTouchEvent(String title, int x, int y, long eventTime) { final Key key = mKeyDetector.detectHitKey(x, y); final String code = KeyDetector.printableCode(key); - final long delta = eventTime - mPreviousEventTime; Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title, - (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, code)); - mPreviousEventTime = eventTime; + (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, eventTime, code)); } } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 6b6ec2b45..f44e6328b 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -108,7 +108,7 @@ public class BinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord, final WordCallback callback) { + final CharSequence previousWord) { if (mNativeDict == 0) return null; int[] codePoints = StringUtils.toCodePointArray(previousWord.toString()); @@ -141,15 +141,13 @@ public class BinaryDictionary extends Dictionary { mBigramScores[j], SuggestedWordInfo.KIND_CORRECTION)); } } - Utils.addAllSuggestions(mDicTypeId, Dictionary.BIGRAM, suggestions, callback); return suggestions; } // proximityInfo and/or prevWordForBigrams may not be null. @Override public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { final int count = getSuggestions(codes, prevWordForBigrams, proximityInfo, mOutputChars, mScores, mSpaceIndices); @@ -168,7 +166,6 @@ public class BinaryDictionary extends Dictionary { mScores[j], SuggestedWordInfo.KIND_CORRECTION)); } } - Utils.addAllSuggestions(mDicTypeId, Dictionary.UNIGRAM, suggestions, callback); return suggestions; } diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index 55913b8eb..99a04da72 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -35,52 +35,26 @@ public abstract class Dictionary { public static final int BIGRAM = 1; public static final int NOT_A_PROBABILITY = -1; - /** - * Interface to be implemented by classes requesting words to be fetched from the dictionary. - * @see #getWords(WordComposer, CharSequence, WordCallback, ProximityInfo) - */ - public interface WordCallback { - /** - * Adds a word to a list of suggestions. The word is expected to be ordered based on - * the provided score. - * @param word the character array containing the word - * @param spaceIndices the indices of inserted spaces - * @param wordOffset starting offset of the word in the character array - * @param wordLength length of valid characters in the character array - * @param score the score of occurrence. This is normalized between 1 and 255, but - * can exceed those limits - * @param dicTypeId of the dictionary where word was from - * @param dataType tells type of this data, either UNIGRAM or BIGRAM - * @return true if the word was added, false if no more words are required - */ - boolean addWord(char[] word, int[] spaceIndices, int wordOffset, int wordLength, int score, - int dicTypeId, int dataType); - } /** * Searches for words in the dictionary that match the characters in the composer. Matched - * words are added through the callback object. - * @param composer the key sequence to match + * words are returned as an ArrayList. + * @param composer the key sequence to match with coordinate info, as a WordComposer * @param prevWordForBigrams the previous word, or null if none - * @param callback the callback object to send matched words to as possible candidates * @param proximityInfo the object for key proximity. May be ignored by some implementations. * @return the list of suggestions - * @see WordCallback#addWord(char[], int, int, int, int, int) */ abstract public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo); + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo); /** - * Searches for pairs in the bigram dictionary that matches the previous word and all the - * possible words following are added through the callback object. + * Searches for pairs in the bigram dictionary that matches the previous word. * @param composer the key sequence to match * @param previousWord the word before - * @param callback the callback object to send possible word following previous word * @return the list of suggestions */ public abstract ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, - final CharSequence previousWord, final WordCallback callback); + final CharSequence previousWord); /** * Checks if the given word occurs in the dictionary diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index 6b424f88f..169e70745 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -53,19 +53,18 @@ public class DictionaryCollection extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getWords(final WordComposer composer, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; if (dictionaries.isEmpty()) return null; // To avoid creating unnecessary objects, we get the list out of the first // dictionary and add the rest to it if not null, hence the get(0) ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getWords(composer, - prevWordForBigrams, callback, proximityInfo); + prevWordForBigrams, proximityInfo); if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); final int length = dictionaries.size(); for (int i = 0; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getWords(composer, - prevWordForBigrams, callback, proximityInfo); + prevWordForBigrams, proximityInfo); if (null != sugg) suggestions.addAll(sugg); } return suggestions; @@ -73,18 +72,18 @@ public class DictionaryCollection extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer composer, - final CharSequence previousWord, final WordCallback callback) { + final CharSequence previousWord) { final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; if (dictionaries.isEmpty()) return null; // To avoid creating unnecessary objects, we get the list out of the first // dictionary and add the rest to it if not null, hence the get(0) ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getBigrams(composer, - previousWord, callback); + previousWord); if (null == suggestions) suggestions = new ArrayList<SuggestedWordInfo>(); final int length = dictionaries.size(); for (int i = 0; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = - dictionaries.get(i).getBigrams(composer, previousWord, callback); + dictionaries.get(i).getBigrams(composer, previousWord); if (null != sugg) suggestions.addAll(sugg); } return suggestions; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 732bc1802..c076fa0f9 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -196,22 +196,19 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { asyncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } protected final ArrayList<SuggestedWordInfo> getWordsInner(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { // Ensure that there are no concurrent calls to getWords. If there are, do nothing and // return. if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - return mBinaryDictionary.getWords(codes, prevWordForBigrams, callback, - proximityInfo); + return mBinaryDictionary.getWords(codes, prevWordForBigrams, proximityInfo); } } finally { mLocalDictionaryController.unlock(); @@ -222,17 +219,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord, final WordCallback callback) { + final CharSequence previousWord) { asyncReloadDictionaryIfRequired(); - return getBigramsInner(codes, previousWord, callback); + return getBigramsInner(codes, previousWord); } protected ArrayList<SuggestedWordInfo> getBigramsInner(final WordComposer codes, - final CharSequence previousWord, final WordCallback callback) { + final CharSequence previousWord) { if (mLocalDictionaryController.tryLock()) { try { if (mBinaryDictionary != null) { - return mBinaryDictionary.getBigrams(codes, previousWord, callback); + return mBinaryDictionary.getBigrams(codes, previousWord); } } finally { mLocalDictionaryController.unlock(); diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java index 7d131a664..f19d77be2 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java @@ -249,8 +249,7 @@ public class ExpandableDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { synchronized (mUpdatingLock) { // If we need to update, start off a background task if (mRequiresReload) startDictionaryLoadingTaskLocked(); @@ -262,7 +261,6 @@ public class ExpandableDictionary extends Dictionary { } final ArrayList<SuggestedWordInfo> suggestions = getWordsInner(codes, prevWordForBigrams, proximityInfo); - Utils.addAllSuggestions(mDicTypeId, Dictionary.UNIGRAM, suggestions, callback); return suggestions; } @@ -614,11 +612,10 @@ public class ExpandableDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getBigrams(final WordComposer codes, - final CharSequence previousWord, final WordCallback callback) { + final CharSequence previousWord) { if (!reloadDictionaryIfRequired()) { final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<SuggestedWordInfo>(); runBigramReverseLookUp(previousWord, suggestions); - Utils.addAllSuggestions(mDicTypeId, Dictionary.BIGRAM, suggestions, callback); return suggestions; } return null; diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 61a8e2831..a4332936d 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -26,6 +26,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; @@ -34,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. */ -public class Suggest implements Dictionary.WordCallback { +public class Suggest { public static final String TAG = Suggest.class.getSimpleName(); public static final int APPROX_MAX_WORD_LENGTH = 32; @@ -58,53 +59,61 @@ public class Suggest implements Dictionary.WordCallback { 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 for the unigram map, internal to LatinIME - public static final String DICT_KEY_USER_HISTORY_UNIGRAM = "history_unigram"; - // User history dictionary for the bigram map, internal to LatinIME - public static final String DICT_KEY_USER_HISTORY_BIGRAM = "history_bigram"; + // 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; private ContactsBinaryDictionary mContactsDict; private WhitelistDictionary mWhiteListDictionary; - private final ConcurrentHashMap<String, Dictionary> mUnigramDictionaries = - new ConcurrentHashMap<String, Dictionary>(); - private final ConcurrentHashMap<String, Dictionary> mBigramDictionaries = + private final ConcurrentHashMap<String, Dictionary> mDictionaries = new ConcurrentHashMap<String, Dictionary>(); public static final int MAX_SUGGESTIONS = 18; private float mAutoCorrectionThreshold; - private ArrayList<SuggestedWordInfo> mSuggestions = new ArrayList<SuggestedWordInfo>(); - private CharSequence mConsideredWord; - // 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; + private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; public Suggest(final Context context, final Locale locale) { initAsynchronously(context, locale); + mLocale = locale; } /* package for test */ Suggest(final Context context, final File dictionary, final long startOffset, final long length, final Locale locale) { final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary, startOffset, length /* useFullEditDistance */, false, locale); + mLocale = locale; mMainDictionary = mainDict; - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, mainDict); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, mainDict); + addOrReplaceDictionary(mDictionaries, DICT_KEY_MAIN, mainDict); initWhitelistAndAutocorrectAndPool(context, locale); } private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) { mWhiteListDictionary = new WhitelistDictionary(context, locale); - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary); + addOrReplaceDictionary(mDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary); } private void initAsynchronously(final Context context, final Locale locale) { @@ -133,8 +142,7 @@ public class Suggest implements Dictionary.WordCallback { public void run() { final DictionaryCollection newMainDict = DictionaryFactory.createMainDictionaryFromManager(context, locale); - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_MAIN, newMainDict); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_MAIN, newMainDict); + addOrReplaceDictionary(mDictionaries, DICT_KEY_MAIN, newMainDict); mMainDictionary = newMainDict; } }.start(); @@ -155,7 +163,7 @@ public class Suggest implements Dictionary.WordCallback { } public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() { - return mUnigramDictionaries; + return mDictionaries; } public static int getApproxMaxWordLength() { @@ -167,7 +175,7 @@ public class Suggest implements Dictionary.WordCallback { * before the main dictionary, if set. This refers to the system-managed user dictionary. */ public void setUserDictionary(UserBinaryDictionary userDictionary) { - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER, userDictionary); + addOrReplaceDictionary(mDictionaries, DICT_KEY_USER, userDictionary); } /** @@ -177,15 +185,11 @@ public class Suggest implements Dictionary.WordCallback { */ public void setContactsDictionary(ContactsBinaryDictionary contactsDictionary) { mContactsDict = contactsDictionary; - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); + addOrReplaceDictionary(mDictionaries, DICT_KEY_CONTACTS, contactsDictionary); } public void setUserHistoryDictionary(UserHistoryDictionary userHistoryDictionary) { - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER_HISTORY_UNIGRAM, - userHistoryDictionary); - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_HISTORY_BIGRAM, - userHistoryDictionary); + addOrReplaceDictionary(mDictionaries, DICT_KEY_USER_HISTORY, userHistoryDictionary); } public void setAutoCorrectionThreshold(float threshold) { @@ -209,39 +213,6 @@ public class Suggest implements Dictionary.WordCallback { return sb; } - private static final WordComposer sEmptyWordComposer = new WordComposer(); - public SuggestedWords getBigramPredictions(CharSequence prevWordForBigram) { - LatinImeLogger.onStartSuggestion(prevWordForBigram); - mIsFirstCharCapitalized = false; - mIsAllUpperCase = false; - mTrailingSingleQuotesCount = 0; - mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); - - // Treating USER_TYPED as UNIGRAM suggestion for logging now. - LatinImeLogger.onAddSuggestedWord("", Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); - mConsideredWord = ""; - - getAllBigrams(prevWordForBigram, sEmptyWordComposer); - - SuggestedWordInfo.removeDups(mSuggestions); - - return new SuggestedWords(mSuggestions, - false /* typedWordValid */, - false /* hasAutoCorrectionCandidate */, - false /* allowsToBeAutoCorrected */, - false /* isPunctuationSuggestions */, - false /* isObsoleteSuggestions */, - true /* isPrediction */); - } - - // Compatibility for tests. TODO: remove this - public SuggestedWords getSuggestedWords( - final WordComposer wordComposer, CharSequence prevWordForBigram, - final ProximityInfo proximityInfo, final boolean isCorrectionEnabled) { - return getSuggestedWords(wordComposer, prevWordForBigram, proximityInfo, - isCorrectionEnabled, false); - } - // TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder public SuggestedWords getSuggestedWords( final WordComposer wordComposer, CharSequence prevWordForBigram, @@ -251,7 +222,8 @@ public class Suggest implements Dictionary.WordCallback { mIsFirstCharCapitalized = !isPrediction && wordComposer.isFirstCharCapitalized(); mIsAllUpperCase = !isPrediction && wordComposer.isAllUpperCase(); mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); - mSuggestions = new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); + final ArrayList<SuggestedWordInfo> suggestions = + new ArrayList<SuggestedWordInfo>(MAX_SUGGESTIONS); final String typedWord = wordComposer.getTypedWord(); final String consideredWord = mTrailingSingleQuotesCount > 0 @@ -259,12 +231,32 @@ public class Suggest implements Dictionary.WordCallback { : typedWord; // Treating USER_TYPED as UNIGRAM suggestion for logging now. LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM); - mConsideredWord = consideredWord; if (wordComposer.size() <= 1 && isCorrectionEnabled) { // At first character typed, search only the bigrams if (!TextUtils.isEmpty(prevWordForBigram)) { - getAllBigrams(prevWordForBigram, wordComposer); + final CharSequence lowerPrevWord; + if (StringUtils.hasUpperCase(prevWordForBigram)) { + // TODO: Must pay attention to locale when changing case. + lowerPrevWord = prevWordForBigram.toString().toLowerCase(); + } else { + 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); + if (null != lowerPrevWord) { + localSuggestions.addAll(dictionary.getBigrams(wordComposer, lowerPrevWord)); + } + for (final SuggestedWordInfo suggestion : localSuggestions) { + final String suggestionStr = suggestion.mWord.toString(); + addWord(suggestionStr.toCharArray(), null, 0, suggestionStr.length(), + suggestion.mScore, dicTypeId, Dictionary.BIGRAM, + suggestions, consideredWord); + } + } } } else if (wordComposer.size() > 1) { final WordComposer wordComposerForLookup; @@ -277,12 +269,20 @@ public class Suggest implements Dictionary.WordCallback { wordComposerForLookup = wordComposer; } // At second character typed, search the unigrams (scores being affected by bigrams) - for (final String key : mUnigramDictionaries.keySet()) { + for (final String key : mDictionaries.keySet()) { // Skip UserUnigramDictionary and WhitelistDictionary to lookup - if (key.equals(DICT_KEY_USER_HISTORY_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) + if (key.equals(DICT_KEY_USER_HISTORY) || key.equals(DICT_KEY_WHITELIST)) continue; - final Dictionary dictionary = mUnigramDictionaries.get(key); - dictionary.getWords(wordComposerForLookup, prevWordForBigram, this, proximityInfo); + 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) { + final String suggestionStr = suggestion.mWord.toString(); + addWord(suggestionStr.toCharArray(), null, 0, suggestionStr.length(), + suggestion.mScore, dicTypeId, Dictionary.UNIGRAM, + suggestions, consideredWord); + } } } @@ -292,8 +292,8 @@ public class Suggest implements Dictionary.WordCallback { final boolean hasAutoCorrection; if (isCorrectionEnabled) { final CharSequence autoCorrection = - AutoCorrection.computeAutoCorrectionWord(mUnigramDictionaries, wordComposer, - mSuggestions, consideredWord, mAutoCorrectionThreshold, + AutoCorrection.computeAutoCorrectionWord(mDictionaries, wordComposer, + suggestions, consideredWord, mAutoCorrectionThreshold, whitelistedWord); hasAutoCorrection = (null != autoCorrection); } else { @@ -306,25 +306,25 @@ public class Suggest implements Dictionary.WordCallback { for (int i = mTrailingSingleQuotesCount - 1; i >= 0; --i) { sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE); } - mSuggestions.add(0, new SuggestedWordInfo(sb.toString(), + suggestions.add(0, new SuggestedWordInfo(sb.toString(), SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); } else { - mSuggestions.add(0, new SuggestedWordInfo(whitelistedWord, + suggestions.add(0, new SuggestedWordInfo(whitelistedWord, SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_WHITELIST)); } } if (!isPrediction) { - mSuggestions.add(0, new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, + suggestions.add(0, new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED)); } - SuggestedWordInfo.removeDups(mSuggestions); + SuggestedWordInfo.removeDups(suggestions); final ArrayList<SuggestedWordInfo> suggestionsList; - if (DBG && !mSuggestions.isEmpty()) { - suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, mSuggestions); + if (DBG && !suggestions.isEmpty()) { + suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestions); } else { - suggestionsList = mSuggestions; + suggestionsList = suggestions; } // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid" @@ -362,23 +362,6 @@ public class Suggest implements Dictionary.WordCallback { isPrediction); } - /** - * Adds all bigram predictions for prevWord. Also checks the lower case version of prevWord if - * it contains any upper case characters. - */ - private void getAllBigrams(final CharSequence prevWord, final WordComposer wordComposer) { - if (StringUtils.hasUpperCase(prevWord)) { - // TODO: Must pay attention to locale when changing case. - final CharSequence lowerPrevWord = prevWord.toString().toLowerCase(); - for (final Dictionary dictionary : mBigramDictionaries.values()) { - dictionary.getBigrams(wordComposer, lowerPrevWord, this); - } - } - for (final Dictionary dictionary : mBigramDictionaries.values()) { - dictionary.getBigrams(wordComposer, prevWord, this); - } - } - private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo( final String typedWord, final ArrayList<SuggestedWordInfo> suggestions) { final SuggestedWordInfo typedWordInfo = suggestions.get(0); @@ -406,19 +389,16 @@ public class Suggest implements Dictionary.WordCallback { } // TODO: Use codepoint instead of char - @Override public boolean addWord(final char[] word, int[] indices, final int offset, final int length, - int score, final int dicTypeId, final int dataType) { + int score, final int dicTypeId, final int dataType, + final ArrayList<SuggestedWordInfo> suggestions, final String consideredWord) { int dataTypeForLog = dataType; - final ArrayList<SuggestedWordInfo> suggestions; - final int prefMaxSuggestions; - suggestions = mSuggestions; - prefMaxSuggestions = MAX_SUGGESTIONS; + final int prefMaxSuggestions = MAX_SUGGESTIONS; int pos = 0; // Check if it's the same word, only caps are different - if (StringUtils.equalsIgnoreCase(mConsideredWord, word, offset, length)) { + if (StringUtils.equalsIgnoreCase(consideredWord, word, offset, length)) { // TODO: remove this surrounding if clause and move this logic to // getSuggestedWordBuilder. if (suggestions.size() > 0) { @@ -476,8 +456,7 @@ public class Suggest implements Dictionary.WordCallback { public void close() { final HashSet<Dictionary> dictionaries = new HashSet<Dictionary>(); - dictionaries.addAll(mUnigramDictionaries.values()); - dictionaries.addAll(mBigramDictionaries.values()); + dictionaries.addAll(mDictionaries.values()); for (final Dictionary dictionary : dictionaries) { dictionary.close(); } diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java index d706022bd..74f27e3cc 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java @@ -33,10 +33,9 @@ public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryD @Override public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java index 984e2e707..5b2a6edec 100644 --- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java @@ -36,10 +36,9 @@ public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionar @Override public synchronized ArrayList<SuggestedWordInfo> getWords(final WordComposer codes, - final CharSequence prevWordForBigrams, final WordCallback callback, - final ProximityInfo proximityInfo) { + final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) { syncReloadDictionaryIfRequired(); - return getWordsInner(codes, prevWordForBigrams, callback, proximityInfo); + return getWordsInner(codes, prevWordForBigrams, proximityInfo); } @Override diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 19ac71876..8f71de0e7 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -531,14 +531,4 @@ public class Utils { } return builder.toString(); } - - public static void addAllSuggestions(final int dicTypeId, final int dataType, - final ArrayList<SuggestedWords.SuggestedWordInfo> suggestions, - final Dictionary.WordCallback callback) { - for (SuggestedWordInfo suggestion : suggestions) { - final String suggestionStr = suggestion.mWord.toString(); - callback.addWord(suggestionStr.toCharArray(), null, 0, suggestionStr.length(), - suggestion.mScore, dicTypeId, dataType); - } - } } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java index 0bbf2acb1..5f4d66091 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java @@ -32,12 +32,12 @@ import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.BinaryDictionary; import com.android.inputmethod.latin.ContactsBinaryDictionary; import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.Dictionary.WordCallback; import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StringUtils; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary; import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary; import com.android.inputmethod.latin.UserBinaryDictionary; @@ -203,7 +203,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService EMPTY_STRING_ARRAY); } - private static class SuggestionsGatherer implements WordCallback { + // TODO: remove this class and replace it by storage local to the session. + private static class SuggestionsGatherer { public static class Result { public final String[] mSuggestions; public final boolean mHasRecommendedSuggestions; @@ -237,9 +238,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService mScores = new int[mMaxLength]; } - @Override synchronized public boolean addWord(char[] word, int[] spaceIndices, int wordOffset, - int wordLength, int score, int dicTypeId, int dataType) { + int wordLength, int score) { final int positionIndex = Arrays.binarySearch(mScores, 0, mLength, score); // binarySearch returns the index if the element exists, and -<insertion index> - 1 // if it doesn't. See documentation for binarySearch. @@ -780,8 +780,13 @@ public class AndroidSpellCheckerService extends SpellCheckerService try { dictInfo = mDictionaryPool.takeOrGetNull(); if (null == dictInfo) return getNotInDictEmptySuggestions(); - dictInfo.mDictionary.getWords(composer, prevWord, suggestionsGatherer, - dictInfo.mProximityInfo); + final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getWords( + composer, prevWord, dictInfo.mProximityInfo); + for (final SuggestedWordInfo suggestion : suggestions) { + final String suggestionStr = suggestion.mWord.toString(); + suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0, + suggestionStr.length(), suggestion.mScore); + } isInDict = dictInfo.mDictionary.isValidWord(text); if (!isInDict && CAPITALIZE_NONE != capitalizeType) { // We want to test the word again if it's all caps or first caps only. |