aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java')
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 75f4aaccd..a61305d51 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -16,15 +16,26 @@
package com.android.inputmethod.latin.inputlogic;
+import android.os.SystemClock;
+import android.view.inputmethod.EditorInfo;
+
import com.android.inputmethod.event.EventInterpreter;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LastComposedWord;
import com.android.inputmethod.latin.LatinIME;
+import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.RichInputConnection;
+import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.WordComposer;
+import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
+import com.android.inputmethod.research.ResearchLogger;
import java.util.TreeSet;
@@ -75,4 +86,182 @@ public final class InputLogic {
public void startInput(final boolean restarting) {
}
+
+ public void onCodeInput(final int primaryCode, final int x, final int y,
+ // TODO: remove these three arguments
+ final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher,
+ final SubtypeSwitcher subtypeSwitcher) {
+ if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+ ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
+ }
+ final long when = SystemClock.uptimeMillis();
+ if (primaryCode != Constants.CODE_DELETE
+ || when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
+ mDeleteCount = 0;
+ }
+ mLastKeyTime = when;
+ mConnection.beginBatchEdit();
+ final KeyboardSwitcher switcher = keyboardSwitcher;
+ // The space state depends only on the last character pressed and its own previous
+ // state. Here, we revert the space state to neutral if the key is actually modifying
+ // the input contents (any non-shift key), which is what we should do for
+ // all inputs that do not result in a special state. Each character handling is then
+ // free to override the state as they see fit.
+ final int spaceState = mSpaceState;
+ if (!mWordComposer.isComposingWord()) {
+ mIsAutoCorrectionIndicatorOn = false;
+ }
+
+ // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
+ if (primaryCode != Constants.CODE_SPACE) {
+ handler.cancelDoubleSpacePeriodTimer();
+ }
+
+ boolean didAutoCorrect = false;
+ switch (primaryCode) {
+ case Constants.CODE_DELETE:
+ mSpaceState = SpaceState.NONE;
+ handleBackspace(spaceState);
+ LatinImeLogger.logOnDelete(x, y);
+ break;
+ case Constants.CODE_SHIFT:
+ // Note: Calling back to the keyboard on Shift key is handled in
+ // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
+ final Keyboard currentKeyboard = switcher.getKeyboard();
+ if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
+ // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
+ // alphabetic shift and shift while in symbol layout.
+ handleRecapitalize();
+ }
+ break;
+ case Constants.CODE_CAPSLOCK:
+ // Note: Changing keyboard to shift lock state is handled in
+ // {@link KeyboardSwitcher#onCodeInput(int)}.
+ break;
+ case Constants.CODE_SWITCH_ALPHA_SYMBOL:
+ // Note: Calling back to the keyboard on symbol key is handled in
+ // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
+ break;
+ case Constants.CODE_SETTINGS:
+ onSettingsKeyPressed();
+ break;
+ case Constants.CODE_SHORTCUT:
+ subtypeSwitcher.switchToShortcutIME(mLatinIME);
+ break;
+ case Constants.CODE_ACTION_NEXT:
+ performEditorAction(EditorInfo.IME_ACTION_NEXT);
+ break;
+ case Constants.CODE_ACTION_PREVIOUS:
+ performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
+ break;
+ case Constants.CODE_LANGUAGE_SWITCH:
+ handleLanguageSwitchKey();
+ break;
+ case Constants.CODE_EMOJI:
+ // Note: Switching emoji keyboard is being handled in
+ // {@link KeyboardState#onCodeInput(int,int)}.
+ break;
+ case Constants.CODE_ENTER:
+ final EditorInfo editorInfo = getCurrentInputEditorInfo();
+ final int imeOptionsActionId =
+ InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo);
+ if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) {
+ // Either we have an actionLabel and we should performEditorAction with actionId
+ // regardless of its value.
+ performEditorAction(editorInfo.actionId);
+ } else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) {
+ // We didn't have an actionLabel, but we had another action to execute.
+ // EditorInfo.IME_ACTION_NONE explicitly means no action. In contrast,
+ // EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an action, so it
+ // means there should be an action and the app didn't bother to set a specific
+ // code for it - presumably it only handles one. It does not have to be treated
+ // in any specific way: anything that is not IME_ACTION_NONE should be sent to
+ // performEditorAction.
+ performEditorAction(imeOptionsActionId);
+ } else {
+ // No action label, and the action from imeOptions is NONE: this is a regular
+ // enter key that should input a carriage return.
+ didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState);
+ }
+ break;
+ case Constants.CODE_SHIFT_ENTER:
+ didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState);
+ break;
+ default:
+ didAutoCorrect = handleNonSpecialCharacter(primaryCode, x, y, spaceState);
+ break;
+ }
+ switcher.onCodeInput(primaryCode);
+ // Reset after any single keystroke, except shift, capslock, and symbol-shift
+ if (!didAutoCorrect && primaryCode != Constants.CODE_SHIFT
+ && primaryCode != Constants.CODE_CAPSLOCK
+ && primaryCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
+ mLastComposedWord.deactivate();
+ if (Constants.CODE_DELETE != primaryCode) {
+ mEnteredText = null;
+ }
+ mConnection.endBatchEdit();
+ }
+
+ /**
+ * Handle inputting a code point to the editor.
+ *
+ * Non-special keys are those that generate a single code point.
+ * This includes all letters, digits, punctuation, separators, emoji. It excludes keys that
+ * manage keyboard-related stuff like shift, language switch, settings, layout switch, or
+ * any key that results in multiple code points like the ".com" key.
+ *
+ * @param code the code point associated with the key.
+ * @param x the x-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
+ * @param y the y-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
+ * @param spaceState the space state at start of the batch input.
+ * @return whether this caused an auto-correction to happen.
+ */
+ private boolean handleNonSpecialCharacter(final int code, final int x, final int y,
+ final int spaceState) {
+ return mLatinIME.handleNonSpecialCharacter(code, x, y, spaceState);
+ }
+
+ /**
+ * Handle a press on the backspace key.
+ * @param spaceState The space state at start of this batch edit.
+ */
+ private void handleBackspace(final int spaceState) {
+ mLatinIME.handleBackspace(spaceState);
+ }
+
+ /**
+ * Handle a press on the language switch key (the "globe key")
+ */
+ private void handleLanguageSwitchKey() {
+ mLatinIME.handleLanguageSwitchKey();
+ }
+
+ /**
+ * Processes a recapitalize event.
+ */
+ private void handleRecapitalize() {
+ mLatinIME.handleRecapitalize();
+ }
+
+ /**
+ * @return the editor info for the current editor
+ */
+ private EditorInfo getCurrentInputEditorInfo() {
+ return mLatinIME.getCurrentInputEditorInfo();
+ }
+
+ /**
+ * @param actionId the action to perform
+ */
+ private void performEditorAction(final int actionId) {
+ mConnection.performEditorAction(actionId);
+ }
+
+ /**
+ * Handle a press on the settings key.
+ */
+ private void onSettingsKeyPressed() {
+ mLatinIME.onSettingsKeyPressed();
+ }
}