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

Commit 7ab7f66c authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Fix adjusting key's label/code case

With this fix, we may probably be able to revert I76c3e917 (Make
KeySpecParser case insensitive).

Bug: 6561272
Change-Id: Ic7571560d7b422ffc9a07f0acecd388e0b330d50
parent 739ff3cf
Loading
Loading
Loading
Loading
+20 −27
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.util.Arrays;
import java.util.Locale;

/**
 * Class for describing the position and characteristics of a single key in the keyboard.
@@ -240,7 +241,8 @@ public class Key {

        mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
                | row.getDefaultKeyLabelFlags();
        final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
        final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId);
        final Locale locale = params.mId.mLocale;
        int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
        String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);

@@ -276,8 +278,8 @@ public class Key {
            actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
            mMoreKeys = new MoreKeySpec[moreKeys.length];
            for (int i = 0; i < moreKeys.length; i++) {
                mMoreKeys[i] = new MoreKeySpec(adjustCaseOfStringForKeyboardId(
                        moreKeys[i], preserveCase, params.mId), params.mCodesSet);
                mMoreKeys[i] = new MoreKeySpec(
                        moreKeys[i], needsToUpperCase, locale, params.mCodesSet);
            }
        } else {
            mMoreKeys = null;
@@ -287,17 +289,17 @@ public class Key {
        if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
            mLabel = params.mId.mCustomActionLabel;
        } else {
            mLabel = adjustCaseOfStringForKeyboardId(style.getString(keyAttr,
                    R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId);
            mLabel = KeySpecParser.toUpperCaseOfStringForLocale(style.getString(keyAttr,
                    R.styleable.Keyboard_Key_keyLabel), needsToUpperCase, locale);
        }
        if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
            mHintLabel = null;
        } else {
            mHintLabel = adjustCaseOfStringForKeyboardId(style.getString(keyAttr,
                    R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId);
            mHintLabel = KeySpecParser.toUpperCaseOfStringForLocale(style.getString(keyAttr,
                    R.styleable.Keyboard_Key_keyHintLabel), needsToUpperCase, locale);
        }
        String outputText = adjustCaseOfStringForKeyboardId(style.getString(keyAttr,
                R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId);
        String outputText = KeySpecParser.toUpperCaseOfStringForLocale(style.getString(keyAttr,
                R.styleable.Keyboard_Key_keyOutputText), needsToUpperCase, locale);
        final int code = KeySpecParser.parseCode(style.getString(keyAttr,
                R.styleable.Keyboard_Key_code), params.mCodesSet, CODE_UNSPECIFIED);
        // Choose the first letter of the label as primary code if not specified.
@@ -326,12 +328,13 @@ public class Key {
                mCode = CODE_OUTPUT_TEXT;
            }
        } else {
            mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId);
            mCode = KeySpecParser.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale);
        }
        mOutputText = outputText;
        mAltCode = adjustCaseOfCodeForKeyboardId(KeySpecParser.parseCode(style.getString(keyAttr,
        mAltCode = KeySpecParser.toUpperCaseOfCodeForLocale(
                KeySpecParser.parseCode(style.getString(keyAttr,
                R.styleable.Keyboard_Key_altCode), params.mCodesSet, CODE_UNSPECIFIED),
                preserveCase, params.mId);
                needsToUpperCase, locale);
        mHashCode = computeHashCode(this);

        keyAttr.recycle();
@@ -341,26 +344,16 @@ public class Key {
        }
    }

    private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase,
            KeyboardId id) {
        if (!Keyboard.isLetterCode(code) || preserveCase) return code;
        final String text = new String(new int[] { code } , 0, 1);
        final String casedText = adjustCaseOfStringForKeyboardId(text, preserveCase, id);
        return StringUtils.codePointCount(casedText) == 1
                ? casedText.codePointAt(0) : CODE_UNSPECIFIED;
    }

    private static String adjustCaseOfStringForKeyboardId(String text, boolean preserveCase,
            KeyboardId id) {
        if (text == null || preserveCase) return text;
        switch (id.mElementId) {
    private static boolean needsToUpperCase(int labelFlags, int keyboardElementId) {
        if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
        switch (keyboardElementId) {
        case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
        case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
        case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
        case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
            return text.toUpperCase(id.mLocale);
            return true;
        default:
            return text;
            return false;
        }
    }

+32 −11
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.inputmethod.keyboard.internal;

import static com.android.inputmethod.keyboard.Keyboard.CODE_UNSPECIFIED;

import android.text.TextUtils;

import com.android.inputmethod.keyboard.Keyboard;
@@ -24,6 +26,7 @@ import com.android.inputmethod.latin.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;

/**
 * The string parser of more keys specification.
@@ -63,10 +66,14 @@ public class KeySpecParser {
        public final String mOutputText;
        public final int mIconId;

        public MoreKeySpec(final String moreKeySpec, final KeyboardCodesSet codesSet) {
            mCode = getCode(moreKeySpec, codesSet);
            mLabel = getLabel(moreKeySpec);
            mOutputText = getOutputText(moreKeySpec);
        public MoreKeySpec(final String moreKeySpec, boolean needsToUpperCase, Locale locale,
                final KeyboardCodesSet codesSet) {
            mCode = toUpperCaseOfCodeForLocale(getCode(moreKeySpec, codesSet),
                    needsToUpperCase, locale);
            mLabel = toUpperCaseOfStringForLocale(getLabel(moreKeySpec),
                    needsToUpperCase, locale);
            mOutputText = toUpperCaseOfStringForLocale(getOutputText(moreKeySpec),
                    needsToUpperCase, locale);
            mIconId = getIconId(moreKeySpec);
        }
    }
@@ -256,9 +263,8 @@ public class KeySpecParser {
        }
        if (out == null) {
            return array;
        } else {
            return out.toArray(new String[out.size()]);
        }
        return out.toArray(new String[out.size()]);
    }

    public static String[] insertAdditionalMoreKeys(String[] moreKeySpecs,
@@ -427,13 +433,12 @@ public class KeySpecParser {
        final String remain = (size - start > 0) ? text.substring(start) : null;
        if (list == null) {
            return remain != null ? new String[] { remain } : null;
        } else {
        }
        if (remain != null) {
            list.add(remain);
        }
        return list.toArray(new String[list.size()]);
    }
    }

    public static int getIntValue(String[] moreKeys, String key, int defaultValue) {
        if (moreKeys == null) {
@@ -476,4 +481,20 @@ public class KeySpecParser {
        }
        return value;
    }

    public static int toUpperCaseOfCodeForLocale(int code, boolean needsToUpperCase,
            Locale locale) {
        if (!Keyboard.isLetterCode(code) || !needsToUpperCase) return code;
        final String text = new String(new int[] { code } , 0, 1);
        final String casedText = KeySpecParser.toUpperCaseOfStringForLocale(
                text, needsToUpperCase, locale);
        return StringUtils.codePointCount(casedText) == 1
                ? casedText.codePointAt(0) : CODE_UNSPECIFIED;
    }

    public static String toUpperCaseOfStringForLocale(String text, boolean needsToUpperCase,
            Locale locale) {
        if (text == null || !needsToUpperCase) return text;
        return text.toUpperCase(locale);
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -34,9 +34,6 @@ public class KeyboardCodesSet {

    public int getCode(final String name) {
        Integer id = sNameToIdMap.get(name);
        if (id == null) {
            id = sNameToIdMap.get(name.toLowerCase());
        }
        if (id == null) throw new RuntimeException("Unknown key code: " + name);
        return mCodes[id];
    }
+10 −9
Original line number Diff line number Diff line
@@ -62,7 +62,8 @@ public class KeySpecParserTests extends AndroidTestCase {
    private void assertParser(String message, String moreKeySpec, String expectedLabel,
            String expectedOutputText, int expectedIcon, int expectedCode) {
        final String labelResolved = KeySpecParser.resolveTextReference(moreKeySpec, mTextsSet);
        final MoreKeySpec spec = new MoreKeySpec(labelResolved, mCodesSet);
        final MoreKeySpec spec = new MoreKeySpec(labelResolved, false /* needsToUpperCase */,
                Locale.US, mCodesSet);
        assertEquals(message + " [label]", expectedLabel, spec.mLabel);
        assertEquals(message + " [ouptputText]", expectedOutputText, spec.mOutputText);
        assertEquals(message + " [icon]",
@@ -149,7 +150,7 @@ public class KeySpecParserTests extends AndroidTestCase {
                "|", null, ICON_UNDEFINED, '|');
        assertParser("Single letter with code", "a|" + CODE_SETTINGS,
                "a", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Single letter with CODE", "a|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Single letter with CODE", "a|" + CODE_SETTINGS_UPPERCASE,
                "a", null, ICON_UNDEFINED, mCodeSettings);
    }

@@ -213,11 +214,11 @@ public class KeySpecParserTests extends AndroidTestCase {
                "a|c", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with code", "abc|" + CODE_SETTINGS,
                "abc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Label with CODE", "abc|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Label with CODE", "abc|" + CODE_SETTINGS_UPPERCASE,
                "abc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped label with code", "a\\|c|" + CODE_SETTINGS,
                "a|c", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped label with CODE", "a\\|c|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Escaped label with CODE", "a\\|c|" + CODE_SETTINGS_UPPERCASE,
                "a|c", null, ICON_UNDEFINED, mCodeSettings);
    }

@@ -240,19 +241,19 @@ public class KeySpecParserTests extends AndroidTestCase {
                null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
        assertParser("Label starts with bang and code", "!bc|" + CODE_SETTINGS,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Label starts with bang and CODE", "!bc|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Label starts with bang and CODE", "!bc|" + CODE_SETTINGS_UPPERCASE,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Label contains bang and code", "a!c|" + CODE_SETTINGS,
                "a!c", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Label contains bang and CODE", "a!c|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Label contains bang and CODE", "a!c|" + CODE_SETTINGS_UPPERCASE,
                "a!c", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped bang label with code", "\\!bc|" + CODE_SETTINGS,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped bang label with CODE", "\\!bc|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("Escaped bang label with CODE", "\\!bc|" + CODE_SETTINGS_UPPERCASE,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Icon with code", ICON_SETTINGS + "|" + CODE_SETTINGS,
                null, null, mSettingsIconId, mCodeSettings);
        assertParser("ICON with CODE", ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE,
        assertParserError("ICON with CODE", ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE,
                null, null, mSettingsIconId, mCodeSettings);
    }

@@ -264,7 +265,7 @@ public class KeySpecParserTests extends AndroidTestCase {

        assertParser("Action next as more key", "!text/label_next_key|!code/key_action_next",
                "Next", null, ICON_UNDEFINED, mCodeActionNext);
        assertParser("ACTION NEXT AS MORE KEY", "!TEXT/LABEL_NEXT_KEY|!CODE/KEY_ACTION_NEXT",
        assertParserError("ACTION NEXT AS MORE KEY", "!TEXT/LABEL_NEXT_KEY|!CODE/KEY_ACTION_NEXT",
                "Next", null, ICON_UNDEFINED, mCodeActionNext);

        assertParser("Popular domain",