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

Commit 4faac7d9 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Make isValidSystemNonAuxAsciiCapableIme stateless

This CL simplifies SettingsLib by making
isValidSystemNonAuxAsciiCapableIme() method stateless.

Although this can be a minor user-visible behavior change, we believe
it is acceptable because the behavior we are going to drop is a
fallback rule in case there is no system IME that could be considered
ASCII capable without actual AsciiCapable attribute..  Even without
this fallback rule the System Settings does not fall into a bad state.
It only affects the sort order of the IME enabler page and minor
optional cosmetic behavior.

The bottom line is that if a pre-installed IME is ASCII capable, it
really should annotate itself to be so, rather than relying on some
heuristic logic that we have had.

With this CL, SettingsLib no longer depends on InputMethodUtils.

Fix: 77730201
Test: atest InputMethodPreferenceTest
Test: make RunSettingsLibRoboTests -j
Change-Id: I1352bf42dcb9219a370a16a381ea39c43c57637a
parent b1eaf643
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ public class InputMethodAndSubtypeUtil {
    private static final boolean DEBUG = false;
    private static final String TAG = "InputMethdAndSubtypeUtl";

    private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
    private static final char INPUT_METHOD_SEPARATER = ':';
    private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';';
    private static final int NOT_A_SUBTYPE_ID = -1;
@@ -177,7 +178,7 @@ public class InputMethodAndSubtypeUtil {
            final boolean isCurrentInputMethod = imiId.equals(currentInputMethodId);
            final boolean systemIme = imi.isSystem();
            if ((!hasHardKeyboard && InputMethodSettingValuesWrapper.getInstance(
                    context.getActivity()).isAlwaysCheckedIme(imi, context.getActivity()))
                    context.getActivity()).isAlwaysCheckedIme(imi))
                    || isImeChecked) {
                if (!enabledIMEsAndSubtypesMap.containsKey(imiId)) {
                    // imiId has just been enabled
@@ -416,4 +417,19 @@ public class InputMethodAndSubtypeUtil {
        }
        return configurationLocale;
    }

    public static boolean isValidSystemNonAuxAsciiCapableIme(InputMethodInfo imi) {
        if (imi.isAuxiliaryIme() || !imi.isSystem()) {
            return false;
        }
        final int subtypeCount = imi.getSubtypeCount();
        for (int i = 0; i < subtypeCount; ++i) {
            final InputMethodSubtype subtype = imi.getSubtypeAt(i);
            if (SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
                    && subtype.isAsciiCapable()) {
                return true;
            }
        }
        return false;
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ public class InputMethodPreference extends RestrictedSwitchPreference implements
        }
        mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
        mHasPriorityInSorting = imi.isSystem()
                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
                && InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi);
        setOnPreferenceClickListener(this);
        setOnPreferenceChangeListener(this);
    }
@@ -197,8 +197,7 @@ public class InputMethodPreference extends RestrictedSwitchPreference implements
    }

    public void updatePreferenceViews() {
        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
                mImi, getContext());
        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(mImi);
        // When this preference has a switch and an input method should be always enabled,
        // this preference should be disabled to prevent accidentally disabling an input method.
        // This preference should also be disabled in case the admin does not allow this input
+5 −47
Original line number Diff line number Diff line
@@ -22,15 +22,11 @@ import android.content.Context;
import android.util.Log;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.inputmethod.InputMethodUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;

/**
 * This class is a wrapper for {@link InputMethodManager} and
@@ -47,7 +43,6 @@ public class InputMethodSettingValuesWrapper {
    private final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
    private final ContentResolver mContentResolver;
    private final InputMethodManager mImm;
    private final HashSet<InputMethodInfo> mAsciiCapableEnabledImis = new HashSet<>();

    public static InputMethodSettingValuesWrapper getInstance(Context context) {
        if (sInstance == null) {
@@ -70,50 +65,32 @@ public class InputMethodSettingValuesWrapper {
    public void refreshAllInputMethodAndSubtypes() {
        mMethodList.clear();
        mMethodList.addAll(mImm.getInputMethodList());
        updateAsciiCapableEnabledImis();
    }

    // TODO: Add a cts to ensure at least one AsciiCapableSubtypeEnabledImis exist
    private void updateAsciiCapableEnabledImis() {
        mAsciiCapableEnabledImis.clear();
        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
        for (final InputMethodInfo imi : enabledImis) {
            final int subtypeCount = imi.getSubtypeCount();
            for (int i = 0; i < subtypeCount; ++i) {
                final InputMethodSubtype subtype = imi.getSubtypeAt(i);
                if (InputMethodUtils.SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
                        && subtype.isAsciiCapable()) {
                    mAsciiCapableEnabledImis.add(imi);
                    break;
                }
            }
        }
    }

    public List<InputMethodInfo> getInputMethodList() {
        return new ArrayList<>(mMethodList);
    }

    public boolean isAlwaysCheckedIme(InputMethodInfo imi, Context context) {
    public boolean isAlwaysCheckedIme(InputMethodInfo imi) {
        final boolean isEnabled = isEnabledImi(imi);
        if (getEnabledInputMethodList().size() <= 1 && isEnabled) {
            return true;
        }

        final int enabledValidSystemNonAuxAsciiCapableImeCount =
                getEnabledValidSystemNonAuxAsciiCapableImeCount(context);
                getEnabledValidSystemNonAuxAsciiCapableImeCount();

        return enabledValidSystemNonAuxAsciiCapableImeCount <= 1
                && !(enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabled)
                && imi.isSystem()
                && isValidSystemNonAuxAsciiCapableIme(imi, context);
                && InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi);
    }

    private int getEnabledValidSystemNonAuxAsciiCapableImeCount(Context context) {
    private int getEnabledValidSystemNonAuxAsciiCapableImeCount() {
        int count = 0;
        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
        for (final InputMethodInfo imi : enabledImis) {
            if (isValidSystemNonAuxAsciiCapableIme(imi, context)) {
            if (InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi)) {
                ++count;
            }
        }
@@ -133,25 +110,6 @@ public class InputMethodSettingValuesWrapper {
        return false;
    }

    public boolean isValidSystemNonAuxAsciiCapableIme(InputMethodInfo imi, Context context) {
        if (imi.isAuxiliaryIme()) {
            return false;
        }
        final Locale systemLocale = context.getResources().getConfiguration().locale;
        if (InputMethodUtils.isSystemImeThatHasSubtypeOf(imi, context,
                    true /* checkDefaultAttribute */, systemLocale, false /* checkCountry */,
                    InputMethodUtils.SUBTYPE_MODE_ANY)) {
            return true;
        }
        if (mAsciiCapableEnabledImis.isEmpty()) {
            Log.w(TAG, "ascii capable subtype enabled imi not found. Fall back to English"
                    + " Keyboard subtype.");
            return InputMethodUtils.containsSubtypeOf(imi, Locale.ENGLISH, false /* checkCountry */,
                    InputMethodUtils.SUBTYPE_MODE_KEYBOARD);
        }
        return mAsciiCapableEnabledImis.contains(imi);
    }

    /**
     * Returns the list of the enabled {@link InputMethodInfo} determined by
     * {@link android.provider.Settings.Secure#ENABLED_INPUT_METHODS} rather than just returning
+0 −1
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodUtils;

import java.text.Collator;
import java.util.Locale;
+1 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ public class InputMethodPreferenceTest {
        final InputMethodSubtype systemLocaleSubtype =
                new InputMethodSubtype.InputMethodSubtypeBuilder()
                        .setIsAsciiCapable(true)
                        .setSubtypeMode("keyboard")
                        .setSubtypeLocale(systemLocale.getLanguage())
                        .build();

Loading