aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/LatinIME.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java336
1 files changed, 221 insertions, 115 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 83a306818..db8f269eb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -36,6 +36,8 @@ import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Debug;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
@@ -184,13 +186,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_UPDATE_SHIFT_STATE = 0;
private static final int MSG_PENDING_IMS_CALLBACK = 1;
private static final int MSG_UPDATE_SUGGESTION_STRIP = 2;
+ private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3;
+
+ private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
private long mDoubleSpacesTurnIntoPeriodTimeout;
private long mDoubleSpaceTimerStart;
- public UIHandler(LatinIME outerInstance) {
+ public UIHandler(final LatinIME outerInstance) {
super(outerInstance);
}
@@ -205,7 +210,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
final LatinIME latinIme = getOuterInstance();
final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher;
switch (msg.what) {
@@ -215,6 +220,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_UPDATE_SHIFT_STATE:
switcher.updateShiftState();
break;
+ case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
+ latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords)msg.obj,
+ msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT);
+ break;
}
}
@@ -239,6 +248,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
removeMessages(MSG_UPDATE_SHIFT_STATE);
}
+ public void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
+ final boolean dismissGestureFloatingPreviewText) {
+ removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ final int arg1 = dismissGestureFloatingPreviewText
+ ? ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT : 0;
+ obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1, 0, suggestedWords)
+ .sendToTarget();
+ }
+
public void startDoubleSpacesTimer() {
mDoubleSpaceTimerStart = SystemClock.uptimeMillis();
}
@@ -276,7 +294,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHasPendingStartInput = false;
}
- private void executePendingImsCallback(LatinIME latinIme, EditorInfo editorInfo,
+ private void executePendingImsCallback(final LatinIME latinIme, final EditorInfo editorInfo,
boolean restarting) {
if (mHasPendingFinishInputView)
latinIme.onFinishInputViewInternal(mHasPendingFinishInput);
@@ -287,7 +305,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetPendingImsCallback();
}
- public void onStartInput(EditorInfo editorInfo, boolean restarting) {
+ public void onStartInput(final EditorInfo editorInfo, final boolean restarting) {
if (hasMessages(MSG_PENDING_IMS_CALLBACK)) {
// Typically this is the second onStartInput after orientation changed.
mHasPendingStartInput = true;
@@ -303,7 +321,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
+ public void onStartInputView(final EditorInfo editorInfo, final boolean restarting) {
if (hasMessages(MSG_PENDING_IMS_CALLBACK)
&& KeyboardId.equivalentEditorInfoForKeyboard(editorInfo, mAppliedEditorInfo)) {
// Typically this is the second onStartInputView after orientation changed.
@@ -323,7 +341,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- public void onFinishInputView(boolean finishingInput) {
+ public void onFinishInputView(final boolean finishingInput) {
if (hasMessages(MSG_PENDING_IMS_CALLBACK)) {
// Typically this is the first onFinishInputView after orientation changed.
mHasPendingFinishInputView = true;
@@ -425,7 +443,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note that this method is called from a non-UI thread.
@Override
- public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable) {
+ public void onUpdateMainDictionaryAvailability(final boolean isMainDictionaryAvailable) {
mIsMainDictionaryAvailable = isMainDictionaryAvailable;
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
@@ -529,7 +547,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onConfigurationChanged(Configuration conf) {
+ public void onConfigurationChanged(final Configuration conf) {
// System locale has been changed. Needs to reload keyboard.
if (mSubtypeSwitcher.onConfigurationChanged(conf, this)) {
loadKeyboard();
@@ -555,7 +573,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void setInputView(View view) {
+ public void setInputView(final View view) {
super.setInputView(view);
mExtractArea = getWindow().getWindow().getDecorView()
.findViewById(android.R.id.extractArea);
@@ -570,23 +588,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void setCandidatesView(View view) {
+ public void setCandidatesView(final View view) {
// To ensure that CandidatesView will never be set.
return;
}
@Override
- public void onStartInput(EditorInfo editorInfo, boolean restarting) {
+ public void onStartInput(final EditorInfo editorInfo, final boolean restarting) {
mHandler.onStartInput(editorInfo, restarting);
}
@Override
- public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
+ public void onStartInputView(final EditorInfo editorInfo, final boolean restarting) {
mHandler.onStartInputView(editorInfo, restarting);
}
@Override
- public void onFinishInputView(boolean finishingInput) {
+ public void onFinishInputView(final boolean finishingInput) {
mHandler.onFinishInputView(finishingInput);
}
@@ -596,19 +614,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
+ public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) {
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
// is not guaranteed. It may even be called at the same time on a different thread.
mSubtypeSwitcher.updateSubtype(subtype);
loadKeyboard();
}
- private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) {
+ private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInput(editorInfo, restarting);
}
@SuppressWarnings("deprecation")
- private void onStartInputViewInternal(EditorInfo editorInfo, boolean restarting) {
+ private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInputView(editorInfo, restarting);
final KeyboardSwitcher switcher = mKeyboardSwitcher;
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
@@ -700,6 +718,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
+ mConnection.resetCachesUponCursorMove(mLastSelectionStart);
+
if (isDifferentTextField) {
mainKeyboardView.closing();
loadSettings();
@@ -749,7 +769,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
getCurrentInputConnection());
}
super.onWindowHidden();
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.closing();
}
@@ -763,16 +783,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ResearchLogger.getInstance().latinIME_onFinishInputInternal();
}
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.closing();
}
}
- private void onFinishInputViewInternal(boolean finishingInput) {
+ private void onFinishInputViewInternal(final boolean finishingInput) {
super.onFinishInputView(finishingInput);
mKeyboardSwitcher.onFinishInputView();
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.cancelAllMessages();
}
@@ -781,9 +801,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onUpdateSelection(int oldSelStart, int oldSelEnd,
- int newSelStart, int newSelEnd,
- int composingSpanStart, int composingSpanEnd) {
+ public void onUpdateSelection(final int oldSelStart, final int oldSelEnd,
+ final int newSelStart, final int newSelEnd,
+ final int composingSpanStart, final int composingSpanEnd) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
composingSpanStart, composingSpanEnd);
if (DEBUG) {
@@ -823,7 +843,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// we know for sure the cursor moved while we were composing and we should reset
// the state.
final boolean noComposingSpan = composingSpanStart == -1 && composingSpanEnd == -1;
- if (!mExpectingUpdateSelection) {
+ if (!mExpectingUpdateSelection
+ && !mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart)) {
// TAKE CARE: there is a race condition when we enter this test even when the user
// did not explicitly move the cursor. This happens when typing fast, where two keys
// turn this flag on in succession and both onUpdateSelection() calls arrive after
@@ -839,7 +860,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSpaceState = SPACE_STATE_NONE;
if ((!mWordComposer.isComposingWord()) || selectionChanged || noComposingSpan) {
- resetEntireInputState();
+ resetEntireInputState(newSelStart);
}
mHandler.postUpdateShiftState();
@@ -880,7 +901,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
* cause the suggestions strip to disappear and re-appear.
*/
@Override
- public void onExtractedCursorMovement(int dx, int dy) {
+ public void onExtractedCursorMovement(final int dx, final int dy) {
if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) return;
super.onExtractedCursorMovement(dx, dy);
@@ -900,7 +921,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) {
+ public void onDisplayCompletions(final CompletionInfo[] applicationSpecifiedCompletions) {
if (DEBUG) {
Log.i(TAG, "Received completions:");
if (applicationSpecifiedCompletions != null) {
@@ -942,7 +963,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) {
+ private void setSuggestionStripShownInternal(final boolean shown,
+ final boolean needsInputViewShown) {
// TODO: Modify this if we support suggestions with hard keyboard
if (onEvaluateInputViewShown() && mSuggestionsContainer != null) {
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@@ -960,7 +982,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void setSuggestionStripShown(boolean shown) {
+ private void setSuggestionStripShown(final boolean shown) {
setSuggestionStripShownInternal(shown, /* needsInputViewShown */true);
}
@@ -970,7 +992,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return currentHeight;
}
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView == null) {
return 0;
}
@@ -990,9 +1012,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onComputeInsets(InputMethodService.Insets outInsets) {
+ public void onComputeInsets(final InputMethodService.Insets outInsets) {
super.onComputeInsets(outInsets);
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView == null || mSuggestionsContainer == null) {
return;
}
@@ -1043,10 +1065,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// This will reset the whole input state to the starting state. It will clear
// the composing word, reset the last composed word, tell the inputconnection about it.
- private void resetEntireInputState() {
+ private void resetEntireInputState(final int newCursorPosition) {
resetComposingState(true /* alsoResetLastComposedWord */);
- clearSuggestionStrip();
- mConnection.finishComposingText();
+ if (mCurrentSettings.mBigramPredictionEnabled) {
+ clearSuggestionStrip();
+ } else {
+ setSuggestionStrip(mCurrentSettings.mSuggestPuncList, false);
+ }
+ mConnection.resetCachesUponCursorMove(newCursorPosition);
}
private void resetComposingState(final boolean alsoResetLastComposedWord) {
@@ -1055,7 +1081,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
}
- private void commitTyped(final int separatorCode) {
+ private void commitTyped(final String separatorString) {
if (!mWordComposer.isComposingWord()) return;
final CharSequence typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
@@ -1063,7 +1089,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
mLastComposedWord = mWordComposer.commitWord(
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
- separatorCode, prevWord);
+ separatorString, prevWord);
}
}
@@ -1092,7 +1118,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note: getCursorCapsMode() returns the current capitalization mode that is any
// combination of CAP_MODE_CHARACTERS, CAP_MODE_WORDS, and CAP_MODE_SENTENCES. 0 means none
// of them.
- return mConnection.getCursorCapsMode(inputType);
+ return mConnection.getCursorCapsMode(inputType, mSubtypeSwitcher.getCurrentSubtypeLocale());
}
// Factor in auto-caps and manual caps and compute the current caps mode.
@@ -1153,12 +1179,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
// pressed.
@Override
- public boolean addWordToUserDictionary(String word) {
+ public boolean addWordToUserDictionary(final String word) {
mUserDictionary.addWordToUserDictionary(word, 128);
return true;
}
- private static boolean isAlphabet(int code) {
+ private static boolean isAlphabet(final int code) {
return Character.isLetter(code);
}
@@ -1171,7 +1197,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public static final int CODE_SHOW_INPUT_METHOD_PICKER = 1;
@Override
- public boolean onCustomRequest(int requestCode) {
+ public boolean onCustomRequest(final int requestCode) {
if (isShowingOptionDialog()) return false;
switch (requestCode) {
case CODE_SHOW_INPUT_METHOD_PICKER:
@@ -1189,11 +1215,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
- private static int getActionId(Keyboard keyboard) {
+ private static int getActionId(final Keyboard keyboard) {
return keyboard != null ? keyboard.mId.imeActionId() : EditorInfo.IME_ACTION_NONE;
}
- private void performEditorAction(int actionId) {
+ private void performEditorAction(final int actionId) {
mConnection.performEditorAction(actionId);
}
@@ -1216,7 +1242,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void sendUpDownEnterOrBackspace(final int code) {
+ private void sendDownUpKeyEventForBackwardCompatibility(final int code) {
final long eventTime = SystemClock.uptimeMillis();
mConnection.sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, code, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
@@ -1226,11 +1252,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE));
}
- private void sendKeyCodePoint(int code) {
+ private void sendKeyCodePoint(final int code) {
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') {
- super.sendKeyChar((char)code);
+ sendDownUpKeyEventForBackwardCompatibility(code - '0' + KeyEvent.KEYCODE_0);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_sendKeyCodePoint(code);
}
@@ -1245,7 +1271,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// a hardware keyboard event on pressing enter or delete. This is bad for many
// reasons (there are race conditions with commits) but some applications are
// relying on this behavior so we continue to support it for older apps.
- sendUpDownEnterOrBackspace(KeyEvent.KEYCODE_ENTER);
+ sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_ENTER);
} else {
final String text = new String(new int[] { code }, 0, 1);
mConnection.commitText(text, text.length());
@@ -1254,7 +1280,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Implementation of {@link KeyboardActionListener}.
@Override
- public void onCodeInput(int primaryCode, int x, int y) {
+ public void onCodeInput(final int primaryCode, final int x, final int y) {
final long when = SystemClock.uptimeMillis();
if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0;
@@ -1309,7 +1335,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case Keyboard.CODE_RESEARCH:
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().presentResearchDialog(this);
+ ResearchLogger.getInstance().onResearchKeySelected(this);
}
break;
default:
@@ -1340,7 +1366,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!didAutoCorrect && primaryCode != Keyboard.CODE_SHIFT
&& primaryCode != Keyboard.CODE_SWITCH_ALPHA_SYMBOL)
mLastComposedWord.deactivate();
- mEnteredText = null;
+ if (Keyboard.CODE_DELETE != primaryCode) {
+ mEnteredText = null;
+ }
mConnection.endBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
@@ -1349,10 +1377,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Called from PointerTracker through the KeyboardActionListener interface
@Override
- public void onTextInput(CharSequence rawText) {
+ public void onTextInput(final CharSequence rawText) {
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
- commitCurrentAutoCorrection(LastComposedWord.NOT_A_SEPARATOR);
+ commitCurrentAutoCorrection(rawText.toString());
+ } else {
+ resetComposingState(true /* alsoResetLastComposedWord */);
}
mHandler.postUpdateSuggestionStrip();
final CharSequence text = specificTldProcessingOnTextInput(rawText);
@@ -1365,14 +1395,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
mSpaceState = SPACE_STATE_NONE;
mEnteredText = text;
- resetComposingState(true /* alsoResetLastComposedWord */);
}
@Override
public void onStartBatchInput() {
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
- commitCurrentAutoCorrection(LastComposedWord.NOT_A_SEPARATOR);
+ commitTyped(LastComposedWord.NOT_A_SEPARATOR);
mExpectingUpdateSelection = true;
// TODO: Can we remove this?
mSpaceState = SPACE_STATE_PHANTOM;
@@ -1382,40 +1411,102 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.setCapitalizedModeAtStartComposingTime(getActualCapsMode());
}
- @Override
- public void onUpdateBatchInput(InputPointers batchPointers) {
- mWordComposer.setBatchInputPointers(batchPointers);
- final SuggestedWords suggestedWords = getSuggestedWords();
- showSuggestionStrip(suggestedWords, null);
- final String gestureFloatingPreviewText = (suggestedWords.size() > 0)
+ private static final class BatchInputUpdater implements Handler.Callback {
+ private final Handler mHandler;
+ private LatinIME mLatinIme;
+
+ private BatchInputUpdater() {
+ final HandlerThread handlerThread = new HandlerThread(
+ BatchInputUpdater.class.getSimpleName());
+ handlerThread.start();
+ mHandler = new Handler(handlerThread.getLooper(), this);
+ }
+
+ // Initialization-on-demand holder
+ private static final class OnDemandInitializationHolder {
+ public static final BatchInputUpdater sInstance = new BatchInputUpdater();
+ }
+
+ public static BatchInputUpdater getInstance() {
+ return OnDemandInitializationHolder.sInstance;
+ }
+
+ private static final int MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 1;
+
+ @Override
+ public boolean handleMessage(final Message msg) {
+ switch (msg.what) {
+ case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
+ final SuggestedWords suggestedWords = getSuggestedWordsGesture(
+ (InputPointers)msg.obj, mLatinIme);
+ showGesturePreviewAndSuggestionStrip(
+ suggestedWords, false /* dismissGestureFloatingPreviewText */, mLatinIme);
+ break;
+ }
+ return true;
+ }
+
+ public void updateGesturePreviewAndSuggestionStrip(final InputPointers batchPointers,
+ final LatinIME latinIme) {
+ mLatinIme = latinIme;
+ if (mHandler.hasMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP)) {
+ return;
+ }
+ mHandler.obtainMessage(
+ MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, batchPointers)
+ .sendToTarget();
+ }
+
+ public void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
+ final boolean dismissGestureFloatingPreviewText, final LatinIME latinIme) {
+ latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ suggestedWords, dismissGestureFloatingPreviewText);
+ }
+
+ // {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to
+ // be synchronized.
+ public synchronized SuggestedWords getSuggestedWordsGesture(
+ final InputPointers batchPointers, final LatinIME latinIme) {
+ latinIme.mWordComposer.setBatchInputPointers(batchPointers);
+ return latinIme.getSuggestedWords(Suggest.SESSION_GESTURE);
+ }
+ }
+
+ private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
+ final boolean dismissGestureFloatingPreviewText) {
+ final String batchInputText = (suggestedWords.size() > 0)
? suggestedWords.getWord(0) : null;
- mKeyboardSwitcher.getMainKeyboardView()
- .showGestureFloatingPreviewText(gestureFloatingPreviewText);
+ final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ mainKeyboardView.showGestureFloatingPreviewText(batchInputText);
+ showSuggestionStrip(suggestedWords, null);
+ if (dismissGestureFloatingPreviewText) {
+ mainKeyboardView.dismissGestureFloatingPreviewText();
+ }
}
@Override
- public void onEndBatchInput(InputPointers batchPointers) {
- mWordComposer.setBatchInputPointers(batchPointers);
- final SuggestedWords suggestedWords = getSuggestedWords();
- showSuggestionStrip(suggestedWords, null);
- final String gestureFloatingPreviewText = (suggestedWords.size() > 0)
+ public void onUpdateBatchInput(final InputPointers batchPointers) {
+ BatchInputUpdater.getInstance().updateGesturePreviewAndSuggestionStrip(batchPointers, this);
+ }
+
+ @Override
+ public void onEndBatchInput(final InputPointers batchPointers) {
+ final BatchInputUpdater batchInputUpdater = BatchInputUpdater.getInstance();
+ final SuggestedWords suggestedWords = batchInputUpdater.getSuggestedWordsGesture(
+ batchPointers, this);
+ batchInputUpdater.showGesturePreviewAndSuggestionStrip(
+ suggestedWords, true /* dismissGestureFloatingPreviewText */, this);
+ final String batchInputText = (suggestedWords.size() > 0)
? suggestedWords.getWord(0) : null;
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- mainKeyboardView.showGestureFloatingPreviewText(gestureFloatingPreviewText);
- mainKeyboardView.dismissGestureFloatingPreviewText();
- if (suggestedWords == null || suggestedWords.size() == 0) {
+ if (TextUtils.isEmpty(batchInputText)) {
return;
}
- final CharSequence text = suggestedWords.getWord(0);
- if (TextUtils.isEmpty(text)) {
- return;
- }
- mWordComposer.setBatchInputWord(text);
+ mWordComposer.setBatchInputWord(batchInputText);
mConnection.beginBatchEdit();
if (SPACE_STATE_PHANTOM == mSpaceState) {
sendKeyCodePoint(Keyboard.CODE_SPACE);
}
- mConnection.setComposingText(text, 1);
+ mConnection.setComposingText(batchInputText, 1);
mExpectingUpdateSelection = true;
mConnection.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
@@ -1451,18 +1542,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// In many cases, we may have to put the keyboard in auto-shift state again.
mHandler.postUpdateShiftState();
- if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
- // Cancel multi-character input: remove the text we just entered.
- // This is triggered on backspace after a key that inputs multiple characters,
- // like the smiley key or the .com key.
- final int length = mEnteredText.length();
- mConnection.deleteSurroundingText(length, 0);
- // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
- // In addition we know that spaceState is false, and that we should not be
- // reverting any autocorrect at this point. So we can safely return.
- return;
- }
-
if (mWordComposer.isComposingWord()) {
final int length = mWordComposer.size();
if (length > 0) {
@@ -1483,6 +1562,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
revertCommit();
return;
}
+ if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
+ // Cancel multi-character input: remove the text we just entered.
+ // This is triggered on backspace after a key that inputs multiple characters,
+ // like the smiley key or the .com key.
+ final int length = mEnteredText.length();
+ mConnection.deleteSurroundingText(length, 0);
+ mEnteredText = null;
+ // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
+ // In addition we know that spaceState is false, and that we should not be
+ // reverting any autocorrect at this point. So we can safely return.
+ return;
+ }
if (SPACE_STATE_DOUBLE == spaceState) {
mHandler.cancelDoubleSpacesTimer();
if (mConnection.revertDoubleSpace()) {
@@ -1518,7 +1609,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// a hardware keyboard event on pressing enter or delete. This is bad for many
// reasons (there are race conditions with commits) but some applications are
// relying on this behavior so we continue to support it for older apps.
- sendUpDownEnterOrBackspace(KeyEvent.KEYCODE_DEL);
+ sendDownUpKeyEventForBackwardCompatibility(KeyEvent.KEYCODE_DEL);
} else {
mConnection.deleteSurroundingText(1, 0);
}
@@ -1626,10 +1717,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Handle separator
if (mWordComposer.isComposingWord()) {
if (mCurrentSettings.mCorrectionEnabled) {
- commitCurrentAutoCorrection(primaryCode);
+ // TODO: maybe cache Strings in an <String> sparse array or something
+ commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
didAutoCorrect = true;
} else {
- commitTyped(primaryCode);
+ commitTyped(new String(new int[]{primaryCode}, 0, 1));
}
}
@@ -1660,7 +1752,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
swapSwapperAndSpace();
mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
} else if (SPACE_STATE_PHANTOM == spaceState
- && !mCurrentSettings.isWeakSpaceStripper(primaryCode)) {
+ && !mCurrentSettings.isWeakSpaceStripper(primaryCode)
+ && !mCurrentSettings.isPhantomSpacePromotingSymbol(primaryCode)) {
// If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the
// space. For example, if I type "Good dat", pick "day" from the suggestion strip
@@ -1761,12 +1854,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
- final SuggestedWords suggestedWords = getSuggestedWords();
+ final SuggestedWords suggestedWords = getSuggestedWords(Suggest.SESSION_TYPING);
final String typedWord = mWordComposer.getTypedWord();
showSuggestionStrip(suggestedWords, typedWord);
}
- private SuggestedWords getSuggestedWords() {
+ private SuggestedWords getSuggestedWords(final int sessionId) {
final String typedWord = mWordComposer.getTypedWord();
// Get the word on which we should search the bigrams. If we are composing a word, it's
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
@@ -1777,7 +1870,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWordComposer.isComposingWord() ? 2 : 1);
final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer,
prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(),
- mCurrentSettings.mCorrectionEnabled);
+ mCurrentSettings.mCorrectionEnabled, sessionId);
return maybeRetrieveOlderSuggestions(typedWord, suggestedWords);
}
@@ -1834,7 +1927,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestionStripShown(isSuggestionsStripVisible());
}
- private void commitCurrentAutoCorrection(final int separatorCodePoint) {
+ private void commitCurrentAutoCorrection(final String separatorString) {
// Complete any pending suggestions query first
if (mHandler.hasPendingUpdateSuggestions()) {
updateSuggestionStrip();
@@ -1848,13 +1941,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
throw new RuntimeException("We have an auto-correction but the typed word "
+ "is empty? Impossible! I must commit suicide.");
}
- Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorCodePoint);
+ Utils.Stats.onAutoCorrection(typedWord, autoCorrection.toString(), separatorString);
mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
- separatorCodePoint);
+ separatorString);
if (!typedWord.equals(autoCorrection)) {
// This will make the correction flash for a short while as a visual clue
- // to the user that auto-correction happened.
+ // to the user that auto-correction happened. It has no other effect; in particular
+ // note that this won't affect the text inside the text field AT ALL: it only makes
+ // the segment of text starting at the supplied index and running for the length
+ // of the auto-correction flash. At this moment, the "typedWord" argument is
+ // ignored by TextView.
mConnection.commitCorrection(
new CorrectionInfo(mLastSelectionEnd - typedWord.length(),
typedWord, autoCorrection));
@@ -1949,7 +2046,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
* Commits the chosen word to the text field and saves it for later retrieval.
*/
private void commitChosenWord(final CharSequence chosenWord, final int commitType,
- final int separatorCode) {
+ final String separatorString) {
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
@@ -1960,7 +2057,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings.
mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord.toString(),
- separatorCode, prevWord);
+ separatorString, prevWord);
}
private void setPunctuationSuggestions() {
@@ -2030,7 +2127,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
final int cancelLength = committedWord.length();
final int separatorLength = LastComposedWord.getSeparatorLength(
- mLastComposedWord.mSeparatorCode);
+ mLastComposedWord.mSeparatorString);
// TODO: should we check our saved separator against the actual contents of the text view?
final int deleteLength = cancelLength + separatorLength;
if (DEBUG) {
@@ -2051,10 +2148,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mUserHistoryDictionary.cancelAddingUserHistory(
previousWord.toString(), committedWord.toString());
}
- mConnection.commitText(originallyTypedWord, 1);
- // Re-insert the separator
- sendKeyCodePoint(mLastComposedWord.mSeparatorCode);
- Utils.Stats.onSeparator(mLastComposedWord.mSeparatorCode,
+ mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
+ Utils.Stats.onSeparator(mLastComposedWord.mSeparatorString,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_revertCommit(originallyTypedWord);
@@ -2067,7 +2162,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// Used by the RingCharBuffer
- public boolean isWordSeparator(int code) {
+ public boolean isWordSeparator(final int code) {
return mCurrentSettings.isWordSeparator(code);
}
@@ -2099,14 +2194,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Callback called by PointerTracker through the KeyboardActionListener. This is called when a
// key is depressed; release matching call is onReleaseKey below.
@Override
- public void onPressKey(int primaryCode) {
+ public void onPressKey(final int primaryCode) {
mKeyboardSwitcher.onPressKey(primaryCode);
}
// Callback by PointerTracker through the KeyboardActionListener. This is called when a key
// is released; press matching call is onPressKey above.
@Override
- public void onReleaseKey(int primaryCode, boolean withSliding) {
+ public void onReleaseKey(final int primaryCode, final boolean withSliding) {
mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding);
// If accessibility is on, ensure the user receives keyboard state updates.
@@ -2135,7 +2230,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// receive ringer mode change and network state change.
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
mSubtypeSwitcher.onNetworkStateChanged(intent);
@@ -2156,14 +2251,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
launchSubActivity(DebugSettingsActivity.class);
}
- public void launchKeyboardedDialogActivity(Class<? extends Activity> activityClass) {
+ public void launchKeyboardedDialogActivity(final Class<? extends Activity> activityClass) {
// Put the text in the attached EditText into a safe, saved state before switching to a
// new activity that will also use the soft keyboard.
commitTyped(LastComposedWord.NOT_A_SEPARATOR);
launchSubActivity(activityClass);
}
- private void launchSubActivity(Class<? extends Activity> activityClass) {
+ private void launchSubActivity(final Class<? extends Activity> activityClass) {
Intent intent = new Intent();
intent.setClass(LatinIME.this, activityClass);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -2203,7 +2298,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
showOptionDialog(builder.create());
}
- public void showOptionDialog(AlertDialog dialog) {
+ public void showOptionDialog(final AlertDialog dialog) {
final IBinder windowToken = mKeyboardSwitcher.getMainKeyboardView().getWindowToken();
if (windowToken == null) {
return;
@@ -2223,8 +2318,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
dialog.show();
}
+ public void debugDumpStateAndCrashWithException(final String context) {
+ final StringBuilder s = new StringBuilder();
+ s.append("Target application : ").append(mTargetApplicationInfo.name)
+ .append("\nPackage : ").append(mTargetApplicationInfo.packageName)
+ .append("\nTarget app sdk version : ")
+ .append(mTargetApplicationInfo.targetSdkVersion)
+ .append("\nAttributes : ").append(mCurrentSettings.getInputAttributesDebugString())
+ .append("\nContext : ").append(context);
+ throw new RuntimeException(s.toString());
+ }
+
@Override
- protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ protected void dump(final FileDescriptor fd, final PrintWriter fout, final String[] args) {
super.dump(fd, fout, args);
final Printer p = new PrintWriterPrinter(fout);