InputMethodUtilsTest.java revision 622b44d00fdbddf6717fd8bc9515111fec71115b
1f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka/*
2f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * Copyright (C) 2013 The Android Open Source Project
3f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka *
4f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License");
5f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * you may not use this file except in compliance with the License.
6f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * You may obtain a copy of the License at
7f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka *
8f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka *      http://www.apache.org/licenses/LICENSE-2.0
9f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka *
10f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software
11f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS,
12f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * See the License for the specific language governing permissions and
14f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka * limitations under the License.
15f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka */
16f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
1735f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawapackage com.android.internal.inputmethod;
18f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
19f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.content.Context;
20f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.content.pm.ApplicationInfo;
21f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.content.pm.ResolveInfo;
22f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.content.pm.ServiceInfo;
235d64399c51de861261267a937502c6a13c50a239Yohei Yukawaimport android.content.res.Configuration;
2435f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawaimport android.os.Parcel;
25f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.InstrumentationTestCase;
26f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.suitebuilder.annotation.SmallTest;
272028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArrayMap;
282028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArraySet;
295d64399c51de861261267a937502c6a13c50a239Yohei Yukawaimport android.util.LocaleList;
30f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.view.inputmethod.InputMethodInfo;
31443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawaimport android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
322028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.view.inputmethod.InputMethodSubtype;
33f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
34f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport java.util.ArrayList;
35f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport java.util.List;
36bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawaimport java.util.Locale;
37b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawaimport java.util.Objects;
38f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
3935f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawapublic class InputMethodUtilsTest extends InstrumentationTestCase {
40f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_AUX = true;
41f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_DEFAULT = true;
42e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE = true;
43cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa    private static final boolean IS_ASCII_CAPABLE = true;
44e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE = true;
45bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final boolean IS_SYSTEM_READY = true;
46e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_EN = new Locale("en");
47bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final Locale LOCALE_EN_US = new Locale("en", "US");
48d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
49d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_IN = new Locale("en", "IN");
50e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI = new Locale("fi");
51e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI_FI = new Locale("fi", "FI");
52e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL = new Locale("fil");
53e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL_PH = new Locale("fil", "PH");
54e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR = new Locale("fr");
55e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
56d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_HI = new Locale("hi");
57174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_JA = new Locale("ja");
5859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
59b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
60b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
61e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_IN = new Locale("in");
62e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_ID = new Locale("id");
63174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH = new Locale("ht");
64174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
65174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
6659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
6759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_VOICE = "voice";
68e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String SUBTYPE_MODE_ANY = null;
69e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
70e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
71e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
72e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            "EnabledWhenDefaultIsNotAsciiCapable";
73f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
74f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
7559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testVoiceImes() throws Exception {
7659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
77b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
78b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
79b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
80b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
81b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
82b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
83b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
84b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
85b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
86d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
8759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
88b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
89b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
90b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
91b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
92b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
93b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
94b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
95b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
96b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
97d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
9859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
99b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
100b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
101b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
102b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
103b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
104b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
105b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
106b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
107b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
108f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
109f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
110f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
11159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testKeyboardImes() throws Exception {
11259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
113b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
114b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
115b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
116b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
117b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
11859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
11959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
120b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
121b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
122b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
123b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
124b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
12559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
12659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_IN
127b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
128b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
129b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
130b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
131b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
13259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
13359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: hi
134b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
135b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
136b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
137b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
138b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
13959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
14059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
141b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
142b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
143b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
144b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.japanese",
145b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
146b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
147b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_CN
148b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
149b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
150b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
151b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.pinyin",
152b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
153b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
154b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_TW
155b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // Note: In this case, no IME is suitable for the system locale. Hence we will pick up a
156b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // fallback IME regardless of the "default" attribute.
157b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
158b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
159b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
160b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
161b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
162f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
163f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
164589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    @SmallTest
165589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    public void testParcelable() throws Exception {
166b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final ArrayList<InputMethodInfo> originalList = getSamplePreinstalledImes("en-rUS");
167589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        final List<InputMethodInfo> clonedList = cloneViaParcel(originalList);
168589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertNotNull(clonedList);
169c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList);
170c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertNotNull(clonedClonedList);
171589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertEquals(originalList, clonedList);
172c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList, clonedClonedList);
173c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(originalList.size(), clonedList.size());
174c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList.size(), clonedClonedList.size());
175589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        for (int imeIndex = 0; imeIndex < originalList.size(); ++imeIndex) {
176c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(originalList.get(imeIndex), clonedList.get(imeIndex));
177c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(clonedList.get(imeIndex), clonedClonedList.get(imeIndex));
178589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
179589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
180589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
181e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
182e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testGetImplicitlyApplicableSubtypesLocked() throws Exception {
183e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
184e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
185e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
186e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
187e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
188e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
189e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFrCA = createDummyInputMethodSubtype("fr_CA",
190e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
191e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
192e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFr = createDummyInputMethodSubtype("fr_CA",
193e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
194e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
195e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
196e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
197e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
198e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
199e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
200e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
201e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
202e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
203e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
204e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype autoSubtype = createDummyInputMethodSubtype("auto",
205e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
206e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
207e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoJa = createDummyInputMethodSubtype("ja",
208e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
209e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
210e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype =
211e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
212e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
213e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
214e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2 =
215e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
216e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
217e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
218e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
219e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that an automatic subtype (overridesImplicitlyEnabledSubtype:true) is
220e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected no matter what locale is specified.
221e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
222622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
223e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
224e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
225e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
226e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
227e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(autoSubtype);  // overridesImplicitlyEnabledSubtype == true
228e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
229e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
230e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
231e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
232e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
233e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
234e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2355d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
2365d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_US))
2375d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
2385d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
239e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
240e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(autoSubtype, result.get(0));
241e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
242e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
243e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
244e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no no automatic subtype
245e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
246e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
247622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
248e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);  // locale == "en_US"
249e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
250e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
251e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
252e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
253e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
254e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
255e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
256e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
257e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
258e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2595d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
2605d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_US))
2615d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
2625d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
263e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnUS, result.get(0));
264e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
265e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
266e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
267e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no automatic subtype
268e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
269e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
270622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
271e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
272e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB); // locale == "en_GB"
273e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
274e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
275e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
276e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
277e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
278e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
279e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
280e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2815d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
2825d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_GB))
2835d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
2845d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
285e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
286e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnGB, result.get(0));
287e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
288e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
289e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // If there is no automatic subtype (overridesImplicitlyEnabledSubtype:true) and
290e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // any subtype whose locale is exactly equal to the specified locale in the given list,
291e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // try to find a subtype whose language is equal to the language part of the given locale.
292e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Here make sure that a subtype (locale: "fr_CA") can be found with locale: "fr".
293e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
294622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
295e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFrCA);  // locale == "fr_CA"
296e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
297e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
298e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
299e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
300e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
301e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
302e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
303e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
304e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3055d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
3065d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_FR))
3075d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
3085d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
309e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
310e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
311e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
312e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Then make sure that a subtype (locale: "fr") can be found with locale: "fr_CA".
313e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
314622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
315e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFr);  // locale == "fr"
316e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
317e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
318e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
319e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
320e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
321e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
322e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
323e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
324e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3255d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
3265d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_FR_CA))
3275d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
3285d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
329e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
330e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
331e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
332e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
333e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that subtypes which have "EnabledWhenDefaultIsNotAsciiCapable" in its
334e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // extra value is selected if and only if all other selected IMEs are not AsciiCapable.
335e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
336622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
337e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
338e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);    // not ASCII capable
339e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
340e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
341e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
342e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
343e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
344e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
345e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3465d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
3475d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_JA_JP))
3485d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
3495d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
350e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(3, result.size());
351e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
352e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, result.get(1));
353e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2, result.get(2));
354e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
355e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
356e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code can be handled.
357e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
358622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
359e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
360e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
361e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
362e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
363e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
364e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
365e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3665d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
3675d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_FIL_PH))
3685d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
3695d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
370e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
371e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFil, result.get(0));
372e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
373e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
374e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that we never end up matching "fi" (finnish) with "fil" (filipino).
375e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Also make sure that the first subtype will be used as the last-resort candidate.
376e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
377622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
378e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
379e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
380e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
381e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
382e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
383e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
384e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
385e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3865d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
3875d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_FI))
3885d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
3895d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
390e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
391e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
392e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
393e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
394e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that "in" and "id" conversion is taken into account.
395e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
396622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
397e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
398e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
399e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
400e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
401e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
402e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
403e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4045d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
4055d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_IN))
4065d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
4075d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
408e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
409e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
410e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
411e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
412622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
413e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
414e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
415e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
416e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
417e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
418e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
419e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4205d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
4215d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_ID))
4225d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
4235d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
424e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
425e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
426e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
427e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
428622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
429e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
430e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
431e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
432e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
433e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
434e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
435e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4365d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
4375d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_IN))
4385d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
4395d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
440e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
441e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
442e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
443e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
444622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
445e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
446e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
447e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
448e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
449e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
450e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
451e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4525d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
4535d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            createTargetContextWithLocales(new LocaleList(LOCALE_ID))
4545d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                                    .getResources(),
4555d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                            imi);
456e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
457e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
458e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
459e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
460e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
461e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
462e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testContainsSubtypeOf() throws Exception {
463e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
464e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
465e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
466e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
467e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
468e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
469e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
470e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
471e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
472e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFilPH = createDummyInputMethodSubtype("fil_PH",
473e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
474e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
475e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
476e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
477e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
478e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
479e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
480e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
481e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
482e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final boolean CHECK_COUNTRY = true;
483e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
484e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
485622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
486e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
487e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
488e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
489e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
490e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
491e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
492e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, !CHECK_COUNTRY,
493e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
494e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, CHECK_COUNTRY,
495e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
496e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
497e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
498e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
499e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
500e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
501e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
502e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
503e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
504e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
505e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
506e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
507e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
508e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
509e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, !CHECK_COUNTRY,
510e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
511e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, CHECK_COUNTRY,
512e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
513e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
514e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
515e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil") can be handled.
516e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
517622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
518e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
519e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
520e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
521e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
522e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
523e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
524e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
525e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
526e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
527e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
528e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
529e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
530e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
531e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
532e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
533e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
534e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
535e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
536e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
537e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
538e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
539e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
540e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
541e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
542e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil_PH") can be handled.
543e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
544622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
545e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFilPH);
546e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
547e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
548e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
549e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
550e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
551e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
552e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
553e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
554e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
555e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
556e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
557e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
558e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
559e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
560e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
561e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
562e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
563e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
564e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
565e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
566e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
567e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
568e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
569e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "in" can be queried with "id".
570e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
571622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
572e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
573e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
574e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
575e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
576e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
577e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
578e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
579e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
580e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
581e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
582e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
583e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
584e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
585e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
586e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
587e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
588e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "id" can be queried with "in".
589e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
590622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
591e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
592e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
593e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
594e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
595e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
596e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
597e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
598e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
599f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
600e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
601e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
602e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
603f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
604e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
605e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
606e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
607e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
60859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes,
609b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final Locale systemLocale, final boolean isSystemReady, String... expectedImeNames) {
6105d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Context context = createTargetContextWithLocales(new LocaleList(systemLocale));
6115d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final String[] actualImeNames = getPackageNames(
6125d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, preinstalledImes));
613b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertEquals(expectedImeNames.length, actualImeNames.length);
614b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < expectedImeNames.length; ++i) {
615b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            assertEquals(expectedImeNames[i], actualImeNames[i]);
616b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
61759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    }
61859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
619589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) {
620589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        Parcel p = null;
621589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        try {
622589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p = Parcel.obtain();
623589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.writeTypedList(list);
624589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.setDataPosition(0);
625589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            return p.createTypedArrayList(InputMethodInfo.CREATOR);
626589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        } finally {
627589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            if (p != null) {
628589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa                p.recycle();
629589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            }
630589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
631589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
632589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
6335d64399c51de861261267a937502c6a13c50a239Yohei Yukawa    private Context createTargetContextWithLocales(final LocaleList locales) {
6345d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Configuration resourceConfiguration = new Configuration();
6355d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        resourceConfiguration.setLocales(locales);
6365d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        return getInstrumentation()
6375d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .getTargetContext()
6385d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .createConfigurationContext(resourceConfiguration);
639bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
640bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
641b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private String[] getPackageNames(final ArrayList<InputMethodInfo> imis) {
642b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final String[] packageNames = new String[imis.size()];
643b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < imis.size(); ++i) {
644b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            packageNames[i] = imis.get(i).getPackageName();
645bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        }
646bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        return packageNames;
647bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
648bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
649c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
650c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected, actual);
651c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
652c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        for (int subtypeIndex = 0; subtypeIndex < expected.getSubtypeCount(); ++subtypeIndex) {
653c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype expectedSubtype = expected.getSubtypeAt(subtypeIndex);
654c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype actualSubtype = actual.getSubtypeAt(subtypeIndex);
655e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(expectedSubtype, actualSubtype);
656c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        }
657c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    }
658c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa
659e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static void verifyEquality(InputMethodSubtype expected, InputMethodSubtype actual) {
660e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected, actual);
661e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected.hashCode(), actual.hashCode());
662e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
663e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
664f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
665f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            CharSequence label, boolean isAuxIme, boolean isDefault,
666f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            List<InputMethodSubtype> subtypes) {
667f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ResolveInfo ri = new ResolveInfo();
668f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ServiceInfo si = new ServiceInfo();
669f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ApplicationInfo ai = new ApplicationInfo();
670f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.packageName = packageName;
671f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.enabled = true;
672f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.flags |= ApplicationInfo.FLAG_SYSTEM;
673f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.applicationInfo = ai;
674f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.enabled = true;
675f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.packageName = packageName;
676f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.name = name;
677f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.exported = true;
678f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.nonLocalizedLabel = label;
679f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ri.serviceInfo = si;
680f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        return new InputMethodInfo(ri, isAuxIme, "", subtypes, 1, isDefault);
681f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
682f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
683f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
684cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
685e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            boolean isAsciiCapable, boolean isEnabledWhenDefaultIsNotAsciiCapable) {
686e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
687e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final StringBuilder subtypeExtraValue = new StringBuilder();
688e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isEnabledWhenDefaultIsNotAsciiCapable) {
689e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
690e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
691e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
692e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
693e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // TODO: Remove following code. InputMethodSubtype#isAsciiCapable() has been publicly
694e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // available since API level 19 (KitKat). We no longer need to rely on extra value.
695e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isAsciiCapable) {
696e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
697e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ASCII_CAPABLE);
698e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
699e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
700443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa        return new InputMethodSubtypeBuilder()
701443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeNameResId(0)
702443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeIconResId(0)
703443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeLocale(locale)
704443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeMode(mode)
705e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                .setSubtypeExtraValue(subtypeExtraValue.toString())
706443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setIsAuxiliary(isAuxiliary)
707443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
708cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa                .setIsAsciiCapable(isAsciiCapable)
709443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .build();
710f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
711f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
71259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithDefaultVoiceIme() {
71359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
71459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
715622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
716e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
717e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
718e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
71959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
720e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
721e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
72259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultAutoVoiceIme",
72359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice0", "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes));
72459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
72559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        preinstalledImes.addAll(getImesWithoutDefaultVoiceIme());
72659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
727f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
728f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
72959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithoutDefaultVoiceIme() {
73059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
73159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
732622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
733e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
734e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
735e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
73659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
737e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
738e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
73959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0",
74059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes));
74159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
74259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
743622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
744e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
745e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
746e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
74759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
748e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
749e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
75059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1",
75159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes));
75259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
75359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
754622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
75559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
756e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
757e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
75859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultVoiceIme2",
75959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes));
76059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
76159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
762622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
76359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
764e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
765e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
76659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultEnKeyboardIme",
76759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.keyboard0", "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes));
76859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
76959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
770f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
771f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
772b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static boolean contains(final String[] textList, final String textToBeChecked) {
773b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        if (textList == null) {
774b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            return false;
775b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
776b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (final String text : textList) {
777b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            if (Objects.equals(textToBeChecked, text)) {
778b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                return true;
779b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            }
780b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
781b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        return false;
782b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    }
783b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
784b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static ArrayList<InputMethodInfo> getSamplePreinstalledImes(final String localeString) {
78559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
78659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
78759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Voice IME
78859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
789b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = false;
790622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
79159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
792e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
793e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
79459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.voice",
795b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.voice", "DummyVoiceIme", IS_AUX, isDefaultIme,
79659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
79759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
79859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Hindi IME
79959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
800b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "hi", "en-rIN" }, localeString);
801622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
80259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            // TODO: This subtype should be marked as IS_ASCII_CAPABLE
80359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
804e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
805e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
80659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
807e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
808e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
80959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.hindi",
810b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.hindi", "DummyHindiIme", !IS_AUX, isDefaultIme,
81159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
81259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
813f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
81459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Pinyin IME
81559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
816b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "zh-rCN" }, localeString);
817622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
81859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
819e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
820e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
821b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.pinyin",
822b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.pinyin", "DummyPinyinIme", !IS_AUX, isDefaultIme,
82359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
82459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
825f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
826b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // a dummy Korean IME
82759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
828b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ko" }, localeString);
829622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
83059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
831e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
832e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
83359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.korean",
834b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.korean", "DummyKoreanIme", !IS_AUX, isDefaultIme,
83559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
83659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
837589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
83859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Latin IME
83959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
840b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(
841b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    new String[]{ "en-rUS", "en-rGB", "en-rIN", "en", "hi" }, localeString);
842622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
84359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
844e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
845e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
84659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
847e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
848e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
84959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
850e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
851e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
85259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
853e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
854e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
85559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.latin",
856b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, isDefaultIme,
85759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
85859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
85959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
86059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Japanese IME
86159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
862b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ja", "ja-rJP" }, localeString);
863622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
86459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
865e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
866e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
86759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
868e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
869e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
87059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.japanese",
87159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "com.android.apps.inputmethod.japanese", "DummyJapaneseIme", !IS_AUX,
872b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    isDefaultIme, subtypes));
87359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
874d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
87559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
876d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    }
877174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
878174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    @SmallTest
879174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    public void testGetSuitableLocalesForSpellChecker() throws Exception {
880174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
881174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
882174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
883174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
884174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(0));
885174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(1));
886174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
887174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
888174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
889174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
890174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
891174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
892174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
893174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(0));
894174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
895174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
896174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
897174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
898174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
899174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
900174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
901174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
902174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(0));
903174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
904174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
905174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
906174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
907174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
908174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
909174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
910174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(4, locales.size());
911174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_IN, locales.get(0));
912174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
913174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
914174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(3));
915174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
916174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
917174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
918174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
919174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
920174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
921174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
922174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
923174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
924174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
925174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
926174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
927174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
928174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test 3-letter language code.
929174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
930174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
931174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
932174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
933174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL_PH, locales.get(0));
934174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL, locales.get(1));
935174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
936174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
937174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
938174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
939174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
940174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test variant.
941174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
942174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
943174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
944174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(6, locales.size());
945174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH_TH, locales.get(0));
946174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH, locales.get(1));
947174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH, locales.get(2));
948174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(3));
949174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(4));
950174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(5));
951174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
952174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
953174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test Locale extension.
954174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
955174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithoutVariant = LOCALE_JA_JP;
956174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithVariant = new Locale.Builder()
957174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setLocale(LOCALE_JA_JP)
958174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setExtension('x', "android")
959174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .build();
960174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertFalse(localeWithoutVariant.equals(localeWithVariant));
961174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
962174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
963174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
964174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
965174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
966174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
967174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
968174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
969174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
970174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
971174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    }
9722028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
973290e4e471b325d4afca9e36d55b54d83254b2e29Seigo Nonaka    @SmallTest
9742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    public void testParseInputMethodsAndSubtypesString() {
9752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Trivial cases.
9762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString("").isEmpty());
9782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString(null).isEmpty());
9792028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9802028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
9812028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // No subtype cases.
9822028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9832028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9842028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0");
9852028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
9862028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9872028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
9882028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9892028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9902028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9912028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0:ime1");
9922028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
9932028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9942028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
9952028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
9962028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime1").isEmpty());
9972028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9982028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
9992028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Input metho IDs and their subtypes.
10002028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10012028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10022028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0");
10032028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
10042028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10052028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
10062028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
10072028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
10082028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10092028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10102028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10112028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype0");
10122028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
10132028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10142028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
10152028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
10162028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
10172028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10182028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10192028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10202028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype1");
10212028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
10222028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10232028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
10242028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes.size());
10252028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
10262028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype1"));
10272028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10282028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10292028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10302028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10312028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0:ime1;subtype1");
10322028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10332028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10342028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10352028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10362028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes0.size());
10372028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10382028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10392028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10402028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
10412028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype1"));
10422028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10432028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10442028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10452028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10462028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype2");
10472028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10482028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10492028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10502028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10512028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10522028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10532028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10542028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10552028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10562028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
10572028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10582028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10592028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10602028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10612028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10622028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2");
10632028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10642028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10652028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10662028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10672028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10682028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10692028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10702028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10712028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10722028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
10732028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10792028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2:ime2");
10802028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(3, r.size());
10812028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10822028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10832028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime2"));
10842028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10852028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10862028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10872028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10882028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10892028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10902028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
10912028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10922028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10932028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10942028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes2 = r.get("ime2");
10952028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes2.isEmpty());
10962028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10972028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    }
10982a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
10992a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    @SmallTest
11002a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    public void testbuildInputMethodsAndSubtypesString() {
11012a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11022a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11032a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
11042a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11052a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11062a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11072a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
11082a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
11092a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11102a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11112a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11122a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11132a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11142a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11152a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0;subtype0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
11162a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11172a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11182a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11192a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11202a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11212a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11222a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11232a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11242a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // We do not expect what order will be used to concatenate items in
11252a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // InputMethodUtils.buildInputMethodsAndSubtypesString() hence enumerate all possible
11262a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // permutations here.
11272a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11282a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1");
11292a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0");
11302a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11312a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11322a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11332a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11342a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11352a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
11362a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11372a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11382a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11392a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0:ime1");
11402a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0");
11412a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11422a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11432a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11442a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11452a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11462a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11472a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11482a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11492a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11502a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11512a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11522a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1");
11532a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;ime0;subtype0");
11542a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11552a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11562a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11572a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11582a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11592a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11602a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11612a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11622a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11632a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11642a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11652a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11662a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1");
11672a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1");
11682a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype0;subtype1");
11692a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype1;subtype0");
11702a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11712a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11722a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11732a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11742a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11752a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11762a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11772a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11782a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11792a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
11802a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype1");
11812a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
11822a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11832a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11842a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1;subtype1");
11852a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype1:ime0;subtype0");
11862a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11872a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11882a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11892a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11902a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11912a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11922a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11932a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11942a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11952a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11962a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
11972a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype2");
11982a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype3");
11992a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
12002a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
12012a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
12022a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype2;subtype3");
12032a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype2;subtype3");
12042a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype3;subtype2");
12052a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype3;subtype2");
12062a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype2;subtype3:ime0;subtype0;subtype1");
12072a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime2;subtype3;subtype2:ime0;subtype0;subtype1");
12082a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime3;subtype2;subtype3:ime0;subtype1;subtype0");
12092a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime4;subtype3;subtype2:ime0;subtype1;subtype0");
12102a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
12112a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
12122a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
12132a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    }
1214226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1215226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    @SmallTest
1216226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    public void testConstructLocaleFromString() throws Exception {
1217226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en"), InputMethodUtils.constructLocaleFromString("en"));
1218226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US"), InputMethodUtils.constructLocaleFromString("en_US"));
1219226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US", "POSIX"),
1220226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("en_US_POSIX"));
1221226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1222226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
1223226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // support three letter language codes, and used "tl" (Tagalog) as the language string for
1224226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // "fil" (Filipino).
1225226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil"), InputMethodUtils.constructLocaleFromString("tl"));
1226226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH"), InputMethodUtils.constructLocaleFromString("tl_PH"));
1227226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH", "POSIX"),
1228226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("tl_PH_POSIX"));
1229226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1230226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
1231226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a"), InputMethodUtils.constructLocaleFromString("a"));
1232226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a b c"), InputMethodUtils.constructLocaleFromString("a b c"));
1233226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en-US"), InputMethodUtils.constructLocaleFromString("en-US"));
1234226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    }
1235f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka}
1236