am 3dbc3ece: am e04c8b10: am b8d76477: Add the input style to SuggestedWords.

* commit '3dbc3ece2614cb9d694e2f1d9607accd5eac7fc4':
  Add the input style to SuggestedWords.
main
Jean Chalard 2014-08-14 18:13:33 +00:00 committed by Android Git Automerger
commit 670644b2f1
9 changed files with 99 additions and 57 deletions

View File

@ -257,6 +257,8 @@ public class Event {
public boolean isConsumed() { return 0 != (FLAG_CONSUMED & mFlags); }
public boolean isGesture() { return EVENT_TYPE_GESTURE == mEventType; }
// Returns whether this is a fake key press from the suggestion strip. This happens with
// punctuation signs selected from the suggestion strip.
public boolean isSuggestionStripPress() {

View File

@ -33,7 +33,7 @@ public class InputTransaction {
// Initial conditions
public final SettingsValues mSettingsValues;
private final Event mEvent;
public final Event mEvent;
public final long mTimestamp;
public final int mSpaceState;
public final int mShiftState;

View File

@ -138,7 +138,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
new Runnable() {
@Override
public void run() {
mHandler.postUpdateSuggestionStrip();
mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
}
});
private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
@ -220,7 +220,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_UPDATE_SUGGESTION_STRIP:
cancelUpdateSuggestionStrip();
latinIme.mInputLogic.performUpdateSuggestionStripSync(
latinIme.mSettings.getCurrent());
latinIme.mSettings.getCurrent(), msg.arg1 /* inputStyle */);
break;
case MSG_UPDATE_SHIFT_STATE:
switcher.requestUpdatingShiftState(latinIme.getCurrentAutoCapsState(),
@ -270,8 +270,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
public void postUpdateSuggestionStrip() {
sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP), mDelayUpdateSuggestions);
public void postUpdateSuggestionStrip(final int inputStyle) {
sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP, inputStyle,
0 /* ignored */), mDelayUpdateSuggestions);
}
public void postReopenDictionaries() {
@ -1060,7 +1061,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
applicationSpecifiedCompletions);
final SuggestedWords suggestedWords = new SuggestedWords(applicationSuggestedWords,
null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */);
false /* isObsoleteSuggestions */, false /* isPrediction */,
SuggestedWords.INPUT_STYLE_APPLICATION_SPECIFIED /* inputStyle */);
// When in fullscreen mode, show completions generated by the application forcibly
setSuggestedWords(suggestedWords);
}
@ -1451,7 +1453,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// TODO[IL]: Move this out of LatinIME.
public void getSuggestedWords(final int sessionId, final int sequenceNumber,
public void getSuggestedWords(final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
if (keyboard == null) {
@ -1459,7 +1461,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard.getProximityInfo(),
mKeyboardSwitcher.getKeyboardShiftMode(), sessionId, sequenceNumber, callback);
mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback);
}
@Override
@ -1543,7 +1545,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
default: // SHIFT_NO_UPDATE
}
if (inputTransaction.requiresUpdateSuggestions()) {
mHandler.postUpdateSuggestionStrip();
final int inputStyle;
if (inputTransaction.mEvent.isSuggestionStripPress()) {
// Suggestion strip press: no input.
inputStyle = SuggestedWords.INPUT_STYLE_NONE;
} else if (inputTransaction.mEvent.isGesture()) {
inputStyle = SuggestedWords.INPUT_STYLE_TAIL_BATCH;
} else {
inputStyle = SuggestedWords.INPUT_STYLE_TYPING;
}
mHandler.postUpdateSuggestionStrip(inputStyle);
}
if (inputTransaction.didAffectContents()) {
mSubtypeState.setCurrentSubtypeHasBeenUsed();

View File

@ -35,7 +35,8 @@ public final class PunctuationSuggestions extends SuggestedWords {
false /* typedWordValid */,
false /* hasAutoCorrectionCandidate */,
false /* isObsoleteSuggestions */,
false /* isPrediction */);
false /* isPrediction */,
INPUT_STYLE_NONE /* inputStyle */);
}
/**

View File

@ -40,13 +40,8 @@ public final class Suggest {
// Session id for
// {@link #getSuggestedWords(WordComposer,String,ProximityInfo,boolean,int)}.
// We are sharing the same ID between typing and gesture to save RAM footprint.
public static final int SESSION_TYPING = 0;
public static final int SESSION_GESTURE = 0;
// TODO: rename this to CORRECTION_OFF
public static final int CORRECTION_NONE = 0;
// TODO: rename this to CORRECTION_ON
public static final int CORRECTION_FULL = 1;
public static final int SESSION_ID_TYPING = 0;
public static final int SESSION_ID_GESTURE = 0;
// Close to -2**31
private static final int SUPPRESS_SUGGEST_THRESHOLD = -2000000000;
@ -75,14 +70,15 @@ public final class Suggest {
public void getSuggestedWords(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final boolean isCorrectionEnabled, final int sessionId, final int sequenceNumber,
final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
if (wordComposer.isBatchMode()) {
getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo,
settingsValuesForSuggestion, sessionId, sequenceNumber, callback);
settingsValuesForSuggestion, inputStyle, sequenceNumber, callback);
} else {
getSuggestedWordsForTypingInput(wordComposer, prevWordsInfo, proximityInfo,
settingsValuesForSuggestion, isCorrectionEnabled, sequenceNumber, callback);
getSuggestedWordsForNonBatchInput(wordComposer, prevWordsInfo, proximityInfo,
settingsValuesForSuggestion, inputStyle, isCorrectionEnabled,
sequenceNumber, callback);
}
}
@ -120,11 +116,11 @@ public final class Suggest {
return firstSuggestedWordInfo.mWord;
}
// Retrieves suggestions for the typing input
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions.
private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int inputStyle,
final boolean isCorrectionEnabled, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final String typedWord = wordComposer.getTypedWord();
@ -135,7 +131,7 @@ public final class Suggest {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
SESSION_TYPING);
SESSION_ID_TYPING);
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount);
@ -197,7 +193,8 @@ public final class Suggest {
// rename the attribute or change the value.
!resultsArePredictions && !allowsToBeAutoCorrected /* typedWordValid */,
hasAutoCorrection /* willAutoCorrect */,
false /* isObsoleteSuggestions */, resultsArePredictions, sequenceNumber));
false /* isObsoleteSuggestions */, resultsArePredictions,
inputStyle, sequenceNumber));
}
// Retrieves suggestions for the batch input
@ -205,10 +202,11 @@ public final class Suggest {
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int sessionId, final int sequenceNumber,
final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion, sessionId);
wordComposer, prevWordsInfo, proximityInfo, settingsValuesForSuggestion,
SESSION_ID_GESTURE);
final ArrayList<SuggestedWordInfo> suggestionsContainer =
new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
@ -246,7 +244,8 @@ public final class Suggest {
true /* typedWordValid */,
false /* willAutoCorrect */,
false /* isObsoleteSuggestions */,
false /* isPrediction */, sequenceNumber));
false /* isPrediction */,
inputStyle, sequenceNumber));
}
private static ArrayList<SuggestedWordInfo> getSuggestionsInfoListWithDebugInfo(

View File

@ -31,12 +31,20 @@ public class SuggestedWords {
public static final int INDEX_OF_AUTO_CORRECTION = 1;
public static final int NOT_A_SEQUENCE_NUMBER = -1;
public static final int INPUT_STYLE_NONE = 0;
public static final int INPUT_STYLE_TYPING = 1;
public static final int INPUT_STYLE_UPDATE_BATCH = 2;
public static final int INPUT_STYLE_TAIL_BATCH = 3;
public static final int INPUT_STYLE_APPLICATION_SPECIFIED = 4;
public static final int INPUT_STYLE_RECORRECTION = 5;
// The maximum number of suggestions available.
public static final int MAX_SUGGESTIONS = 18;
private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = new ArrayList<>(0);
public static final SuggestedWords EMPTY = new SuggestedWords(
EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false);
EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false,
INPUT_STYLE_NONE);
public final String mTypedWord;
public final boolean mTypedWordValid;
@ -46,6 +54,9 @@ public class SuggestedWords {
public final boolean mWillAutoCorrect;
public final boolean mIsObsoleteSuggestions;
public final boolean mIsPrediction;
// How the input for these suggested words was done by the user. Must be one of the
// INPUT_STYLE_* constants above.
public final int mInputStyle;
public final int mSequenceNumber; // Sequence number for auto-commit.
protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
public final ArrayList<SuggestedWordInfo> mRawSuggestions;
@ -55,9 +66,10 @@ public class SuggestedWords {
final boolean typedWordValid,
final boolean willAutoCorrect,
final boolean isObsoleteSuggestions,
final boolean isPrediction) {
final boolean isPrediction,
final int inputStyle) {
this(suggestedWordInfoList, rawSuggestions, typedWordValid, willAutoCorrect,
isObsoleteSuggestions, isPrediction, NOT_A_SEQUENCE_NUMBER);
isObsoleteSuggestions, isPrediction, inputStyle, NOT_A_SEQUENCE_NUMBER);
}
public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
@ -66,11 +78,12 @@ public class SuggestedWords {
final boolean willAutoCorrect,
final boolean isObsoleteSuggestions,
final boolean isPrediction,
final int inputStyle,
final int sequenceNumber) {
this(suggestedWordInfoList, rawSuggestions,
(suggestedWordInfoList.isEmpty() || isPrediction) ? null
: suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction,
typedWordValid, willAutoCorrect, isObsoleteSuggestions, isPrediction, inputStyle,
sequenceNumber);
}
@ -81,6 +94,7 @@ public class SuggestedWords {
final boolean willAutoCorrect,
final boolean isObsoleteSuggestions,
final boolean isPrediction,
final int inputStyle,
final int sequenceNumber) {
mSuggestedWordInfoList = suggestedWordInfoList;
mRawSuggestions = rawSuggestions;
@ -88,6 +102,7 @@ public class SuggestedWords {
mWillAutoCorrect = willAutoCorrect;
mIsObsoleteSuggestions = isObsoleteSuggestions;
mIsPrediction = isPrediction;
mInputStyle = inputStyle;
mSequenceNumber = sequenceNumber;
mTypedWord = typedWord;
}
@ -367,7 +382,7 @@ public class SuggestedWords {
// SuggestedWords is an immutable object, as much as possible. We must not just remove
// words from the member ArrayList as some other parties may expect the object to never change.
public SuggestedWords getSuggestedWordsExcludingTypedWord() {
public SuggestedWords getSuggestedWordsExcludingTypedWord(final int inputStyle) {
final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
String typedWord = null;
for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
@ -383,7 +398,7 @@ public class SuggestedWords {
// no auto-correction should take place hence willAutoCorrect = false.
return new SuggestedWords(newSuggestions, null /* rawSuggestions */, typedWord,
true /* typedWordValid */, false /* willAutoCorrect */, mIsObsoleteSuggestions,
mIsPrediction, NOT_A_SEQUENCE_NUMBER);
mIsPrediction, inputStyle, NOT_A_SEQUENCE_NUMBER);
}
// Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
@ -402,6 +417,7 @@ public class SuggestedWords {
SuggestedWordInfo.NOT_A_CONFIDENCE));
}
return new SuggestedWords(newSuggestions, null /* rawSuggestions */, mTypedWordValid,
mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction);
mWillAutoCorrect, mIsObsoleteSuggestions, mIsPrediction,
INPUT_STYLE_TAIL_BATCH);
}
}

View File

@ -216,7 +216,7 @@ public final class InputLogic {
} else {
resetComposingState(true /* alsoResetLastComposedWord */);
}
handler.postUpdateSuggestionStrip();
handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_TYPING);
final String text = performSpecificTldProcessingOnTextInput(rawText);
if (SpaceState.PHANTOM == mSpaceState) {
promotePhantomSpace(settingsValues);
@ -288,9 +288,6 @@ public final class InputLogic {
return inputTransaction;
}
// We need to log before we commit, because the word composer will store away the user
// typed word.
final String replacedWord = mWordComposer.getTypedWord();
commitChosenWord(settingsValues, suggestion,
LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
mConnection.endBatchEdit();
@ -311,7 +308,8 @@ public final class InputLogic {
mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
handler.postUpdateSuggestionStrip();
// That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
}
return inputTransaction;
}
@ -1299,7 +1297,8 @@ public final class InputLogic {
prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive);
}
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues) {
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
final int inputStyle) {
// Check if we have a suggestion engine attached.
if (!settingsValues.needsToLookupSuggestions()) {
if (mWordComposer.isComposingWord()) {
@ -1317,8 +1316,8 @@ public final class InputLogic {
}
final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<>();
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
mInputLogicHandler.getSuggestedWords(inputStyle, SuggestedWords.NOT_A_SEQUENCE_NUMBER,
new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
final String typedWord = mWordComposer.getTypedWord();
@ -1379,7 +1378,7 @@ public final class InputLogic {
if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)) {
// Show predictions.
mWordComposer.setCapitalizedModeAtStartComposingTime(WordComposer.CAPS_MODE_OFF);
mLatinIME.mHandler.postUpdateSuggestionStrip();
mLatinIME.mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_RECORRECTION);
return;
}
final TextRange range = mConnection.getWordRangeAtCursor(
@ -1444,7 +1443,7 @@ public final class InputLogic {
// If there weren't any suggestion spans on this word, suggestions#size() will be 1
// if shouldIncludeResumedWordInSuggestions is true, 0 otherwise. In this case, we
// have no useful suggestions, so we will try to compute some for it instead.
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_ID_TYPING,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(
@ -1457,7 +1456,8 @@ public final class InputLogic {
// case. The #getSuggestedWordsExcludingTypedWord() method sets
// willAutoCorrect to false.
suggestedWords = suggestedWordsIncludingTypedWord
.getSuggestedWordsExcludingTypedWord();
.getSuggestedWordsExcludingTypedWord(SuggestedWords
.INPUT_STYLE_RECORRECTION);
} else {
// No saved suggestions, and we were unable to compute any good one
// either. Rather than displaying an empty suggestion strip, we'll
@ -1477,6 +1477,7 @@ public final class InputLogic {
null /* rawSuggestions */, typedWord,
false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */,
SuggestedWords.INPUT_STYLE_RECORRECTION,
SuggestedWords.NOT_A_SEQUENCE_NUMBER);
mIsAutoCorrectionIndicatorOn = false;
mLatinIME.mHandler.showSuggestionStrip(suggestedWords);
@ -1773,7 +1774,8 @@ public final class InputLogic {
SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords);
return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
true /* isObsoleteSuggestions */, false /* isPrediction */);
true /* isObsoleteSuggestions */, false /* isPrediction */,
oldSuggestedWords.mInputStyle);
}
/**
@ -1956,7 +1958,15 @@ public final class InputLogic {
// Complete any pending suggestions query first
if (handler.hasPendingUpdateSuggestions()) {
handler.cancelUpdateSuggestionStrip();
performUpdateSuggestionStripSync(settingsValues);
// To know the input style here, we should retrieve the in-flight "update suggestions"
// message and read its arg1 member here. However, the Handler class does not let
// us retrieve this message, so we can't do that. But in fact, we notice that
// we only ever come here when the input style was typing. In the case of batch
// input, we update the suggestions synchronously when the tail batch comes. Likewise
// for application-specified completions. As for recorrections, we never auto-correct,
// so we don't come here either. Hence, the input style is necessarily
// INPUT_STYLE_TYPING.
performUpdateSuggestionStripSync(settingsValues, SuggestedWords.INPUT_STYLE_TYPING);
}
final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
@ -2052,7 +2062,7 @@ public final class InputLogic {
}
public void getSuggestedWords(final SettingsValues settingsValues,
final ProximityInfo proximityInfo, final int keyboardShiftMode, final int sessionId,
final ProximityInfo proximityInfo, final int keyboardShiftMode, final int inputStyle,
final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions(
getActualCapsMode(settingsValues, keyboardShiftMode));
@ -2068,6 +2078,6 @@ public final class InputLogic {
settingsValues.mPhraseGestureEnabled,
settingsValues.mAdditionalFeaturesSettingValues),
settingsValues.mAutoCorrectionEnabledPerUserSettings,
sessionId, sequenceNumber, callback);
inputStyle, sequenceNumber, callback);
}
}

View File

@ -96,7 +96,7 @@ class InputLogicHandler implements Handler.Callback {
public boolean handleMessage(final Message msg) {
switch (msg.what) {
case MSG_GET_SUGGESTED_WORDS:
mLatinIME.getSuggestedWords(msg.arg1 /* sessionId */,
mLatinIME.getSuggestedWords(msg.arg1 /* inputStyle */,
msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj);
break;
}
@ -134,7 +134,8 @@ class InputLogicHandler implements Handler.Callback {
return;
}
mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
getSuggestedWords(Suggest.SESSION_GESTURE, sequenceNumber,
getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH
: SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber,
new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(SuggestedWords suggestedWords) {
@ -205,9 +206,9 @@ class InputLogicHandler implements Handler.Callback {
updateBatchInput(batchPointers, sequenceNumber, true /* isTailBatchInput */);
}
public void getSuggestedWords(final int sessionId, final int sequenceNumber,
public void getSuggestedWords(final int inputStyle, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
mNonUIThreadHandler.obtainMessage(
MSG_GET_SUGGESTED_WORDS, sessionId, sequenceNumber, callback).sendToTarget();
MSG_GET_SUGGESTED_WORDS, inputStyle, sequenceNumber, callback).sendToTarget();
}
}

View File

@ -48,7 +48,8 @@ public class SuggestedWordsTests extends AndroidTestCase {
false /* typedWordValid */,
false /* willAutoCorrect */,
false /* isObsoleteSuggestions */,
false /* isPrediction*/);
false /* isPrediction*/,
SuggestedWords.INPUT_STYLE_NONE);
assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
assertEquals("typed", words.getWord(0));
assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED));
@ -57,7 +58,8 @@ public class SuggestedWordsTests extends AndroidTestCase {
assertEquals("4", words.getWord(5));
assertTrue(words.getInfo(5).isKindOf(SuggestedWordInfo.KIND_CORRECTION));
final SuggestedWords wordsWithoutTyped = words.getSuggestedWordsExcludingTypedWord();
final SuggestedWords wordsWithoutTyped = words.getSuggestedWordsExcludingTypedWord(
SuggestedWords.INPUT_STYLE_NONE);
assertEquals(words.size() - 1, wordsWithoutTyped.size());
assertEquals("0", wordsWithoutTyped.getWord(0));
assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(SuggestedWordInfo.KIND_CORRECTION));