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

Commit 12903991 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Fix Serbian Latin subtype handling"

parents dabc1297 fec52199
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@
        <item>hi_ZZ</item>
        <item>sr_ZZ</item>
    </string-array>
    <string name="subtype_in_root_locale_hi_ZZ">Hinglish</string>
    <string name="subtype_in_root_locale_sr_ZZ">Srpski</string>

    <!-- Generic subtype label -->
    <string name="subtype_generic">%s</string>
+4 −7
Original line number Diff line number Diff line
@@ -214,8 +214,7 @@
    <!-- Description for Hinglish (https://en.wikipedia.org/wiki/Hinglish) keyboard subtype [CHAR LIMIT=25] -->
    <string name="subtype_hi_ZZ">Hinglish</string>
    <!-- Description for Serbian (Latin) keyboard subtype [CHAR LIMIT=25]
         (Latin) can be an abbreviation to fit in the CHAR LIMIT.
         Note for Serbian translator: this should be translated with Latin script and (Latin) should be omitted. -->
         (Latin) can be an abbreviation to fit in the CHAR LIMIT. -->
    <string name="subtype_sr_ZZ">Serbian (Latin)</string>
    <!-- Description for English (UK) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
         (UK) should be an abbreviation of United Kingdom to fit in the CHAR LIMIT.
@@ -233,16 +232,14 @@
         This should be identical to subtype_hi_ZZ aside from the trailing (%s). -->
    <string name="subtype_with_layout_hi_ZZ">Hinglish (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
    <!-- Description for Serbian (Latin) keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
         This should be identical to subtype_sr_ZZ aside from the trailing (%s).
         Note for Serbian translator: this should be translated with Latin script. -->
         This should be identical to subtype_sr_ZZ aside from the trailing (%s). -->
    <string name="subtype_with_layout_sr_ZZ">Serbian (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
    <!-- Description for "LANGUAGE_NAME" (Traditional) keyboard subtype [CHAR LIMIT=25]
         (Traditional) can be an abbreviation to fit in the CHAR LIMIT. -->
    <string name="subtype_generic_traditional"><xliff:g id="LANGUAGE_NAME" example="Nepali">%s</xliff:g> (Traditional)</string>
    <!-- Description for "LANGUAGE_NAME" (Compact) keyboard subtype [CHAR LIMIT=25]
         (Compact) can be an abbreviation to fit in the CHAR LIMIT.
         TODO: Remove translatable=false once we are settled down with the naming. -->
    <string name="subtype_generic_compact" translatable="false"><xliff:g id="LANGUAGE_NAME" example="Hindi">%s</xliff:g> (Compact)</string>
         (Compact) can be an abbreviation to fit in the CHAR LIMIT. -->
    <string name="subtype_generic_compact"><xliff:g id="LANGUAGE_NAME" example="Hindi">%s</xliff:g> (Compact)</string>
    <!-- This string is displayed in a language list that allows to choose a language for
suggestions in a software keyboard. This setting won't give suggestions in any particular
language, hence "No language".
+20 −6
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import com.android.inputmethod.latin.RichInputMethodSubtype;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;

/**
@@ -59,7 +58,8 @@ public final class SubtypeLocaleUtils {
    // Keyboard layout to subtype name resource id map.
    private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = new HashMap<>();
    // Exceptional locale whose name should be displayed in Locale.ROOT.
    static final HashSet<String> sExceptionalLocaleDisplayedInRootLocale = new HashSet<>();
    private static final HashMap<String, Integer> sExceptionalLocaleDisplayedInRootLocale =
            new HashMap<>();
    // Exceptional locale to subtype name resource id map.
    private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap = new HashMap<>();
    // Exceptional locale to subtype name with layout resource id map.
@@ -73,6 +73,8 @@ public final class SubtypeLocaleUtils {
            "string/subtype_with_layout_";
    private static final String SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX =
            "string/subtype_no_language_";
    private static final String SUBTYPE_NAME_RESOURCE_IN_ROOT_LOCALE_PREFIX =
            "string/subtype_in_root_locale_";
    // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value.
    // This is for compatibility to keep the same subtype ids as pre-JellyBean.
    private static final HashMap<String, String> sLocaleAndExtraValueToKeyboardLayoutSetMap =
@@ -117,7 +119,10 @@ public final class SubtypeLocaleUtils {
        final String[] exceptionalLocaleInRootLocale = res.getStringArray(
                R.array.subtype_locale_displayed_in_root_locale);
        for (int i = 0; i < exceptionalLocaleInRootLocale.length; i++) {
            sExceptionalLocaleDisplayedInRootLocale.add(exceptionalLocaleInRootLocale[i]);
            final String localeString = exceptionalLocaleInRootLocale[i];
            final String resourceName = SUBTYPE_NAME_RESOURCE_IN_ROOT_LOCALE_PREFIX + localeString;
            final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME);
            sExceptionalLocaleDisplayedInRootLocale.put(localeString, resId);
        }

        final String[] exceptionalLocales = res.getStringArray(
@@ -171,7 +176,7 @@ public final class SubtypeLocaleUtils {
        if (NO_LANGUAGE.equals(localeString)) {
            return sResources.getConfiguration().locale;
        }
        if (sExceptionalLocaleDisplayedInRootLocale.contains(localeString)) {
        if (sExceptionalLocaleDisplayedInRootLocale.containsKey(localeString)) {
            return Locale.ROOT;
        }
        return LocaleUtils.constructLocaleFromString(localeString);
@@ -190,7 +195,7 @@ public final class SubtypeLocaleUtils {
    public static String getSubtypeLanguageDisplayName(final String localeString) {
        final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString);
        final String languageString;
        if (sExceptionalLocaleDisplayedInRootLocale.contains(localeString)) {
        if (sExceptionalLocaleDisplayedInRootLocale.containsKey(localeString)) {
            languageString = localeString;
        } else {
            final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
@@ -205,7 +210,16 @@ public final class SubtypeLocaleUtils {
            // No language subtype should be displayed in system locale.
            return sResources.getString(R.string.subtype_no_language);
        }
        final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
        final Integer exceptionalNameResId;
        if (displayLocale.equals(Locale.ROOT)
                && sExceptionalLocaleDisplayedInRootLocale.containsKey(localeString)) {
            exceptionalNameResId = sExceptionalLocaleDisplayedInRootLocale.get(localeString);
        } else if (sExceptionalLocaleToNameIdsMap.containsKey(localeString)) {
            exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
        } else {
            exceptionalNameResId = null;
        }

        final String displayName;
        if (exceptionalNameResId != null) {
            final RunInLocale<String> getExceptionalName = new RunInLocale<String>() {
+13 −15
Original line number Diff line number Diff line
@@ -17,9 +17,7 @@
package com.android.inputmethod.keyboard;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.test.AndroidTestCase;
import android.view.ContextThemeWrapper;
import android.view.inputmethod.EditorInfo;
@@ -62,8 +60,8 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
        }
    };

    private SharedPreferences mSharedPreferences;
    private String mSavedAdditionalSubtypes;
    private RichInputMethodManager mRichImm;
    private InputMethodSubtype[] mSavedAdditionalSubtypes;
    private int mScreenMetrics;

    protected abstract int getKeyboardThemeForTests();
@@ -72,15 +70,17 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
    protected void setUp() throws Exception {
        super.setUp();
        final Context context = getContext();
        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        final Resources res = context.getResources();
        RichInputMethodManager.init(context);
        mRichImm = RichInputMethodManager.getInstance();

        // Save additional subtypes preference.
        mSavedAdditionalSubtypes = Settings.readPrefAdditionalSubtypes(mSharedPreferences, res);
        final String predefinedSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
                res.getStringArray(R.array.predefined_subtypes));
        // Reset additional subtypes to predefined ones.
        Settings.writePrefAdditionalSubtypes(mSharedPreferences, predefinedSubtypes);
        // Save and reset additional subtypes preference.
        mSavedAdditionalSubtypes = mRichImm.getAdditionalSubtypes(context);
        final InputMethodSubtype[] predefinedAdditionalSubtypes =
                AdditionalSubtypeUtils.createAdditionalSubtypesArray(
                        AdditionalSubtypeUtils.createPrefSubtypes(
                                res.getStringArray(R.array.predefined_subtypes)));
        mRichImm.setAdditionalInputMethodSubtypes(predefinedAdditionalSubtypes);

        final KeyboardTheme keyboardTheme = KeyboardTheme.searchKeyboardThemeById(
                getKeyboardThemeForTests(), KeyboardTheme.KEYBOARD_THEMES);
@@ -88,10 +88,8 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
        KeyboardLayoutSet.onKeyboardThemeChanged();

        mScreenMetrics = Settings.readScreenMetrics(res);
        RichInputMethodManager.init(context);
        final RichInputMethodManager richImm = RichInputMethodManager.getInstance();

        final InputMethodInfo imi = richImm.getInputMethodInfoOfThisIme();
        final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme();
        final int subtypeCount = imi.getSubtypeCount();
        for (int index = 0; index < subtypeCount; index++) {
            mAllSubtypesList.add(imi.getSubtypeAt(index));
@@ -101,7 +99,7 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
    @Override
    protected void tearDown() throws Exception {
        // Restore additional subtypes preference.
        Settings.writePrefAdditionalSubtypes(mSharedPreferences, mSavedAdditionalSubtypes);
        mRichImm.setAdditionalInputMethodSubtypes(mSavedAdditionalSubtypes);
        super.tearDown();
    }

+87 −30
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;

import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.RichInputMethodSubtype;

@@ -36,6 +37,7 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {

    private RichInputMethodManager mRichImm;
    private Resources mRes;
    private InputMethodSubtype mSavedAddtionalSubtypes[];

    RichInputMethodSubtype EN_US;
    RichInputMethodSubtype EN_GB;
@@ -45,6 +47,8 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
    RichInputMethodSubtype FR_CH;
    RichInputMethodSubtype DE;
    RichInputMethodSubtype DE_CH;
    RichInputMethodSubtype HI;
    RichInputMethodSubtype SR;
    RichInputMethodSubtype ZZ;
    RichInputMethodSubtype DE_QWERTY;
    RichInputMethodSubtype FR_QWERTZ;
@@ -54,17 +58,27 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
    RichInputMethodSubtype ZZ_AZERTY;
    RichInputMethodSubtype ZZ_PC;

    // This is a preliminary subtype and may not exist.
    RichInputMethodSubtype HI_LATN;
    // These are preliminary subtypes and may not exist.
    RichInputMethodSubtype HI_LATN; // Hinglish
    RichInputMethodSubtype SR_LATN; // Serbian Latin
    RichInputMethodSubtype HI_LATN_DVORAK;
    RichInputMethodSubtype SR_LATN_QWERTY;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        final Context context = getContext();
        mRes = context.getResources();
        RichInputMethodManager.init(context);
        mRichImm = RichInputMethodManager.getInstance();
        mRes = context.getResources();
        SubtypeLocaleUtils.init(context);

        // Save and reset additional subtypes
        mSavedAddtionalSubtypes = mRichImm.getAdditionalSubtypes(context);
        final InputMethodSubtype[] predefinedAddtionalSubtypes =
                AdditionalSubtypeUtils.createAdditionalSubtypesArray(
                        AdditionalSubtypeUtils.createPrefSubtypes(
                                mRes.getStringArray(R.array.predefined_subtypes)));
        mRichImm.setAdditionalInputMethodSubtypes(predefinedAddtionalSubtypes);

        final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme();
        final int subtypeCount = imi.getSubtypeCount();
@@ -89,6 +103,10 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
                Locale.GERMAN.toString(), "qwertz"));
        DE_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                "de_CH", "swiss"));
        HI = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                "hi", "hindi"));
        SR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                "sr", "south_slavic"));
        ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"));
        DE_QWERTY = new RichInputMethodSubtype(
@@ -117,7 +135,25 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
                "hi_ZZ", "qwerty");
        if (hiLatn != null) {
            HI_LATN = new RichInputMethodSubtype(hiLatn);
            HI_LATN_DVORAK = new RichInputMethodSubtype(
                    AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
                            "hi_ZZ", "dvorak"));
        }
        final InputMethodSubtype srLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                "sr_ZZ", "serbian_qwertz");
        if (srLatn != null) {
            SR_LATN = new RichInputMethodSubtype(srLatn);
            SR_LATN_QWERTY = new RichInputMethodSubtype(
                    AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
                            "sr_ZZ", "qwerty"));
        }
    }

    @Override
    protected void tearDown() throws Exception {
        // Restore additional subtypes.
        mRichImm.setAdditionalInputMethodSubtypes(mSavedAddtionalSubtypes);
        super.tearDown();
    }

    public void testAllFullDisplayNameForSpacebar() {
@@ -150,10 +186,11 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
                continue;
            }
            final Locale locale = locales[0];
            if (SubtypeLocaleUtils.sExceptionalLocaleDisplayedInRootLocale.contains(
                    locale.toString())) {
            final Locale displayLocale = SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale(
                    locale.toString());
            if (Locale.ROOT.equals(displayLocale)) {
                // Skip test because the language part of this locale string doesn't represent
                // the locale to be displayed on the spacebar (for example hi_ZZ and Hinglish).
                // the locale to be displayed on the spacebar (for example Hinglish).
                continue;
            }
            final String spacebarText = subtype.getMiddleDisplayName();
@@ -162,7 +199,7 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
                        subtype.getRawSubtype()), spacebarText);
            } else {
                assertEquals(subtypeName,
                        SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()),
                        SubtypeLocaleUtils.getSubtypeLanguageDisplayName(locale.toString()),
                        spacebarText);
            }
        }
@@ -171,7 +208,7 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
    // InputMethodSubtype's display name for spacebar text in its locale.
    //               isAdditionalSubtype (T=true, F=false)
    // locale layout         |  Middle     Full
    // ------ ------- - --------- ----------------------
    // ------ -------------- - --------- ----------------------
    //  en_US qwerty         F  English   English (US)           exception
    //  en_GB qwerty         F  English   English (UK)           exception
    //  es_US spanish        F  Español   Español (EE.UU.)       exception
@@ -180,11 +217,17 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
    //  fr_CH swiss          F  Français  Français (Suisse)
    //  de    qwertz         F  Deutsch   Deutsch
    //  de_CH swiss          F  Deutsch   Deutsch (Schweiz)
    //  hi_ZZ qwerty  F  Hinglish  Hinglish
    //  hi    hindi          F  हिन्दी       हिन्दी
    //  hi_ZZ qwerty         F  Hinglish  Hinglish               exception
    //  sr    south_slavic   F  Српски    Српски
    //  sr_ZZ serbian_qwertz F  Srpski    Srpski                 exception
    //  zz    qwerty         F  QWERTY    QWERTY
    //  fr    qwertz         T  Français  Français
    //  de    qwerty         T  Deutsch   Deutsch
    //  en_US azerty         T  English   English (US)
    //  en_GB dvorak         T  English   English (UK)
    //  hi_ZZ dvorak         T  Hinglish  Hinglish               exception
    //  sr_ZZ qwerty         T  Srpski    Srpski                 exception
    //  zz    azerty         T  AZERTY    AZERTY

    private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
@@ -198,11 +241,9 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
            assertEquals("fr_CH", "Français (Suisse)", FR_CH.getFullDisplayName());
            assertEquals("de", "Deutsch", DE.getFullDisplayName());
            assertEquals("de_CH", "Deutsch (Schweiz)", DE_CH.getFullDisplayName());
            assertEquals("hi", "हिन्दी", HI.getFullDisplayName());
            assertEquals("sr", "Српски", SR.getFullDisplayName());
            assertEquals("zz", "QWERTY", ZZ.getFullDisplayName());
            // This is a preliminary subtype and may not exist.
            if (HI_LATN != null) {
                assertEquals("hi_ZZ", "Hinglish", HI_LATN.getFullDisplayName());
            }

            assertEquals("en_US", "English", EN_US.getMiddleDisplayName());
            assertEquals("en_GB", "English", EN_GB.getMiddleDisplayName());
@@ -213,10 +254,16 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
            assertEquals("de", "Deutsch", DE.getMiddleDisplayName());
            assertEquals("de_CH", "Deutsch", DE_CH.getMiddleDisplayName());
            assertEquals("zz", "QWERTY", ZZ.getMiddleDisplayName());
            // This is a preliminary subtype and may not exist.

            // These are preliminary subtypes and may not exist.
            if (HI_LATN != null) {
                assertEquals("hi_ZZ", "Hinglish", HI_LATN.getFullDisplayName());
                assertEquals("hi_ZZ", "Hinglish", HI_LATN.getMiddleDisplayName());
            }
            if (SR_LATN != null) {
                assertEquals("sr_ZZ", "Srpski", SR_LATN.getFullDisplayName());
                assertEquals("sr_ZZ", "Srpski", SR_LATN.getMiddleDisplayName());
            }
            return null;
        }
    };
@@ -239,6 +286,16 @@ public class SpacebarLanguageUtilsTests extends AndroidTestCase {
            assertEquals("es_US colemak", "Español", ES_US_COLEMAK.getMiddleDisplayName());
            assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getMiddleDisplayName());
            assertEquals("zz pc", "PC", ZZ_PC.getMiddleDisplayName());

            // These are preliminary subtypes and may not exist.
            if (HI_LATN_DVORAK != null) {
                assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getFullDisplayName());
                assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getMiddleDisplayName());
            }
            if (SR_LATN_QWERTY != null) {
                assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getFullDisplayName());
                assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getMiddleDisplayName());
            }
            return null;
        }
    };
Loading