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

Commit 07bd7320 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Reenable DynamicRotationList for language-switching-aware IMEs

In order to reenable DynamicRotationList for
language-switching-aware IMEs, this CL reverts
I84291fd4a7d6192b3bd0c366c49 with fixing a bug that the dynamic
rotation state is reset even when the list of input methods is
not changed.

With this CL, the dynamic rotation state is preserved when the
enabled input methods is not changed actually.

BUG: 7043015
Change-Id: I506828c7a363e79f1c767eeb28f0d3746ff1cb0d
parent dc31af2d
Loading
Loading
Loading
Loading
+74 −17
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.TreeMap;

/**
@@ -117,6 +118,24 @@ public class InputMethodSubtypeSwitchingController {
                    + " mIsSystemLanguage=" + mIsSystemLanguage
                    + "}";
        }

        @Override
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            }
            if (o instanceof ImeSubtypeListItem) {
                final ImeSubtypeListItem that = (ImeSubtypeListItem)o;
                if (!Objects.equals(this.mImi, that.mImi)) {
                    return false;
                }
                if (this.mSubtypeId != that.mSubtypeId) {
                    return false;
                }
                return true;
            }
            return false;
        }
    }

    private static class InputMethodAndSubtypeList {
@@ -276,7 +295,7 @@ public class InputMethodSubtypeSwitchingController {
        private final List<ImeSubtypeListItem> mImeSubtypeList;
        private final int[] mUsageHistoryOfSubtypeListItemIndex;

        public DynamicRotationList(final List<ImeSubtypeListItem> imeSubtypeListItems) {
        private DynamicRotationList(final List<ImeSubtypeListItem> imeSubtypeListItems) {
            mImeSubtypeList = imeSubtypeListItems;
            mUsageHistoryOfSubtypeListItemIndex = new int[mImeSubtypeList.size()];
            final int N = mImeSubtypeList.size();
@@ -347,15 +366,53 @@ public class InputMethodSubtypeSwitchingController {

    @VisibleForTesting
    public static class ControllerImpl {
        // TODO: Switch to DynamicRotationList for smarter rotation.
        private final StaticRotationList mSwitchingAwareSubtypeList;
        private final StaticRotationList mSwitchingUnawareSubtypeList;
        private final DynamicRotationList mSwitchingAwareRotationList;
        private final StaticRotationList mSwitchingUnawareRotationList;

        public ControllerImpl(final List<ImeSubtypeListItem> sortedItems) {
            mSwitchingAwareSubtypeList = new StaticRotationList(filterImeSubtypeList(sortedItems,
                    true /* supportsSwitchingToNextInputMethod */));
            mSwitchingUnawareSubtypeList = new StaticRotationList(filterImeSubtypeList(sortedItems,
                    false /* supportsSwitchingToNextInputMethod */));
        public static ControllerImpl createFrom(final ControllerImpl currentInstance,
                final List<ImeSubtypeListItem> sortedEnabledItems) {
            DynamicRotationList switchingAwareRotationList = null;
            {
                final List<ImeSubtypeListItem> switchingAwareImeSubtypes =
                        filterImeSubtypeList(sortedEnabledItems,
                                true /* supportsSwitchingToNextInputMethod */);
                if (currentInstance != null &&
                        currentInstance.mSwitchingAwareRotationList != null &&
                        Objects.equals(currentInstance.mSwitchingAwareRotationList.mImeSubtypeList,
                                switchingAwareImeSubtypes)) {
                    // Can reuse the current instance.
                    switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList;
                }
                if (switchingAwareRotationList == null) {
                    switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
                }
            }

            StaticRotationList switchingUnawareRotationList = null;
            {
                final List<ImeSubtypeListItem> switchingUnawareImeSubtypes = filterImeSubtypeList(
                        sortedEnabledItems, false /* supportsSwitchingToNextInputMethod */);
                if (currentInstance != null &&
                        currentInstance.mSwitchingUnawareRotationList != null &&
                        Objects.equals(
                                currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList,
                                switchingUnawareImeSubtypes)) {
                    // Can reuse the current instance.
                    switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList;
                }
                if (switchingUnawareRotationList == null) {
                    switchingUnawareRotationList =
                            new StaticRotationList(switchingUnawareImeSubtypes);
                }
            }

            return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList);
        }

        private ControllerImpl(final DynamicRotationList switchingAwareRotationList,
                final StaticRotationList switchingUnawareRotationList) {
            mSwitchingAwareRotationList = switchingAwareRotationList;
            mSwitchingUnawareRotationList = switchingUnawareRotationList;
        }

        public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme, InputMethodInfo imi,
@@ -364,10 +421,10 @@ public class InputMethodSubtypeSwitchingController {
                return null;
            }
            if (imi.supportsSwitchingToNextInputMethod()) {
                return mSwitchingAwareSubtypeList.getNextInputMethodLocked(onlyCurrentIme, imi,
                return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
                        subtype);
            } else {
                return mSwitchingUnawareSubtypeList.getNextInputMethodLocked(onlyCurrentIme, imi,
                return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
                        subtype);
            }
        }
@@ -376,10 +433,9 @@ public class InputMethodSubtypeSwitchingController {
            if (imi == null) {
                return;
            }
            // TODO: Enable the following code when DynamicRotationList is enabled.
            // if (imi.supportsSwitchingToNextInputMethod()) {
            //     mSwitchingAwareSubtypeList.onUserAction(imi, subtype);
            // }
            if (imi.supportsSwitchingToNextInputMethod()) {
                mSwitchingAwareRotationList.onUserAction(imi, subtype);
            }
        }

        private static List<ImeSubtypeListItem> filterImeSubtypeList(
@@ -424,7 +480,8 @@ public class InputMethodSubtypeSwitchingController {

    public void resetCircularListLocked(Context context) {
        mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
        mController = new ControllerImpl(mSubtypeList.getSortedInputMethodAndSubtypeList());
        mController = ControllerImpl.createFrom(mController,
                mSubtypeList.getSortedInputMethodAndSubtypeList());
    }

    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
+26 −4
Original line number Diff line number Diff line
@@ -172,7 +172,8 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
        final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);

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

        // switching-aware loop
        assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -214,9 +215,8 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
                disabledSubtypeUnawareIme, null);
    }

    // This test is disabled until DynamicRotationList is enabled.
    @SmallTest
    public void DISABLED_testControllerImplWithUserAction() throws Exception {
    public void testControllerImplWithUserAction() throws Exception {
        final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
        final ImeSubtypeListItem latinIme_en_US = enabledItems.get(0);
        final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
@@ -226,7 +226,8 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
        final ImeSubtypeListItem japaneseIme_ja_JP = enabledItems.get(5);
        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_JP = enabledItems.get(6);

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

        // === switching-aware loop ===
        assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -272,5 +273,26 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
                subtypeUnawareIme, null);
        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                switchUnawareJapaneseIme_ja_JP, null);

        // Rotation order should be preserved when created with the same subtype list.
        final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
        final ControllerImpl newController = ControllerImpl.createFrom(controller,
                sameEnabledItems);
        assertRotationOrder(newController, false /* onlyCurrentIme */,
                japaneseIme_ja_JP, latinIme_fr, latinIme_en_US);
        assertRotationOrder(newController, false /* onlyCurrentIme */,
                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 ControllerImpl anotherController = ControllerImpl.createFrom(controller,
                differentEnabledItems);
        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
                latinIme_en_US, latinIme_fr);
        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
                switchingUnawarelatinIme_en_UK, switchUnawareJapaneseIme_ja_JP);
    }
}