am b52055bf: Merge "Use PrevWordsInfo instead of String in Java side."

* commit 'b52055bfd167df67cf4ef155324c2e896c7a20cf':
  Use PrevWordsInfo instead of String in Java side.
main
Keisuke Kuroyanagi 2014-05-19 05:03:46 +00:00 committed by Android Git Automerger
commit a8daf43e92
20 changed files with 137 additions and 101 deletions

View File

@ -265,7 +265,7 @@ public final class BinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
if (!isValidDictionary()) { if (!isValidDictionary()) {
@ -274,8 +274,8 @@ public final class BinaryDictionary extends Dictionary {
Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE); Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE);
// TODO: toLowerCase in the native code // TODO: toLowerCase in the native code
final int[] prevWordCodePointArray = (null == prevWord) final int[] prevWordCodePointArray = (null == prevWordsInfo.mPrevWord)
? null : StringUtils.toCodePointArray(prevWord); ? null : StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
final InputPointers inputPointers = composer.getInputPointers(); final InputPointers inputPointers = composer.getInputPointers();
final boolean isGesture = composer.isBatchMode(); final boolean isGesture = composer.isBatchMode();
final int inputSize; final int inputSize;

View File

@ -69,7 +69,7 @@ public abstract class Dictionary {
* Searches for suggestions for a given context. For the moment the context is only the * Searches for suggestions for a given context. For the moment the context is only the
* previous word. * previous word.
* @param composer the key sequence to match with coordinate info, as a WordComposer * @param composer the key sequence to match with coordinate info, as a WordComposer
* @param prevWord the previous word, or null if none * @param prevWordsInfo the information of previous words.
* @param proximityInfo the object for key proximity. May be ignored by some implementations. * @param proximityInfo the object for key proximity. May be ignored by some implementations.
* @param blockOffensiveWords whether to block potentially offensive words * @param blockOffensiveWords whether to block potentially offensive words
* @param additionalFeaturesOptions options about additional features used for the suggestion. * @param additionalFeaturesOptions options about additional features used for the suggestion.
@ -79,10 +79,8 @@ public abstract class Dictionary {
* different language weight is used. * different language weight is used.
* @return the list of suggestions (possibly null if none) * @return the list of suggestions (possibly null if none)
*/ */
// TODO: pass more context than just the previous word, to enable better suggestions (n-gram
// and more)
abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight); final int sessionId, final float[] inOutLanguageWeight);
@ -156,7 +154,7 @@ public abstract class Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
return null; return null;

View File

@ -57,7 +57,7 @@ public final class DictionaryCollection extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries;
@ -65,13 +65,13 @@ public final class DictionaryCollection extends Dictionary {
// To avoid creating unnecessary objects, we get the list out of the first // 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) // dictionary and add the rest to it if not null, hence the get(0)
ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
sessionId, inOutLanguageWeight); sessionId, inOutLanguageWeight);
if (null == suggestions) suggestions = CollectionUtils.newArrayList(); if (null == suggestions) suggestions = CollectionUtils.newArrayList();
final int length = dictionaries.size(); final int length = dictionaries.size();
for (int i = 1; i < length; ++ i) { for (int i = 1; i < length; ++ i) {
final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
sessionId, inOutLanguageWeight); sessionId, inOutLanguageWeight);
if (null != sugg) suggestions.addAll(sugg); if (null != sugg) suggestions.addAll(sugg);
} }

View File

@ -444,7 +444,7 @@ public class DictionaryFacilitatorForSuggest {
// TODO: Revise the way to fusion suggestion results. // TODO: Revise the way to fusion suggestion results.
public SuggestionResults getSuggestionResults(final WordComposer composer, public SuggestionResults getSuggestionResults(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final ArrayList<SuggestedWordInfo> rawSuggestions) { final int sessionId, final ArrayList<SuggestedWordInfo> rawSuggestions) {
final Dictionaries dictionaries = mDictionaries; final Dictionaries dictionaries = mDictionaries;
@ -455,7 +455,7 @@ public class DictionaryFacilitatorForSuggest {
final Dictionary dictionary = dictionaries.getDict(dictType); final Dictionary dictionary = dictionaries.getDict(dictType);
if (null == dictionary) continue; if (null == dictionary) continue;
final ArrayList<SuggestedWordInfo> dictionarySuggestions = final ArrayList<SuggestedWordInfo> dictionarySuggestions =
dictionary.getSuggestions(composer, prevWord, proximityInfo, dictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, blockOffensiveWords, additionalFeaturesOptions, sessionId,
languageWeight); languageWeight);
if (null == dictionarySuggestions) continue; if (null == dictionarySuggestions) continue;

View File

@ -367,7 +367,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
reloadDictionaryIfRequired(); reloadDictionaryIfRequired();
@ -380,7 +380,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return null; return null;
} }
final ArrayList<SuggestedWordInfo> suggestions = final ArrayList<SuggestedWordInfo> suggestions =
mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, blockOffensiveWords, additionalFeaturesOptions, sessionId,
inOutLanguageWeight); inOutLanguageWeight);
if (mBinaryDictionary.isCorrupted()) { if (mBinaryDictionary.isCorrupted()) {

View File

@ -1428,8 +1428,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (DEBUG) { if (DEBUG) {
if (mInputLogic.mWordComposer.isComposingWord() if (mInputLogic.mWordComposer.isComposingWord()
|| mInputLogic.mWordComposer.isBatchMode()) { || mInputLogic.mWordComposer.isBatchMode()) {
final String previousWord final PrevWordsInfo prevWordsInfo
= mInputLogic.mWordComposer.getPreviousWordForSuggestion(); = mInputLogic.mWordComposer.getPrevWordsInfoForSuggestion();
// TODO: this is for checking consistency with older versions. Remove this when // TODO: this is for checking consistency with older versions. Remove this when
// we are confident this is stable. // we are confident this is stable.
// We're checking the previous word in the text field against the memorized previous // We're checking the previous word in the text field against the memorized previous
@ -1438,14 +1438,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion( final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion(
currentSettings.mSpacingAndPunctuations, currentSettings.mSpacingAndPunctuations,
mInputLogic.mWordComposer.isComposingWord() ? 2 : 1); mInputLogic.mWordComposer.isComposingWord() ? 2 : 1);
if (!TextUtils.equals(previousWord, rereadPrevWord)) { if (!TextUtils.equals(prevWordsInfo.mPrevWord, rereadPrevWord)) {
throw new RuntimeException("Unexpected previous word: " throw new RuntimeException("Unexpected previous word: "
+ previousWord + " <> " + rereadPrevWord); + prevWordsInfo.mPrevWord + " <> " + rereadPrevWord);
} }
} }
} }
mInputLogic.mSuggest.getSuggestedWords(mInputLogic.mWordComposer, mInputLogic.mSuggest.getSuggestedWords(mInputLogic.mWordComposer,
mInputLogic.mWordComposer.getPreviousWordForSuggestion(), mInputLogic.mWordComposer.getPrevWordsInfoForSuggestion(),
keyboard.getProximityInfo(), currentSettings.mBlockPotentiallyOffensive, keyboard.getProximityInfo(), currentSettings.mBlockPotentiallyOffensive,
currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId, currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId,
sequenceNumber, callback); sequenceNumber, callback);

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.latin;
public class PrevWordsInfo {
// The previous word. May be null after resetting and before starting a new composing word, or
// when there is no context like at the start of text for example. It can also be set to null
// externally when the user enters a separator that does not let bigrams across, like a period
// or a comma.
public final String mPrevWord;
public PrevWordsInfo(final String prevWord) {
mPrevWord = prevWord;
}
}

View File

@ -50,12 +50,12 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
if (mLock.readLock().tryLock()) { if (mLock.readLock().tryLock()) {
try { try {
return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, return mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, blockOffensiveWords, additionalFeaturesOptions, sessionId,
inOutLanguageWeight); inOutLanguageWeight);
} finally { } finally {

View File

@ -71,17 +71,17 @@ public final class Suggest {
} }
public void getSuggestedWords(final WordComposer wordComposer, public void getSuggestedWords(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled, final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
final int[] additionalFeaturesOptions, final int sessionId, final int sequenceNumber, final int[] additionalFeaturesOptions, final int sessionId, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) { final OnGetSuggestedWordsCallback callback) {
LatinImeLogger.onStartSuggestion(prevWordForBigram); LatinImeLogger.onStartSuggestion(prevWordsInfo.mPrevWord);
if (wordComposer.isBatchMode()) { if (wordComposer.isBatchMode()) {
getSuggestedWordsForBatchInput(wordComposer, prevWordForBigram, proximityInfo, getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, sequenceNumber, blockOffensiveWords, additionalFeaturesOptions, sessionId, sequenceNumber,
callback); callback);
} else { } else {
getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo, getSuggestedWordsForTypingInput(wordComposer, prevWordsInfo, proximityInfo,
blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions, blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions,
sequenceNumber, callback); sequenceNumber, callback);
} }
@ -90,7 +90,7 @@ public final class Suggest {
// Retrieves suggestions for the typing input // Retrieves suggestions for the typing input
// and calls the callback function with the suggestions. // and calls the callback function with the suggestions.
private void getSuggestedWordsForTypingInput(final WordComposer wordComposer, private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled, final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
final int[] additionalFeaturesOptions, final int sequenceNumber, final int[] additionalFeaturesOptions, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) { final OnGetSuggestedWordsCallback callback) {
@ -108,7 +108,7 @@ public final class Suggest {
rawSuggestions = null; rawSuggestions = null;
} }
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
additionalFeaturesOptions, SESSION_TYPING, rawSuggestions); additionalFeaturesOptions, SESSION_TYPING, rawSuggestions);
final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
@ -215,7 +215,7 @@ public final class Suggest {
// Retrieves suggestions for the batch input // Retrieves suggestions for the batch input
// and calls the callback function with the suggestions. // and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer, private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
final String prevWordForBigram, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final int sequenceNumber, final int sessionId, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) { final OnGetSuggestedWordsCallback callback) {
@ -226,7 +226,7 @@ public final class Suggest {
rawSuggestions = null; rawSuggestions = null;
} }
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
additionalFeaturesOptions, sessionId, rawSuggestions); additionalFeaturesOptions, sessionId, rawSuggestions);
for (SuggestedWordInfo wordInfo : suggestionResults) { for (SuggestedWordInfo wordInfo : suggestionResults) {
LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType); LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType);

View File

@ -46,11 +46,9 @@ public final class WordComposer {
// The list of events that served to compose this string. // The list of events that served to compose this string.
private final ArrayList<Event> mEvents; private final ArrayList<Event> mEvents;
private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH); private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH);
// The previous word (before the composing word). Used as context for suggestions. May be null // The information of previous words (before the composing word). Must not be null. Used as
// after resetting and before starting a new composing word, or when there is no context like // context for suggestions.
// at the start of text for example. It can also be set to null externally when the user private PrevWordsInfo mPrevWordsInfo;
// enters a separator that does not let bigrams across, like a period or a comma.
private String mPreviousWordForSuggestion;
private String mAutoCorrection; private String mAutoCorrection;
private boolean mIsResumed; private boolean mIsResumed;
private boolean mIsBatchMode; private boolean mIsBatchMode;
@ -87,7 +85,7 @@ public final class WordComposer {
mIsBatchMode = false; mIsBatchMode = false;
mCursorPositionWithinWord = 0; mCursorPositionWithinWord = 0;
mRejectedBatchModeSuggestion = null; mRejectedBatchModeSuggestion = null;
mPreviousWordForSuggestion = null; mPrevWordsInfo = new PrevWordsInfo(null);
refreshTypedWordCache(); refreshTypedWordCache();
} }
@ -119,7 +117,7 @@ public final class WordComposer {
mIsBatchMode = false; mIsBatchMode = false;
mCursorPositionWithinWord = 0; mCursorPositionWithinWord = 0;
mRejectedBatchModeSuggestion = null; mRejectedBatchModeSuggestion = null;
mPreviousWordForSuggestion = null; mPrevWordsInfo = new PrevWordsInfo(null);
refreshTypedWordCache(); refreshTypedWordCache();
} }
@ -309,7 +307,7 @@ public final class WordComposer {
CoordinateUtils.yFromArray(coordinates, i))); CoordinateUtils.yFromArray(coordinates, i)));
} }
mIsResumed = true; mIsResumed = true;
mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString(); mPrevWordsInfo = new PrevWordsInfo(null == previousWord ? null : previousWord.toString());
} }
/** /**
@ -320,8 +318,8 @@ public final class WordComposer {
return mTypedWordCache.toString(); return mTypedWordCache.toString();
} }
public String getPreviousWordForSuggestion() { public PrevWordsInfo getPrevWordsInfoForSuggestion() {
return mPreviousWordForSuggestion; return mPrevWordsInfo;
} }
/** /**
@ -379,7 +377,7 @@ public final class WordComposer {
public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode, public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode,
final CharSequence previousWord) { final CharSequence previousWord) {
mCapitalizedMode = mode; mCapitalizedMode = mode;
mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString(); mPrevWordsInfo = new PrevWordsInfo(null == previousWord ? null : previousWord.toString());
} }
/** /**
@ -430,7 +428,7 @@ public final class WordComposer {
mCapsCount = 0; mCapsCount = 0;
mDigitsCount = 0; mDigitsCount = 0;
mIsBatchMode = false; mIsBatchMode = false;
mPreviousWordForSuggestion = committedWord.toString(); mPrevWordsInfo = new PrevWordsInfo(committedWord.toString());
mCombinerChain.reset(); mCombinerChain.reset();
mEvents.clear(); mEvents.clear();
mCodePointSize = 0; mCodePointSize = 0;
@ -448,11 +446,11 @@ public final class WordComposer {
// when the user inputs a separator that's not whitespace (including the case of the // when the user inputs a separator that's not whitespace (including the case of the
// double-space-to-period feature). // double-space-to-period feature).
public void discardPreviousWordForSuggestion() { public void discardPreviousWordForSuggestion() {
mPreviousWordForSuggestion = null; mPrevWordsInfo = new PrevWordsInfo(null);
} }
public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord, public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
final String previousWord) { final PrevWordsInfo prevWordsInfo) {
mEvents.clear(); mEvents.clear();
Collections.copy(mEvents, lastComposedWord.mEvents); Collections.copy(mEvents, lastComposedWord.mEvents);
mInputPointers.set(lastComposedWord.mInputPointers); mInputPointers.set(lastComposedWord.mInputPointers);
@ -463,7 +461,7 @@ public final class WordComposer {
mCursorPositionWithinWord = mCodePointSize; mCursorPositionWithinWord = mCodePointSize;
mRejectedBatchModeSuggestion = null; mRejectedBatchModeSuggestion = null;
mIsResumed = true; mIsResumed = true;
mPreviousWordForSuggestion = previousWord; mPrevWordsInfo = prevWordsInfo;
} }
public boolean isBatchMode() { public boolean isBatchMode() {

View File

@ -23,6 +23,7 @@ import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo; import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo; import android.view.textservice.TextInfo;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -57,7 +58,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
final int offset = ssi.getOffsetAt(i); final int offset = ssi.getOffsetAt(i);
final int length = ssi.getLengthAt(i); final int length = ssi.getLengthAt(i);
final String subText = typedText.substring(offset, offset + length); final String subText = typedText.substring(offset, offset + length);
final String prevWord = currentWord; final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(currentWord);
currentWord = subText; currentWord = subText;
if (!subText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { if (!subText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
continue; continue;
@ -73,7 +74,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
if (TextUtils.isEmpty(splitText)) { if (TextUtils.isEmpty(splitText)) {
continue; continue;
} }
if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWord) == null) { if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWordsInfo) == null) {
continue; continue;
} }
final int newLength = splitText.length(); final int newLength = splitText.length();
@ -148,7 +149,8 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
} else { } else {
prevWord = null; prevWord = null;
} }
retval[i] = onGetSuggestionsInternal(textInfos[i], prevWord, suggestionsLimit); final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(prevWord);
retval[i] = onGetSuggestionsInternal(textInfos[i], prevWordsInfo, suggestionsLimit);
retval[i].setCookieAndSequence(textInfos[i].getCookie(), retval[i].setCookieAndSequence(textInfos[i].getCookie(),
textInfos[i].getSequence()); textInfos[i].getSequence());
} }

View File

@ -31,6 +31,7 @@ import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer; import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
@ -71,26 +72,26 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE); new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE);
// TODO: Support n-gram input // TODO: Support n-gram input
private static String generateKey(String query, String prevWord) { private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) {
if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWord)) { if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWordsInfo.mPrevWord)) {
return query; return query;
} }
return query + CHAR_DELIMITER + prevWord; return query + CHAR_DELIMITER + prevWordsInfo.mPrevWord;
} }
// TODO: Support n-gram input public SuggestionsParams getSuggestionsFromCache(String query,
public SuggestionsParams getSuggestionsFromCache(String query, String prevWord) { final PrevWordsInfo prevWordsInfo) {
return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWord)); return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWordsInfo));
} }
// TODO: Support n-gram input
public void putSuggestionsToCache( public void putSuggestionsToCache(
String query, String prevWord, String[] suggestions, int flags) { final String query, final PrevWordsInfo prevWordsInfo,
final String[] suggestions, final int flags) {
if (suggestions == null || TextUtils.isEmpty(query)) { if (suggestions == null || TextUtils.isEmpty(query)) {
return; return;
} }
mUnigramSuggestionsInfoCache.put( mUnigramSuggestionsInfoCache.put(
generateKey(query, prevWord), new SuggestionsParams(suggestions, flags)); generateKey(query, prevWordsInfo), new SuggestionsParams(suggestions, flags));
} }
public void clearCache() { public void clearCache() {
@ -259,11 +260,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
} }
protected SuggestionsInfo onGetSuggestionsInternal( protected SuggestionsInfo onGetSuggestionsInternal(
final TextInfo textInfo, final String prevWord, final int suggestionsLimit) { final TextInfo textInfo, final PrevWordsInfo prevWordsInfo,
final int suggestionsLimit) {
try { try {
final String inText = textInfo.getText(); final String inText = textInfo.getText();
final SuggestionsParams cachedSuggestionsParams = final SuggestionsParams cachedSuggestionsParams =
mSuggestionsCache.getSuggestionsFromCache(inText, prevWord); mSuggestionsCache.getSuggestionsFromCache(inText, prevWordsInfo);
if (cachedSuggestionsParams != null) { if (cachedSuggestionsParams != null) {
if (DBG) { if (DBG) {
Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags); Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags);
@ -325,7 +327,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
composer.setComposingWord(codePoints, coordinates, null /* previousWord */); composer.setComposingWord(codePoints, coordinates, null /* previousWord */);
// TODO: make a spell checker option to block offensive words or not // TODO: make a spell checker option to block offensive words or not
final ArrayList<SuggestedWordInfo> suggestions = final ArrayList<SuggestedWordInfo> suggestions =
dictInfo.mDictionary.getSuggestions(composer, prevWord, dictInfo.mDictionary.getSuggestions(composer, prevWordsInfo,
dictInfo.getProximityInfo(), true /* blockOffensiveWords */, dictInfo.getProximityInfo(), true /* blockOffensiveWords */,
null /* additionalFeaturesOptions */, 0 /* sessionId */, null /* additionalFeaturesOptions */, 0 /* sessionId */,
null /* inOutLanguageWeight */); null /* inOutLanguageWeight */);
@ -369,7 +371,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
.getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS()
: 0); : 0);
final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions);
mSuggestionsCache.putSuggestionsToCache(text, prevWord, result.mSuggestions, flags); mSuggestionsCache.putSuggestionsToCache(text, prevWordsInfo, result.mSuggestions,
flags);
return retval; return retval;
} catch (RuntimeException e) { } catch (RuntimeException e) {
// Don't kill the keyboard if there is a bug in the spell checker // Don't kill the keyboard if there is a bug in the spell checker

View File

@ -20,6 +20,7 @@ import android.util.Log;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
@ -52,7 +53,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
// TODO: this dummy dictionary should be a singleton in the Dictionary class. // TODO: this dummy dictionary should be a singleton in the Dictionary class.
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
return noSuggestions; return noSuggestions;

View File

@ -20,6 +20,7 @@ import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.ContactsBinaryDictionary; import com.android.inputmethod.latin.ContactsBinaryDictionary;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
@ -36,11 +37,11 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
final String prevWordForBigrams, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
synchronized (mLock) { synchronized (mLock) {
return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, return super.getSuggestions(codes, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight); blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight);
} }
} }

View File

@ -19,6 +19,7 @@ package com.android.inputmethod.latin.spellcheck;
import android.content.Context; import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.UserBinaryDictionary; import com.android.inputmethod.latin.UserBinaryDictionary;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
@ -41,11 +42,11 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic
@Override @Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
final String prevWordForBigrams, final ProximityInfo proximityInfo, final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) { final int sessionId, final float[] inOutLanguageWeight) {
synchronized (mLock) { synchronized (mLock) {
return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, return super.getSuggestions(codes, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight); blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight);
} }
} }

View File

@ -24,6 +24,7 @@ import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords;
@ -88,13 +89,13 @@ public class DistracterFilter {
/** /**
* Determine whether a word is a distracter to words in dictionaries. * Determine whether a word is a distracter to words in dictionaries.
* *
* @param prevWord the previous word, or null if none. * @param prevWordsInfo the information of previous words.
* @param testedWord the word that will be tested to see whether it is a distracter to words * @param testedWord the word that will be tested to see whether it is a distracter to words
* in dictionaries. * in dictionaries.
* @param locale the locale of words. * @param locale the locale of words.
* @return true if testedWord is a distracter, otherwise false. * @return true if testedWord is a distracter, otherwise false.
*/ */
public boolean isDistracterToWordsInDictionaries(final String prevWord, public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo,
final String testedWord, final Locale locale) { final String testedWord, final Locale locale) {
if (mKeyboard == null || locale == null) { if (mKeyboard == null || locale == null) {
return false; return false;
@ -113,7 +114,7 @@ public class DistracterFilter {
final int[] codePoints = StringUtils.toCodePointArray(testedWord); final int[] codePoints = StringUtils.toCodePointArray(testedWord);
final int[] coordinates; final int[] coordinates;
coordinates = mKeyboard.getCoordinates(codePoints); coordinates = mKeyboard.getCoordinates(codePoints);
composer.setComposingWord(codePoints, coordinates, prevWord); composer.setComposingWord(codePoints, coordinates, prevWordsInfo.mPrevWord);
final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord); final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord);
final String consideredWord = trailingSingleQuotesCount > 0 ? final String consideredWord = trailingSingleQuotesCount > 0 ?
@ -133,7 +134,7 @@ public class DistracterFilter {
} }
} }
}; };
mSuggest.getSuggestedWords(composer, prevWord, mKeyboard.getProximityInfo(), mSuggest.getSuggestedWords(composer, prevWordsInfo, mKeyboard.getProximityInfo(),
true /* blockOffensiveWords */, true /* isCorrectionEnbaled */, true /* blockOffensiveWords */, true /* isCorrectionEnbaled */,
null /* additionalFeaturesOptions */, 0 /* sessionId */, null /* additionalFeaturesOptions */, 0 /* sessionId */,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, callback); SuggestedWords.NOT_A_SEQUENCE_NUMBER, callback);

View File

@ -20,6 +20,7 @@ import android.util.Log;
import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import java.util.ArrayList; import java.util.ArrayList;
@ -85,7 +86,7 @@ public final class LanguageModelParam {
final ArrayList<LanguageModelParam> languageModelParams = final ArrayList<LanguageModelParam> languageModelParams =
CollectionUtils.newArrayList(); CollectionUtils.newArrayList();
final int N = tokens.size(); final int N = tokens.size();
String prevWord = null; PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null);
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
final String tempWord = tokens.get(i); final String tempWord = tokens.get(i);
if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) {
@ -102,7 +103,7 @@ public final class LanguageModelParam {
+ tempWord + "\""); + tempWord + "\"");
} }
// Sentence terminator found. Split. // Sentence terminator found. Split.
prevWord = null; prevWordsInfo = new PrevWordsInfo(null);
continue; continue;
} }
if (DEBUG_TOKEN) { if (DEBUG_TOKEN) {
@ -110,19 +111,19 @@ public final class LanguageModelParam {
} }
final LanguageModelParam languageModelParam = final LanguageModelParam languageModelParam =
detectWhetherVaildWordOrNotAndGetLanguageModelParam( detectWhetherVaildWordOrNotAndGetLanguageModelParam(
prevWord, tempWord, timestamp, dictionaryFacilitator, prevWordsInfo, tempWord, timestamp, dictionaryFacilitator,
distracterFilter); distracterFilter);
if (languageModelParam == null) { if (languageModelParam == null) {
continue; continue;
} }
languageModelParams.add(languageModelParam); languageModelParams.add(languageModelParam);
prevWord = languageModelParam.mTargetWord; prevWordsInfo = new PrevWordsInfo(languageModelParam.mTargetWord);
} }
return languageModelParams; return languageModelParams;
} }
private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam( private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam(
final String prevWord, final String targetWord, final int timestamp, final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp,
final DictionaryFacilitatorForSuggest dictionaryFacilitator, final DictionaryFacilitatorForSuggest dictionaryFacilitator,
final DistracterFilter distracterFilter) { final DistracterFilter distracterFilter) {
final Locale locale = dictionaryFacilitator.getLocale(); final Locale locale = dictionaryFacilitator.getLocale();
@ -133,14 +134,14 @@ public final class LanguageModelParam {
// distracterFilter in the following code. If targetWord is a distracter, // distracterFilter in the following code. If targetWord is a distracter,
// it should be filtered out. // it should be filtered out.
if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) { if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) {
return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp, return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp,
true /* isValidWord */, locale); true /* isValidWord */, locale);
} }
final String lowerCaseTargetWord = targetWord.toLowerCase(locale); final String lowerCaseTargetWord = targetWord.toLowerCase(locale);
if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) { if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) {
// Add the lower-cased word. // Add the lower-cased word.
return createAndGetLanguageModelParamOfWord(prevWord, lowerCaseTargetWord, return createAndGetLanguageModelParamOfWord(prevWordsInfo, lowerCaseTargetWord,
timestamp, true /* isValidWord */, locale); timestamp, true /* isValidWord */, locale);
} }
@ -150,26 +151,26 @@ public final class LanguageModelParam {
// Adding such a word to dictonaries would interfere with entering in-dictionary words. For // Adding such a word to dictonaries would interfere with entering in-dictionary words. For
// example, adding "mot" to dictionaries might interfere with entering "not". // example, adding "mot" to dictionaries might interfere with entering "not".
// This kind of OOV should be filtered out. // This kind of OOV should be filtered out.
if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord, locale)) { if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, targetWord, locale)) {
return null; return null;
} }
return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp, return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp,
false /* isValidWord */, locale); false /* isValidWord */, locale);
} }
private static LanguageModelParam createAndGetLanguageModelParamOfWord( private static LanguageModelParam createAndGetLanguageModelParamOfWord(
final String prevWord, final String targetWord, final int timestamp, final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp,
final boolean isValidWord, final Locale locale) { final boolean isValidWord, final Locale locale) {
final String word; final String word;
if (StringUtils.getCapitalizationType(targetWord) == StringUtils.CAPITALIZE_FIRST if (StringUtils.getCapitalizationType(targetWord) == StringUtils.CAPITALIZE_FIRST
&& prevWord == null && !isValidWord) { && prevWordsInfo.mPrevWord == null && !isValidWord) {
word = targetWord.toLowerCase(locale); word = targetWord.toLowerCase(locale);
} else { } else {
word = targetWord; word = targetWord;
} }
final int unigramProbability = isValidWord ? final int unigramProbability = isValidWord ?
UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD; UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD;
if (prevWord == null) { if (prevWordsInfo.mPrevWord == null) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "--- add unigram: current(" Log.d(TAG, "--- add unigram: current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word); + (isValidWord ? "Valid" : "OOV") + ") = " + word);
@ -177,12 +178,12 @@ public final class LanguageModelParam {
return new LanguageModelParam(word, unigramProbability, timestamp); return new LanguageModelParam(word, unigramProbability, timestamp);
} }
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "--- add bigram: prev = " + prevWord + ", current(" Log.d(TAG, "--- add bigram: prev = " + prevWordsInfo.mPrevWord + ", current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word); + (isValidWord ? "Valid" : "OOV") + ") = " + word);
} }
final int bigramProbability = isValidWord ? final int bigramProbability = isValidWord ?
BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD; BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD;
return new LanguageModelParam(prevWord, word, unigramProbability, return new LanguageModelParam(prevWordsInfo.mPrevWord, word, unigramProbability,
bigramProbability, timestamp); bigramProbability, timestamp);
} }
} }

View File

@ -36,50 +36,50 @@ public class DistracterFilterTest extends InputTestsBase {
} }
public void testIsDistractorToWordsInDictionaries() { public void testIsDistractorToWordsInDictionaries() {
final String EMPTY_PREV_WORD = null; final PrevWordsInfo EMPTY_PREV_WORDS_INFO = new PrevWordsInfo(null);
final Locale localeEnUs = new Locale("en", "US"); final Locale localeEnUs = new Locale("en", "US");
String typedWord = "alot"; String typedWord = "alot";
// For this test case, we consider "alot" is a distracter to "a lot". // For this test case, we consider "alot" is a distracter to "a lot".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "mot"; typedWord = "mot";
// For this test case, we consider "mot" is a distracter to "not". // For this test case, we consider "mot" is a distracter to "not".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "wierd"; typedWord = "wierd";
// For this test case, we consider "wierd" is a distracter to "weird". // For this test case, we consider "wierd" is a distracter to "weird".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "hoe"; typedWord = "hoe";
// For this test case, we consider "hoe" is a distracter to "how". // For this test case, we consider "hoe" is a distracter to "how".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "nit"; typedWord = "nit";
// For this test case, we consider "nit" is a distracter to "not". // For this test case, we consider "nit" is a distracter to "not".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "ill"; typedWord = "ill";
// For this test case, we consider "ill" is a distracter to "I'll". // For this test case, we consider "ill" is a distracter to "I'll".
assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "asdfd"; typedWord = "asdfd";
// For this test case, we consider "asdfd" is not a distracter to any word in dictionaries. // For this test case, we consider "asdfd" is not a distracter to any word in dictionaries.
assertFalse( assertFalse(
mDistracterFilter.isDistracterToWordsInDictionaries( mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
typedWord = "thank"; typedWord = "thank";
// For this test case, we consider "thank" is not a distracter to any other word // For this test case, we consider "thank" is not a distracter to any other word
// in dictionaries. // in dictionaries.
assertFalse( assertFalse(
mDistracterFilter.isDistracterToWordsInDictionaries( mDistracterFilter.isDistracterToWordsInDictionaries(
EMPTY_PREV_WORD, typedWord, localeEnUs)); EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs));
} }
} }

View File

@ -57,14 +57,14 @@ public class WordComposerTests extends AndroidTestCase {
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
// Check the previous word is still there // Check the previous word is still there
assertEquals(PREVWORD, wc.getPreviousWordForSuggestion()); assertEquals(PREVWORD, wc.getPrevWordsInfoForSuggestion().mPrevWord);
// Move the cursor past the end of the word // Move the cursor past the end of the word
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15));
// Do what LatinIME does when the cursor is moved outside of the word, // Do what LatinIME does when the cursor is moved outside of the word,
// and check the behavior is correct. // and check the behavior is correct.
wc.reset(); wc.reset();
assertNull(wc.getPreviousWordForSuggestion()); assertNull(wc.getPrevWordsInfoForSuggestion().mPrevWord);
// \uD861\uDED7 is 𨛗, a character outside the BMP // \uD861\uDED7 is 𨛗, a character outside the BMP
final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh"; final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh";
@ -83,37 +83,37 @@ public class WordComposerTests extends AndroidTestCase {
assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); assertTrue(wc.isCursorFrontOrMiddleOfComposingWord());
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
assertNull(wc.getPreviousWordForSuggestion()); assertNull(wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
STR_WITHIN_BMP); STR_WITHIN_BMP);
wc.setCursorPositionWithinWord(3); wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion()); assertEquals(STR_WITHIN_BMP, wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
STR_WITH_SUPPLEMENTARY_CHAR); STR_WITH_SUPPLEMENTARY_CHAR);
wc.setCursorPositionWithinWord(3); wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion()); assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
STR_WITHIN_BMP); STR_WITHIN_BMP);
wc.setCursorPositionWithinWord(3); wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3));
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1));
assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion()); assertEquals(STR_WITHIN_BMP, wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
null /* previousWord */); null /* previousWord */);
wc.setCursorPositionWithinWord(3); wc.setCursorPositionWithinWord(3);
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9));
assertNull(wc.getPreviousWordForSuggestion()); assertNull(wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
STR_WITH_SUPPLEMENTARY_CHAR); STR_WITH_SUPPLEMENTARY_CHAR);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10)); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10));
assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion()); assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPrevWordsInfoForSuggestion().mPrevWord);
wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR, wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
null /* previousWord */); null /* previousWord */);

View File

@ -44,6 +44,7 @@ LATINIME_SRC_FILES_FOR_DICTTOOL := \
latin/InputPointers.java \ latin/InputPointers.java \
latin/LastComposedWord.java \ latin/LastComposedWord.java \
latin/LatinImeLogger.java \ latin/LatinImeLogger.java \
latin/PrevWordsInfo.java \
latin/SuggestedWords.java \ latin/SuggestedWords.java \
latin/WordComposer.java \ latin/WordComposer.java \
latin/settings/NativeSuggestOptions.java \ latin/settings/NativeSuggestOptions.java \