Fix a bug with wrong auto-correct cancellation
Auto-correct cancellation would sometimes kick in at wrong times, causing crashes. Bug: 5784542 Change-Id: I68dd6b8d9237ce9b66af2dc63e77ba6dd5fd69ddmain
parent
752d8cc4fc
commit
0fd625bcfd
|
@ -1071,7 +1071,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
public void commitTyped(final InputConnection ic) {
|
||||
if (!mWordComposer.isComposingWord()) return;
|
||||
final CharSequence typedWord = mWordComposer.getTypedWord();
|
||||
mWordComposer.onCommitWord();
|
||||
mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_USER_TYPED_WORD);
|
||||
if (typedWord.length() > 0) {
|
||||
if (ic != null) {
|
||||
ic.commitText(typedWord, 1);
|
||||
|
@ -1802,7 +1802,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
}
|
||||
Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
|
||||
mExpectingUpdateSelection = true;
|
||||
commitBestWord(autoCorrection);
|
||||
commitChosenWord(autoCorrection, WordComposer.COMMIT_TYPE_DECIDED_WORD);
|
||||
// Add the word to the user unigram dictionary if it's not a known word
|
||||
addToUserUnigramAndBigramDictionaries(autoCorrection,
|
||||
UserUnigramDictionary.FREQUENCY_FOR_TYPED);
|
||||
|
@ -1868,7 +1868,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
return;
|
||||
}
|
||||
mExpectingUpdateSelection = true;
|
||||
commitBestWord(suggestion);
|
||||
commitChosenWord(suggestion, WordComposer.COMMIT_TYPE_MANUAL_PICK);
|
||||
// Add the word to the auto dictionary if it's not a known word
|
||||
if (index == 0) {
|
||||
addToUserUnigramAndBigramDictionaries(suggestion,
|
||||
|
@ -1927,7 +1927,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
/**
|
||||
* Commits the chosen word to the text field and saves it for later retrieval.
|
||||
*/
|
||||
private void commitBestWord(CharSequence bestWord) {
|
||||
private void commitChosenWord(final CharSequence bestWord, final int commitType) {
|
||||
final KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||
if (!switcher.isKeyboardAvailable())
|
||||
return;
|
||||
|
@ -1942,7 +1942,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
ic.commitText(bestWord, 1);
|
||||
}
|
||||
}
|
||||
mWordComposer.onCommitWord();
|
||||
// TODO: figure out here if this is an auto-correct or if the best word is actually
|
||||
// what user typed. Note: currently this is done much later in
|
||||
// WordComposer#didAutoCorrectToAnotherWord by string equality of the remembered
|
||||
// strings.
|
||||
mWordComposer.onCommitWord(commitType);
|
||||
}
|
||||
|
||||
private static final WordComposer sEmptyWordComposer = new WordComposer();
|
||||
|
@ -2118,7 +2122,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
// Re-insert the separator
|
||||
ic.commitText(separator, 1);
|
||||
mWordComposer.deleteAutoCorrection();
|
||||
mWordComposer.onCommitWord();
|
||||
mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_CANCEL_AUTO_CORRECT);
|
||||
Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE,
|
||||
WordComposer.NOT_A_COORDINATE);
|
||||
mHandler.cancelUpdateBigramPredictions();
|
||||
|
|
|
@ -33,6 +33,23 @@ public class WordComposer {
|
|||
public static final int NOT_A_CODE = KeyDetector.NOT_A_CODE;
|
||||
public static final int NOT_A_COORDINATE = -1;
|
||||
|
||||
// TODO: Straighten out commit behavior so that the flags here are more understandable,
|
||||
// and possibly adjust their names.
|
||||
// COMMIT_TYPE_USER_TYPED_WORD is used when the word committed is the exact typed word, with
|
||||
// no hinting from the IME. It happens when some external event happens (rotating the device,
|
||||
// for example) or when auto-correction is off by settings or editor attributes.
|
||||
public static final int COMMIT_TYPE_USER_TYPED_WORD = 0;
|
||||
// COMMIT_TYPE_MANUAL_PICK is used when the user pressed a field in the suggestion strip.
|
||||
public static final int COMMIT_TYPE_MANUAL_PICK = 1;
|
||||
// COMMIT_TYPE_DECIDED_WORD is used when the IME commits the word it decided was best
|
||||
// for the current user input. It may be different from what the user typed (true auto-correct)
|
||||
// or it may be exactly what the user typed if it's in the dictionary or the IME does not have
|
||||
// enough confidence in any suggestion to auto-correct (auto-correct to typed word).
|
||||
public static final int COMMIT_TYPE_DECIDED_WORD = 2;
|
||||
// COMMIT_TYPE_CANCEL_AUTO_CORRECT is used upon committing back the old word upon cancelling
|
||||
// an auto-correction.
|
||||
public static final int COMMIT_TYPE_CANCEL_AUTO_CORRECT = 3;
|
||||
|
||||
// Storage for all the info about the current input.
|
||||
private static class CharacterStore {
|
||||
/**
|
||||
|
@ -329,10 +346,23 @@ public class WordComposer {
|
|||
return mCurrentWord.mAutoCorrection;
|
||||
}
|
||||
|
||||
// TODO: pass the information about what was committed and how. Was it an auto-correction?
|
||||
// Was it a completion? Was is what the user typed?
|
||||
public void onCommitWord() {
|
||||
// `type' should be one of the COMMIT_TYPE_* constants above.
|
||||
public void onCommitWord(final int type) {
|
||||
mCommittedWordSavedForSuggestionResuming = mCurrentWord;
|
||||
// Note: currently, we come here whenever we commit a word. If it's any *other* kind that
|
||||
// DECIDED_WORD, we should reset mAutoCorrection so that we don't attempt to cancel later.
|
||||
// If it's a DECIDED_WORD, it may be an actual auto-correction by the IME, or what the user
|
||||
// typed because the IME decided *not* to auto-correct for whatever reason.
|
||||
// Ideally we would also null it when it was a DECIDED_WORD that was not an auto-correct.
|
||||
// As it happens these two cases should behave differently, because the former can be
|
||||
// canceled while the latter can't. Currently, we figure this out in
|
||||
// #didAutoCorrectToAnotherWord with #equals(). It would be marginally cleaner to do it
|
||||
// here, but it would be slower (since we would #equals() for each commit, instead of
|
||||
// only on cancel), and ultimately we want to figure it out even earlier anyway.
|
||||
if (type != COMMIT_TYPE_DECIDED_WORD) {
|
||||
// Only ever revert an auto-correct.
|
||||
mCommittedWordSavedForSuggestionResuming.mAutoCorrection = null;
|
||||
}
|
||||
// TODO: improve performance by swapping buffers instead of creating a new object.
|
||||
mCurrentWord = new CharacterStore();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue