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;
2523cbe85610f780134cc77dd4a54732a22ed6e86eYohei Yukawaimport android.os.LocaleList;
2635f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawaimport android.os.Parcel;
27f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.InstrumentationTestCase;
28f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataokaimport android.test.suitebuilder.annotation.SmallTest;
292028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArrayMap;
302028ddaa5024dfc9844376f2032115aee360155aSeigo Nonakaimport android.util.ArraySet;
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
40e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawaimport static org.hamcrest.MatcherAssert.assertThat;
41e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawaimport static org.hamcrest.Matchers.isIn;
42e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawaimport static org.hamcrest.Matchers.not;
43e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa
4435f743713dfeb4e9138fee0f7bb6a7ee1da53521Yohei Yukawapublic class InputMethodUtilsTest extends InstrumentationTestCase {
45f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_AUX = true;
46f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static final boolean IS_DEFAULT = true;
47e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE = true;
48cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa    private static final boolean IS_ASCII_CAPABLE = true;
49e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final boolean IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE = true;
50bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final boolean IS_SYSTEM_READY = true;
51e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_EN = new Locale("en");
52bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    private static final Locale LOCALE_EN_US = new Locale("en", "US");
53d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
54d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_EN_IN = new Locale("en", "IN");
55e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI = new Locale("fi");
56e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FI_FI = new Locale("fi", "FI");
57e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL = new Locale("fil");
58e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FIL_PH = new Locale("fil", "PH");
59e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR = new Locale("fr");
60e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
61d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    private static final Locale LOCALE_HI = new Locale("hi");
62174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_JA = new Locale("ja");
6359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
64b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
65b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
66e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_IN = new Locale("in");
67e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final Locale LOCALE_ID = new Locale("id");
68174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH = new Locale("ht");
69174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
70174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
7159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
7259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static final String SUBTYPE_MODE_VOICE = "voice";
7342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa    private static final String SUBTYPE_MODE_HANDWRITING = "handwriting";
74e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String SUBTYPE_MODE_ANY = null;
75e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
76e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
77e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static final String EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
78e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            "EnabledWhenDefaultIsNotAsciiCapable";
79f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
80f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
8159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testVoiceImes() throws Exception {
8259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
83b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
84b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
85b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
86b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
87b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
88b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
89b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
90b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
91b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
92d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
9359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
94b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
95b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
96b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
97b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
98b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
99b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
100b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
101b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
102b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
103d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
10459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
105b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
106b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
107b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
108b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme");
109b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
110b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
111b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
112b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
113b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "DummyNonDefaultAutoVoiceIme1");
114f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
115f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
116f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    @SmallTest
11759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    public void testKeyboardImes() throws Exception {
11859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_US
119b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
120b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
121b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rUS"), LOCALE_EN_US,
122b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
123b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
12459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
12559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_GB
126b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
127b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
128b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rGB"), LOCALE_EN_GB,
129b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
130b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
13159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
13259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: en_IN
133b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
134b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
135b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("en-rIN"), LOCALE_EN_IN,
136b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
137b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
13859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
13959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: hi
140b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
141b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
142b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("hi"), LOCALE_HI,
143b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.hindi",
144b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.voice");
14559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
14659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // locale: ja_JP
147b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
148b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
149b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("ja-rJP"), LOCALE_JA_JP,
150b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.japanese",
151b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
152b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
153b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_CN
154b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
155b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
156b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rCN"), LOCALE_ZH_CN,
157b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.pinyin",
158b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
159b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
160b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // locale: zh_TW
161b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // Note: In this case, no IME is suitable for the system locale. Hence we will pick up a
162b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // fallback IME regardless of the "default" attribute.
163b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
164b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                !IS_SYSTEM_READY, "com.android.apps.inputmethod.latin");
165b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertDefaultEnabledImes(getSamplePreinstalledImes("zh-rTW"), LOCALE_ZH_TW,
166b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                IS_SYSTEM_READY, "com.android.apps.inputmethod.latin",
167b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                "com.android.apps.inputmethod.voice");
168f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
169f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
170589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    @SmallTest
171589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    public void testParcelable() throws Exception {
172b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final ArrayList<InputMethodInfo> originalList = getSamplePreinstalledImes("en-rUS");
173589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        final List<InputMethodInfo> clonedList = cloneViaParcel(originalList);
174589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertNotNull(clonedList);
175c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList);
176c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertNotNull(clonedClonedList);
177589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        assertEquals(originalList, clonedList);
178c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList, clonedClonedList);
179c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(originalList.size(), clonedList.size());
180c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(clonedList.size(), clonedClonedList.size());
181589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        for (int imeIndex = 0; imeIndex < originalList.size(); ++imeIndex) {
182c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(originalList.get(imeIndex), clonedList.get(imeIndex));
183c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            verifyEquality(clonedList.get(imeIndex), clonedClonedList.get(imeIndex));
184589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
185589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
186589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
187e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
188e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testGetImplicitlyApplicableSubtypesLocked() throws Exception {
189e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
190e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
191e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
192e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
193e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
194e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
195e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa        final InputMethodSubtype nonAutoEnIN = createDummyInputMethodSubtype("en_IN",
196e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
197e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
198e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFrCA = createDummyInputMethodSubtype("fr_CA",
199e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
200e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
201e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFr = createDummyInputMethodSubtype("fr_CA",
202e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
203e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
204e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
205e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
206e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
207e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
208e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
209e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
210e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
211e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
212e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
213e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype autoSubtype = createDummyInputMethodSubtype("auto",
214e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
215e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
216e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoJa = createDummyInputMethodSubtype("ja",
217e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
218e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
21942275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        final InputMethodSubtype nonAutoHi = createDummyInputMethodSubtype("hi",
22042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
22142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
222238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        final InputMethodSubtype nonAutoSrCyrl = createDummyInputMethodSubtype("sr",
223238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                "sr-Cyrl", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
224238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
225238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
226238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        final InputMethodSubtype nonAutoSrLatn = createDummyInputMethodSubtype("sr_ZZ",
227238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                "sr-Latn", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
228238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
229238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
23042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        final InputMethodSubtype nonAutoHandwritingEn = createDummyInputMethodSubtype("en",
23142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
23242275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
23380861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa        final InputMethodSubtype nonAutoHandwritingFr = createDummyInputMethodSubtype("fr",
23480861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa                SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
23580861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa                !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
236238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        final InputMethodSubtype nonAutoHandwritingSrCyrl = createDummyInputMethodSubtype("sr",
237238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                "sr-Cyrl", SUBTYPE_MODE_HANDWRITING, !IS_AUX,
238238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
239238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
240238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        final InputMethodSubtype nonAutoHandwritingSrLatn = createDummyInputMethodSubtype("sr_ZZ",
241238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                "sr-Latn", SUBTYPE_MODE_HANDWRITING, !IS_AUX,
242238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
243238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
244e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype =
245e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
246e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
247e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
248e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2 =
249e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
250e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
251e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                        IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
252e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
253e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that an automatic subtype (overridesImplicitlyEnabledSubtype:true) is
254e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected no matter what locale is specified.
255e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
256622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
257e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
258e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
259e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
260e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
261e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(autoSubtype);  // overridesImplicitlyEnabledSubtype == true
262e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
263e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
26480861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
26580861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
266e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
267e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
268e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
269e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
270e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2715d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
272fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_US), imi);
273e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
274e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(autoSubtype, result.get(0));
275e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
276e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
277e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
278e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no no automatic subtype
279e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
280e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
281622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
282e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);  // locale == "en_US"
283e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB);
284e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
285e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
286e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
287e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
28880861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
28980861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
290e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
291e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
292e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
293e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
294e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
2955d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
296fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_US), imi);
29780861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            assertEquals(2, result.size());
298e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnUS, result.get(0));
29980861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            verifyEquality(nonAutoHandwritingEn, result.get(1));
300e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
301e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
302e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is exactly equal to the specified locale is
303e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // selected as long as there is no automatic subtype
304e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // (overridesImplicitlyEnabledSubtype:true) in the given list.
305e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
306622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
307e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
308e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnGB); // locale == "en_GB"
309e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
310e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
311e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
31280861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
31380861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
314e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
315e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
316e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
317e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
318e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3195d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
320fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_EN_GB), imi);
32180861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            assertEquals(2, result.size());
322e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnGB, result.get(0));
32380861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            verifyEquality(nonAutoHandwritingEn, result.get(1));
324e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
325e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
326e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // If there is no automatic subtype (overridesImplicitlyEnabledSubtype:true) and
327e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // any subtype whose locale is exactly equal to the specified locale in the given list,
328e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // try to find a subtype whose language is equal to the language part of the given locale.
329e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Here make sure that a subtype (locale: "fr_CA") can be found with locale: "fr".
330e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
331622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
332e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFrCA);  // locale == "fr_CA"
333e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
334e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
335e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
336e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
33780861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
33880861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
339e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
340e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
341e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
342e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
343e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3445d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
345fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FR), imi);
34680861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            assertEquals(2, result.size());
347e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
34880861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            verifyEquality(nonAutoHandwritingFr, result.get(1));
349e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
350e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Then make sure that a subtype (locale: "fr") can be found with locale: "fr_CA".
351e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
352622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
353e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFr);  // locale == "fr"
354e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
355e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
356e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
357e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
35880861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
35980861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
360e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
361e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
362e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
363e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
364e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3655d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
366fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FR_CA), imi);
36780861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            assertEquals(2, result.size());
368e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFrCA, result.get(0));
36980861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            verifyEquality(nonAutoHandwritingFr, result.get(1));
370e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
371e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
372e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that subtypes which have "EnabledWhenDefaultIsNotAsciiCapable" in its
373e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // extra value is selected if and only if all other selected IMEs are not AsciiCapable.
374e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
375622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
376e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
377e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);    // not ASCII capable
378e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
379e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
38080861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
38180861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
382e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
383e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
384e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
385e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
386e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
3875d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
388fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_JA_JP), imi);
389e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(3, result.size());
390e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
391e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, result.get(1));
392e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2, result.get(2));
393e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
394e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
39542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        // Make sure that if there is no subtype that matches the language requested, then we just
39642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        // use the first keyboard subtype.
39742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        {
39842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
39942275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHi);
40042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnUS);
40142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
40280861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
40342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
40442275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
40542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin",
40642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
40742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    subtypes);
40842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> result =
40942275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
41042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                            getResourcesForLocales(LOCALE_JA_JP), imi);
41142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            assertEquals(1, result.size());
41242275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            verifyEquality(nonAutoHi, result.get(0));
41342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        }
41442275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        {
41542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
41642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnUS);
41742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHi);
41842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
41980861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
42042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
42142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
42242275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin",
42342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
42442275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    subtypes);
42542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> result =
42642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
42742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                            getResourcesForLocales(LOCALE_JA_JP), imi);
42842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            assertEquals(1, result.size());
42942275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            verifyEquality(nonAutoEnUS, result.get(0));
43042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        }
43142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        {
43242275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
43342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
43480861ff1c0b3ca2c6cdf6fb4a224f3a015bd44bdYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
43542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnUS);
43642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoHi);
43742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
43842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
43942275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin",
44042275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
44142275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    subtypes);
44242275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            final ArrayList<InputMethodSubtype> result =
44342275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
44442275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa                            getResourcesForLocales(LOCALE_JA_JP), imi);
44542275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            assertEquals(1, result.size());
44642275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa            verifyEquality(nonAutoEnUS, result.get(0));
44742275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa        }
44842275bc8b32f342cad7778d28ade59eea12a983cYohei Yukawa
449238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        // Make sure that both language and script are taken into account to find the best matching
450238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        // subtype.
451238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        {
452238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
453238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoEnUS);
454238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrCyrl);
455238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrLatn);
456238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
457238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
458238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrCyrl);
459238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrLatn);
460238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
461238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin",
462238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
463238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    subtypes);
464238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> result =
465238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
466238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                            getResourcesForLocales(Locale.forLanguageTag("sr-Latn-RS")), imi);
467238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertEquals(2, result.size());
468238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoSrLatn, isIn(result));
469238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoHandwritingSrLatn, isIn(result));
470238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        }
471238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        {
472238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
473238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoEnUS);
474238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrCyrl);
475238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrLatn);
476238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
477238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
478238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrCyrl);
479238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrLatn);
480238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
481238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin",
482238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
483238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    subtypes);
484238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> result =
485238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
486238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                            getResourcesForLocales(Locale.forLanguageTag("sr-Cyrl-RS")), imi);
487238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertEquals(2, result.size());
488238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoSrCyrl, isIn(result));
489238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoHandwritingSrCyrl, isIn(result));
490238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        }
491238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa
492238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        // Make sure that secondary locales are taken into account to find the best matching
493238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        // subtype.
494238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        {
495238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
496238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoEnUS);
497238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoEnGB);
498238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrCyrl);
499238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoSrLatn);
500238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoFr);
501238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoFrCA);
502238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingEn);
503238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingFr);
504238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrCyrl);
505238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            subtypes.add(nonAutoHandwritingSrLatn);
506238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
507238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin",
508238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
509238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    subtypes);
510238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            final ArrayList<InputMethodSubtype> result =
511238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
512238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                            getResourcesForLocales(
513238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                                    Locale.forLanguageTag("sr-Latn-RS-x-android"),
514238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                                    Locale.forLanguageTag("ja-JP"),
515238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                                    Locale.forLanguageTag("fr-FR"),
516238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                                    Locale.forLanguageTag("en-GB"),
517238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                                    Locale.forLanguageTag("en-US")),
518238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                            imi);
519238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertEquals(6, result.size());
520238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoEnGB, isIn(result));
521238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoFr, isIn(result));
522238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoSrLatn, isIn(result));
523238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoHandwritingEn, isIn(result));
524238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoHandwritingFr, isIn(result));
525238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            assertThat(nonAutoHandwritingSrLatn, isIn(result));
526238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        }
527238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa
528e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code can be handled.
529e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
530622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
531e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
532e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
533e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
534e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
535e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
536e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
537e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
5385d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
539fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FIL_PH), imi);
540e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
541e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoFil, result.get(0));
542e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
543e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
544e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that we never end up matching "fi" (finnish) with "fil" (filipino).
545e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Also make sure that the first subtype will be used as the last-resort candidate.
546e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
547622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
548e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoJa);
549e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
550e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
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            final ArrayList<InputMethodSubtype> result =
5565d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
557fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_FI), imi);
558e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
559e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoJa, result.get(0));
560e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
561e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
562e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that "in" and "id" conversion is taken into account.
563e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
564622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
565e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
566e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
567e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
568e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
569e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
570e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
571e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
5725d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
573fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_IN), imi);
574e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
575e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
576e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
577e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
578622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
579e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
580e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
581e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
582e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
583e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
584e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
585e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
5865d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
587fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_ID), imi);
588e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
589e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoIn, result.get(0));
590e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
591e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
592622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
593e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
594e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
595e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
596e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
597e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
598e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
599e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
6005d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
601fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_IN), imi);
602e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
603e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
604e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
605e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
606622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
607e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
608e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
609e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
610e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
611e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
612e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
613e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final ArrayList<InputMethodSubtype> result =
6145d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
615fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa                            getResourcesForLocales(LOCALE_ID), imi);
616e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertEquals(1, result.size());
617e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(nonAutoId, result.get(0));
618e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
619e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa
620e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa        // If there is no automatic subtype (overridesImplicitlyEnabledSubtype:true) and the system
621e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa        // provides multiple locales, we try to enable multiple subtypes.
622e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa        {
623e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
624e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoEnUS);
625e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoFrCA);
626e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoIn);
627e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoJa);
628e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoFil);
629e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
630e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
631e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
632e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                    "com.android.apps.inputmethod.latin",
633e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
634e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                    subtypes);
635e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            final ArrayList<InputMethodSubtype> result =
636e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
637e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa                            getResourcesForLocales(LOCALE_FR, LOCALE_EN_US, LOCALE_JA_JP), imi);
638e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoFrCA, isIn(result));
639e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoEnUS, isIn(result));
640e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoJa, isIn(result));
641e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoIn, not(isIn(result)));
642e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, not(isIn(result)));
643e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa            assertThat(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, not(isIn(result)));
644e985c240e3feb62ea38d5b4e386be083ca0f215bYohei Yukawa        }
645e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
646e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
647e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    @SmallTest
648e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    public void testContainsSubtypeOf() throws Exception {
649e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
650e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
651e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
652e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
653e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
654e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
655e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
656e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
657e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
658e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoFilPH = createDummyInputMethodSubtype("fil_PH",
659e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
660e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
661e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
662e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
663e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
664e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
665e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
666e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
667e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
668e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final boolean CHECK_COUNTRY = true;
669e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
670e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
671622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
672e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
673e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
674e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
675e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
676e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
677e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
678e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, !CHECK_COUNTRY,
679e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
680e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, CHECK_COUNTRY,
681e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
682e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
683e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
684e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
685e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
686e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
687e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
688e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
689e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_VOICE));
690e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, !CHECK_COUNTRY,
691e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
692e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_US, CHECK_COUNTRY,
693e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_ANY));
694e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
695e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, !CHECK_COUNTRY,
696e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
697e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN_GB, CHECK_COUNTRY,
698e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
699e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
700e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
701e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil") can be handled.
702e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
703622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
704e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFil);
705e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
706e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
707e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
708e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
709e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
710e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
711e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
712e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
713e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
714e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
715e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
716e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
717e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
718e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
719e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
720e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
721e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
722e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
723e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
724e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
725e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
726e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
727e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
728e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that 3-letter language code ("fil_PH") can be handled.
729e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
730622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
731e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoFilPH);
732e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
733e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
734e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
735e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
736e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
737e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
738e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, CHECK_COUNTRY,
739e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
740e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, !CHECK_COUNTRY,
741e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
742e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL_PH, CHECK_COUNTRY,
743e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
744e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
745e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, !CHECK_COUNTRY,
746e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
747e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI, CHECK_COUNTRY,
748e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
749e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, !CHECK_COUNTRY,
750e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
751e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertFalse(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FI_FI, CHECK_COUNTRY,
752e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
753e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
754e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
755e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "in" can be queried with "id".
756e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
757622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
758e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoIn);
759e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
760e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
761e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
762e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
763e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
764e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
765e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
766e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
767e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
768e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
769e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
770e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
771e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
772e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
773e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
774e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // Make sure that a subtype whose locale is "id" can be queried with "in".
775e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        {
776622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
777e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoId);
778e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(nonAutoEnUS);
779e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            final InputMethodInfo imi = createDummyInputMethodInfo(
780e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin",
781e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
782e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    subtypes);
783e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
784e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
785f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, CHECK_COUNTRY,
786e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
787e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, !CHECK_COUNTRY,
788e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
789f487e0e395a4e49f28c6448339d57357667756c6Yohei Yukawa            assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_ID, CHECK_COUNTRY,
790e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    SUBTYPE_MODE_KEYBOARD));
791e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
792e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
793e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
79459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes,
795b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final Locale systemLocale, final boolean isSystemReady, String... expectedImeNames) {
7965d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Context context = createTargetContextWithLocales(new LocaleList(systemLocale));
7975d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final String[] actualImeNames = getPackageNames(
7985d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, preinstalledImes));
799b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        assertEquals(expectedImeNames.length, actualImeNames.length);
800b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < expectedImeNames.length; ++i) {
801b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            assertEquals(expectedImeNames[i], actualImeNames[i]);
802b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
80359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    }
80459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
805589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) {
806589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        Parcel p = null;
807589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        try {
808589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p = Parcel.obtain();
809589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.writeTypedList(list);
810589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            p.setDataPosition(0);
811589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            return p.createTypedArrayList(InputMethodInfo.CREATOR);
812589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        } finally {
813589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            if (p != null) {
814589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa                p.recycle();
815589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa            }
816589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa        }
817589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa    }
818589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
8195d64399c51de861261267a937502c6a13c50a239Yohei Yukawa    private Context createTargetContextWithLocales(final LocaleList locales) {
8205d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        final Configuration resourceConfiguration = new Configuration();
8215d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        resourceConfiguration.setLocales(locales);
8225d64399c51de861261267a937502c6a13c50a239Yohei Yukawa        return getInstrumentation()
8235d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .getTargetContext()
8245d64399c51de861261267a937502c6a13c50a239Yohei Yukawa                .createConfigurationContext(resourceConfiguration);
825bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
826bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
827fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa    private Resources getResourcesForLocales(Locale... locales) {
828fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa        return createTargetContextWithLocales(new LocaleList(locales)).getResources();
829fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa    }
830fc843713bc3c5558a7288c02aabe2474264e4ca3Yohei Yukawa
831b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private String[] getPackageNames(final ArrayList<InputMethodInfo> imis) {
832b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        final String[] packageNames = new String[imis.size()];
833b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (int i = 0; i < imis.size(); ++i) {
834b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            packageNames[i] = imis.get(i).getPackageName();
835bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        }
836bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa        return packageNames;
837bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa    }
838bca817b2e2623c49bbb618f78fe207bedf57f266Yohei Yukawa
839c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
840c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected, actual);
841c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
842c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        for (int subtypeIndex = 0; subtypeIndex < expected.getSubtypeCount(); ++subtypeIndex) {
843c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype expectedSubtype = expected.getSubtypeAt(subtypeIndex);
844c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa            final InputMethodSubtype actualSubtype = actual.getSubtypeAt(subtypeIndex);
845e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            verifyEquality(expectedSubtype, actualSubtype);
846c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa        }
847c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa    }
848c18cd393f65146fac03a9bdfa45380a69460ee98Yohei Yukawa
849e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    private static void verifyEquality(InputMethodSubtype expected, InputMethodSubtype actual) {
850e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected, actual);
851e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        assertEquals(expected.hashCode(), actual.hashCode());
852e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa    }
853e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
854f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
855f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            CharSequence label, boolean isAuxIme, boolean isDefault,
856f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka            List<InputMethodSubtype> subtypes) {
857f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ResolveInfo ri = new ResolveInfo();
858f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ServiceInfo si = new ServiceInfo();
859f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        final ApplicationInfo ai = new ApplicationInfo();
860f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.packageName = packageName;
861f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.enabled = true;
862f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ai.flags |= ApplicationInfo.FLAG_SYSTEM;
863f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.applicationInfo = ai;
864f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.enabled = true;
865f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.packageName = packageName;
866f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.name = name;
867f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.exported = true;
868f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        si.nonLocalizedLabel = label;
869f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        ri.serviceInfo = si;
870f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka        return new InputMethodInfo(ri, isAuxIme, "", subtypes, 1, isDefault);
871f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
872f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
873f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
874cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
875e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            boolean isAsciiCapable, boolean isEnabledWhenDefaultIsNotAsciiCapable) {
876238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa        return createDummyInputMethodSubtype(locale, null /* languageTag */, mode, isAuxiliary,
877238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                overridesImplicitlyEnabledSubtype, isAsciiCapable,
878238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                isEnabledWhenDefaultIsNotAsciiCapable);
879238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa    }
880e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
881238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa    private static InputMethodSubtype createDummyInputMethodSubtype(String locale,
882238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            String languageTag, String mode, boolean isAuxiliary,
883238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            boolean overridesImplicitlyEnabledSubtype, boolean isAsciiCapable,
884238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa            boolean isEnabledWhenDefaultIsNotAsciiCapable) {
885e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        final StringBuilder subtypeExtraValue = new StringBuilder();
886e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isEnabledWhenDefaultIsNotAsciiCapable) {
887e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
888e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
889e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
890e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
891e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // TODO: Remove following code. InputMethodSubtype#isAsciiCapable() has been publicly
892e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        // available since API level 19 (KitKat). We no longer need to rely on extra value.
893e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        if (isAsciiCapable) {
894e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
895e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypeExtraValue.append(EXTRA_VALUE_ASCII_CAPABLE);
896e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa        }
897e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa
898443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa        return new InputMethodSubtypeBuilder()
899443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeNameResId(0)
900443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeIconResId(0)
901443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeLocale(locale)
902238faad984786f0227fe6c0cf6ea2a5ecff3a4bcYohei Yukawa                .setLanguageTag(languageTag)
903443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setSubtypeMode(mode)
904e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                .setSubtypeExtraValue(subtypeExtraValue.toString())
905443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setIsAuxiliary(isAuxiliary)
906443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
907cfcbddaff269cbb35192c21e557d34aece2f3d6cYohei Yukawa                .setIsAsciiCapable(isAsciiCapable)
908443c2bafd824779a75cd4b922b6839a8df9795e9Yohei Yukawa                .build();
909f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
910f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
91159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithDefaultVoiceIme() {
91259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
91359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
914622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
915e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
916e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
917e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
91859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
919e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
920e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
92159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultAutoVoiceIme",
92259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice0", "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes));
92359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
92459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        preinstalledImes.addAll(getImesWithoutDefaultVoiceIme());
92559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
926f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
927f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
92859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa    private static ArrayList<InputMethodInfo> getImesWithoutDefaultVoiceIme() {
92959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
93059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
931622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
932e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
933e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
934e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
93559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
936e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
937e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
93859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0",
93959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes));
94059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
94159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
942622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
943e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa            subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
944e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
945e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
94659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
947e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
948e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
94959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1",
95059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes));
95159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
95259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
953622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
95459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
955e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
956e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
95759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultVoiceIme2",
95859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes));
95959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
96059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
961622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
96259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
963e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
964e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
96559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultEnKeyboardIme",
96659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "dummy.keyboard0", "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes));
96759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
96859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
969f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka    }
970f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
971b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static boolean contains(final String[] textList, final String textToBeChecked) {
972b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        if (textList == null) {
973b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            return false;
974b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
975b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        for (final String text : textList) {
976b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            if (Objects.equals(textToBeChecked, text)) {
977b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                return true;
978b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            }
979b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        }
980b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        return false;
981b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    }
982b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa
983b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa    private static ArrayList<InputMethodInfo> getSamplePreinstalledImes(final String localeString) {
98459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
98559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
98659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Voice IME
98759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
988b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = false;
989622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
99059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
991e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
992e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
99359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.voice",
994b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.voice", "DummyVoiceIme", IS_AUX, isDefaultIme,
99559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
99659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
99759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Hindi IME
99859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
999b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "hi", "en-rIN" }, localeString);
1000622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
100159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            // TODO: This subtype should be marked as IS_ASCII_CAPABLE
100259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1003e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1004e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
100559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1006e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1007e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
100859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.hindi",
1009b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.inputmethod.hindi", "DummyHindiIme", !IS_AUX, isDefaultIme,
101059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
101159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
1012f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
101359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Pinyin IME
101459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
1015b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "zh-rCN" }, localeString);
1016622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
101759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1018e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1019e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
1020b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.pinyin",
1021b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.pinyin", "DummyPinyinIme", !IS_AUX, isDefaultIme,
102259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
102359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
1024f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka
1025b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa        // a dummy Korean IME
102659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
1027b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ko" }, localeString);
1028622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
102959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1030e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1031e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
103259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.korean",
1033b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.korean", "DummyKoreanIme", !IS_AUX, isDefaultIme,
103459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
103559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
1036589800485d770cab7b159ffcf4b18c10ae2aee6dYohei Yukawa
103759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Latin IME
103859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
1039b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(
1040b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    new String[]{ "en-rUS", "en-rGB", "en-rIN", "en", "hi" }, localeString);
1041622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
104259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1043e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
1044e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
104559cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1046e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
1047e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
104859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1049e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
1050e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
105159cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1052e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
1053e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
105459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.latin",
1055b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, isDefaultIme,
105659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    subtypes));
105759cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
105859cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa
105959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        // a dummy Japanese IME
106059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        {
1061b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa            final boolean isDefaultIme = contains(new String[]{ "ja", "ja-rJP" }, localeString);
1062622b44d00fdbddf6717fd8bc9515111fec71115bYohei Yukawa            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
106359cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1064e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1065e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
106659cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            subtypes.add(createDummyInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
1067e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
1068e72d1c82743c4d573e529d4da3866c1fcea35c77Yohei Yukawa                    !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
106959cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa            preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.japanese",
107059cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa                    "com.android.apps.inputmethod.japanese", "DummyJapaneseIme", !IS_AUX,
1071b21220efae92a56ff7b4b781fa614a6e3a8a3007Yohei Yukawa                    isDefaultIme, subtypes));
107259cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        }
1073d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa
107459cccf93d28648a77860a30349e52b7eeb98436cYohei Yukawa        return preinstalledImes;
1075d77adfe52d44396c54a4ce3a7f1e823e8618f27cYohei Yukawa    }
1076174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1077174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    @SmallTest
1078174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    public void testGetSuitableLocalesForSpellChecker() throws Exception {
1079174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1080174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1081174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
1082174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
1083174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(0));
1084174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(1));
1085174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
1086174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1087174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1088174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1089174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1090174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
1091174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
1092174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(0));
1093174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
1094174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(2));
1095174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1096174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1097174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1098174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1099174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
1100174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(3, locales.size());
1101174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(0));
1102174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
1103174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
1104174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1105174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1106174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1107174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1108174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
1109174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(4, locales.size());
1110174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_IN, locales.get(0));
1111174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(1));
1112174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(2));
1113174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN, locales.get(3));
1114174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1115174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1116174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1117174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1118174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
1119174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
1120174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
1121174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
1122174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
1123174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
1124174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
1125174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1126174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1127174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test 3-letter language code.
1128174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1129174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1130174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
1131174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
1132174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL_PH, locales.get(0));
1133174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_FIL, locales.get(1));
1134174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
1135174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
1136174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
1137174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1138174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1139174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test variant.
1140174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1141174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1142174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
1143174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(6, locales.size());
1144174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH_TH, locales.get(0));
1145174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH_TH, locales.get(1));
1146174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_TH, locales.get(2));
1147174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(3));
1148174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(4));
1149174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(5));
1150174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1151174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1152174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        // Test Locale extension.
1153174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        {
1154174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithoutVariant = LOCALE_JA_JP;
1155174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final Locale localeWithVariant = new Locale.Builder()
1156174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setLocale(LOCALE_JA_JP)
1157174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .setExtension('x', "android")
1158174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    .build();
1159174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertFalse(localeWithoutVariant.equals(localeWithVariant));
1160174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa
1161174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            final ArrayList<Locale> locales =
1162174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa                    InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
1163174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(5, locales.size());
1164174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA_JP, locales.get(0));
1165174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_JA, locales.get(1));
1166174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_US, locales.get(2));
1167174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(LOCALE_EN_GB, locales.get(3));
1168174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa            assertEquals(Locale.ENGLISH, locales.get(4));
1169174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa        }
1170174843afb629c57af19e14ee3ec4a91358061dd9Yohei Yukawa    }
11712028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
1172290e4e471b325d4afca9e36d55b54d83254b2e29Seigo Nonaka    @SmallTest
11732028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    public void testParseInputMethodsAndSubtypesString() {
11742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Trivial cases.
11752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
11762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString("").isEmpty());
11772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString(null).isEmpty());
11782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
11792028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
11802028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // No subtype cases.
11812028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
11822028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
11832028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0");
11842028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
11852028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
11862028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
11872028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
11882028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
11892028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
11902028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0:ime1");
11912028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
11922028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
11932028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime0").isEmpty());
11942028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
11952028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.get("ime1").isEmpty());
11962028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
11972028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
11982028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        // Input metho IDs and their subtypes.
11992028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12002028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12012028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0");
12022028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
12032028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12042028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
12052028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
12062028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
12072028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12082028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12092028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12102028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype0");
12112028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
12122028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12132028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
12142028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes.size());
12152028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
12162028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12172028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12182028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12192028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype1");
12202028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, r.size());
12212028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12222028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes = r.get("ime0");
12232028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes.size());
12242028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype0"));
12252028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes.contains("subtype1"));
12262028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12272028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12282028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12292028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
12302028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0:ime1;subtype1");
12312028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
12322028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12332028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
12342028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
12352028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes0.size());
12362028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
12372028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
12382028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
12392028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
12402028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype1"));
12412028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12422028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12432028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12442028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
12452028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype2");
12462028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
12472028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12482028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
12492028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
12502028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
12512028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
12522028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
12532028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
12542028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
12552028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(1, subtypes1.size());
12562028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
12572028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12582028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12592028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12602028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
12612028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2");
12622028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, r.size());
12632028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12642028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
12652028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
12662028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
12672028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
12682028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
12692028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
12702028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
12712028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
12722028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
12732028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
12742028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12752028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        {
12762028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArrayMap<String, ArraySet<String>> r =
12772028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                    InputMethodUtils.parseInputMethodsAndSubtypesString(
12782028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2:ime2");
12792028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(3, r.size());
12802028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime0"));
12812028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime1"));
12822028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(r.containsKey("ime2"));
12832028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes0 = r.get("ime0");
12842028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes0.size());
12852028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype0"));
12862028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
12872028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
12882028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes1 = r.get("ime1");
12892028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertEquals(2, subtypes1.size());
12902028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes0.contains("subtype1"));
12912028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes1.contains("subtype2"));
12922028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka
12932028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            ArraySet<String> subtypes2 = r.get("ime2");
12942028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka            assertTrue(subtypes2.isEmpty());
12952028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka        }
12962028ddaa5024dfc9844376f2032115aee360155aSeigo Nonaka    }
12972a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
12982a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    @SmallTest
12992a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    public void testbuildInputMethodsAndSubtypesString() {
13002a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13012a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13022a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
13032a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13042a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13052a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13062a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
13072a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
13082a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13092a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13102a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13112a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13122a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13132a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13142a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertEquals("ime0;subtype0", InputMethodUtils.buildInputMethodsAndSubtypesString(map));
13152a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13162a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13172a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13182a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13192a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13202a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
13212a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13222a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13232a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // We do not expect what order will be used to concatenate items in
13242a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // InputMethodUtils.buildInputMethodsAndSubtypesString() hence enumerate all possible
13252a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            // permutations here.
13262a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
13272a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1");
13282a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0");
13292a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
13302a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
13312a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13322a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13332a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13342a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", new ArraySet<String>());
13352a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
13362a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13372a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
13382a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0:ime1");
13392a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0");
13402a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
13412a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
13422a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13432a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13442a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13452a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13462a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13472a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13482a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
13492a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13502a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
13512a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1");
13522a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;ime0;subtype0");
13532a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
13542a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
13552a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13562a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13572a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13582a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13592a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13602a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
13612a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13622a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", new ArraySet<String>());
13632a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13642a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
13652a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1");
13662a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1");
13672a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype0;subtype1");
13682a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1:ime0;subtype1;subtype0");
13692a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
13702a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
13712a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13722a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13732a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13742a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13752a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13762a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13772a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13782a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
13792a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype1");
13802a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
13812a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13822a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
13832a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0:ime1;subtype1");
13842a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype1:ime0;subtype0");
13852a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
13862a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
13872a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
13882a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        {
13892a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
13902a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes1 = new ArraySet<>();
13912a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype0");
13922a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes1.add("subtype1");
13932a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime0", subtypes1);
13942a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
13952a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> subtypes2 = new ArraySet<>();
13962a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype2");
13972a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            subtypes2.add("subtype3");
13982a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            map.put("ime1", subtypes2);
13992a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka
14002a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            ArraySet<String> validSequences = new ArraySet<>();
14012a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype2;subtype3");
14022a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype2;subtype3");
14032a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype0;subtype1:ime1;subtype3;subtype2");
14042a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime0;subtype1;subtype0:ime1;subtype3;subtype2");
14052a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime1;subtype2;subtype3:ime0;subtype0;subtype1");
14062a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime2;subtype3;subtype2:ime0;subtype0;subtype1");
14072a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime3;subtype2;subtype3:ime0;subtype1;subtype0");
14082a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            validSequences.add("ime4;subtype3;subtype2:ime0;subtype1;subtype0");
14092a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka            assertTrue(validSequences.contains(
14102a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka                    InputMethodUtils.buildInputMethodsAndSubtypesString(map)));
14112a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka        }
14122a099bcd6fe974bad47363c214a7bb327484aff8Seigo Nonaka    }
1413226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1414226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    @SmallTest
1415226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    public void testConstructLocaleFromString() throws Exception {
1416226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en"), InputMethodUtils.constructLocaleFromString("en"));
1417226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US"), InputMethodUtils.constructLocaleFromString("en_US"));
1418226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en", "US", "POSIX"),
1419226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("en_US_POSIX"));
1420226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1421226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
1422226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // support three letter language codes, and used "tl" (Tagalog) as the language string for
1423226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // "fil" (Filipino).
1424226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil"), InputMethodUtils.constructLocaleFromString("tl"));
1425226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH"), InputMethodUtils.constructLocaleFromString("tl_PH"));
1426226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("fil", "PH", "POSIX"),
1427226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa                InputMethodUtils.constructLocaleFromString("tl_PH_POSIX"));
1428226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa
1429226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
1430226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a"), InputMethodUtils.constructLocaleFromString("a"));
1431226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("a b c"), InputMethodUtils.constructLocaleFromString("a b c"));
1432226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa        assertEquals(new Locale("en-US"), InputMethodUtils.constructLocaleFromString("en-US"));
1433226c4bba676da8b84eb6506276053dfe2725a03bYohei Yukawa    }
1434f1367b7e903a2a69a8f833bb272e91d77abd57c6Satoshi Kataoka}
1435