Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 587e3a0f authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Fix InputMethodSubtypeSwitchingController tests

When checking the switching-aware loop order, we only use 3 items, with
an user action on the second item, and then on the third item. Due to
the circular nature of the order, an user action on the last item
results in the same order. This adds an additional subtypeAwareIme to
ensure the order is modified and checked accurately. Additionally this
inlines the systemLocale parameter of createTestItem as it was always
the same.

Flag: TEST_ONLY
Test: atest InputMethodSubtypeSwitchingControllerTest
Bug: 347693610
Change-Id: I5f8c9519713b1731b46fb809df80db8b3deb289a
parent 19e9179b
Loading
Loading
Loading
Loading
+95 −95
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeS
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public final class InputMethodSubtypeSwitchingControllerTest {
@@ -65,17 +64,17 @@ public final class InputMethodSubtypeSwitchingControllerTest {
    private static void addTestImeSubtypeListItems(@NonNull List<ImeSubtypeListItem> items,
            @NonNull String imeName, @NonNull String imeLabel,
            @Nullable List<String> subtypeLocales, boolean supportsSwitchingToNextInputMethod) {
        final ResolveInfo ri = new ResolveInfo();
        final ServiceInfo si = new ServiceInfo();
        final ApplicationInfo ai = new ApplicationInfo();
        ai.packageName = TEST_PACKAGE_NAME;
        ai.enabled = true;
        final ServiceInfo si = new ServiceInfo();
        si.applicationInfo = ai;
        si.enabled = true;
        si.packageName = TEST_PACKAGE_NAME;
        si.name = imeName;
        si.exported = true;
        si.nonLocalizedLabel = imeLabel;
        final ResolveInfo ri = new ResolveInfo();
        ri.serviceInfo = si;
        List<InputMethodSubtype> subtypes = null;
        if (subtypeLocales != null) {
@@ -102,8 +101,7 @@ public final class InputMethodSubtypeSwitchingControllerTest {
    @NonNull
    private static ImeSubtypeListItem createTestItem(@NonNull ComponentName imeComponentName,
            @NonNull String imeName, @NonNull String subtypeName,
            @NonNull String subtypeLocale, int subtypeIndex,
            @NonNull String systemLocale) {
            @NonNull String subtypeLocale, int subtypeIndex) {
        final var ai = new ApplicationInfo();
        ai.packageName = imeComponentName.getPackageName();
        ai.enabled = true;
@@ -125,26 +123,26 @@ public final class InputMethodSubtypeSwitchingControllerTest {
                .build());
        final InputMethodInfo imi = new InputMethodInfo(ri, TEST_IS_AUX_IME,
                TEST_SETTING_ACTIVITY_NAME, subtypes, TEST_IS_DEFAULT_RES_ID,
                TEST_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */,
                TEST_IS_VR_IME);
                TEST_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */, TEST_IS_VR_IME);
        return new ImeSubtypeListItem(imeName, subtypeName, imi, subtypeIndex, subtypeLocale,
                systemLocale);
                SYSTEM_LOCALE);
    }

    @NonNull
    private static List<ImeSubtypeListItem> createEnabledImeSubtypes() {
        final var items = new ArrayList<ImeSubtypeListItem>();
        addTestImeSubtypeListItems(items, "LatinIme", "LatinIme", Arrays.asList("en_US", "fr"),
        addTestImeSubtypeListItems(items, "LatinIme", "LatinIme", List.of("en_US", "fr"),
                true /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items, "switchUnawareLatinIme", "switchUnawareLatinIme",
                Arrays.asList("en_UK", "hi"),
                false /* supportsSwitchingToNextInputMethod*/);
                List.of("en_UK", "hi"), false /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items, "subtypeAwareIme", "subtypeAwareIme", null,
                true /* supportsSwitchingToNextInputMethod */);
        addTestImeSubtypeListItems(items, "subtypeUnawareIme", "subtypeUnawareIme", null,
                false /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items, "JapaneseIme", "JapaneseIme", Arrays.asList("ja_JP"),
        addTestImeSubtypeListItems(items, "JapaneseIme", "JapaneseIme", List.of("ja_JP"),
                true /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items, "switchUnawareJapaneseIme", "switchUnawareJapaneseIme",
                Arrays.asList("ja_JP"), false /* supportsSwitchingToNextInputMethod*/);
                List.of("ja_JP"), false /* supportsSwitchingToNextInputMethod*/);
        return items;
    }

@@ -153,11 +151,11 @@ public final class InputMethodSubtypeSwitchingControllerTest {
        final var items = new ArrayList<ImeSubtypeListItem>();
        addTestImeSubtypeListItems(items,
                "UnknownIme", "UnknownIme",
                Arrays.asList("en_US", "hi"),
                List.of("en_US", "hi"),
                true /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items,
                "UnknownSwitchingUnawareIme", "UnknownSwitchingUnawareIme",
                Arrays.asList("en_US"),
                List.of("en_US"),
                false /* supportsSwitchingToNextInputMethod*/);
        addTestImeSubtypeListItems(items, "UnknownSubtypeUnawareIme",
                "UnknownSubtypeUnawareIme", null,
@@ -209,16 +207,17 @@ public final class InputMethodSubtypeSwitchingControllerTest {
        final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
        final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
        final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
        final ImeSubtypeListItem subtypeAwareIme = enabledItems.get(4);
        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(5);
        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);

        final ControllerImpl controller = ControllerImpl.createFrom(
                null /* currentInstance */, enabledItems);

        // switching-aware loop
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
                latinIme_en_us, latinIme_fr, subtypeAwareIme, japaneseIme_ja_jp);

        // switching-unaware loop
        assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -230,6 +229,8 @@ public final class InputMethodSubtypeSwitchingControllerTest {
                latinIme_en_us, latinIme_fr);
        assertRotationOrder(controller, true /* onlyCurrentIme */,
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                subtypeAwareIme, null);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                subtypeUnawareIme, null);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
@@ -261,55 +262,56 @@ public final class InputMethodSubtypeSwitchingControllerTest {
        final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
        final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
        final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
        final ImeSubtypeListItem switchingUnawarelatinIme_en_uk = enabledItems.get(2);
        final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
        final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
        final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
        final ImeSubtypeListItem subtypeAwareIme = enabledItems.get(4);
        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(5);
        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);

        final ControllerImpl controller = ControllerImpl.createFrom(
                null /* currentInstance */, enabledItems);

        // === switching-aware loop ===
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
                latinIme_en_us, latinIme_fr, subtypeAwareIme, japaneseIme_ja_jp);
        // Then notify that a user did something for latinIme_fr.
        onUserAction(controller, latinIme_fr);
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
                latinIme_fr, latinIme_en_us, subtypeAwareIme, japaneseIme_ja_jp);
        // Then notify that a user did something for latinIme_fr again.
        onUserAction(controller, latinIme_fr);
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
        // Then notify that a user did something for japaneseIme_ja_JP.
        onUserAction(controller, latinIme_fr);
                latinIme_fr, latinIme_en_us, subtypeAwareIme, japaneseIme_ja_jp);
        // Then notify that a user did something for subtypeAwareIme.
        onUserAction(controller, subtypeAwareIme);
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
                subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
        // Check onlyCurrentIme == true.
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                japaneseIme_ja_jp, null);
        assertRotationOrder(controller, true /* onlyCurrentIme */,
                latinIme_fr, latinIme_en_us);
        assertRotationOrder(controller, true /* onlyCurrentIme */,
                latinIme_en_us, latinIme_fr);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                subtypeAwareIme, null);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                japaneseIme_ja_jp, null);

        // === switching-unaware loop ===
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                switchUnawareJapaneseIme_ja_jp);
        // User action should be ignored for switching unaware IMEs.
        onUserAction(controller, switchingUnawarelatinIme_hi);
        onUserAction(controller, switchingUnawareLatinIme_hi);
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                switchUnawareJapaneseIme_ja_jp);
        // User action should be ignored for switching unaware IMEs.
        onUserAction(controller, switchUnawareJapaneseIme_ja_jp);
        onUserAction(controller, subtypeUnawareIme);
        assertRotationOrder(controller, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                switchUnawareJapaneseIme_ja_jp);
        // Check onlyCurrentIme == true.
        assertRotationOrder(controller, true /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi);
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                subtypeUnawareIme, null);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
@@ -320,28 +322,28 @@ public final class InputMethodSubtypeSwitchingControllerTest {
        final ControllerImpl newController = ControllerImpl.createFrom(controller,
                sameEnabledItems);
        assertRotationOrder(newController, false /* onlyCurrentIme */,
                japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
                subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
        assertRotationOrder(newController, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                switchUnawareJapaneseIme_ja_jp);

        // Rotation order should be initialized when created with a different subtype list.
        final List<ImeSubtypeListItem> differentEnabledItems = Arrays.asList(
                latinIme_en_us, latinIme_fr, switchingUnawarelatinIme_en_uk,
                switchUnawareJapaneseIme_ja_jp);
        final List<ImeSubtypeListItem> differentEnabledItems = List.of(
                latinIme_en_us, latinIme_fr, subtypeAwareIme, switchingUnawareLatinIme_en_uk,
                switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
        final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
                differentEnabledItems);
        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
                latinIme_en_us, latinIme_fr);
                latinIme_en_us, latinIme_fr, subtypeAwareIme);
        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_uk, switchUnawareJapaneseIme_ja_jp);
                switchingUnawareLatinIme_en_uk, switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
    }

    @Test
    public void testImeSubtypeListItem() {
        final var items = new ArrayList<ImeSubtypeListItem>();
        addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
                Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
                List.of("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
                true /* supportsSwitchingToNextInputMethod*/);
        final ImeSubtypeListItem item_en_us = items.get(0);
        final ImeSubtypeListItem item_fr = items.get(1);
@@ -376,61 +378,61 @@ public final class InputMethodSubtypeSwitchingControllerTest {
        final ComponentName imeY1 = new ComponentName("com.example.imeY", "Ime1");
        final ComponentName imeZ1 = new ComponentName("com.example.imeZ", "Ime1");
        {
            final List<ImeSubtypeListItem> items = Arrays.asList(
            final List<ImeSubtypeListItem> items = List.of(
                    // Subtypes of two IMEs that have the same display name "X".
                    // Subtypes that has the same locale of the system's.
                    createTestItem(imeX1, "X", "E", "en_US", 0, "en_US"),
                    createTestItem(imeX2, "X", "E", "en_US", 0, "en_US"),
                    createTestItem(imeX1, "X", "Z", "en_US", 3, "en_US"),
                    createTestItem(imeX2, "X", "Z", "en_US", 3, "en_US"),
                    createTestItem(imeX1, "X", "", "en_US", 6, "en_US"),
                    createTestItem(imeX2, "X", "", "en_US", 6, "en_US"),
                    createTestItem(imeX1, "X", "E", "en_US", 0),
                    createTestItem(imeX2, "X", "E", "en_US", 0),
                    createTestItem(imeX1, "X", "Z", "en_US", 3),
                    createTestItem(imeX2, "X", "Z", "en_US", 3),
                    createTestItem(imeX1, "X", "", "en_US", 6),
                    createTestItem(imeX2, "X", "", "en_US", 6),
                    // Subtypes that has the same language of the system's.
                    createTestItem(imeX1, "X", "E", "en", 1, "en_US"),
                    createTestItem(imeX2, "X", "E", "en", 1, "en_US"),
                    createTestItem(imeX1, "X", "Z", "en", 4, "en_US"),
                    createTestItem(imeX2, "X", "Z", "en", 4, "en_US"),
                    createTestItem(imeX1, "X", "", "en", 7, "en_US"),
                    createTestItem(imeX2, "X", "", "en", 7, "en_US"),
                    createTestItem(imeX1, "X", "E", "en", 1),
                    createTestItem(imeX2, "X", "E", "en", 1),
                    createTestItem(imeX1, "X", "Z", "en", 4),
                    createTestItem(imeX2, "X", "Z", "en", 4),
                    createTestItem(imeX1, "X", "", "en", 7),
                    createTestItem(imeX2, "X", "", "en", 7),
                    // Subtypes that has different language than the system's.
                    createTestItem(imeX1, "X", "A", "hi_IN", 27, "en_US"),
                    createTestItem(imeX2, "X", "A", "hi_IN", 27, "en_US"),
                    createTestItem(imeX1, "X", "E", "ja", 2, "en_US"),
                    createTestItem(imeX2, "X", "E", "ja", 2, "en_US"),
                    createTestItem(imeX1, "X", "Z", "ja", 5, "en_US"),
                    createTestItem(imeX2, "X", "Z", "ja", 5, "en_US"),
                    createTestItem(imeX1, "X", "", "ja", 8, "en_US"),
                    createTestItem(imeX2, "X", "", "ja", 8, "en_US"),
                    createTestItem(imeX1, "X", "A", "hi_IN", 27),
                    createTestItem(imeX2, "X", "A", "hi_IN", 27),
                    createTestItem(imeX1, "X", "E", "ja", 2),
                    createTestItem(imeX2, "X", "E", "ja", 2),
                    createTestItem(imeX1, "X", "Z", "ja", 5),
                    createTestItem(imeX2, "X", "Z", "ja", 5),
                    createTestItem(imeX1, "X", "", "ja", 8),
                    createTestItem(imeX2, "X", "", "ja", 8),

                    // Subtypes of IME "Y".
                    // Subtypes that has the same locale of the system's.
                    createTestItem(imeY1, "Y", "E", "en_US", 9, "en_US"),
                    createTestItem(imeY1, "Y", "Z", "en_US", 12, "en_US"),
                    createTestItem(imeY1, "Y", "", "en_US", 15, "en_US"),
                    createTestItem(imeY1, "Y", "E", "en_US", 9),
                    createTestItem(imeY1, "Y", "Z", "en_US", 12),
                    createTestItem(imeY1, "Y", "", "en_US", 15),
                    // Subtypes that has the same language of the system's.
                    createTestItem(imeY1, "Y", "E", "en", 10, "en_US"),
                    createTestItem(imeY1, "Y", "Z", "en", 13, "en_US"),
                    createTestItem(imeY1, "Y", "", "en", 16, "en_US"),
                    createTestItem(imeY1, "Y", "E", "en", 10),
                    createTestItem(imeY1, "Y", "Z", "en", 13),
                    createTestItem(imeY1, "Y", "", "en", 16),
                    // Subtypes that has different language than the system's.
                    createTestItem(imeY1, "Y", "A", "hi_IN", 28, "en_US"),
                    createTestItem(imeY1, "Y", "E", "ja", 11, "en_US"),
                    createTestItem(imeY1, "Y", "Z", "ja", 14, "en_US"),
                    createTestItem(imeY1, "Y", "", "ja", 17, "en_US"),
                    createTestItem(imeY1, "Y", "A", "hi_IN", 28),
                    createTestItem(imeY1, "Y", "E", "ja", 11),
                    createTestItem(imeY1, "Y", "Z", "ja", 14),
                    createTestItem(imeY1, "Y", "", "ja", 17),

                    // Subtypes of IME Z.
                    // Subtypes that has the same locale of the system's.
                    createTestItem(imeZ1, "", "E", "en_US", 18, "en_US"),
                    createTestItem(imeZ1, "", "Z", "en_US", 21, "en_US"),
                    createTestItem(imeZ1, "", "", "en_US", 24, "en_US"),
                    createTestItem(imeZ1, "", "E", "en_US", 18),
                    createTestItem(imeZ1, "", "Z", "en_US", 21),
                    createTestItem(imeZ1, "", "", "en_US", 24),
                    // Subtypes that has the same language of the system's.
                    createTestItem(imeZ1, "", "E", "en", 19, "en_US"),
                    createTestItem(imeZ1, "", "Z", "en", 22, "en_US"),
                    createTestItem(imeZ1, "", "", "en", 25, "en_US"),
                    createTestItem(imeZ1, "", "E", "en", 19),
                    createTestItem(imeZ1, "", "Z", "en", 22),
                    createTestItem(imeZ1, "", "", "en", 25),
                    // Subtypes that has different language than the system's.
                    createTestItem(imeZ1, "", "A", "hi_IN", 29, "en_US"),
                    createTestItem(imeZ1, "", "E", "ja", 20, "en_US"),
                    createTestItem(imeZ1, "", "Z", "ja", 23, "en_US"),
                    createTestItem(imeZ1, "", "", "ja", 26, "en_US"));
                    createTestItem(imeZ1, "", "A", "hi_IN", 29),
                    createTestItem(imeZ1, "", "E", "ja", 20),
                    createTestItem(imeZ1, "", "Z", "ja", 23),
                    createTestItem(imeZ1, "", "", "ja", 26));

            // Ensure {@link java.lang.Comparable#compareTo} contracts are satisfied.
            for (int i = 0; i < items.size(); ++i) {
@@ -449,10 +451,8 @@ public final class InputMethodSubtypeSwitchingControllerTest {

        {
            // Following two items have the same priority.
            final ImeSubtypeListItem nonSystemLocale1 =
                    createTestItem(imeX1, "X", "A", "ja_JP", 0, "en_US");
            final ImeSubtypeListItem nonSystemLocale2 =
                    createTestItem(imeX1, "X", "A", "hi_IN", 1, "en_US");
            final ImeSubtypeListItem nonSystemLocale1 = createTestItem(imeX1, "X", "A", "ja_JP", 0);
            final ImeSubtypeListItem nonSystemLocale2 = createTestItem(imeX1, "X", "A", "hi_IN", 1);
            assertEquals(0, nonSystemLocale1.compareTo(nonSystemLocale2));
            assertEquals(0, nonSystemLocale2.compareTo(nonSystemLocale1));
            // But those aren't equal to each other.
@@ -462,8 +462,8 @@ public final class InputMethodSubtypeSwitchingControllerTest {

        {
            // Check if ComponentName is also taken into account when comparing two items.
            final ImeSubtypeListItem ime1 = createTestItem(imeX1, "X", "A", "ja_JP", 0, "en_US");
            final ImeSubtypeListItem ime2 = createTestItem(imeX2, "X", "A", "ja_JP", 0, "en_US");
            final ImeSubtypeListItem ime1 = createTestItem(imeX1, "X", "A", "ja_JP", 0);
            final ImeSubtypeListItem ime2 = createTestItem(imeX2, "X", "A", "ja_JP", 0);
            assertTrue(ime1.compareTo(ime2) < 0);
            assertTrue(ime2.compareTo(ime1) > 0);
            // But those aren't equal to each other.