SubtypeLocale.java revision 78173bdf535e38a4f9c3bcc8038151de86071728
1e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka/*
2e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project
3e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka *
4e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
5e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * you may not use this file except in compliance with the License.
6e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * You may obtain a copy of the License at
7e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka *
8e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
9e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka *
10e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
11e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
12e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * See the License for the specific language governing permissions and
14e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * limitations under the License.
15e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka */
16e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka
17e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokapackage com.android.inputmethod.latin;
18e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka
191cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaokaimport static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
201cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka
21e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport android.content.Context;
22e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport android.content.res.Resources;
238abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaokaimport android.view.inputmethod.InputMethodSubtype;
248abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka
25f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaokaimport java.util.HashMap;
26e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport java.util.Locale;
27e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka
28e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokapublic class SubtypeLocale {
29c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka    private static final String TAG = SubtypeLocale.class.getSimpleName();
30c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka
313bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka    // Special language code to represent "no language".
32a58ebc73ae3eb2783713c471d8abb348c7dfc8daTadashi G. Takaoka    public static final String NO_LANGUAGE = "zz";
333bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka
34f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // Exceptional locales to display name map.
35f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    private static final HashMap<String, String> sExceptionalDisplayNamesMap =
36f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka            new HashMap<String, String>();
378abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka
38e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka    private SubtypeLocale() {
39e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka        // Intentional empty constructor for utility class.
40e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka    }
41e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka
42e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka    public static void init(Context context) {
43e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka        final Resources res = context.getResources();
44f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final String[] locales = res.getStringArray(R.array.subtype_locale_exception_keys);
45f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final String[] displayNames = res.getStringArray(R.array.subtype_locale_exception_values);
46f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        for (int i = 0; i < locales.length; i++) {
47f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka            sExceptionalDisplayNamesMap.put(locales[i], displayNames[i]);
48e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka        }
493bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka    }
503bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka
51f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // Get InputMethodSubtype's display name in its locale.
52f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //        isAdditionalSubtype (T=true, F=false)
53f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // locale layout | Short  Middle      Full
54f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // ------ ------ - ---- --------- -----------------
55f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  en_US qwerty F  En  English   English (US)      exception
56f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  en_GB qwerty F  En  English   English (UK)      exception
57f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  fr    azerty F  Fr  Français  Français
58f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  fr_CA qwerty F  Fr  Français  Français (Canada)
59f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  de    qwertz F  De  Deutsch   Deutsch
60f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  zz    qwerty F      QWERTY    QWERTY
61f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  fr    qwertz T  Fr  Français  Français (QWERTZ)
62f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  de    qwerty T  De  Deutsch   Deutsch (QWERTY)
63c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka    //  en_US azerty T  En  English   English (US) (AZERTY)
64f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    //  zz    azerty T      AZERTY    AZERTY
65f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka
66f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // Get InputMethodSubtype's full display name in its locale.
67f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static String getFullDisplayName(InputMethodSubtype subtype) {
68f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        if (isNoLanguage(subtype)) {
69bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka            return getKeyboardLayoutSetDisplayName(subtype);
703bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka        }
71f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka
72c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka        final String exceptionalValue = sExceptionalDisplayNamesMap.get(subtype.getLocale());
73c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka
74f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final Locale locale = getSubtypeLocale(subtype);
75f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        if (AdditionalSubtype.isAdditionalSubtype(subtype)) {
76c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            final String language = (exceptionalValue != null) ? exceptionalValue
77c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka                    : StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
78c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            final String layout = getKeyboardLayoutSetDisplayName(subtype);
79c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            return String.format("%s (%s)", language, layout);
803bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka        }
81c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka
82c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka        if (exceptionalValue != null) {
83c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            return exceptionalValue;
84c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka        }
85c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka
86f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
873bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka    }
883bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka
89f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // Get InputMethodSubtype's middle display name in its locale.
90f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static String getMiddleDisplayName(InputMethodSubtype subtype) {
91f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        if (isNoLanguage(subtype)) {
92bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka            return getKeyboardLayoutSetDisplayName(subtype);
933bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka        }
94f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final Locale locale = getSubtypeLocale(subtype);
95f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
963bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka    }
973bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka
98f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    // Get InputMethodSubtype's short display name in its locale.
99f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static String getShortDisplayName(InputMethodSubtype subtype) {
100f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        if (isNoLanguage(subtype)) {
101f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka            return "";
1023bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka        }
103f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final Locale locale = getSubtypeLocale(subtype);
104f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return StringUtils.toTitleCase(locale.getLanguage(), locale);
105cb389ef0d6e6eec737c249e1729c2a2cdc30f341Tadashi G. Takaoka    }
1068abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka
107f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static boolean isNoLanguage(InputMethodSubtype subtype) {
108f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final String localeString = subtype.getLocale();
109f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return localeString.equals(NO_LANGUAGE);
1108abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka    }
1118abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka
112f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static Locale getSubtypeLocale(InputMethodSubtype subtype) {
113f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        final String localeString = subtype.getLocale();
114f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return LocaleUtils.constructLocaleFromString(localeString);
115f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    }
116f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka
117bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka    public static String getKeyboardLayoutSetDisplayName(InputMethodSubtype subtype) {
11878173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka        final String layoutName = getKeyboardLayoutSetName(subtype);
11978173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka        // TODO: This hack should be removed.
12078173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka        if (layoutName.equals(AdditionalSubtype.DVORAK)) {
12178173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka            return StringUtils.toTitleCase(layoutName, Locale.US);
12278173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka        }
12378173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka        return layoutName.toUpperCase();
124bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka    }
125bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka
126f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka    public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) {
1271cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka        final String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET);
1288abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka        // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is
1298abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka        // fixed.
130c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka        if (keyboardLayoutSet == null) {
131c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            android.util.Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " +
132b9fca7a192f3e448220fe79ea89d307f47b0d6b8Tadashi G. Takaoka                    "locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue());
133c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka            return AdditionalSubtype.QWERTY;
134c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka        }
135f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka        return keyboardLayoutSet;
1368abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka    }
137e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka}
138