1d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa/*
2d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * Copyright (C) 2014 The Android Open Source Project
3d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa *
4d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * Licensed under the Apache License, Version 2.0 (the "License");
5d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * you may not use this file except in compliance with the License.
6d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * You may obtain a copy of the License at
7d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa *
8d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa *      http://www.apache.org/licenses/LICENSE-2.0
9d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa *
10d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * Unless required by applicable law or agreed to in writing, software
11d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * distributed under the License is distributed on an "AS IS" BASIS,
12d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * See the License for the specific language governing permissions and
14d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa * limitations under the License.
15d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa */
16d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
17d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawapackage android.os;
18d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
19d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.content.pm.ApplicationInfo;
20d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.content.pm.ResolveInfo;
21d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.content.pm.ServiceInfo;
22d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.test.InstrumentationTestCase;
23d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.test.suitebuilder.annotation.SmallTest;
24d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.view.inputmethod.InputMethodInfo;
25d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.view.inputmethod.InputMethodSubtype;
26d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
27d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
289b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawaimport com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl;
29d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
309b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawaimport com.android.internal.inputmethod.InputMethodUtils;
31d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
32d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport java.util.ArrayList;
33d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport java.util.Arrays;
34d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawaimport java.util.List;
35d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
36d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawapublic class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTestCase {
374013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final String DUMMY_PACKAGE_NAME = "dymmy package name";
384013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final String DUMMY_SETTING_ACTIVITY_NAME = "";
394013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final boolean DUMMY_IS_AUX_IME = false;
404013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final boolean DUMMY_FORCE_DEFAULT = false;
414013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final int DUMMY_IS_DEFAULT_RES_ID = 0;
424013940b62ae2227c9b30d8761d7533ee6190a9fYohei Yukawa    private static final String SYSTEM_LOCALE = "en_US";
439b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
44d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
45d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    private static InputMethodSubtype createDummySubtype(final String locale) {
46d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
47d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        return builder.setSubtypeNameResId(0)
48d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                .setSubtypeIconResId(0)
49d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                .setSubtypeLocale(locale)
50d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                .setIsAsciiCapable(true)
51d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                .build();
52d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    }
53d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
54d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    private static void addDummyImeSubtypeListItems(List<ImeSubtypeListItem> items,
55d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa            String imeName, String imeLabel, List<String> subtypeLocales,
56d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa            boolean supportsSwitchingToNextInputMethod) {
57d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final ResolveInfo ri = new ResolveInfo();
58d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final ServiceInfo si = new ServiceInfo();
59d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final ApplicationInfo ai = new ApplicationInfo();
60d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        ai.packageName = DUMMY_PACKAGE_NAME;
61d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        ai.enabled = true;
62d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.applicationInfo = ai;
63d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.enabled = true;
64d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.packageName = DUMMY_PACKAGE_NAME;
65d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.name = imeName;
66d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.exported = true;
67d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        si.nonLocalizedLabel = imeLabel;
68d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        ri.serviceInfo = si;
699b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        List<InputMethodSubtype> subtypes = null;
709b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        if (subtypeLocales != null) {
719b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            subtypes = new ArrayList<InputMethodSubtype>();
729b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            for (String subtypeLocale : subtypeLocales) {
739b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                subtypes.add(createDummySubtype(subtypeLocale));
749b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            }
75d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        }
76d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final InputMethodInfo imi = new InputMethodInfo(ri, DUMMY_IS_AUX_IME,
77d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                DUMMY_SETTING_ACTIVITY_NAME, subtypes, DUMMY_IS_DEFAULT_RES_ID,
78d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                DUMMY_FORCE_DEFAULT, supportsSwitchingToNextInputMethod);
799b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        if (subtypes == null) {
809b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            items.add(new ImeSubtypeListItem(imeName, null /* variableName */, imi,
819b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                    NOT_A_SUBTYPE_ID, null, SYSTEM_LOCALE));
829b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        } else {
839b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            for (int i = 0; i < subtypes.size(); ++i) {
849b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                final String subtypeLocale = subtypeLocales.get(i);
859b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                items.add(new ImeSubtypeListItem(imeName, subtypeLocale, imi, i, subtypeLocale,
869b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                        SYSTEM_LOCALE));
879b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            }
88d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        }
89d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    }
90d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
919b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    private static List<ImeSubtypeListItem> createEnabledImeSubtypes() {
92d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
939b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme", Arrays.asList("en_US", "fr"),
94d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                true /* supportsSwitchingToNextInputMethod*/);
959b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "switchUnawareLatinIme", "switchUnawareLatinIme",
96d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                Arrays.asList("en_UK", "hi"),
97d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                false /* supportsSwitchingToNextInputMethod*/);
989b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "subtypeUnawareIme", "subtypeUnawareIme", null,
999b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                false /* supportsSwitchingToNextInputMethod*/);
1009b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "JapaneseIme", "JapaneseIme", Arrays.asList("ja_JP"),
101d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                true /* supportsSwitchingToNextInputMethod*/);
1029b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "switchUnawareJapaneseIme", "switchUnawareJapaneseIme",
1039b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                Arrays.asList("ja_JP"), false /* supportsSwitchingToNextInputMethod*/);
1049b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        return items;
1059b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    }
1069b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1079b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    private static List<ImeSubtypeListItem> createDisabledImeSubtypes() {
1089b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
1099b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items,
1109b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                "UnknownIme", "UnknownIme",
1119b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                Arrays.asList("en_US", "hi"),
1129b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                true /* supportsSwitchingToNextInputMethod*/);
1139b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items,
1149b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                "UnknownSwitchingUnawareIme", "UnknownSwitchingUnawareIme",
1159b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                Arrays.asList("en_US"),
1169b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                false /* supportsSwitchingToNextInputMethod*/);
1179b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        addDummyImeSubtypeListItems(items, "UnknownSubtypeUnawareIme",
1189b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                "UnknownSubtypeUnawareIme", null,
119d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa                false /* supportsSwitchingToNextInputMethod*/);
120d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa        return items;
121d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    }
122d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
1239b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    private void assertNextInputMethod(final ControllerImpl controller,
1249b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            final boolean onlyCurrentIme,
1259b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            final ImeSubtypeListItem currentItem, final ImeSubtypeListItem nextItem) {
1269b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        InputMethodSubtype subtype = null;
1279b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        if (currentItem.mSubtypeName != null) {
1289b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa            subtype = createDummySubtype(currentItem.mSubtypeName.toString());
1299b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        }
1309b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme,
1319b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                currentItem.mImi, subtype);
1329b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertEquals(nextItem, nextIme);
133d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    }
134d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa
135a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    private void assertRotationOrder(final ControllerImpl controller,
136a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final boolean onlyCurrentIme,
137a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
138a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final int N = expectedRotationOrderOfImeSubtypeList.length;
139a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        for (int i = 0; i < N; i++) {
140a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final int currentIndex = i;
141a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final int nextIndex = (currentIndex + 1) % N;
142a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final ImeSubtypeListItem currentItem =
143a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                    expectedRotationOrderOfImeSubtypeList[currentIndex];
144a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final ImeSubtypeListItem nextItem = expectedRotationOrderOfImeSubtypeList[nextIndex];
145a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            assertNextInputMethod(controller, onlyCurrentIme, currentItem, nextItem);
146a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        }
147a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    }
148a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
149a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    private void onUserAction(final ControllerImpl controller,
150a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            final ImeSubtypeListItem subtypeListItem) {
151a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        InputMethodSubtype subtype = null;
152a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        if (subtypeListItem.mSubtypeName != null) {
153a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa            subtype = createDummySubtype(subtypeListItem.mSubtypeName.toString());
154a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        }
155a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        controller.onUserActionLocked(subtypeListItem.mImi, subtype);
156a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    }
157a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
158d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    @SmallTest
1599b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa    public void testControllerImpl() throws Exception {
1609b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final List<ImeSubtypeListItem> disabledItems = createDisabledImeSubtypes();
1619b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem disabledIme_en_US = disabledItems.get(0);
1629b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem disabledIme_hi = disabledItems.get(1);
1639b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem disabledSwitchingUnawareIme = disabledItems.get(2);
1649b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem disabledSubtypeUnawareIme = disabledItems.get(3);
1659b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1669b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
1679b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
1689b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
1699b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
1709b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
1719b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
1729b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
1739b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
1749b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
17507bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final ControllerImpl controller = ControllerImpl.createFrom(
17607bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                null /* currentInstance */, enabledItems);
1779b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1789b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        // switching-aware loop
179a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
180a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
1819b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1829b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        // switching-unaware loop
183a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
184a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
185a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchUnawareJapaneseIme_ja_JP);
1869b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1879b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        // test onlyCurrentIme == true
188a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, true /* onlyCurrentIme */,
1899b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                latinIme_en_US, latinIme_fr);
190a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, true /* onlyCurrentIme */,
1919b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
1929b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
1939b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                subtypeUnawareIme, null);
1949b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
1959b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                japaneseIme_ja_JP, null);
1969b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
1979b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                switchUnawareJapaneseIme_ja_JP, null);
1989b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa
1999b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        // Make sure that disabled IMEs are not accepted.
2009b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, false /* onlyCurrentIme */,
2019b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledIme_en_US, null);
2029b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, false /* onlyCurrentIme */,
2039b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledIme_hi, null);
2049b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, false /* onlyCurrentIme */,
2059b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledSwitchingUnawareIme, null);
2069b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, false /* onlyCurrentIme */,
2079b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledSubtypeUnawareIme, null);
2089b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
2099b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledIme_en_US, null);
2109b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
2119b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledIme_hi, null);
2129b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
2139b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledSwitchingUnawareIme, null);
2149b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
2159b29d04565e1faf0a49054f538ed1881cb24fe12Yohei Yukawa                disabledSubtypeUnawareIme, null);
216d1da11529813f6d3f51518b5fe028e0b8084f5ccYohei Yukawa    }
217a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
218a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    @SmallTest
21907bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa    public void testControllerImplWithUserAction() throws Exception {
220a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
221a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
222a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
223a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem switchingUnawarelatinIme_en_UK = enabledItems.get(2);
224a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
225a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
226a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
227a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);
228a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
22907bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final ControllerImpl controller = ControllerImpl.createFrom(
23007bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                null /* currentInstance */, enabledItems);
231a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
232a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // === switching-aware loop ===
233a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
234a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_en_US, latinIme_fr, japaneseIme_ja_JP);
235a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // Then notify that a user did something for latinIme_fr.
236a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        onUserAction(controller, latinIme_fr);
237a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
238a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
239a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // Then notify that a user did something for latinIme_fr again.
240a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        onUserAction(controller, latinIme_fr);
241a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
242a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_fr, latinIme_en_US, japaneseIme_ja_JP);
243a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // Then notify that a user did something for japaneseIme_ja_JP.
244a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        onUserAction(controller, latinIme_fr);
245a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
246a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
247a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // Check onlyCurrentIme == true.
248a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
249a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                japaneseIme_ja_JP, null);
250a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, true /* onlyCurrentIme */,
251a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_fr, latinIme_en_US);
252a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, true /* onlyCurrentIme */,
253a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                latinIme_en_US, latinIme_fr);
254a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa
255a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // === switching-unaware loop ===
256a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
257a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
258a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchUnawareJapaneseIme_ja_JP);
259a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // User action should be ignored for switching unaware IMEs.
260a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        onUserAction(controller, switchingUnawarelatinIme_hi);
261a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
262a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
263a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchUnawareJapaneseIme_ja_JP);
264a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // User action should be ignored for switching unaware IMEs.
265a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        onUserAction(controller, switchUnawareJapaneseIme_ja_JP);
266a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, false /* onlyCurrentIme */,
267a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
268a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchUnawareJapaneseIme_ja_JP);
269a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        // Check onlyCurrentIme == true.
270a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertRotationOrder(controller, true /* onlyCurrentIme */,
271a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi);
272a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
273a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                subtypeUnawareIme, null);
274a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa        assertNextInputMethod(controller, true /* onlyCurrentIme */,
275a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa                switchUnawareJapaneseIme_ja_JP, null);
27607bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa
27707bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        // Rotation order should be preserved when created with the same subtype list.
27807bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
27907bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final ControllerImpl newController = ControllerImpl.createFrom(controller,
28007bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                sameEnabledItems);
28107bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        assertRotationOrder(newController, false /* onlyCurrentIme */,
28207bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
28307bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        assertRotationOrder(newController, false /* onlyCurrentIme */,
28407bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                switchingUnawarelatinIme_en_UK, switchingUnawarelatinIme_hi, subtypeUnawareIme,
28507bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                switchUnawareJapaneseIme_ja_JP);
28607bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa
28707bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        // Rotation order should be initialized when created with a different subtype list.
28807bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final List<ImeSubtypeListItem> differentEnabledItems = Arrays.asList(
28907bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                latinIme_en_US, latinIme_fr, switchingUnawarelatinIme_en_UK,
29007bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                switchUnawareJapaneseIme_ja_JP);
29107bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
29207bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                differentEnabledItems);
29307bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
29407bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                latinIme_en_US, latinIme_fr);
29507bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
29607bd732034fbf4ce0e51b99c7199edf20dff1565Yohei Yukawa                switchingUnawarelatinIme_en_UK, switchUnawareJapaneseIme_ja_JP);
297a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa    }
29871cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa
29971cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa    @SmallTest
30071cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa    public void testImeSubtypeListItem() throws Exception {
30171cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
30271cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme",
30371cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa                Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
30471cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa                true /* supportsSwitchingToNextInputMethod*/);
30571cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_en_US = items.get(0);
30671cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_fr = items.get(1);
30771cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_en = items.get(2);
30871cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_enn = items.get(3);
30971cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_e = items.get(4);
31071cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        final ImeSubtypeListItem item_EN_US = items.get(5);
31171cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa
31271cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertTrue(item_en_US.mIsSystemLocale);
31371cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_fr.mIsSystemLocale);
31471cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_en.mIsSystemLocale);
31571cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_en.mIsSystemLocale);
31671cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_enn.mIsSystemLocale);
31771cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_e.mIsSystemLocale);
31871cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_EN_US.mIsSystemLocale);
31971cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa
32071cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertTrue(item_en_US.mIsSystemLanguage);
32171cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_fr.mIsSystemLanguage);
32271cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertTrue(item_en.mIsSystemLanguage);
32371cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_enn.mIsSystemLocale);
32471cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_e.mIsSystemLocale);
32571cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa        assertFalse(item_EN_US.mIsSystemLocale);
32671cf0a32d0d9a45653704a671154f26a8bc3132bYohei Yukawa    }
327a9bda774276f1c5a1fc6fd67a7782a06e696be8fYohei Yukawa}
328