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

Commit 8ad53168 authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Merge non-hardware and hardware IME rotation lists

Currently InputMethodSubtypeSwitchingController has two lists used for
switching, one which includes all non-auxiliary IMEs and subtypes, and
one that is only used for hardware keyboard shortcut switching, based on
the value of isSuitableForPhysicalKeyboardLayoutMapping.

However, all the subtypes suitable for physical (hardware) keyboards
are also non-auxiliary. Thus, this leads to more memory usage for
essentialy duplicate entries. Moreover, this also interferes with the
recency update logic: if the user types using a hardware keyboard for
some subtype, this will update the order in the hardware specific list,
without updating the order in the general list, despite the same
subtype being present in both.

To avoid creating both lists, reduce duplication and improve the
behaviour, this change merges the two lists into one.

Flag: EXEMPT cleanup
Bug: 350969542
Bug: 347693610
Test: atest InputMethodSubtypeSwitchingControllerTest
Change-Id: I762e1bfe98deaf1534fd1a209f8face7a12a6a52
parent 69343de8
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -4028,9 +4028,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        if (currentImi == null) {
            return false;
        }
        final ImeSubtypeListItem nextSubtype = userData.mSwitchingController
                .getNextInputMethod(currentImi, bindingController.getCurrentSubtype(),
                        onlyCurrentIme, MODE_AUTO, true /* forward */);
        final ImeSubtypeListItem nextSubtype = userData.mSwitchingController.getNext(currentImi,
                bindingController.getCurrentSubtype(), onlyCurrentIme, false /* forHardware */,
                MODE_AUTO, true /* forward */);
        if (nextSubtype == null) {
            return false;
        }
@@ -4047,9 +4047,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        if (currentImi == null) {
            return false;
        }
        final ImeSubtypeListItem nextSubtype = userData.mSwitchingController
                .getNextInputMethod(currentImi, bindingController.getCurrentSubtype(),
                        false /* onlyCurrentIme */, MODE_AUTO, true /* forward */);
        final ImeSubtypeListItem nextSubtype = userData.mSwitchingController.getNext(currentImi,
                bindingController.getCurrentSubtype(), false /* onlyCurrentIme */,
                false /* forHardware */, MODE_AUTO, true /* forward */);
        return nextSubtype != null;
    }

@@ -4588,7 +4588,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                settings.getSelectedInputMethodSubtypeIndex(lastInputMethodId);

        final List<ImeSubtypeListItem> items = userData.mSwitchingController
                .getItemsForImeSwitcherMenu(includeAuxiliary);
                .getItems(true /* forMenu */, includeAuxiliary);
        if (items.isEmpty()) {
            Slog.w(TAG, "Show switching menu failed, items is empty,"
                    + " showAuxSubtypes: " + showAuxSubtypes
@@ -5242,8 +5242,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            return;
        }
        final var currentSubtype = bindingController.getCurrentSubtype();
        final var nextItem = userData.mSwitchingController.getNextInputMethodForHardware(
                currentImi, currentSubtype, false /* onlyCurrentIme */, MODE_AUTO,
        final var nextItem = userData.mSwitchingController.getNext(currentImi, currentSubtype,
                false /* onlyCurrentIme */, true /* forHardware */, MODE_AUTO,
                direction > 0 /* forward */);
        if (nextItem == null) {
            Slog.i(TAG, "Hardware keyboard switching shortcut,"
+26 −78
Original line number Diff line number Diff line
@@ -242,42 +242,24 @@ final class InputMethodSubtypeSwitchingController {
    }

    /**
     * Gets the list of enabled input methods and subtypes used for switching.
     *
     * @param forHardware whether to filter by subtypes suitable for hardware keyboard only.
     */
    @GuardedBy("ImfLock.class")
    @NonNull
    List<ImeSubtypeListItem> getItemsForSwitching(boolean forHardware) {
        final var res = new ArrayList<ImeSubtypeListItem>();
        for (int i = 0; i < mEnabledItems.size(); i++) {
            final var item = mEnabledItems.get(i);
            final boolean valid = forHardware ? item.mSuitableForHardware : !item.mIsAuxiliary;
            if (valid) {
                res.add(item);
            }
        }
        return res;
    }

    /**
     * Gets the list of enabled input method and subtypes shown in the IME Switcher Menu.
     * Gets the list of enabled input methods and subtypes.
     *
     * @param forMenu          whether to filter by items to be shown in the IME Switcher Menu.
     * @param includeAuxiliary whether to include auxiliary subtypes.
     */
    @GuardedBy("ImfLock.class")
    @NonNull
    List<ImeSubtypeListItem> getItemsForImeSwitcherMenu(boolean includeAuxiliary) {
    List<ImeSubtypeListItem> getItems(boolean forMenu, boolean includeAuxiliary) {
        final var res = new ArrayList<ImeSubtypeListItem>();
        for (int i = 0; i < mEnabledItems.size(); i++) {
            final var item = mEnabledItems.get(i);
            if (!item.mShowInImeSwitcherMenu) {
            if (forMenu && !item.mShowInImeSwitcherMenu) {
                continue;
            }

            if (includeAuxiliary || !item.mIsAuxiliary) {
                res.add(item);
            if (!includeAuxiliary && item.mIsAuxiliary) {
                continue;
            }
            res.add(item);
        }
        return res;
    }
@@ -384,13 +366,14 @@ final class InputMethodSubtypeSwitchingController {
         * @param imi            the input method to find the next value from.
         * @param subtype        the input method subtype to find the next value from, if any.
         * @param onlyCurrentIme whether to consider only subtypes of the current input method.
         * @param forHardware    whether to consider only subtypes suitable for hardware keyboard.
         * @param useRecency     whether to use the recency order, or the static order.
         * @param forward        whether to search forwards to backwards in the list.
         * @return the next input method and subtype if found, otherwise {@code null}.
         */
        @Nullable
        ImeSubtypeListItem next(@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
                boolean onlyCurrentIme, boolean useRecency, boolean forward) {
                boolean onlyCurrentIme, boolean forHardware, boolean useRecency, boolean forward) {
            if (mItems.isEmpty()) {
                return null;
            }
@@ -409,9 +392,11 @@ final class InputMethodSubtypeSwitchingController {
                final int nextIndex = (index + i * incrementSign + size) % size;
                final int mappedIndex = useRecency ? mRecencyMap[nextIndex] : nextIndex;
                final var nextItem = mItems.get(mappedIndex);
                if (!onlyCurrentIme || nextItem.mImi.equals(imi)) {
                    return nextItem;
                if ((onlyCurrentIme && !nextItem.mImi.equals(imi))
                        || (forHardware && !nextItem.mSuitableForHardware)) {
                    continue;
                }
                return nextItem;
            }
            return null;
        }
@@ -508,11 +493,6 @@ final class InputMethodSubtypeSwitchingController {
    @NonNull
    private RotationList mRotationList = new RotationList(Collections.emptyList());

    /** List of input methods and subtypes suitable for hardware keyboards. */
    @GuardedBy("ImfLock.class")
    @NonNull
    private RotationList mHardwareRotationList = new RotationList(Collections.emptyList());

    /**
     * Whether there was a user action since the last input method and subtype switch.
     * Used to determine the switching behaviour for {@link #MODE_AUTO}.
@@ -525,20 +505,13 @@ final class InputMethodSubtypeSwitchingController {
     * equal to the existing ones (regardless of recency order), the update is skipped and the
     * current recency order is kept. Otherwise, the recency order is reset.
     *
     * @param sortedEnabledItems    the sorted list of enabled input methods and subtypes.
     * @param hardwareKeyboardItems the unsorted list of enabled input method and subtypes
     *                              suitable for hardware keyboards.
     * @param enabledItems the list of enabled input methods and subtypes.
     */
    @GuardedBy("ImfLock.class")
    @VisibleForTesting
    void update(@NonNull List<ImeSubtypeListItem> sortedEnabledItems,
            @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) {
        if (!Objects.equals(mRotationList.mItems, sortedEnabledItems)) {
            mRotationList = new RotationList(sortedEnabledItems);
        }

        if (!Objects.equals(mHardwareRotationList.mItems, hardwareKeyboardItems)) {
            mHardwareRotationList = new RotationList(hardwareKeyboardItems);
    void update(@NonNull List<ImeSubtypeListItem> enabledItems) {
        if (!mRotationList.mItems.equals(enabledItems)) {
            mRotationList = new RotationList(enabledItems);
        }
    }

@@ -551,39 +524,19 @@ final class InputMethodSubtypeSwitchingController {
     * @param imi            the input method to find the next value from.
     * @param subtype        the input method subtype to find the next value from, if any.
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @param forHardware    whether to consider only subtypes
     *                       {@link InputMethodSubtype#isSuitableForPhysicalKeyboardLayoutMapping
     *                       suitable for hardware keyboard}.
     * @param mode           the switching mode.
     * @param forward        whether to search search forwards or backwards in the list.
     * @return the next input method and subtype if found, otherwise {@code null}.
     */
    @GuardedBy("ImfLock.class")
    @Nullable
    ImeSubtypeListItem getNextInputMethod(@NonNull InputMethodInfo imi,
            @Nullable InputMethodSubtype subtype, boolean onlyCurrentIme, @SwitchMode int mode,
            boolean forward) {
        return mRotationList.next(imi, subtype, onlyCurrentIme, isRecency(mode, forward), forward);
    }

    /**
     * Gets the next input method and subtype suitable for hardware keyboards, starting from the
     * given ones, in the given direction.
     *
     * <p>If the given input method and subtype are not found, this returns the most recent
     * input method and subtype.
     *
     * @param imi            the input method to find the next value from.
     * @param subtype        the input method subtype to find the next value from, if any.
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @param mode           the switching mode
     * @param forward        whether to search search forwards or backwards in the list.
     * @return the next input method and subtype if found, otherwise {@code null}.
     */
    @GuardedBy("ImfLock.class")
    @Nullable
    ImeSubtypeListItem getNextInputMethodForHardware(@NonNull InputMethodInfo imi,
            @Nullable InputMethodSubtype subtype, boolean onlyCurrentIme,
            @SwitchMode int mode, boolean forward) {
        return mHardwareRotationList.next(imi, subtype, onlyCurrentIme, isRecency(mode, forward),
                forward);
    ImeSubtypeListItem getNext(@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
            boolean onlyCurrentIme, boolean forHardware, @SwitchMode int mode, boolean forward) {
        return mRotationList.next(imi, subtype, onlyCurrentIme, forHardware,
                isRecency(mode, forward), forward);
    }

    /**
@@ -597,9 +550,7 @@ final class InputMethodSubtypeSwitchingController {
     */
    @GuardedBy("ImfLock.class")
    boolean onUserAction(@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
        boolean recencyUpdated = false;
        recencyUpdated |= mRotationList.setMostRecent(imi, subtype);
        recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype);
        final boolean recencyUpdated = mRotationList.setMostRecent(imi, subtype);
        if (recencyUpdated) {
            mUserActionSinceSwitch = true;
        }
@@ -631,8 +582,6 @@ final class InputMethodSubtypeSwitchingController {
    void dump(@NonNull Printer pw, @NonNull String prefix) {
        pw.println(prefix + "mRotationList:");
        mRotationList.dump(pw, prefix + "  ");
        pw.println(prefix + "mHardwareRotationList:");
        mHardwareRotationList.dump(pw, prefix + "  ");
        pw.println(prefix + "mEnabledItems:");
        for (int i = 0; i < mEnabledItems.size(); i++) {
            final var item = mEnabledItems.get(i);
@@ -654,7 +603,6 @@ final class InputMethodSubtypeSwitchingController {
    @GuardedBy("ImfLock.class")
    void update(@NonNull Context context, @NonNull InputMethodSettings settings) {
        mEnabledItems = getEnabledInputMethodsAndSubtypes(context, settings);
        update(getItemsForSwitching(false /* forHardware */),
                getItemsForSwitching(true /* forHardware */));
        update(getItems(false /* forMenu */, false /* includeAuxiliary */));
    }
}
+139 −93

File changed.

Preview size limit exceeded, changes collapsed.