InputMethodUtilsTest.java revision fc843713bc3c5558a7288c02aabe2474264e4ca3
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;
24fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawaimport android.content.res.Resources;
2535f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawaimport android.os.Parcel;
26f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.InstrumentationTestCase;
27f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.suitebuilder.annotation.SmallTest;
282028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArrayMap;
292028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArraySet;
305d64399c51de861261267a937502c6a13c50a239Yohei Yukawaimport android.util.LocaleList;
31f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.view.inputmethod.InputMethodInfo;
32443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawaimport android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
332028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.view.inputmethod.InputMethodSubtype;
34f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
35f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport java.util.ArrayList;
36f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport java.util.List;
37bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawaimport java.util.Locale;
38b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawaimport java.util.Objects;
39f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
4035f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawapublic class InputMethodUtilsTest extends InstrumentationTestCase {
41f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_AUX = true;
42f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_DEFAULT = true;
43e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE = true;
44cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa    private static final boolean IS_ASCII_CAPABLE = true;
45e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE = true;
46bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final boolean IS_SYSTEM_READY = true;
47e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_EN = new Locale("en");
48bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final Locale LOCALE_EN_US = new Locale("en", "US");
49d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
50d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_IN = new Locale("en", "IN");
51e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI = new Locale("fi");
52e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI_FI = new Locale("fi", "FI");
53e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL = new Locale("fil");
54e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL_PH = new Locale("fil", "PH");
55e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR = new Locale("fr");
56e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
57d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_HI = new Locale("hi");
58174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_JA = new Locale("ja");
5959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
60b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
61b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
62e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_IN = new Locale("in");
63e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_ID = new Locale("id");
64174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH = new Locale("ht");
65174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
66174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
6759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
6859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_VOICE = "voice";
69e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String SUBTYPE_MODE_ANY = null;
70e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
71e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
72e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
73e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            "EnabledWhenDefaultIsNotAsciiCapable";
74f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
75f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
7659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testVoiceImes() throws Exception {
7759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
78b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
79b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
80b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
81b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
82b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
83b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
84b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
85b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
86b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
87d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
8859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
89b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
90b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
91b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
92b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
93b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
94b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
95b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
96b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
97b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
98d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
9959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
100b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
101b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
102b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
103b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
104b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
105b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
106b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
107b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
108b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
109f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
110f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
111f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
11259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testKeyboardImes() throws Exception {
11359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
114b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
115b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
116b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
117b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
118b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
11959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
12059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
121b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
122b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
123b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
124b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
125b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
12659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
12759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_IN
128b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
129b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
130b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
131b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
132b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
13359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
13459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: hi
135b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
136b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
137b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
138b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
139b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
14059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
14159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
142b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
143b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
144b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
145b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.japanese",
146b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
147b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
148b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_CN
149b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
150b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
151b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
152b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.pinyin",
153b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
154b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
155b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_TW
156b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // Note: In this case, no IME is suitable for the system locale. Hence we will pick up a
157b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // fallback IME regardless of the "default" attribute.
158b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
159b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
160b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
161b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
162b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
163f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
164f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
165589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    @SmallTest
166589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    public void testParcelable() throws Exception {
167b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final ArrayList<InputMethodInfo> originalList = getSamplePreinstalledImes("en-rUS");
168589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        final List<InputMethodInfo> clonedList = cloneViaParcel(originalList);
169589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertNotNull(clonedList);
170c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList);
171c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertNotNull(clonedClonedList);
172589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertEquals(originalList, clonedList);
173c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList, clonedClonedList);
174c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(originalList.size(), clonedList.size());
175c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList.size(), clonedClonedList.size());
176589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        for (int imeIndex = 0; imeIndex < originalList.size(); ++imeIndex) {
177c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(originalList.get(imeIndex), clonedList.get(imeIndex));
178c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(clonedList.get(imeIndex), clonedClonedList.get(imeIndex));
179589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
180589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
181589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
182e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
183e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testGetImplicitlyApplicableSubtypesLocked() throws Exception {
184e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
185e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
186e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
187e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
188e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
189e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
190e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFrCA = createDummyInputMethodSubtype("fr_CA",
191e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
192e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
193e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFr = createDummyInputMethodSubtype("fr_CA",
194e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
195e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
196e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
197e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
198e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
199e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
200e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
201e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
202e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
203e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
204e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
205e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype autoSubtype = createDummyInputMethodSubtype("auto",
206e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
207e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
208e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoJa = createDummyInputMethodSubtype("ja",
209e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
210e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
211e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype =
212e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
213e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
214e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
215e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2 =
216e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
217e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
218e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
219e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
220e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that an automatic subtype (overridesImplicitlyEnabledSubtype:true) is
221e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected no matter what locale is specified.
222e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
223622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
224e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
225e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
226e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
227e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
228e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(autoSubtype);  // overridesImplicitlyEnabledSubtype == true
229e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
230e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
231e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
232e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
233e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
234e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
235e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2365d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
237fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_US), imi);
238e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
239e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(autoSubtype, result.get(0));
240e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
241e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
242e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
243e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no no automatic subtype
244e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
245e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
246622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
247e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);  // locale == "en_US"
248e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
249e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
250e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
251e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
252e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
253e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
254e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
255e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
256e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
257e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2585d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
259fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_US), imi);
260e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnUS, result.get(0));
261e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
262e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
263e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
264e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no automatic subtype
265e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
266e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
267622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
268e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
269e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB); // locale == "en_GB"
270e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
271e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
272e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
273e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
274e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
275e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
276e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
277e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2785d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
279fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_GB), imi);
280e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
281e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnGB, result.get(0));
282e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
283e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
284e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // If there is no automatic subtype (overridesImplicitlyEnabledSubtype:true) and
285e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // any subtype whose locale is exactly equal to the specified locale in the given list,
286e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // try to find a subtype whose language is equal to the language part of the given locale.
287e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Here make sure that a subtype (locale: "fr_CA") can be found with locale: "fr".
288e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
289622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
290e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFrCA);  // locale == "fr_CA"
291e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
292e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
293e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
294e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
295e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
296e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
297e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
298e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
299e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3005d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
301fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FR), imi);
302e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
303e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
304e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
305e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Then make sure that a subtype (locale: "fr") can be found with locale: "fr_CA".
306e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
307622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
308e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFr);  // locale == "fr"
309e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
310e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
311e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
312e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
313e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
314e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
315e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
316e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
317e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3185d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
319fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FR_CA), imi);
320e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
321e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
322e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
323e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
324e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that subtypes which have "EnabledWhenDefaultIsNotAsciiCapable" in its
325e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // extra value is selected if and only if all other selected IMEs are not AsciiCapable.
326e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
327622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
328e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
329e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);    // not ASCII capable
330e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
331e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
332e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
333e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
334e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
335e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
336e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3375d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
338fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_JA_JP), imi);
339e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(3, result.size());
340e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
341e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, result.get(1));
342e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2, result.get(2));
343e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
344e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
345e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code can be handled.
346e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
347622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
348e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
349e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
350e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
351e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
352e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
353e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
354e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3555d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
356fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FIL_PH), imi);
357e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
358e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFil, result.get(0));
359e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
360e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
361e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that we never end up matching "fi" (finnish) with "fil" (filipino).
362e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Also make sure that the first subtype will be used as the last-resort candidate.
363e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
364622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
365e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
366e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
367e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
368e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
369e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
370e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
371e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
372e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3735d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
374fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FI), imi);
375e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
376e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
377e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
378e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
379e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that "in" and "id" conversion is taken into account.
380e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
381622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
382e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
383e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
384e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
385e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
386e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
387e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
388e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3895d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
390fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_IN), imi);
391e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
392e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
393e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
394e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
395622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
396e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
397e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
398e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
399e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
400e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
401e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
402e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4035d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
404fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_ID), imi);
405e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
406e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
407e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
408e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
409622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
410e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
411e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
412e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
413e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
414e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
415e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
416e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4175d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
418fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_IN), imi);
419e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
420e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
421e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
422e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
423622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
424e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
425e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
426e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
427e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
428e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
429e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
430e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
4315d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
432fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_ID), imi);
433e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
434e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
435e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
436e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
437e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
438e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
439e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testContainsSubtypeOf() throws Exception {
440e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
441e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
442e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
443e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
444e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
445e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
446e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
447e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
448e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
449e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFilPH = createDummyInputMethodSubtype("fil_PH",
450e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
451e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
452e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
453e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
454e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
455e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
456e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
457e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
458e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
459e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final boolean CHECK_COUNTRY = true;
460e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
461e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
462622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
463e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
464e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
465e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
466e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
467e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
468e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
469e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, !CHECK_COUNTRY,
470e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
471e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, CHECK_COUNTRY,
472e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
473e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
474e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
475e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
476e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
477e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
478e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
479e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
480e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
481e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
482e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
483e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
484e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
485e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
486e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, !CHECK_COUNTRY,
487e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
488e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, CHECK_COUNTRY,
489e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
490e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
491e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
492e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil") can be handled.
493e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
494622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
495e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
496e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
497e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
498e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
499e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
500e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
501e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
502e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
503e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
504e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
505e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
506e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
507e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
508e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
509e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
510e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
511e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
512e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
513e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
514e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
515e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
516e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
517e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
518e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
519e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil_PH") can be handled.
520e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
521622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
522e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFilPH);
523e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
524e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
525e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
526e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
527e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
528e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
529e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
530e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
531e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
532e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
533e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
534e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
535e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
536e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
537e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
538e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
539e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
540e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
541e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
542e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
543e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
544e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
545e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
546e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "in" can be queried with "id".
547e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
548622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
549e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
550e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
551e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
552e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
553e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
554e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
555e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
556e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
557e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
558e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
559e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
560e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
561e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
562e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
563e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
564e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
565e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "id" can be queried with "in".
566e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
567622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
568e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
569e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
570e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
571e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
572e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
573e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
574e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
575e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
576f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
577e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
578e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
579e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
580f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
581e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
582e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
583e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
584e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
58559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes,
586b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final Locale systemLocale, final boolean isSystemReady, String... expectedImeNames) {
5875d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Context context = createTargetContextWithLocales(new LocaleList(systemLocale));
5885d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final String[] actualImeNames = getPackageNames(
5895d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, preinstalledImes));
590b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertEquals(expectedImeNames.length, actualImeNames.length);
591b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < expectedImeNames.length; ++i) {
592b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            assertEquals(expectedImeNames[i], actualImeNames[i]);
593b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
59459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    }
59559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
596589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) {
597589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        Parcel p = null;
598589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        try {
599589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p = Parcel.obtain();
600589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.writeTypedList(list);
601589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.setDataPosition(0);
602589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            return p.createTypedArrayList(InputMethodInfo.CREATOR);
603589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        } finally {
604589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            if (p != null) {
605589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa                p.recycle();
606589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            }
607589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
608589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
609589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
6105d64399c51de861261267a937502c6a13c50a239Yohei Yukawa    private Context createTargetContextWithLocales(final LocaleList locales) {
6115d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Configuration resourceConfiguration = new Configuration();
6125d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        resourceConfiguration.setLocales(locales);
6135d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        return getInstrumentation()
6145d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .getTargetContext()
6155d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .createConfigurationContext(resourceConfiguration);
616bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
617bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
618fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa    private Resources getResourcesForLocales(Locale... locales) {
619fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa        return createTargetContextWithLocales(new LocaleList(locales)).getResources();
620fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa    }
621fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa
622b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private String[] getPackageNames(final ArrayList<InputMethodInfo> imis) {
623b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final String[] packageNames = new String[imis.size()];
624b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < imis.size(); ++i) {
625b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            packageNames[i] = imis.get(i).getPackageName();
626bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        }
627bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        return packageNames;
628bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
629bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
630c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
631c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected, actual);
632c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
633c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        for (int subtypeIndex = 0; subtypeIndex < expected.getSubtypeCount(); ++subtypeIndex) {
634c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype expectedSubtype = expected.getSubtypeAt(subtypeIndex);
635c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype actualSubtype = actual.getSubtypeAt(subtypeIndex);
636e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(expectedSubtype, actualSubtype);
637c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        }
638c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    }
639c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa
640e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static void verifyEquality(InputMethodSubtype expected, InputMethodSubtype actual) {
641e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected, actual);
642e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected.hashCode(), actual.hashCode());
643e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
644e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
645f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
646f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            CharSequence label, boolean isAuxIme, boolean isDefault,
647f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            List<InputMethodSubtype> subtypes) {
648f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ResolveInfo ri = new ResolveInfo();
649f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ServiceInfo si = new ServiceInfo();
650f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ApplicationInfo ai = new ApplicationInfo();
651f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.packageName = packageName;
652f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.enabled = true;
653f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.flags |= ApplicationInfo.FLAG_SYSTEM;
654f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.applicationInfo = ai;
655f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.enabled = true;
656f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.packageName = packageName;
657f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.name = name;
658f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.exported = true;
659f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.nonLocalizedLabel = label;
660f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ri.serviceInfo = si;
661f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        return new InputMethodInfo(ri, isAuxIme, "", subtypes, 1, isDefault);
662f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
663f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
664f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
665cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
666e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            boolean isAsciiCapable, boolean isEnabledWhenDefaultIsNotAsciiCapable) {
667e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
668e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final StringBuilder subtypeExtraValue = new StringBuilder();
669e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isEnabledWhenDefaultIsNotAsciiCapable) {
670e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
671e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
672e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
673e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
674e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // TODO: Remove following code. InputMethodSubtype#isAsciiCapable() has been publicly
675e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // available since API level 19 (KitKat). We no longer need to rely on extra value.
676e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isAsciiCapable) {
677e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
678e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ASCII_CAPABLE);
679e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
680e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
681443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa        return new InputMethodSubtypeBuilder()
682443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeNameResId(0)
683443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeIconResId(0)
684443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeLocale(locale)
685443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeMode(mode)
686e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                .setSubtypeExtraValue(subtypeExtraValue.toString())
687443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setIsAuxiliary(isAuxiliary)
688443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
689cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa                .setIsAsciiCapable(isAsciiCapable)
690443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .build();
691f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
692f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
69359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithDefaultVoiceIme() {
69459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
69559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
696622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
697e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
698e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
699e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
70059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
701e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
702e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
70359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultAutoVoiceIme",
70459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice0", "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes));
70559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
70659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        preinstalledImes.addAll(getImesWithoutDefaultVoiceIme());
70759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
708f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
709f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
71059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithoutDefaultVoiceIme() {
71159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
71259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
713622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
714e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
715e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
716e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
71759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
718e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
719e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
72059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0",
72159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes));
72259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
72359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
724622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
725e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
726e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
727e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
72859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
729e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
730e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
73159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1",
73259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes));
73359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
73459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
735622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
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("DummyNonDefaultVoiceIme2",
74059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes));
74159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
74259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
743622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
74459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
745e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
746e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
74759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultEnKeyboardIme",
74859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.keyboard0", "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes));
74959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
75059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
751f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
752f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
753b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static boolean contains(final String[] textList, final String textToBeChecked) {
754b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        if (textList == null) {
755b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            return false;
756b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
757b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (final String text : textList) {
758b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            if (Objects.equals(textToBeChecked, text)) {
759b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                return true;
760b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            }
761b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
762b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        return false;
763b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    }
764b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
765b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static ArrayList<InputMethodInfo> getSamplePreinstalledImes(final String localeString) {
76659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
76759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
76859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Voice IME
76959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
770b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = false;
771622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
77259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
773e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
774e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
77559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.voice",
776b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.voice", "DummyVoiceIme", IS_AUX, isDefaultIme,
77759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
77859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
77959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Hindi IME
78059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
781b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "hi", "en-rIN" }, localeString);
782622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
78359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            // TODO: This subtype should be marked as IS_ASCII_CAPABLE
78459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
785e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
786e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
78759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
788e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
789e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
79059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.hindi",
791b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.hindi", "DummyHindiIme", !IS_AUX, isDefaultIme,
79259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
79359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
794f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
79559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Pinyin IME
79659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
797b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "zh-rCN" }, localeString);
798622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
79959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
800e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
801e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
802b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.pinyin",
803b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.pinyin", "DummyPinyinIme", !IS_AUX, isDefaultIme,
80459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
80559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
806f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
807b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // a dummy Korean IME
80859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
809b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ko" }, localeString);
810622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
81159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
812e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
813e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
81459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.korean",
815b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.korean", "DummyKoreanIme", !IS_AUX, isDefaultIme,
81659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
81759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
818589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
81959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Latin IME
82059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
821b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(
822b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    new String[]{ "en-rUS", "en-rGB", "en-rIN", "en", "hi" }, localeString);
823622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
82459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
825e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
826e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
82759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
828e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
829e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
83059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", 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            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
834e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
835e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
83659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.latin",
837b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, isDefaultIme,
83859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
83959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
84059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
84159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Japanese IME
84259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
843b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ja", "ja-rJP" }, localeString);
844622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
84559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
846e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
847e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
84859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
849e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
850e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
85159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.japanese",
85259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "com.android.apps.inputmethod.japanese", "DummyJapaneseIme", !IS_AUX,
853b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    isDefaultIme, subtypes));
85459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
855d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
85659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
857d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    }
858174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
859174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    @SmallTest
860174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    public void testGetSuitableLocalesForSpellChecker() throws Exception {
861174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
862174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
863174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
864174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
865174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(0));
866174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(1));
867174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
868174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
869174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
870174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
871174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
872174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
873174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
874174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(0));
875174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
876174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
877174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
878174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
879174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
880174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
881174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
882174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
883174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(0));
884174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
885174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
886174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
887174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
888174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
889174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
890174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
891174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(4, locales.size());
892174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_IN, locales.get(0));
893174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
894174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
895174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(3));
896174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
897174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
898174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
899174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
900174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
901174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
902174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
903174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
904174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
905174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
906174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
907174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
908174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
909174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test 3-letter language code.
910174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
911174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
912174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
913174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
914174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL_PH, locales.get(0));
915174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL, locales.get(1));
916174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
917174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
918174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
919174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
920174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
921174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test variant.
922174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
923174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
924174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
925174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(6, locales.size());
926174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH_TH, locales.get(0));
927174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH, locales.get(1));
928174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH, locales.get(2));
929174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(3));
930174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(4));
931174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(5));
932174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
933174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
934174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test Locale extension.
935174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
936174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithoutVariant = LOCALE_JA_JP;
937174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithVariant = new Locale.Builder()
938174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setLocale(LOCALE_JA_JP)
939174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setExtension('x', "android")
940174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .build();
941174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertFalse(localeWithoutVariant.equals(localeWithVariant));
942174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
943174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
944174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
945174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
946174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
947174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
948174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
949174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
950174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
951174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
952174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    }
9532028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
954290e4e471b325d4afca9e36d55b54d83254b2e29Seigo Nonaka    @SmallTest
9552028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    public void testParseInputMethodsAndSubtypesString() {
9562028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Trivial cases.
9572028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9582028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString("").isEmpty());
9592028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString(null).isEmpty());
9602028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9612028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
9622028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // No subtype cases.
9632028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9642028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9652028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0");
9662028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
9672028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9682028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
9692028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9702028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9712028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9722028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0:ime1");
9732028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
9742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
9762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
9772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime1").isEmpty());
9782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9792028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
9802028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Input metho IDs and their subtypes.
9812028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9822028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9832028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0");
9842028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
9852028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9862028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
9872028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
9882028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
9892028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9902028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
9912028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
9922028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype0");
9932028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
9942028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
9952028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
9962028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
9972028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
9982028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
9992028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10002028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10012028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype1");
10022028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
10032028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10042028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
10052028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes.size());
10062028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
10072028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype1"));
10082028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10092028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10102028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10112028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10122028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0:ime1;subtype1");
10132028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10142028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10152028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10162028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10172028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes0.size());
10182028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10192028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10202028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10212028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
10222028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype1"));
10232028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10242028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10252028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10262028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10272028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype2");
10282028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10292028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10302028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10312028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10322028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10332028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10342028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10352028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10362028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10372028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
10382028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10392028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10402028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10412028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10422028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10432028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2");
10442028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
10452028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10462028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10472028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10482028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10492028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10502028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10512028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10522028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10532028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
10542028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10552028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10562028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10572028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
10582028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
10592028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
10602028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2:ime2");
10612028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(3, r.size());
10622028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
10632028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
10642028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime2"));
10652028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
10662028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
10672028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
10682028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10692028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10702028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
10712028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
10722028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
10732028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
10742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
10752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes2 = r.get("ime2");
10762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes2.isEmpty());
10772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
10782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    }
10792a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
10802a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    @SmallTest
10812a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    public void testbuildInputMethodsAndSubtypesString() {
10822a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
10832a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
10842a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
10852a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
10862a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
10872a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
10882a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
10892a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
10902a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
10912a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
10922a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
10932a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
10942a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
10952a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
10962a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0;subtype0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
10972a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
10982a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
10992a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11002a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11012a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11022a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11032a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11042a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11052a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // We do not expect what order will be used to concatenate items in
11062a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // InputMethodUtils.buildInputMethodsAndSubtypesString() hence enumerate all possible
11072a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // permutations here.
11082a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11092a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1");
11102a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0");
11112a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11122a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11132a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11142a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11152a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11162a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
11172a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11182a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11192a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11202a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0:ime1");
11212a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0");
11222a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11232a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11242a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11252a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11262a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11272a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11282a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11292a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11302a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11312a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11322a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11332a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1");
11342a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;ime0;subtype0");
11352a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11362a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11372a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11382a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11392a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11402a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11412a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11422a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11432a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11442a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
11452a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11462a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11472a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1");
11482a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1");
11492a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype0;subtype1");
11502a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype1;subtype0");
11512a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11522a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11532a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11542a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11552a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11562a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11572a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11582a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11592a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11602a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
11612a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype1");
11622a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
11632a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11642a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11652a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1;subtype1");
11662a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype1:ime0;subtype0");
11672a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11682a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11692a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11702a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
11712a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
11722a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
11732a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
11742a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
11752a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
11762a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11772a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
11782a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype2");
11792a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype3");
11802a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
11812a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
11822a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
11832a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype2;subtype3");
11842a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype2;subtype3");
11852a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype3;subtype2");
11862a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype3;subtype2");
11872a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype2;subtype3:ime0;subtype0;subtype1");
11882a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime2;subtype3;subtype2:ime0;subtype0;subtype1");
11892a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime3;subtype2;subtype3:ime0;subtype1;subtype0");
11902a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime4;subtype3;subtype2:ime0;subtype1;subtype0");
11912a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
11922a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
11932a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
11942a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    }
1195226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1196226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    @SmallTest
1197226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    public void testConstructLocaleFromString() throws Exception {
1198226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en"), InputMethodUtils.constructLocaleFromString("en"));
1199226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US"), InputMethodUtils.constructLocaleFromString("en_US"));
1200226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US", "POSIX"),
1201226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("en_US_POSIX"));
1202226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1203226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
1204226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // support three letter language codes, and used "tl" (Tagalog) as the language string for
1205226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // "fil" (Filipino).
1206226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil"), InputMethodUtils.constructLocaleFromString("tl"));
1207226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH"), InputMethodUtils.constructLocaleFromString("tl_PH"));
1208226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH", "POSIX"),
1209226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("tl_PH_POSIX"));
1210226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1211226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
1212226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a"), InputMethodUtils.constructLocaleFromString("a"));
1213226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a b c"), InputMethodUtils.constructLocaleFromString("a b c"));
1214226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en-US"), InputMethodUtils.constructLocaleFromString("en-US"));
1215226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    }
1216f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka}
1217