diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index d59497d6a..2e7e82637 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -104,7 +104,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar */ public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey"; - // TODO: Remove this private option. /** * The private IME option used to indicate that the given text field needs * ASCII code points input. @@ -200,6 +199,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private UserUnigramDictionary mUserUnigramDictionary; private boolean mIsUserDictionaryAvailable; + private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; private WordComposer mWordComposer = new WordComposer(); private int mCorrectionMode; @@ -729,6 +729,17 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar : String.format("inputType=0x%08x imeOptions=0x%08x", editorInfo.inputType, editorInfo.imeOptions))); } + if (Utils.inPrivateImeOptions(null, IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo)) { + Log.w(TAG, "Deprecated private IME option specified: " + + editorInfo.privateImeOptions); + Log.w(TAG, "Use " + getPackageName() + "." + IME_OPTION_NO_MICROPHONE + " instead"); + } + if (Utils.inPrivateImeOptions(getPackageName(), IME_OPTION_FORCE_ASCII, editorInfo)) { + Log.w(TAG, "Deprecated private IME option specified: " + + editorInfo.privateImeOptions); + Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead"); + } + LatinImeLogger.onStartInputView(editorInfo); // In landscape mode, this method gets called without the input view being created. if (inputView == null) { @@ -759,7 +770,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar inputView.closing(); mEnteredText = null; - mWordComposer.reset(); + resetComposingState(true /* alsoResetLastComposedWord */); mDeleteCount = 0; mSpaceState = SPACE_STATE_NONE; @@ -871,7 +882,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (((mWordComposer.isComposingWord()) || mVoiceProxy.isVoiceInputHighlighted()) && (selectionChanged || candidatesCleared)) { - mWordComposer.reset(); + resetComposingState(true /* alsoResetLastComposedWord */); updateSuggestions(); final InputConnection ic = getCurrentInputConnection(); if (ic != null) { @@ -880,7 +891,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mComposingStateManager.onFinishComposingText(); mVoiceProxy.setVoiceInputHighlighted(false); } else if (!mWordComposer.isComposingWord()) { - mWordComposer.reset(); + // TODO: is the following reset still needed, given that we are not composing + // a word? + resetComposingState(true /* alsoResetLastComposedWord */); updateSuggestions(); } } @@ -964,7 +977,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar .setHasMinimalSuggestion(false); // When in fullscreen mode, show completions generated by the application setSuggestions(builder.build()); - mWordComposer.deleteAutoCorrection(); + // TODO: is this the right thing to do? What should we auto-correct to in + // this case? This says to keep whatever the user typed. + mWordComposer.setAutoCorrection(mWordComposer.getTypedWord()); setSuggestionStripShown(true); } } @@ -1083,10 +1098,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return super.onKeyUp(keyCode, event); } + private void resetComposingState(final boolean alsoResetLastComposedWord) { + mWordComposer.reset(); + if (alsoResetLastComposedWord) + mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; + } + public void commitTyped(final InputConnection ic) { if (!mWordComposer.isComposingWord()) return; final CharSequence typedWord = mWordComposer.getTypedWord(); - mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_USER_TYPED_WORD); + mLastComposedWord = mWordComposer.commitWord(LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD); if (typedWord.length() > 0) { if (ic != null) { ic.commitText(typedWord, 1); @@ -1253,6 +1274,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.cancelDoubleSpacesTimer(); } + boolean didAutoCorrect = false; switch (primaryCode) { case Keyboard.CODE_DELETE: mSpaceState = SPACE_STATE_NONE; @@ -1289,7 +1311,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar default: mSpaceState = SPACE_STATE_NONE; if (mSettingsValues.isWordSeparator(primaryCode)) { - handleSeparator(primaryCode, x, y, spaceState); + didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState); } else { handleCharacter(primaryCode, keyCodes, x, y, spaceState); } @@ -1298,6 +1320,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } switcher.onCodeInput(primaryCode); // Reset after any single keystroke + if (!didAutoCorrect) + mLastComposedWord.deactivate(); mEnteredText = null; } @@ -1315,7 +1339,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT); mSpaceState = SPACE_STATE_NONE; mEnteredText = text; - mWordComposer.reset(); + resetComposingState(true /* alsoResetLastComposedWord */); } @Override @@ -1373,7 +1397,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // resuming here. The behavior needs to be different according to text field types, // and it would be much clearer to test for them explicitly here rather than // relying on implicit values like "whether the suggestion strip is displayed". - if (mWordComposer.didAutoCorrectToAnotherWord()) { + if (mLastComposedWord.canCancelAutoCorrect()) { Utils.Stats.onAutoCorrectionCancellation(); cancelAutoCorrect(ic); return; @@ -1485,7 +1509,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // separator and it should be treated as a normal character, except in the first // position where it should not start composing a word. isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != code); - mWordComposer.reset(); + // Here we don't need to reset the last composed word. It will be reset + // when we commit this one, if we ever do; if on the other hand we backspace + // it entirely and resume suggestions on the previous word, we'd like to still + // have touch coordinates for it. + resetComposingState(false /* alsoResetLastComposedWord */); clearSuggestions(); mComposingStateManager.onFinishComposingText(); } @@ -1537,7 +1565,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - private void handleSeparator(final int primaryCode, final int x, final int y, + // Returns true if we did an autocorrection, false otherwise. + private boolean handleSeparator(final int primaryCode, final int x, final int y, final int spaceState) { mVoiceProxy.handleSeparator(); mComposingStateManager.onFinishComposingText(); @@ -1548,6 +1577,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.postUpdateSuggestions(); } + boolean didAutoCorrect = false; // Handle separator final InputConnection ic = getCurrentInputConnection(); if (ic != null) { @@ -1562,6 +1592,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar && !mInputAttributes.mInputTypeNoAutoCorrect; if (shouldAutoCorrect && primaryCode != Keyboard.CODE_SINGLE_QUOTE) { commitCurrentAutoCorrection(primaryCode, ic); + didAutoCorrect = true; } else { commitTyped(ic); } @@ -1617,12 +1648,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (ic != null) { ic.endBatchEdit(); } + return didAutoCorrect; } private CharSequence getTextWithUnderline(final CharSequence text) { return mComposingStateManager.isAutoCorrectionIndicatorOn() ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text) - : mWordComposer.getTypedWord(); + : text; } private void handleClose() { @@ -1837,7 +1869,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint); mExpectingUpdateSelection = true; - commitChosenWord(autoCorrection, WordComposer.COMMIT_TYPE_DECIDED_WORD); + commitChosenWord(autoCorrection, LastComposedWord.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); @@ -1907,7 +1939,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar LatinImeLogger.logOnManualSuggestion(mWordComposer.getTypedWord().toString(), suggestion.toString(), index, suggestions.mWords); mExpectingUpdateSelection = true; - commitChosenWord(suggestion, WordComposer.COMMIT_TYPE_MANUAL_PICK); + commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK); // Add the word to the auto dictionary if it's not a known word if (index == 0) { addToUserUnigramAndBigramDictionaries(suggestion, @@ -1975,9 +2007,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } // 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 + // LastComposedWord#canCancelAutoCorrect by string equality of the remembered // strings. - mWordComposer.onCommitWord(commitType); + mLastComposedWord = mWordComposer.commitWord(commitType); } private static final WordComposer sEmptyWordComposer = new WordComposer(); @@ -2141,12 +2173,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // "ic" must not be null private void cancelAutoCorrect(final InputConnection ic) { - mWordComposer.resumeSuggestionOnKeptWord(); - final String originallyTypedWord = mWordComposer.getTypedWord(); - final CharSequence autoCorrectedTo = mWordComposer.getAutoCorrectionOrNull(); + final String originallyTypedWord = mLastComposedWord.mTypedWord; + final CharSequence autoCorrectedTo = mLastComposedWord.mAutoCorrection; final int cancelLength = autoCorrectedTo.length(); final CharSequence separator = ic.getTextBeforeCursor(1, 0); if (DEBUG) { + if (mWordComposer.isComposingWord()) { + throw new RuntimeException("cancelAutoCorrect, but we are composing a word"); + } final String wordBeforeCursor = ic.getTextBeforeCursor(cancelLength + 1, 0).subSequence(0, cancelLength) .toString(); @@ -2165,8 +2199,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ic.commitText(originallyTypedWord, 1); // Re-insert the separator ic.commitText(separator, 1); - mWordComposer.deleteAutoCorrection(); - mWordComposer.onCommitWord(WordComposer.COMMIT_TYPE_CANCEL_AUTO_CORRECT); + mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; Utils.Stats.onSeparator(separator.charAt(0), WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); mHandler.cancelUpdateBigramPredictions(); @@ -2180,7 +2213,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Note: in the interest of code simplicity, we may want to just call // restartSuggestionsOnWordBeforeCursorIfAtEndOfWord instead, but retrieving // the old WordComposer allows to reuse the actual typed coordinates. - mWordComposer.resumeSuggestionOnKeptWord(); + mWordComposer.resumeSuggestionOnLastComposedWord(mLastComposedWord); // We resume suggestion, and then we want to set the composing text to the content // of the word composer again. But since we just manually picked a word, there is // no composing text at the moment, so we have to delete the word before we set a @@ -2229,10 +2262,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final CharSequence textBeforeCursor = ic.getTextBeforeCursor(2, 0); // NOTE: This does not work with surrogate pairs. Hopefully when the keyboard is able to // enter surrogate pairs this code will have been removed. - if (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1)) { - // We should not have come here if the text before the cursor is not a space. - throw new RuntimeException("Tried to revert a swap of punctuation but we didn't " + if (TextUtils.isEmpty(textBeforeCursor) + || (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1))) { + // We may only come here if the application is changing the text while we are typing. + // This is quite a broken case, but not logically impossible, so we shouldn't crash, + // but some debugging log may be in order. + Log.d(TAG, "Tried to revert a swap of punctuation but we didn't " + "find a space just before the cursor."); + return false; } ic.beginBatchEdit(); ic.deleteSurroundingText(2, 0); |