Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50545309 authored by Jean Chalard's avatar Jean Chalard Committed by Android (Google) Code Review
Browse files

Merge "[IL122] Put the code, x and y in the transaction"

parents dbe531ef 29881854
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -30,12 +30,25 @@ public class InputTransaction {
    public static final int SHIFT_UPDATE_LATER = 2;
    public static final int SHIFT_UPDATE_LATER = 2;


    // Initial conditions
    // Initial conditions
    // If the key inserts a code point, mKeyCode is always equal to the code points. Otherwise,
    // it's always a code that may not be a code point, typically a negative number.
    public final int mKeyCode;
    public final int mX; // Pressed x-coordinate, or one of Constants.*_COORDINATE
    public final int mY; // Pressed y-coordinate, or one of Constants.*_COORDINATE
    public final long mTimestamp;
    public final int mSpaceState;
    public final int mShiftState;
    public final int mShiftState;


    // Outputs
    // Outputs
    private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
    private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;


    public InputTransaction(final int shiftState) {
    public InputTransaction(final int keyCode, final int x, final int y, final long timestamp,
            final int spaceState, final int shiftState) {
        mKeyCode = keyCode;
        mX = x;
        mY = y;
        mTimestamp = timestamp;
        mSpaceState = spaceState;
        mShiftState = shiftState;
        mShiftState = shiftState;
    }
    }


+2 −2
Original line number Original line Diff line number Diff line
@@ -323,7 +323,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
    }
    }


    // Note that we need primaryCode argument because the keyboard may in shifted state and the
    // Note that we need primaryCode argument because the keyboard may in shifted state and the
    // primaryCode is different from {@link Key#mCode}.
    // primaryCode is different from {@link Key#mKeyCode}.
    private void callListenerOnCodeInput(final Key key, final int primaryCode, final int x,
    private void callListenerOnCodeInput(final Key key, final int primaryCode, final int x,
            final int y, final long eventTime) {
            final int y, final long eventTime) {
        final boolean ignoreModifierKey = mIsInDraggingFinger && key.isModifier();
        final boolean ignoreModifierKey = mIsInDraggingFinger && key.isModifier();
@@ -360,7 +360,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
    }
    }


    // Note that we need primaryCode argument because the keyboard may be in shifted state and the
    // Note that we need primaryCode argument because the keyboard may be in shifted state and the
    // primaryCode is different from {@link Key#mCode}.
    // primaryCode is different from {@link Key#mKeyCode}.
    private void callListenerOnRelease(final Key key, final int primaryCode,
    private void callListenerOnRelease(final Key key, final int primaryCode,
            final boolean withSliding) {
            final boolean withSliding) {
        // See the comment at {@link #callListenerOnPressAndCheckKeyboardLayoutChange(Key}}.
        // See the comment at {@link #callListenerOnPressAndCheckKeyboardLayoutChange(Key}}.
+1 −0
Original line number Original line Diff line number Diff line
@@ -144,6 +144,7 @@ public final class Constants {


    public static final int NOT_A_CODE = -1;
    public static final int NOT_A_CODE = -1;
    public static final int NOT_A_CURSOR_POSITION = -1;
    public static final int NOT_A_CURSOR_POSITION = -1;
    // TODO: replace the following constants with state in InputTransaction?
    public static final int NOT_A_COORDINATE = -1;
    public static final int NOT_A_COORDINATE = -1;
    public static final int SUGGESTION_STRIP_COORDINATE = -2;
    public static final int SUGGESTION_STRIP_COORDINATE = -2;
    public static final int SPELL_CHECKER_COORDINATE = -3;
    public static final int SPELL_CHECKER_COORDINATE = -3;
+77 −83
Original line number Original line Diff line number Diff line
@@ -361,38 +361,33 @@ public final class InputLogic {
            final SettingsValues settingsValues,
            final SettingsValues settingsValues,
            // TODO: remove these two arguments
            // TODO: remove these two arguments
            final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) {
            final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) {
        final InputTransaction inputTransaction = new InputTransaction(code, x, y,
                SystemClock.uptimeMillis(), mSpaceState,
                getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()));
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
            ResearchLogger.latinIME_onCodeInput(code, x, y);
            ResearchLogger.latinIME_onCodeInput(inputTransaction.mKeyCode,
                    inputTransaction.mX, inputTransaction.mY);
        }
        }
        final long when = SystemClock.uptimeMillis();
        if (inputTransaction.mKeyCode != Constants.CODE_DELETE
        final InputTransaction inputTransaction = new InputTransaction(
                || inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
                getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()));
        if (code != Constants.CODE_DELETE
                || when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
            mDeleteCount = 0;
            mDeleteCount = 0;
        }
        }
        mLastKeyTime = when;
        mLastKeyTime = inputTransaction.mTimestamp;
        mConnection.beginBatchEdit();
        mConnection.beginBatchEdit();
        // 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()) {
        if (!mWordComposer.isComposingWord()) {
            mIsAutoCorrectionIndicatorOn = false;
            mIsAutoCorrectionIndicatorOn = false;
        }
        }


        // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
        // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
        if (code != Constants.CODE_SPACE) {
        if (inputTransaction.mKeyCode != Constants.CODE_SPACE) {
            handler.cancelDoubleSpacePeriodTimer();
            handler.cancelDoubleSpacePeriodTimer();
        }
        }


        boolean didAutoCorrect = false;
        boolean didAutoCorrect = false;
        switch (code) {
        switch (inputTransaction.mKeyCode) {
        case Constants.CODE_DELETE:
        case Constants.CODE_DELETE:
            handleBackspace(settingsValues, spaceState, inputTransaction, handler);
            handleBackspace(settingsValues, inputTransaction, handler);
            LatinImeLogger.logOnDelete(x, y);
            LatinImeLogger.logOnDelete(inputTransaction.mX, inputTransaction.mY);
            break;
            break;
        case Constants.CODE_SHIFT:
        case Constants.CODE_SHIFT:
            performRecapitalization(settingsValues);
            performRecapitalization(settingsValues);
@@ -450,29 +445,31 @@ public final class InputLogic {
            } else {
            } else {
                // No action label, and the action from imeOptions is NONE: this is a regular
                // No action label, and the action from imeOptions is NONE: this is a regular
                // enter key that should input a carriage return.
                // enter key that should input a carriage return.
                didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
                didAutoCorrect = handleNonSpecialCharacter(settingsValues, inputTransaction,
                        x, y, spaceState, inputTransaction, handler);
                        handler);
            }
            }
            break;
            break;
        case Constants.CODE_SHIFT_ENTER:
        case Constants.CODE_SHIFT_ENTER:
            didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
            // TODO: remove this object
                    x, y, spaceState, inputTransaction, handler);
            final InputTransaction tmpTransaction = new InputTransaction(inputTransaction.mKeyCode,
                    inputTransaction.mX, inputTransaction.mY, inputTransaction.mTimestamp,
                    inputTransaction.mSpaceState, inputTransaction.mShiftState);
            didAutoCorrect = handleNonSpecialCharacter(settingsValues, tmpTransaction, handler);
            break;
            break;
        case Constants.CODE_ALPHA_FROM_EMOJI:
        case Constants.CODE_ALPHA_FROM_EMOJI:
            // Note: Switching back from Emoji keyboard to the main keyboard is being handled in
            // Note: Switching back from Emoji keyboard to the main keyboard is being handled in
            // {@link KeyboardState#onCodeInput(int,int)}.
            // {@link KeyboardState#onCodeInput(int,int)}.
            break;
            break;
        default:
        default:
            didAutoCorrect = handleNonSpecialCharacter(settingsValues,
            didAutoCorrect = handleNonSpecialCharacter(settingsValues, inputTransaction, handler);
                    code, x, y, spaceState, inputTransaction, handler);
            break;
            break;
        }
        }
        // Reset after any single keystroke, except shift, capslock, and symbol-shift
        // Reset after any single keystroke, except shift, capslock, and symbol-shift
        if (!didAutoCorrect && code != Constants.CODE_SHIFT
        if (!didAutoCorrect && inputTransaction.mKeyCode != Constants.CODE_SHIFT
                && code != Constants.CODE_CAPSLOCK
                && inputTransaction.mKeyCode != Constants.CODE_CAPSLOCK
                && code != Constants.CODE_SWITCH_ALPHA_SYMBOL)
                && inputTransaction.mKeyCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
            mLastComposedWord.deactivate();
            mLastComposedWord.deactivate();
        if (Constants.CODE_DELETE != code) {
        if (Constants.CODE_DELETE != inputTransaction.mKeyCode) {
            mEnteredText = null;
            mEnteredText = null;
        }
        }
        mConnection.endBatchEdit();
        mConnection.endBatchEdit();
@@ -629,31 +626,27 @@ public final class InputLogic {
     * any key that results in multiple code points like the ".com" key.
     * any key that results in multiple code points like the ".com" key.
     *
     *
     * @param settingsValues The current settings values.
     * @param settingsValues The current settings values.
     * @param codePoint 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.
     * @param inputTransaction The transaction in progress.
     * @param inputTransaction The transaction in progress.
     * @return whether this caused an auto-correction to happen.
     * @return whether this caused an auto-correction to happen.
     */
     */
    private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
    private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
            final int codePoint, final int x, final int y, final int spaceState,
            final InputTransaction inputTransaction,
            final InputTransaction inputTransaction,
            // TODO: remove this argument
            // TODO: remove this argument
            final LatinIME.UIHandler handler) {
            final LatinIME.UIHandler handler) {
        mSpaceState = SpaceState.NONE;
        mSpaceState = SpaceState.NONE;
        final boolean didAutoCorrect;
        final boolean didAutoCorrect;
        if (settingsValues.isWordSeparator(codePoint)
        if (settingsValues.isWordSeparator(inputTransaction.mKeyCode)
                || Character.getType(codePoint) == Character.OTHER_SYMBOL) {
                || Character.getType(inputTransaction.mKeyCode) == Character.OTHER_SYMBOL) {
            didAutoCorrect = handleSeparator(settingsValues, codePoint,
            didAutoCorrect = handleSeparator(settingsValues,
                    Constants.SUGGESTION_STRIP_COORDINATE == x, spaceState, inputTransaction,
                    Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX, inputTransaction,
                    handler);
                    handler);
            if (settingsValues.mIsInternal) {
            if (settingsValues.mIsInternal) {
                LatinImeLoggerUtils.onSeparator((char)codePoint, x, y);
                LatinImeLoggerUtils.onSeparator((char)inputTransaction.mKeyCode,
                        inputTransaction.mX, inputTransaction.mY);
            }
            }
        } else {
        } else {
            didAutoCorrect = false;
            didAutoCorrect = false;
            if (SpaceState.PHANTOM == spaceState) {
            if (SpaceState.PHANTOM == inputTransaction.mSpaceState) {
                if (settingsValues.mIsInternal) {
                if (settingsValues.mIsInternal) {
                    if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
                    if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
                        LatinImeLoggerUtils.onAutoCorrection("", mWordComposer.getTypedWord(), " ",
                        LatinImeLoggerUtils.onAutoCorrection("", mWordComposer.getTypedWord(), " ",
@@ -669,8 +662,7 @@ public final class InputLogic {
                    commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
                    commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
                }
                }
            }
            }
            handleNonSeparator(settingsValues, codePoint, x, y, spaceState,
            handleNonSeparator(settingsValues, inputTransaction, handler);
                    inputTransaction, handler);
        }
        }
        return didAutoCorrect;
        return didAutoCorrect;
    }
    }
@@ -678,14 +670,9 @@ public final class InputLogic {
    /**
    /**
     * Handle a non-separator.
     * Handle a non-separator.
     * @param settingsValues The current settings values.
     * @param settingsValues The current settings values.
     * @param codePoint 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.
     * @param inputTransaction The transaction in progress.
     * @param inputTransaction The transaction in progress.
     */
     */
    private void handleNonSeparator(final SettingsValues settingsValues,
    private void handleNonSeparator(final SettingsValues settingsValues,
            final int codePoint, final int x, final int y, final int spaceState,
            final InputTransaction inputTransaction,
            final InputTransaction inputTransaction,
            // TODO: Remove this argument
            // TODO: Remove this argument
            final LatinIME.UIHandler handler) {
            final LatinIME.UIHandler handler) {
@@ -696,7 +683,8 @@ public final class InputLogic {


        // TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
        // TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
        // See onStartBatchInput() to see how to do it.
        // See onStartBatchInput() to see how to do it.
        if (SpaceState.PHANTOM == spaceState && !settingsValues.isWordConnector(codePoint)) {
        if (SpaceState.PHANTOM == inputTransaction.mSpaceState
                && !settingsValues.isWordConnector(inputTransaction.mKeyCode)) {
            if (isComposingWord) {
            if (isComposingWord) {
                // Sanity check
                // Sanity check
                throw new RuntimeException("Should not be composing here");
                throw new RuntimeException("Should not be composing here");
@@ -718,7 +706,7 @@ public final class InputLogic {
        if (!isComposingWord
        if (!isComposingWord
        // We only start composing if this is a word code point. Essentially that means it's a
        // We only start composing if this is a word code point. Essentially that means it's a
        // a letter or a word connector.
        // a letter or a word connector.
                && settingsValues.isWordCodePoint(codePoint)
                && settingsValues.isWordCodePoint(inputTransaction.mKeyCode)
        // We never go into composing state if suggestions are not requested.
        // We never go into composing state if suggestions are not requested.
                && settingsValues.isSuggestionsRequested() &&
                && settingsValues.isSuggestionsRequested() &&
        // In languages with spaces, we only start composing a word when we are not already
        // In languages with spaces, we only start composing a word when we are not already
@@ -729,8 +717,8 @@ public final class InputLogic {
            // the character is a single quote or a dash. The idea here is, single quote and dash
            // the character is a single quote or a dash. The idea here is, single quote and dash
            // are not separators and they should be treated as normal characters, except in the
            // are not separators and they should be treated as normal characters, except in the
            // first position where they should not start composing a word.
            // first position where they should not start composing a word.
            isComposingWord = (Constants.CODE_SINGLE_QUOTE != codePoint
            isComposingWord = (Constants.CODE_SINGLE_QUOTE != inputTransaction.mKeyCode
                    && Constants.CODE_DASH != codePoint);
                    && Constants.CODE_DASH != inputTransaction.mKeyCode);
            // Here we don't need to reset the last composed word. It will be 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
            // 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
            // it entirely and resume suggestions on the previous word, we'd like to still
@@ -738,7 +726,7 @@ public final class InputLogic {
            resetComposingState(false /* alsoResetLastComposedWord */);
            resetComposingState(false /* alsoResetLastComposedWord */);
        }
        }
        if (isComposingWord) {
        if (isComposingWord) {
            mWordComposer.add(codePoint, x, y);
            mWordComposer.add(inputTransaction.mKeyCode, inputTransaction.mX, inputTransaction.mY);
            // If it's the first letter, make note of auto-caps state
            // If it's the first letter, make note of auto-caps state
            if (mWordComposer.size() == 1) {
            if (mWordComposer.size() == 1) {
                // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
                // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
@@ -750,10 +738,10 @@ public final class InputLogic {
            mConnection.setComposingText(getTextWithUnderline(
            mConnection.setComposingText(getTextWithUnderline(
                    mWordComposer.getTypedWord()), 1);
                    mWordComposer.getTypedWord()), 1);
        } else {
        } else {
            final boolean swapWeakSpace = maybeStripSpace(settingsValues,
            final boolean swapWeakSpace = maybeStripSpace(settingsValues, inputTransaction,
                    codePoint, spaceState, Constants.SUGGESTION_STRIP_COORDINATE == x);
                    Constants.SUGGESTION_STRIP_COORDINATE == inputTransaction.mX);


            sendKeyCodePoint(settingsValues, codePoint);
            sendKeyCodePoint(settingsValues, inputTransaction.mKeyCode);


            if (swapWeakSpace) {
            if (swapWeakSpace) {
                swapSwapperAndSpace(inputTransaction);
                swapSwapperAndSpace(inputTransaction);
@@ -764,27 +752,25 @@ public final class InputLogic {
        }
        }
        handler.postUpdateSuggestionStrip();
        handler.postUpdateSuggestionStrip();
        if (settingsValues.mIsInternal) {
        if (settingsValues.mIsInternal) {
            LatinImeLoggerUtils.onNonSeparator((char)codePoint, x, y);
            LatinImeLoggerUtils.onNonSeparator((char)inputTransaction.mKeyCode, inputTransaction.mX,
                    inputTransaction.mY);
        }
        }
    }
    }


    /**
    /**
     * Handle input of a separator code point.
     * Handle input of a separator code point.
     * @param settingsValues The current settings values.
     * @param settingsValues The current settings values.
     * @param codePoint the code point associated with the key.
     * @param isFromSuggestionStrip whether this code point comes from the suggestion strip.
     * @param isFromSuggestionStrip whether this code point comes from the suggestion strip.
     * @param spaceState the space state at start of the batch input.
     * @param inputTransaction The transaction in progress.
     * @param inputTransaction The transaction in progress.
     * @return whether this caused an auto-correction to happen.
     * @return whether this caused an auto-correction to happen.
     */
     */
    private boolean handleSeparator(final SettingsValues settingsValues,
    private boolean handleSeparator(final SettingsValues settingsValues,
            final int codePoint, final boolean isFromSuggestionStrip, final int spaceState,
            final boolean isFromSuggestionStrip, final InputTransaction inputTransaction,
            final InputTransaction inputTransaction,
            // TODO: remove this argument
            // TODO: remove this argument
            final LatinIME.UIHandler handler) {
            final LatinIME.UIHandler handler) {
        boolean didAutoCorrect = false;
        boolean didAutoCorrect = false;
        // We avoid sending spaces in languages without spaces if we were composing.
        // We avoid sending spaces in languages without spaces if we were composing.
        final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
        final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == inputTransaction.mKeyCode
                && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
                && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
                && mWordComposer.isComposingWord();
                && mWordComposer.isComposingWord();
        if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
        if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
@@ -797,43 +783,47 @@ public final class InputLogic {
        if (mWordComposer.isComposingWord()) {
        if (mWordComposer.isComposingWord()) {
            if (settingsValues.mCorrectionEnabled) {
            if (settingsValues.mCorrectionEnabled) {
                final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
                final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
                        : StringUtils.newSingleCodePointString(codePoint);
                        : StringUtils.newSingleCodePointString(inputTransaction.mKeyCode);
                commitCurrentAutoCorrection(settingsValues, separator, handler);
                commitCurrentAutoCorrection(settingsValues, separator, handler);
                didAutoCorrect = true;
                didAutoCorrect = true;
            } else {
            } else {
                commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
                commitTyped(settingsValues,
                        StringUtils.newSingleCodePointString(inputTransaction.mKeyCode));
            }
            }
        }
        }


        final boolean swapWeakSpace = maybeStripSpace(settingsValues, codePoint, spaceState,
        final boolean swapWeakSpace = maybeStripSpace(settingsValues, inputTransaction,
                isFromSuggestionStrip);
                isFromSuggestionStrip);


        final boolean isInsideDoubleQuoteOrAfterDigit = Constants.CODE_DOUBLE_QUOTE == codePoint
        final boolean isInsideDoubleQuoteOrAfterDigit =
                Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
                && mConnection.isInsideDoubleQuoteOrAfterDigit();
                && mConnection.isInsideDoubleQuoteOrAfterDigit();


        final boolean needsPrecedingSpace;
        final boolean needsPrecedingSpace;
        if (SpaceState.PHANTOM != spaceState) {
        if (SpaceState.PHANTOM != inputTransaction.mSpaceState) {
            needsPrecedingSpace = false;
            needsPrecedingSpace = false;
        } else if (Constants.CODE_DOUBLE_QUOTE == codePoint) {
        } else if (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode) {
            // Double quotes behave like they are usually preceded by space iff we are
            // Double quotes behave like they are usually preceded by space iff we are
            // not inside a double quote or after a digit.
            // not inside a double quote or after a digit.
            needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
            needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
        } else {
        } else {
            needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint);
            needsPrecedingSpace =
                    settingsValues.isUsuallyPrecededBySpace(inputTransaction.mKeyCode);
        }
        }


        if (needsPrecedingSpace) {
        if (needsPrecedingSpace) {
            promotePhantomSpace(settingsValues);
            promotePhantomSpace(settingsValues);
        }
        }
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
            ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord());
            ResearchLogger.latinIME_handleSeparator(inputTransaction.mKeyCode,
                    mWordComposer.isComposingWord());
        }
        }


        if (!shouldAvoidSendingCode) {
        if (!shouldAvoidSendingCode) {
            sendKeyCodePoint(settingsValues, codePoint);
            sendKeyCodePoint(settingsValues, inputTransaction.mKeyCode);
        }
        }


        if (Constants.CODE_SPACE == codePoint) {
        if (Constants.CODE_SPACE == inputTransaction.mKeyCode) {
            if (settingsValues.isSuggestionsRequested()) {
            if (settingsValues.isSuggestionsRequested()) {
                if (maybeDoubleSpacePeriod(settingsValues, handler)) {
                if (maybeDoubleSpacePeriod(settingsValues, handler)) {
                    inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
                    inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
@@ -849,9 +839,9 @@ public final class InputLogic {
            if (swapWeakSpace) {
            if (swapWeakSpace) {
                swapSwapperAndSpace(inputTransaction);
                swapSwapperAndSpace(inputTransaction);
                mSpaceState = SpaceState.SWAP_PUNCTUATION;
                mSpaceState = SpaceState.SWAP_PUNCTUATION;
            } else if ((SpaceState.PHANTOM == spaceState
            } else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
                    && settingsValues.isUsuallyFollowedBySpace(codePoint))
                    && settingsValues.isUsuallyFollowedBySpace(inputTransaction.mKeyCode))
                    || (Constants.CODE_DOUBLE_QUOTE == codePoint
                    || (Constants.CODE_DOUBLE_QUOTE == inputTransaction.mKeyCode
                            && isInsideDoubleQuoteOrAfterDigit)) {
                            && isInsideDoubleQuoteOrAfterDigit)) {
                // If we are in phantom space state, and the user presses a separator, we want to
                // 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
                // stay in phantom space state so that the next keypress has a chance to add the
@@ -879,10 +869,9 @@ public final class InputLogic {
    /**
    /**
     * Handle a press on the backspace key.
     * Handle a press on the backspace key.
     * @param settingsValues The current settings values.
     * @param settingsValues The current settings values.
     * @param spaceState The space state at start of this batch edit.
     * @param inputTransaction The transaction in progress.
     * @param inputTransaction The transaction in progress.
     */
     */
    private void handleBackspace(final SettingsValues settingsValues, final int spaceState,
    private void handleBackspace(final SettingsValues settingsValues,
            final InputTransaction inputTransaction,
            final InputTransaction inputTransaction,
            // TODO: remove this argument
            // TODO: remove this argument
            final LatinIME.UIHandler handler) {
            final LatinIME.UIHandler handler) {
@@ -942,14 +931,14 @@ public final class InputLogic {
                // reverting any autocorrect at this point. So we can safely return.
                // reverting any autocorrect at this point. So we can safely return.
                return;
                return;
            }
            }
            if (SpaceState.DOUBLE == spaceState) {
            if (SpaceState.DOUBLE == inputTransaction.mSpaceState) {
                handler.cancelDoubleSpacePeriodTimer();
                handler.cancelDoubleSpacePeriodTimer();
                if (mConnection.revertDoubleSpacePeriod()) {
                if (mConnection.revertDoubleSpacePeriod()) {
                    // No need to reset mSpaceState, it has already be done (that's why we
                    // No need to reset mSpaceState, it has already be done (that's why we
                    // receive it as a parameter)
                    // receive it as a parameter)
                    return;
                    return;
                }
                }
            } else if (SpaceState.SWAP_PUNCTUATION == spaceState) {
            } else if (SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
                if (mConnection.revertSwapPunctuation()) {
                if (mConnection.revertSwapPunctuation()) {
                    // Likewise
                    // Likewise
                    return;
                    return;
@@ -1065,21 +1054,26 @@ public final class InputLogic {
    /*
    /*
     * Strip a trailing space if necessary and returns whether it's a swap weak space situation.
     * Strip a trailing space if necessary and returns whether it's a swap weak space situation.
     * @param settingsValues The current settings values.
     * @param settingsValues The current settings values.
     * @param codePoint The code point that is about to be inserted.
     * @param inputTransaction The transaction in progress.
     * @param spaceState The space state at start of this batch edit.
     * @param isFromSuggestionStrip Whether this code point is coming from the suggestion strip.
     * @param isFromSuggestionStrip Whether this code point is coming from the suggestion strip.
     * @return whether we should swap the space instead of removing it.
     * @return whether we should swap the space instead of removing it.
     */
     */
    private boolean maybeStripSpace(final SettingsValues settingsValues,
    private boolean maybeStripSpace(final SettingsValues settingsValues,
            final int code, final int spaceState, final boolean isFromSuggestionStrip) {
            final InputTransaction inputTransaction, final boolean isFromSuggestionStrip) {
        if (Constants.CODE_ENTER == code && SpaceState.SWAP_PUNCTUATION == spaceState) {
        if (Constants.CODE_ENTER == inputTransaction.mKeyCode &&
                SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
            mConnection.removeTrailingSpace();
            mConnection.removeTrailingSpace();
            return false;
            return false;
        }
        }
        if ((SpaceState.WEAK == spaceState || SpaceState.SWAP_PUNCTUATION == spaceState)
        if ((SpaceState.WEAK == inputTransaction.mSpaceState
                || SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState)
                && isFromSuggestionStrip) {
                && isFromSuggestionStrip) {
            if (settingsValues.isUsuallyPrecededBySpace(code)) return false;
            if (settingsValues.isUsuallyPrecededBySpace(inputTransaction.mKeyCode)) {
            if (settingsValues.isUsuallyFollowedBySpace(code)) return true;
                return false;
            }
            if (settingsValues.isUsuallyFollowedBySpace(inputTransaction.mKeyCode)) {
                return true;
            }
            mConnection.removeTrailingSpace();
            mConnection.removeTrailingSpace();
        }
        }
        return false;
        return false;