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

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

Merge "Take space state into account for caps (A11)" into jb-mr1-dev

parents 8adc0154 90a91272
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -741,6 +741,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        // switcher.loadKeyboard; in apps like Talk, we come here when the text is sent and the
        // field gets emptied and we need to re-evaluate the shift state, but not the whole layout
        // which would be disruptive.
        // Space state must be updated before calling updateShiftState
        mKeyboardSwitcher.updateShiftState();

        mHandler.cancelUpdateSuggestionStrip();
@@ -1114,11 +1115,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        // unless needed.
        if (mWordComposer.isComposingWord()) return Constants.TextUtils.CAP_MODE_OFF;

        // TODO: This blocking IPC call is heavy. Consider doing this without using IPC calls.
        // 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, mSubtypeSwitcher.getCurrentSubtypeLocale());
        // Warning: this depends on mSpaceState, which may not be the most current value. If
        // mSpaceState gets updated later, whoever called this may need to be told about it.
        return mConnection.getCursorCapsMode(inputType, mSubtypeSwitcher.getCurrentSubtypeLocale(),
                SPACE_STATE_PHANTOM == mSpaceState);
    }

    // Factor in auto-caps and manual caps and compute the current caps mode.
@@ -1391,9 +1391,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        }
        mConnection.commitText(text, 1);
        mConnection.endBatchEdit();
        // Space state must be updated before calling updateShiftState
        mSpaceState = SPACE_STATE_NONE;
        mKeyboardSwitcher.updateShiftState();
        mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
        mSpaceState = SPACE_STATE_NONE;
        mEnteredText = text;
    }

@@ -1509,8 +1510,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        mConnection.setComposingText(batchInputText, 1);
        mExpectingUpdateSelection = true;
        mConnection.endBatchEdit();
        mKeyboardSwitcher.updateShiftState();
        // Space state must be updated before calling updateShiftState
        mSpaceState = SPACE_STATE_PHANTOM;
        mKeyboardSwitcher.updateShiftState();
    }

    private CharSequence specificTldProcessingOnTextInput(final CharSequence text) {
@@ -2019,8 +2021,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        mConnection.endBatchEdit();
        // Don't allow cancellation of manual pick
        mLastComposedWord.deactivate();
        // Space state must be updated before calling updateShiftState
        mSpaceState = SPACE_STATE_PHANTOM;
        // TODO: is this necessary?
        mKeyboardSwitcher.updateShiftState();

        // We should show the "Touch again to save" hint if the user pressed the first entry
+19 −2
Original line number Diff line number Diff line
@@ -190,7 +190,23 @@ public class RichInputConnection {
        }
    }

    public int getCursorCapsMode(final int inputType, final Locale locale) {
    /**
     * Gets the caps modes we should be in after this specific string.
     *
     * This returns a bit set of TextUtils#CAP_MODE_*, masked by the inputType argument.
     * This method also supports faking an additional space after the string passed in argument,
     * to support cases where a space will be added automatically, like in phantom space
     * state for example.
     * Note that for English, we are using American typography rules (which are not specific to
     * American English, it's just the most common set of rules for English).
     *
     * @param inputType a mask of the caps modes to test for.
     * @param locale what language should be considered.
     * @param hasSpaceBefore if we should consider there should be a space after the string.
     * @return the caps modes that should be on as a set of bits
     */
    public int getCursorCapsMode(final int inputType, final Locale locale,
            final boolean hasSpaceBefore) {
        mIC = mParent.getCurrentInputConnection();
        if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
        if (!TextUtils.isEmpty(mComposingText)) return Constants.TextUtils.CAP_MODE_OFF;
@@ -205,7 +221,8 @@ public class RichInputConnection {
        }
        // This never calls InputConnection#getCapsMode - in fact, it's a static method that
        // never blocks or initiates IPC.
        return StringUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale);
        return StringUtils.getCapsMode(mCommittedTextBeforeComposingText, inputType, locale,
                hasSpaceBefore);
    }

    public CharSequence getTextBeforeCursor(final int i, final int j) {
+13 −6
Original line number Diff line number Diff line
@@ -197,13 +197,15 @@ public final class StringUtils {
     * {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
     * {@link TextUtils#CAP_MODE_SENTENCES}.
     * @param locale The locale to consider for capitalization rules
     * @param hasSpaceBefore Whether we should consider there is a space inserted at the end of cs
     *
     * @return Returns the actual capitalization modes that can be in effect
     * at the current position, which is any combination of
     * {@link TextUtils#CAP_MODE_CHARACTERS}, {@link TextUtils#CAP_MODE_WORDS}, and
     * {@link TextUtils#CAP_MODE_SENTENCES}.
     */
    public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale) {
    public static int getCapsMode(final CharSequence cs, final int reqModes, final Locale locale,
            final boolean hasSpaceBefore) {
        // Quick description of what we want to do:
        // CAP_MODE_CHARACTERS is always on.
        // CAP_MODE_WORDS is on if there is some whitespace before the cursor.
@@ -230,6 +232,9 @@ public final class StringUtils {
        // single quote since they aren't start punctuation in the unicode sense, but should still
        // be skipped for English. TODO: does this depend on the language?
        int i;
        if (hasSpaceBefore) {
            i = cs.length() + 1;
        } else {
            for (i = cs.length(); i > 0; i--) {
                final char c = cs.charAt(i - 1);
                if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
@@ -237,6 +242,7 @@ public final class StringUtils {
                    break;
                }
            }
        }

        // We are now on the character that precedes any starting punctuation, so in the most
        // frequent case this will be whitespace or a letter, although it may occasionally be a
@@ -247,6 +253,7 @@ public final class StringUtils {
        // if the first char that's not a space or tab is a start of line (as in, either \n or
        // start of text).
        int j = i;
        if (hasSpaceBefore) --j;
        while (j > 0 && Character.isWhitespace(cs.charAt(j - 1))) {
            j--;
        }
+37 −30
Original line number Diff line number Diff line
@@ -93,22 +93,24 @@ public class StringUtilsTests extends AndroidTestCase {
    }

    private void onePathForCaps(final CharSequence cs, final int expectedResult, final int mask,
            final Locale l) {
            final Locale l, final boolean hasSpaceBefore) {
        int oneTimeResult = expectedResult & mask;
        assertEquals("After >" + cs + "<", oneTimeResult, StringUtils.getCapsMode(cs, mask, l));
        assertEquals("After >" + cs + "<", oneTimeResult,
                StringUtils.getCapsMode(cs, mask, l, hasSpaceBefore));
    }

    private void allPathsForCaps(final CharSequence cs, final int expectedResult, final Locale l) {
    private void allPathsForCaps(final CharSequence cs, final int expectedResult, final Locale l,
            final boolean hasSpaceBefore) {
        final int c = TextUtils.CAP_MODE_CHARACTERS;
        final int w = TextUtils.CAP_MODE_WORDS;
        final int s = TextUtils.CAP_MODE_SENTENCES;
        onePathForCaps(cs, expectedResult, c | w | s, l);
        onePathForCaps(cs, expectedResult, w | s, l);
        onePathForCaps(cs, expectedResult, c | s, l);
        onePathForCaps(cs, expectedResult, c | w, l);
        onePathForCaps(cs, expectedResult, c, l);
        onePathForCaps(cs, expectedResult, w, l);
        onePathForCaps(cs, expectedResult, s, l);
        onePathForCaps(cs, expectedResult, c | w | s, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, w | s, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, c | s, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, c | w, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, c, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, w, l, hasSpaceBefore);
        onePathForCaps(cs, expectedResult, s, l, hasSpaceBefore);
    }

    public void testGetCapsMode() {
@@ -116,26 +118,31 @@ public class StringUtilsTests extends AndroidTestCase {
        final int w = TextUtils.CAP_MODE_WORDS;
        final int s = TextUtils.CAP_MODE_SENTENCES;
        Locale l = Locale.ENGLISH;
        allPathsForCaps("", c | w | s, l);
        allPathsForCaps("Word", c, l);
        allPathsForCaps("Word.", c, l);
        allPathsForCaps("Word ", c | w, l);
        allPathsForCaps("Word. ", c | w | s, l);
        allPathsForCaps("Word..", c, l);
        allPathsForCaps("Word.. ", c | w | s, l);
        allPathsForCaps("Word... ", c | w | s, l);
        allPathsForCaps("Word ... ", c | w | s, l);
        allPathsForCaps("Word . ", c | w, l);
        allPathsForCaps("In the U.S ", c | w, l);
        allPathsForCaps("In the U.S. ", c | w, l);
        allPathsForCaps("Some stuff (e.g. ", c | w, l);
        allPathsForCaps("In the U.S.. ", c | w | s, l);
        allPathsForCaps("\"Word.\" ", c | w | s, l);
        allPathsForCaps("\"Word\". ", c | w | s, l);
        allPathsForCaps("\"Word\" ", c | w, l);
        allPathsForCaps("", c | w | s, l, false);
        allPathsForCaps("Word", c, l, false);
        allPathsForCaps("Word.", c, l, false);
        allPathsForCaps("Word ", c | w, l, false);
        allPathsForCaps("Word. ", c | w | s, l, false);
        allPathsForCaps("Word..", c, l, false);
        allPathsForCaps("Word.. ", c | w | s, l, false);
        allPathsForCaps("Word... ", c | w | s, l, false);
        allPathsForCaps("Word ... ", c | w | s, l, false);
        allPathsForCaps("Word . ", c | w, l, false);
        allPathsForCaps("In the U.S ", c | w, l, false);
        allPathsForCaps("In the U.S. ", c | w, l, false);
        allPathsForCaps("Some stuff (e.g. ", c | w, l, false);
        allPathsForCaps("In the U.S.. ", c | w | s, l, false);
        allPathsForCaps("\"Word.\" ", c | w | s, l, false);
        allPathsForCaps("\"Word\". ", c | w | s, l, false);
        allPathsForCaps("\"Word\" ", c | w, l, false);

        // Test for phantom space
        allPathsForCaps("Word", c | w, l, true);
        allPathsForCaps("Word.", c | w | s, l, true);

        l = Locale.FRENCH;
        allPathsForCaps("\"Word.\" ", c | w, l);
        allPathsForCaps("\"Word\". ", c | w | s, l);
        allPathsForCaps("\"Word\" ", c | w, l);
        allPathsForCaps("\"Word.\" ", c | w, l, false);
        allPathsForCaps("\"Word\". ", c | w | s, l, false);
        allPathsForCaps("\"Word\" ", c | w, l, false);
    }
}