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

Commit 4d27b2ce authored by Tony Mantler's avatar Tony Mantler
Browse files

Move InputMethodAndSubtypeEnabler to SettingsLib and port to TV

Bug: 35315463
Test: adb shell am start -a android.settings.INPUT_METHOD_SUBTYPE_SETTINGS
Change-Id: I17e6e64ff2c01577d4036bccafe7d0b4ad1d5ca5
parent ec6cd665
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -3892,12 +3892,6 @@
    <string name="input_method_settings">Settings</string>
    <!-- Spoken description for IME settings image button [CHAR LIMIT=NONE] -->
    <string name="input_method_settings_button">Settings</string>
    <!-- Title for settings of active input methods in each IME [CHAR LIMIT=35] -->
    <string name="active_input_method_subtypes">Active input methods</string>
    <!-- Title for settings whether or not the framework will select input methods in an IME based
         on the current system locales. (The user can select multiple system locales)
         [CHAR LIMIT=35] -->
    <string name="use_system_language_to_select_input_method_subtypes">Use system languages</string>
    <!-- Input Methods Settings localized format string for generating the appropriate "Foo settings" menu label for the Input Method named "Foo" [CHAR LIMIT=35] -->
    <string name="input_methods_settings_label_format"><xliff:g id="ime_name">%1$s</xliff:g> settings</string>
    <!-- Title for the settings of selecting active input methods of an IME [CHAR LIMIT=35] -->
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;

import java.text.Collator;
import java.util.ArrayList;
+9 −235
Original line number Diff line number Diff line
@@ -16,42 +16,17 @@

package com.android.settings.inputmethod;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeEnablerManager;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment
        implements OnPreferenceChangeListener {
    private boolean mHaveHardKeyboard;
    private final HashMap<String, List<Preference>> mInputMethodAndSubtypePrefsMap =
            new HashMap<>();
    private final HashMap<String, TwoStatePreference> mAutoSelectionPrefsMap = new HashMap<>();
    private InputMethodManager mImm;
    // TODO: Change mInputMethodInfoList to Map
    private List<InputMethodInfo> mInputMethodInfoList;
    private Collator mCollator;
public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
    private InputMethodAndSubtypeEnablerManager mManager;

    @Override
    public int getMetricsCategory() {
@@ -61,9 +36,6 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment
    @Override
    public void onCreate(final Bundle icicle) {
        super.onCreate(icicle);
        mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        final Configuration config = getResources().getConfiguration();
        mHaveHardKeyboard = (config.keyboard == Configuration.KEYBOARD_QWERTY);

        // Input method id should be available from an Intent when this preference is launched as a
        // single Activity (see InputMethodAndSubtypeEnablerActivity). It should be available
@@ -72,18 +44,10 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment
        final String targetImi = getStringExtraFromIntentOrArguments(
                android.provider.Settings.EXTRA_INPUT_METHOD_ID);

        mInputMethodInfoList = mImm.getInputMethodList();
        mCollator = Collator.getInstance();

        final PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity());
        final int imiCount = mInputMethodInfoList.size();
        for (int index = 0; index < imiCount; ++index) {
            final InputMethodInfo imi = mInputMethodInfoList.get(index);
            // Add subtype preferences of this IME when it is specified or no IME is specified.
            if (imi.getId().equals(targetImi) || TextUtils.isEmpty(targetImi)) {
                addInputMethodSubtypePreferences(imi, root);
            }
        }
        final PreferenceScreen root =
                getPreferenceManager().createPreferenceScreen(getPrefContext());
        mManager = new InputMethodAndSubtypeEnablerManager(this);
        mManager.init(this, targetImi, root);
        setPreferenceScreen(root);
    }

@@ -109,202 +73,12 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment
    @Override
    public void onResume() {
        super.onResume();
        // Refresh internal states in mInputMethodSettingValues to keep the latest
        // "InputMethodInfo"s and "InputMethodSubtype"s
        InputMethodSettingValuesWrapper
                .getInstance(getActivity()).refreshAllInputMethodAndSubtypes();
        InputMethodAndSubtypeUtil.loadInputMethodSubtypeList(
                this, getContentResolver(), mInputMethodInfoList, mInputMethodAndSubtypePrefsMap);
        updateAutoSelectionPreferences();
        mManager.refresh(getContext(), this);
    }

    @Override
    public void onPause() {
        super.onPause();
        InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(this, getContentResolver(),
                mInputMethodInfoList, mHaveHardKeyboard);
    }

    @Override
    public boolean onPreferenceChange(final Preference pref, final Object newValue) {
        if (!(newValue instanceof Boolean)) {
            return true; // Invoke default behavior.
        }
        final boolean isChecking = (Boolean) newValue;
        for (final String imiId : mAutoSelectionPrefsMap.keySet()) {
            // An auto select subtype preference is changing.
            if (mAutoSelectionPrefsMap.get(imiId) == pref) {
                final TwoStatePreference autoSelectionPref = (TwoStatePreference) pref;
                autoSelectionPref.setChecked(isChecking);
                // Enable or disable subtypes depending on the auto selection preference.
                setAutoSelectionSubtypesEnabled(imiId, autoSelectionPref.isChecked());
                return false;
            }
        }
        // A subtype preference is changing.
        if (pref instanceof InputMethodSubtypePreference) {
            final InputMethodSubtypePreference subtypePref = (InputMethodSubtypePreference) pref;
            subtypePref.setChecked(isChecking);
            if (!subtypePref.isChecked()) {
                // It takes care of the case where no subtypes are explicitly enabled then the auto
                // selection preference is going to be checked.
                updateAutoSelectionPreferences();
            }
            return false;
        }
        return true; // Invoke default behavior.
    }

    private void addInputMethodSubtypePreferences(final InputMethodInfo imi,
            final PreferenceScreen root) {
        final Context context = getPrefContext();
        final int subtypeCount = imi.getSubtypeCount();
        if (subtypeCount <= 1) {
            return;
        }
        final String imiId = imi.getId();
        final PreferenceCategory keyboardSettingsCategory =
                new PreferenceCategory(getPrefContext());
        root.addPreference(keyboardSettingsCategory);
        final PackageManager pm = getPackageManager();
        final CharSequence label = imi.loadLabel(pm);

        keyboardSettingsCategory.setTitle(label);
        keyboardSettingsCategory.setKey(imiId);
        // TODO: Use toggle Preference if images are ready.
        final TwoStatePreference autoSelectionPref =
                new SwitchWithNoTextPreference(getPrefContext());
        mAutoSelectionPrefsMap.put(imiId, autoSelectionPref);
        keyboardSettingsCategory.addPreference(autoSelectionPref);
        autoSelectionPref.setOnPreferenceChangeListener(this);

        final PreferenceCategory activeInputMethodsCategory =
                new PreferenceCategory(getPrefContext());
        activeInputMethodsCategory.setTitle(R.string.active_input_method_subtypes);
        root.addPreference(activeInputMethodsCategory);

        CharSequence autoSubtypeLabel = null;
        final ArrayList<Preference> subtypePreferences = new ArrayList<>();
        for (int index = 0; index < subtypeCount; ++index) {
            final InputMethodSubtype subtype = imi.getSubtypeAt(index);
            if (subtype.overridesImplicitlyEnabledSubtype()) {
                if (autoSubtypeLabel == null) {
                    autoSubtypeLabel = InputMethodAndSubtypeUtil.getSubtypeLocaleNameAsSentence(
                            subtype, context, imi);
                }
            } else {
                final Preference subtypePref = new InputMethodSubtypePreference(
                        context, subtype, imi);
                subtypePreferences.add(subtypePref);
            }
        }
        Collections.sort(subtypePreferences, new Comparator<Preference>() {
            @Override
            public int compare(final Preference lhs, final Preference rhs) {
                if (lhs instanceof InputMethodSubtypePreference) {
                    return ((InputMethodSubtypePreference) lhs).compareTo(rhs, mCollator);
                }
                return lhs.compareTo(rhs);
            }
        });
        final int prefCount = subtypePreferences.size();
        for (int index = 0; index < prefCount; ++index) {
            final Preference pref = subtypePreferences.get(index);
            activeInputMethodsCategory.addPreference(pref);
            pref.setOnPreferenceChangeListener(this);
            InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref);
        }
        mInputMethodAndSubtypePrefsMap.put(imiId, subtypePreferences);
        if (TextUtils.isEmpty(autoSubtypeLabel)) {
            autoSelectionPref.setTitle(
                    R.string.use_system_language_to_select_input_method_subtypes);
        } else {
            autoSelectionPref.setTitle(autoSubtypeLabel);
        }
    }

    private boolean isNoSubtypesExplicitlySelected(final String imiId) {
        final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
        for (final Preference pref : subtypePrefs) {
            if (pref instanceof TwoStatePreference && ((TwoStatePreference)pref).isChecked()) {
                return false;
            }
        }
        return true;
    }

    private void setAutoSelectionSubtypesEnabled(final String imiId,
            final boolean autoSelectionEnabled) {
        final TwoStatePreference autoSelectionPref = mAutoSelectionPrefsMap.get(imiId);
        if (autoSelectionPref == null) {
            return;
        }
        autoSelectionPref.setChecked(autoSelectionEnabled);
        final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
        for (final Preference pref : subtypePrefs) {
            if (pref instanceof TwoStatePreference) {
                // When autoSelectionEnabled is true, all subtype prefs need to be disabled with
                // implicitly checked subtypes. In case of false, all subtype prefs need to be
                // enabled.
                pref.setEnabled(!autoSelectionEnabled);
                if (autoSelectionEnabled) {
                    ((TwoStatePreference)pref).setChecked(false);
                }
            }
        }
        if (autoSelectionEnabled) {
            InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
                    this, getContentResolver(), mInputMethodInfoList, mHaveHardKeyboard);
            updateImplicitlyEnabledSubtypes(imiId, true /* check */);
        }
    }

    private void updateImplicitlyEnabledSubtypes(final String targetImiId, final boolean check) {
        // When targetImiId is null, apply to all subtypes of all IMEs
        for (final InputMethodInfo imi : mInputMethodInfoList) {
            final String imiId = imi.getId();
            final TwoStatePreference autoSelectionPref = mAutoSelectionPrefsMap.get(imiId);
            // No need to update implicitly enabled subtypes when the user has unchecked the
            // "subtype auto selection".
            if (autoSelectionPref == null || !autoSelectionPref.isChecked()) {
                continue;
            }
            if (imiId.equals(targetImiId) || targetImiId == null) {
                updateImplicitlyEnabledSubtypesOf(imi, check);
            }
        }
    }

    private void updateImplicitlyEnabledSubtypesOf(final InputMethodInfo imi, final boolean check) {
        final String imiId = imi.getId();
        final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
        final List<InputMethodSubtype> implicitlyEnabledSubtypes =
                mImm.getEnabledInputMethodSubtypeList(imi, true);
        if (subtypePrefs == null || implicitlyEnabledSubtypes == null) {
            return;
        }
        for (final Preference pref : subtypePrefs) {
            if (!(pref instanceof TwoStatePreference)) {
                continue;
            }
            final TwoStatePreference subtypePref = (TwoStatePreference)pref;
            subtypePref.setChecked(false);
            if (check) {
                for (final InputMethodSubtype subtype : implicitlyEnabledSubtypes) {
                    final String implicitlyEnabledSubtypePrefKey = imiId + subtype.hashCode();
                    if (subtypePref.getKey().equals(implicitlyEnabledSubtypePrefKey)) {
                        subtypePref.setChecked(true);
                        break;
                    }
                }
            }
        }
    }

    private void updateAutoSelectionPreferences() {
        for (final String imiId : mInputMethodAndSubtypePrefsMap.keySet()) {
            setAutoSelectionSubtypesEnabled(imiId, isNoSubtypesExplicitlySelected(imiId));
        }
        updateImplicitlyEnabledSubtypes(null /* targetImiId */, true /* check */);
        mManager.save(getContext(), this);
    }
}
+0 −431

File deleted.

Preview size limit exceeded, changes collapsed.

+4 −3
Original line number Diff line number Diff line
@@ -16,13 +16,14 @@

package com.android.settings.inputmethod;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.UserHandle;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
@@ -37,12 +38,12 @@ import com.android.internal.inputmethod.InputMethodUtils;
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;

import java.text.Collator;
import java.util.List;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

/**
 * Input method preference.
 *
Loading