Loading java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +164 −110 Original line number Diff line number Diff line Loading @@ -426,119 +426,16 @@ public final class InputLogic { cancelDoubleSpacePeriodCountdown(); } boolean didAutoCorrect = false; final boolean didAutoCorrect; if (processedEvent.isConsumed()) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = processedEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } handleConsumedEvent(inputTransaction); didAutoCorrect = false; } else if (processedEvent.isFunctionalKeyEvent()) { // A special key, like delete, shift, emoji, or the settings key. switch (processedEvent.mKeyCode) { case Constants.CODE_DELETE: handleBackspace(inputTransaction, currentKeyboardScriptId); // Backspace is a functional key, but it affects the contents of the editor. inputTransaction.setDidAffectContents(); break; case Constants.CODE_SHIFT: performRecapitalization(inputTransaction.mSettingsValues); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); if (mSuggestedWords.mIsPrediction) { inputTransaction.setRequiresUpdateSuggestions(); } break; case Constants.CODE_CAPSLOCK: // Note: Changing keyboard to shift lock state is handled in // {@link KeyboardSwitcher#onCodeInput(int)}. break; case Constants.CODE_SYMBOL_SHIFT: // Note: Calling back to the keyboard on the symbol Shift key is handled in // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. 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: // We need to switch to the shortcut IME. This is handled by LatinIME since the // input logic has no business with IME switching. 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_ALPHA_FROM_EMOJI: // Note: Switching back from Emoji keyboard to the main keyboard is being // handled in {@link KeyboardState#onCodeInput(int,int)}. break; case Constants.CODE_SHIFT_ENTER: // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, processedEvent.mKeyCode, processedEvent.mX, processedEvent.mY, processedEvent.isKeyRepeat()); final InputTransaction tmpTransaction = new InputTransaction( inputTransaction.mSettingsValues, tmpEvent, inputTransaction.mTimestamp, inputTransaction.mSpaceState, inputTransaction.mShiftState); didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler); // Shift + Enter is treated as a functional key but it results in adding a new // line, so that does affect the contents of the editor. inputTransaction.setDidAffectContents(); break; default: throw new RuntimeException("Unknown key code : " + processedEvent.mKeyCode); } } else { inputTransaction.setDidAffectContents(); switch (processedEvent.mCodePoint) { 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); didAutoCorrect = handleFunctionalEventAndReturnIfDidAutoCorrect(inputTransaction, currentKeyboardScriptId, handler); } 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(inputTransaction, handler); } break; default: didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); break; } didAutoCorrect = handleNonFunctionalEventAndReturnIfDidAutoCorrect(inputTransaction, handler); } if (!didAutoCorrect && processedEvent.mKeyCode != Constants.CODE_SHIFT && processedEvent.mKeyCode != Constants.CODE_CAPSLOCK Loading Loading @@ -685,6 +582,163 @@ public final class InputLogic { } } /** * Handle a consumed event. * * Consumed events represent events that have already been consumed, typically by the * combining chain. * * @param inputTransaction The transaction in progress. */ private void handleConsumedEvent(final InputTransaction inputTransaction) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = inputTransaction.mEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } } /** * Handle a functional key event. * * A functional event is a special key, like delete, shift, emoji, or the settings key. * 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 inputTransaction The transaction in progress. * @return whether this caused an auto-correction to happen. */ private boolean handleFunctionalEventAndReturnIfDidAutoCorrect( final InputTransaction inputTransaction, // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final Event event = inputTransaction.mEvent; boolean didAutoCorrect = false; switch (event.mKeyCode) { case Constants.CODE_DELETE: handleBackspace(inputTransaction, currentKeyboardScriptId); // Backspace is a functional key, but it affects the contents of the editor. inputTransaction.setDidAffectContents(); break; case Constants.CODE_SHIFT: performRecapitalization(inputTransaction.mSettingsValues); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); if (mSuggestedWords.mIsPrediction) { inputTransaction.setRequiresUpdateSuggestions(); } break; case Constants.CODE_CAPSLOCK: // Note: Changing keyboard to shift lock state is handled in // {@link KeyboardSwitcher#onCodeInput(int)}. break; case Constants.CODE_SYMBOL_SHIFT: // Note: Calling back to the keyboard on the symbol Shift key is handled in // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. 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: // We need to switch to the shortcut IME. This is handled by LatinIME since the // input logic has no business with IME switching. 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_ALPHA_FROM_EMOJI: // Note: Switching back from Emoji keyboard to the main keyboard is being // handled in {@link KeyboardState#onCodeInput(int,int)}. break; case Constants.CODE_SHIFT_ENTER: // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.mKeyCode, event.mX, event.mY, event.isKeyRepeat()); final InputTransaction tmpTransaction = new InputTransaction( inputTransaction.mSettingsValues, tmpEvent, inputTransaction.mTimestamp, inputTransaction.mSpaceState, inputTransaction.mShiftState); didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler); // Shift + Enter is treated as a functional key but it results in adding a new // line, so that does affect the contents of the editor. inputTransaction.setDidAffectContents(); break; default: throw new RuntimeException("Unknown key code : " + event.mKeyCode); } return didAutoCorrect; } /** * Handle an event that is not a functional event. * * These events are generally events that cause input, but in some cases they may do other * things like trigger an editor action. * * @param inputTransaction The transaction in progress. * @return whether this caused an auto-correction to happen. */ private boolean handleNonFunctionalEventAndReturnIfDidAutoCorrect( final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { final Event event = inputTransaction.mEvent; inputTransaction.setDidAffectContents(); boolean didAutoCorrect = false; switch (event.mCodePoint) { 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(inputTransaction, handler); } break; default: didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); break; } return didAutoCorrect; } /** * Handle inputting a code point to the editor. * Loading Loading
java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +164 −110 Original line number Diff line number Diff line Loading @@ -426,119 +426,16 @@ public final class InputLogic { cancelDoubleSpacePeriodCountdown(); } boolean didAutoCorrect = false; final boolean didAutoCorrect; if (processedEvent.isConsumed()) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = processedEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } handleConsumedEvent(inputTransaction); didAutoCorrect = false; } else if (processedEvent.isFunctionalKeyEvent()) { // A special key, like delete, shift, emoji, or the settings key. switch (processedEvent.mKeyCode) { case Constants.CODE_DELETE: handleBackspace(inputTransaction, currentKeyboardScriptId); // Backspace is a functional key, but it affects the contents of the editor. inputTransaction.setDidAffectContents(); break; case Constants.CODE_SHIFT: performRecapitalization(inputTransaction.mSettingsValues); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); if (mSuggestedWords.mIsPrediction) { inputTransaction.setRequiresUpdateSuggestions(); } break; case Constants.CODE_CAPSLOCK: // Note: Changing keyboard to shift lock state is handled in // {@link KeyboardSwitcher#onCodeInput(int)}. break; case Constants.CODE_SYMBOL_SHIFT: // Note: Calling back to the keyboard on the symbol Shift key is handled in // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. 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: // We need to switch to the shortcut IME. This is handled by LatinIME since the // input logic has no business with IME switching. 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_ALPHA_FROM_EMOJI: // Note: Switching back from Emoji keyboard to the main keyboard is being // handled in {@link KeyboardState#onCodeInput(int,int)}. break; case Constants.CODE_SHIFT_ENTER: // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, processedEvent.mKeyCode, processedEvent.mX, processedEvent.mY, processedEvent.isKeyRepeat()); final InputTransaction tmpTransaction = new InputTransaction( inputTransaction.mSettingsValues, tmpEvent, inputTransaction.mTimestamp, inputTransaction.mSpaceState, inputTransaction.mShiftState); didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler); // Shift + Enter is treated as a functional key but it results in adding a new // line, so that does affect the contents of the editor. inputTransaction.setDidAffectContents(); break; default: throw new RuntimeException("Unknown key code : " + processedEvent.mKeyCode); } } else { inputTransaction.setDidAffectContents(); switch (processedEvent.mCodePoint) { 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); didAutoCorrect = handleFunctionalEventAndReturnIfDidAutoCorrect(inputTransaction, currentKeyboardScriptId, handler); } 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(inputTransaction, handler); } break; default: didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); break; } didAutoCorrect = handleNonFunctionalEventAndReturnIfDidAutoCorrect(inputTransaction, handler); } if (!didAutoCorrect && processedEvent.mKeyCode != Constants.CODE_SHIFT && processedEvent.mKeyCode != Constants.CODE_CAPSLOCK Loading Loading @@ -685,6 +582,163 @@ public final class InputLogic { } } /** * Handle a consumed event. * * Consumed events represent events that have already been consumed, typically by the * combining chain. * * @param inputTransaction The transaction in progress. */ private void handleConsumedEvent(final InputTransaction inputTransaction) { // A consumed event may have text to commit and an update to the composing state, so // we evaluate both. With some combiners, it's possible than an event contains both // and we enter both of the following if clauses. final CharSequence textToCommit = inputTransaction.mEvent.getTextToCommit(); if (!TextUtils.isEmpty(textToCommit)) { mConnection.commitText(textToCommit, 1); inputTransaction.setDidAffectContents(); } if (mWordComposer.isComposingWord()) { mConnection.setComposingText(mWordComposer.getTypedWord(), 1); inputTransaction.setDidAffectContents(); inputTransaction.setRequiresUpdateSuggestions(); } } /** * Handle a functional key event. * * A functional event is a special key, like delete, shift, emoji, or the settings key. * 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 inputTransaction The transaction in progress. * @return whether this caused an auto-correction to happen. */ private boolean handleFunctionalEventAndReturnIfDidAutoCorrect( final InputTransaction inputTransaction, // TODO: remove these arguments final int currentKeyboardScriptId, final LatinIME.UIHandler handler) { final Event event = inputTransaction.mEvent; boolean didAutoCorrect = false; switch (event.mKeyCode) { case Constants.CODE_DELETE: handleBackspace(inputTransaction, currentKeyboardScriptId); // Backspace is a functional key, but it affects the contents of the editor. inputTransaction.setDidAffectContents(); break; case Constants.CODE_SHIFT: performRecapitalization(inputTransaction.mSettingsValues); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); if (mSuggestedWords.mIsPrediction) { inputTransaction.setRequiresUpdateSuggestions(); } break; case Constants.CODE_CAPSLOCK: // Note: Changing keyboard to shift lock state is handled in // {@link KeyboardSwitcher#onCodeInput(int)}. break; case Constants.CODE_SYMBOL_SHIFT: // Note: Calling back to the keyboard on the symbol Shift key is handled in // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. 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: // We need to switch to the shortcut IME. This is handled by LatinIME since the // input logic has no business with IME switching. 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_ALPHA_FROM_EMOJI: // Note: Switching back from Emoji keyboard to the main keyboard is being // handled in {@link KeyboardState#onCodeInput(int,int)}. break; case Constants.CODE_SHIFT_ENTER: // TODO: remove this object final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, event.mKeyCode, event.mX, event.mY, event.isKeyRepeat()); final InputTransaction tmpTransaction = new InputTransaction( inputTransaction.mSettingsValues, tmpEvent, inputTransaction.mTimestamp, inputTransaction.mSpaceState, inputTransaction.mShiftState); didAutoCorrect = handleNonSpecialCharacter(tmpTransaction, handler); // Shift + Enter is treated as a functional key but it results in adding a new // line, so that does affect the contents of the editor. inputTransaction.setDidAffectContents(); break; default: throw new RuntimeException("Unknown key code : " + event.mKeyCode); } return didAutoCorrect; } /** * Handle an event that is not a functional event. * * These events are generally events that cause input, but in some cases they may do other * things like trigger an editor action. * * @param inputTransaction The transaction in progress. * @return whether this caused an auto-correction to happen. */ private boolean handleNonFunctionalEventAndReturnIfDidAutoCorrect( final InputTransaction inputTransaction, // TODO: remove this argument final LatinIME.UIHandler handler) { final Event event = inputTransaction.mEvent; inputTransaction.setDidAffectContents(); boolean didAutoCorrect = false; switch (event.mCodePoint) { 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(inputTransaction, handler); } break; default: didAutoCorrect = handleNonSpecialCharacter(inputTransaction, handler); break; } return didAutoCorrect; } /** * Handle inputting a code point to the editor. * Loading