/** * Returns a list of words that match the list of character codes passed in. This list will be * overwritten the next time this function is called. * * @param view a view for retrieving the context for AutoText * @param wordComposer contains what is currently being typed * @param prevWordForBigram previous word (used only for bigram) * @return list of suggestions. */ public List<CharSequence> getSuggestions( View view, WordComposer wordComposer, boolean includeTypedWordIfValid, CharSequence prevWordForBigram) { LatinImeLogger.onStartSuggestion(prevWordForBigram); mHaveCorrection = false; mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); mIsAllUpperCase = wordComposer.isAllUpperCase(); collectGarbage(mSuggestions, mPrefMaxSuggestions); Arrays.fill(mPriorities, 0); Arrays.fill(mNextLettersFrequencies, 0); // Save a lowercase version of the original word mOriginalWord = wordComposer.getTypedWord(); if (mOriginalWord != null) { final String mOriginalWordString = mOriginalWord.toString(); mOriginalWord = mOriginalWordString; mLowerOriginalWord = mOriginalWordString.toLowerCase(); // Treating USER_TYPED as UNIGRAM suggestion for logging now. LatinImeLogger.onAddSuggestedWord( mOriginalWordString, Suggest.DIC_USER_TYPED, Dictionary.DataType.UNIGRAM); } else { mLowerOriginalWord = ""; } if (wordComposer.size() == 1 && (mCorrectionMode == CORRECTION_FULL_BIGRAM || mCorrectionMode == CORRECTION_BASIC)) { // At first character typed, search only the bigrams Arrays.fill(mBigramPriorities, 0); collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS); if (!TextUtils.isEmpty(prevWordForBigram)) { CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase(); if (mMainDict.isValidWord(lowerPrevWord)) { prevWordForBigram = lowerPrevWord; } if (mUserBigramDictionary != null) { mUserBigramDictionary.getBigrams( wordComposer, prevWordForBigram, this, mNextLettersFrequencies); } if (mContactsDictionary != null) { mContactsDictionary.getBigrams( wordComposer, prevWordForBigram, this, mNextLettersFrequencies); } if (mMainDict != null) { mMainDict.getBigrams(wordComposer, prevWordForBigram, this, mNextLettersFrequencies); } char currentChar = wordComposer.getTypedWord().charAt(0); char currentCharUpper = Character.toUpperCase(currentChar); int count = 0; int bigramSuggestionSize = mBigramSuggestions.size(); for (int i = 0; i < bigramSuggestionSize; i++) { if (mBigramSuggestions.get(i).charAt(0) == currentChar || mBigramSuggestions.get(i).charAt(0) == currentCharUpper) { int poolSize = mStringPool.size(); StringBuilder sb = poolSize > 0 ? (StringBuilder) mStringPool.remove(poolSize - 1) : new StringBuilder(getApproxMaxWordLength()); sb.setLength(0); sb.append(mBigramSuggestions.get(i)); mSuggestions.add(count++, sb); if (count > mPrefMaxSuggestions) break; } } } } else if (wordComposer.size() > 1) { // At second character typed, search the unigrams (scores being affected by bigrams) if (mUserDictionary != null || mContactsDictionary != null) { if (mUserDictionary != null) { mUserDictionary.getWords(wordComposer, this, mNextLettersFrequencies); } if (mContactsDictionary != null) { mContactsDictionary.getWords(wordComposer, this, mNextLettersFrequencies); } if (mSuggestions.size() > 0 && isValidWord(mOriginalWord) && (mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)) { mHaveCorrection = true; } } mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM) && mSuggestions.size() > 0) { mHaveCorrection = true; } } if (mOriginalWord != null) { mSuggestions.add(0, mOriginalWord.toString()); } // Check if the first suggestion has a minimum number of characters in common if (wordComposer.size() > 1 && mSuggestions.size() > 1 && (mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)) { if (!haveSufficientCommonality(mLowerOriginalWord, mSuggestions.get(1))) { mHaveCorrection = false; } } if (mAutoTextEnabled) { int i = 0; int max = 6; // Don't autotext the suggestions from the dictionaries if (mCorrectionMode == CORRECTION_BASIC) max = 1; while (i < mSuggestions.size() && i < max) { String suggestedWord = mSuggestions.get(i).toString().toLowerCase(); CharSequence autoText = AutoText.get(suggestedWord, 0, suggestedWord.length(), view); // Is there an AutoText correction? boolean canAdd = autoText != null; // Is that correction already the current prediction (or original word)? canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i)); // Is that correction already the next predicted word? if (canAdd && i + 1 < mSuggestions.size() && mCorrectionMode != CORRECTION_BASIC) { canAdd &= !TextUtils.equals(autoText, mSuggestions.get(i + 1)); } if (canAdd) { mHaveCorrection = true; mSuggestions.add(i + 1, autoText); i++; } i++; } } removeDupes(); return mSuggestions; }