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

Commit 4081fe50 authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Inline IME subtype switching ControllerImpl

This acted mostly as a wrapper which lead to some duplicated code and
documentation, so it can be easily inlined.

The only difference is visible in tests: when updating the controller
with new items, it won't return a new item, but rather mutate the
existing one. Otherwise, callers wouldn't directly access
ControllerImpl, so this remains equivalent.

Flag: EXEMPT REFACTOR
Bug: 347693610
Test: atest InputMethodSubtypeSwitchingControllerTest
Change-Id: Ic0525781ee02c3416c6b27c220759603a5eb9615
parent 948ce5eb
Loading
Loading
Loading
Loading
+149 −231
Original line number Diff line number Diff line
@@ -614,19 +614,18 @@ final class InputMethodSubtypeSwitchingController {
        }
    }

    @VisibleForTesting
    public static class ControllerImpl {

    @NonNull
        private final DynamicRotationList mSwitchingAwareRotationList;
    private DynamicRotationList mSwitchingAwareRotationList =
            new DynamicRotationList(Collections.emptyList());
    @NonNull
        private final StaticRotationList mSwitchingUnawareRotationList;
    private StaticRotationList mSwitchingUnawareRotationList =
            new StaticRotationList(Collections.emptyList());
    /** List of input methods and subtypes. */
        @Nullable
        private final RotationList mRotationList;
    @NonNull
    private RotationList mRotationList = new RotationList(Collections.emptyList());
    /** List of input methods and subtypes suitable for hardware keyboards. */
        @Nullable
        private final RotationList mHardwareRotationList;
    @NonNull
    private RotationList mHardwareRotationList = new RotationList(Collections.emptyList());

    /**
     * Whether there was a user action since the last input method and subtype switch.
@@ -634,81 +633,65 @@ final class InputMethodSubtypeSwitchingController {
     */
    private boolean mUserActionSinceSwitch;

        @NonNull
        public static ControllerImpl createFrom(@Nullable ControllerImpl currentInstance,
                @NonNull List<ImeSubtypeListItem> sortedEnabledItems,
    /**
     * Updates the list of input methods and subtypes used for switching. If the given items are
     * 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.
     */
    @VisibleForTesting
    void update(@NonNull List<ImeSubtypeListItem> sortedEnabledItems,
            @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) {
        final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
                true /* supportsSwitchingToNextInputMethod */);
        final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
                false /* supportsSwitchingToNextInputMethod */);

            final DynamicRotationList switchingAwareRotationList;
            if (currentInstance != null && Objects.equals(
                    currentInstance.mSwitchingAwareRotationList.mImeSubtypeList,
        if (!Objects.equals(mSwitchingAwareRotationList.mImeSubtypeList,
                switchingAwareImeSubtypes)) {
                // Can reuse the current instance.
                switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList;
            } else {
                switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
            mSwitchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
        }

            final StaticRotationList switchingUnawareRotationList;
            if (currentInstance != null && Objects.equals(
                    currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList,
        if (!Objects.equals(mSwitchingUnawareRotationList.mImeSubtypeList,
                switchingUnawareImeSubtypes)) {
                // Can reuse the current instance.
                switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList;
            } else {
                switchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
            mSwitchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
        }

            final RotationList rotationList;
            if (!Flags.imeSwitcherRevamp()) {
                rotationList = null;
            } else if (currentInstance != null && currentInstance.mRotationList != null
                    && Objects.equals(
                            currentInstance.mRotationList.mItems, sortedEnabledItems)) {
                // Can reuse the current instance.
                rotationList = currentInstance.mRotationList;
            } else {
                rotationList = new RotationList(sortedEnabledItems);
        if (Flags.imeSwitcherRevamp()
                && !Objects.equals(mRotationList.mItems, sortedEnabledItems)) {
            mRotationList = new RotationList(sortedEnabledItems);
        }

            final RotationList hardwareRotationList;
            if (!Flags.imeSwitcherRevamp()) {
                hardwareRotationList = null;
            } else if (currentInstance != null && currentInstance.mHardwareRotationList != null
                    && Objects.equals(
                            currentInstance.mHardwareRotationList.mItems, hardwareKeyboardItems)) {
                // Can reuse the current instance.
                hardwareRotationList = currentInstance.mHardwareRotationList;
            } else {
                hardwareRotationList = new RotationList(hardwareKeyboardItems);
        if (Flags.imeSwitcherRevamp()
                && !Objects.equals(mHardwareRotationList.mItems, hardwareKeyboardItems)) {
            mHardwareRotationList = new RotationList(hardwareKeyboardItems);
        }

            return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList,
                    rotationList, hardwareRotationList);
        }

        private ControllerImpl(@NonNull DynamicRotationList switchingAwareRotationList,
                @NonNull StaticRotationList switchingUnawareRotationList,
                @Nullable RotationList rotationList,
                @Nullable RotationList hardwareRotationList) {
            mSwitchingAwareRotationList = switchingAwareRotationList;
            mSwitchingUnawareRotationList = switchingUnawareRotationList;
            mRotationList = rotationList;
            mHardwareRotationList = hardwareRotationList;
    }

    /**
     * Gets the next input method and subtype, 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.</p>
     *
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @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 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}.
     */
    @Nullable
        public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme,
    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
            @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
            @SwitchMode int mode, boolean forward) {
        if (imi == null) {
            return null;
        }
            if (Flags.imeSwitcherRevamp() && mRotationList != null) {
        if (Flags.imeSwitcherRevamp()) {
            return mRotationList.next(imi, subtype, onlyCurrentIme,
                    isRecency(mode, forward), forward);
        } else if (imi.supportsSwitchingToNextInputMethod()) {
@@ -720,11 +703,25 @@ final class InputMethodSubtypeSwitchingController {
        }
    }

    /**
     * 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.</p>
     *
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @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 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}.
     */
    @Nullable
    public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
            @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
            @SwitchMode int mode, boolean forward) {
            if (Flags.imeSwitcherRevamp() && mHardwareRotationList != null) {
        if (Flags.imeSwitcherRevamp()) {
            return mHardwareRotationList.next(imi, subtype, onlyCurrentIme,
                    isRecency(mode, forward), forward);
        }
@@ -744,12 +741,8 @@ final class InputMethodSubtypeSwitchingController {
            @Nullable InputMethodSubtype subtype) {
        boolean recencyUpdated = false;
        if (Flags.imeSwitcherRevamp()) {
                if (mRotationList != null) {
            recencyUpdated |= mRotationList.setMostRecent(imi, subtype);
                }
                if (mHardwareRotationList != null) {
            recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype);
                }
            if (recencyUpdated) {
                mUserActionSinceSwitch = true;
            }
@@ -798,103 +791,28 @@ final class InputMethodSubtypeSwitchingController {
        return result;
    }

        protected void dump(@NonNull Printer pw, @NonNull String prefix) {
    void dump(@NonNull Printer pw, @NonNull String prefix) {
        pw.println(prefix + "mSwitchingAwareRotationList:");
        mSwitchingAwareRotationList.dump(pw, prefix + "  ");
        pw.println(prefix + "mSwitchingUnawareRotationList:");
        mSwitchingUnawareRotationList.dump(pw, prefix + "  ");
        if (Flags.imeSwitcherRevamp()) {
                if (mRotationList != null) {
            pw.println(prefix + "mRotationList:");
            mRotationList.dump(pw, prefix + "  ");
                }
                if (mHardwareRotationList != null) {
            pw.println(prefix + "mHardwareRotationList:");
            mHardwareRotationList.dump(pw, prefix + "  ");
                }
            pw.println(prefix + "User action since last switch: " + mUserActionSinceSwitch);
        }
    }
    }

    @NonNull
    private ControllerImpl mController;

    InputMethodSubtypeSwitchingController() {
        mController = ControllerImpl.createFrom(null, Collections.emptyList(),
                Collections.emptyList());
    }

    /**
     * Called when the user took an action that should update the recency of the current
     * input method and subtype in the switching list.
     *
     * @param imi     the currently selected input method.
     * @param subtype the currently selected input method subtype, if any.
     * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
     */
    public void onUserActionLocked(@NonNull InputMethodInfo imi,
            @Nullable InputMethodSubtype subtype) {
        mController.onUserActionLocked(imi, subtype);
    }

    /** Called when the input method and subtype was changed. */
    public void onInputMethodSubtypeChanged() {
        mController.onInputMethodSubtypeChanged();
    }

    public void resetCircularListLocked(@NonNull Context context,
            @NonNull InputMethodSettings settings) {
        mController = ControllerImpl.createFrom(mController,
                getSortedInputMethodAndSubtypeList(
        update(getSortedInputMethodAndSubtypeList(
                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
                        false /* forImeMenu */, context, settings),
                getInputMethodAndSubtypeListForHardwareKeyboard(context, settings));
    }

    /**
     * Gets the next input method and subtype, 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.</p>
     *
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @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 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}.
     */
    @Nullable
    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
            @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
            @SwitchMode int mode, boolean forward) {
        return mController.getNextInputMethod(onlyCurrentIme, imi, subtype, mode, 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.</p>
     *
     * @param onlyCurrentIme whether to consider only subtypes of the current input method.
     * @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 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}.
     */
    @Nullable
    public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
            @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
            @SwitchMode int mode, boolean forward) {
        return mController.getNextInputMethodForHardware(onlyCurrentIme, imi, subtype, mode,
                forward);
    }

    public void dump(@NonNull Printer pw, @NonNull String prefix) {
        mController.dump(pw, prefix);
    }
}
+73 −92

File changed.

Preview size limit exceeded, changes collapsed.