diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 151 |
1 files changed, 111 insertions, 40 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index cdb3ff945..7dfaf6cee 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -64,6 +64,7 @@ import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.compat.SuggestionSpanUtils; +import com.android.inputmethod.event.EventInterpreter; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; @@ -142,6 +143,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; private final SubtypeSwitcher mSubtypeSwitcher; private final SubtypeState mSubtypeState = new SubtypeState(); + // At start, create a default event interpreter that does nothing by passing it no decoder spec. + // The event interpreter should never be null. + private EventInterpreter mEventInterpreter = new EventInterpreter(); private boolean mIsMainDictionaryAvailable; private UserBinaryDictionary mUserDictionary; @@ -149,6 +153,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private boolean mIsUserDictionaryAvailable; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; + private PositionalInfoForUserDictPendingAddition + mPositionalInfoForUserDictPendingAddition = null; private final WordComposer mWordComposer = new WordComposer(); private RichInputConnection mConnection = new RichInputConnection(this); @@ -779,6 +785,19 @@ public final class LatinIME extends InputMethodService implements KeyboardAction mainKeyboardView.setGesturePreviewMode(mCurrentSettings.mGesturePreviewTrailEnabled, mCurrentSettings.mGestureFloatingPreviewTextEnabled); + // If we have a user dictionary addition in progress, we should check now if we should + // replace the previously committed string with the word that has actually been added + // to the user dictionary. + if (null != mPositionalInfoForUserDictPendingAddition + && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord( + mConnection, editorInfo, mLastSelectionEnd)) { + mPositionalInfoForUserDictPendingAddition = null; + } + // If tryReplaceWithActualWord returns false, we don't know what word was + // added to the user dictionary yet, so we keep the data and defer processing. The word will + // be replaced when the user dictionary reports back with the actual word, which ends + // up calling #onWordAddedToUserDictionary() in this class. + if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } @@ -1209,9 +1228,31 @@ public final class LatinIME extends InputMethodService implements KeyboardAction // Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is // pressed. @Override - public boolean addWordToUserDictionary(final String word) { + public void addWordToUserDictionary(final String word) { + if (TextUtils.isEmpty(word)) { + // Probably never supposed to happen, but just in case. + mPositionalInfoForUserDictPendingAddition = null; + return; + } + mPositionalInfoForUserDictPendingAddition = + new PositionalInfoForUserDictPendingAddition( + word, mLastSelectionEnd, getCurrentInputEditorInfo()); mUserDictionary.addWordToUserDictionary(word, 128); - return true; + } + + public void onWordAddedToUserDictionary(final String newSpelling) { + // If word was added but not by us, bail out + if (null == mPositionalInfoForUserDictPendingAddition) return; + if (mWordComposer.isComposingWord()) { + // We are late... give up and return + mPositionalInfoForUserDictPendingAddition = null; + return; + } + mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling); + if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord( + mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd)) { + mPositionalInfoForUserDictPendingAddition = null; + } } private static boolean isAlphabet(final int code) { @@ -1424,7 +1465,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @Override public void onStartBatchInput() { - BatchInputUpdater.getInstance().onStartBatchInput(); + BatchInputUpdater.getInstance().onStartBatchInput(this); mConnection.beginBatchEdit(); if (mWordComposer.isComposingWord()) { if (ProductionFlag.IS_INTERNAL) { @@ -1490,34 +1531,32 @@ public final class LatinIME extends InputMethodService implements KeyboardAction public boolean handleMessage(final Message msg) { switch (msg.what) { case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP: - updateBatchInput((InputPointers)msg.obj, mLatinIme); + updateBatchInput((InputPointers)msg.obj); break; } return true; } // Run in the UI thread. - public synchronized void onStartBatchInput() { + public synchronized void onStartBatchInput(final LatinIME latinIme) { mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP); + mLatinIme = latinIme; mInBatchInput = true; } // Run in the Handler thread. - private synchronized void updateBatchInput(final InputPointers batchPointers, - final LatinIME latinIme) { + private synchronized void updateBatchInput(final InputPointers batchPointers) { if (!mInBatchInput) { // Batch input has ended or canceled while the message was being delivered. return; } - final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked( - batchPointers, latinIme); - latinIme.mHandler.showGesturePreviewAndSuggestionStrip( + final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( suggestedWords, false /* dismissGestureFloatingPreviewText */); } // Run in the UI thread. - public void onUpdateBatchInput(final InputPointers batchPointers, final LatinIME latinIme) { - mLatinIme = latinIme; + public void onUpdateBatchInput(final InputPointers batchPointers) { if (mHandler.hasMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP)) { return; } @@ -1526,29 +1565,34 @@ public final class LatinIME extends InputMethodService implements KeyboardAction .sendToTarget(); } - public synchronized void onCancelBatchInput(final LatinIME latinIme) { + public synchronized void onCancelBatchInput() { mInBatchInput = false; - latinIme.mHandler.showGesturePreviewAndSuggestionStrip( + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */); } // Run in the UI thread. - public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers, - final LatinIME latinIme) { + public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers) { mInBatchInput = false; - final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked( - batchPointers, latinIme); - latinIme.mHandler.showGesturePreviewAndSuggestionStrip( + final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers); + mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip( suggestedWords, true /* dismissGestureFloatingPreviewText */); return suggestedWords; } // {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to // be synchronized. - private static SuggestedWords getSuggestedWordsGestureLocked( - final InputPointers batchPointers, final LatinIME latinIme) { - latinIme.mWordComposer.setBatchInputPointers(batchPointers); - return latinIme.getSuggestedWords(Suggest.SESSION_GESTURE); + private SuggestedWords getSuggestedWordsGestureLocked(final InputPointers batchPointers) { + mLatinIme.mWordComposer.setBatchInputPointers(batchPointers); + final SuggestedWords suggestedWords = + mLatinIme.getSuggestedWords(Suggest.SESSION_GESTURE); + final int suggestionCount = suggestedWords.size(); + if (suggestionCount <= 1) { + final String mostProbableSuggestion = (suggestionCount == 0) ? null + : suggestedWords.getWord(0); + return mLatinIme.getOlderSuggestions(mostProbableSuggestion); + } + return suggestedWords; } } @@ -1567,13 +1611,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @Override public void onUpdateBatchInput(final InputPointers batchPointers) { - BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers, this); + BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers); } @Override public void onEndBatchInput(final InputPointers batchPointers) { final SuggestedWords suggestedWords = BatchInputUpdater.getInstance().onEndBatchInput( - batchPointers, this); + batchPointers); final String batchInputText = suggestedWords.isEmpty() ? null : suggestedWords.getWord(0); if (TextUtils.isEmpty(batchInputText)) { @@ -1623,7 +1667,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @Override public void onCancelBatchInput() { - BatchInputUpdater.getInstance().onCancelBatchInput(this); + BatchInputUpdater.getInstance().onCancelBatchInput(); } private void handleBackspace(final int spaceState) { @@ -1988,26 +2032,32 @@ public final class LatinIME extends InputMethodService implements KeyboardAction // old suggestions. Also, if we are showing the "add to dictionary" hint, we need to // revert to suggestions - although it is unclear how we can come here if it's displayed. if (suggestedWords.size() > 1 || typedWord.length() <= 1 - || !suggestedWords.mTypedWordValid + || suggestedWords.mTypedWordValid || mSuggestionStripView.isShowingAddToDictionaryHint()) { return suggestedWords; } else { - SuggestedWords previousSuggestions = mSuggestionStripView.getSuggestions(); - if (previousSuggestions == mCurrentSettings.mSuggestPuncList) { - previousSuggestions = SuggestedWords.EMPTY; - } - final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions = - SuggestedWords.getTypedWordAndPreviousSuggestions( - typedWord, previousSuggestions); - return new SuggestedWords(typedWordAndPreviousSuggestions, - false /* typedWordValid */, - false /* hasAutoCorrectionCandidate */, - false /* isPunctuationSuggestions */, - true /* isObsoleteSuggestions */, - false /* isPrediction */); + return getOlderSuggestions(typedWord); } } + private SuggestedWords getOlderSuggestions(final String typedWord) { + SuggestedWords previousSuggestions = mSuggestionStripView.getSuggestions(); + if (previousSuggestions == mCurrentSettings.mSuggestPuncList) { + previousSuggestions = SuggestedWords.EMPTY; + } + if (typedWord == null) { + return previousSuggestions; + } + final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions = + SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); + return new SuggestedWords(typedWordAndPreviousSuggestions, + false /* typedWordValid */, + false /* hasAutoCorrectionCandidate */, + false /* isPunctuationSuggestions */, + true /* isObsoleteSuggestions */, + false /* isPrediction */); + } + private void showSuggestionStrip(final SuggestedWords suggestedWords, final String typedWord) { if (suggestedWords.isEmpty()) { clearSuggestionStrip(); @@ -2333,6 +2383,27 @@ public final class LatinIME extends InputMethodService implements KeyboardAction } } + // Hooks for hardware keyboard + @Override + public boolean onKeyDown(final int keyCode, final KeyEvent event) { + // onHardwareKeyEvent, like onKeyDown returns true if it handled the event, false if + // it doesn't know what to do with it and leave it to the application. For example, + // hardware key events for adjusting the screen's brightness are passed as is. + if (mEventInterpreter.onHardwareKeyEvent(event)) return true; + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onKeyUp(final int keyCode, final KeyEvent event) { + if (mEventInterpreter.onHardwareKeyEvent(event)) return true; + return super.onKeyUp(keyCode, event); + } + + // onKeyDown and onKeyUp are the main events we are interested in. There are two more events + // related to handling of hardware key events that we may want to implement in the future: + // boolean onKeyLongPress(final int keyCode, final KeyEvent event); + // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event); + // receive ringer mode change and network state change. private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override |