Refactor InputMethodAndSubtypeEnabler a bit

Change-Id: Id91b62ed084f98e3a6dc724aac9d926d89a96201
This commit is contained in:
Tadashi G. Takaoka
2014-07-14 15:27:23 +09:00
parent 02701420bb
commit a5db65fe11

View File

@@ -28,7 +28,6 @@ import android.preference.Preference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
@@ -45,16 +44,16 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment { public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
private static final String TAG = InputMethodAndSubtypeEnabler.class.getSimpleName();
private AlertDialog mDialog = null;
private boolean mHaveHardKeyboard; private boolean mHaveHardKeyboard;
final private HashMap<String, List<Preference>> mInputMethodAndSubtypePrefsMap = private final HashMap<String, List<Preference>> mInputMethodAndSubtypePrefsMap =
new HashMap<>(); new HashMap<>();
final private HashMap<String, CheckBoxPreference> mAutoSelectionPrefsMap = new HashMap<>(); private final HashMap<String, CheckBoxPreference> mAutoSelectionPrefsMap = new HashMap<>();
private InputMethodManager mImm; private InputMethodManager mImm;
// TODO: Change mInputMethodInfoList to Map // TODO: Change mInputMethodInfoList to Map
private List<InputMethodInfo> mInputMethodInfoList; private List<InputMethodInfo> mInputMethodInfoList;
private String mInputMethodId; private String mInputMethodId;
private Collator mCollator;
private AlertDialog mDialog = null;
@Override @Override
public void onCreate(final Bundle icicle) { public void onCreate(final Bundle icicle) {
@@ -71,6 +70,7 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
android.provider.Settings.EXTRA_INPUT_METHOD_ID); android.provider.Settings.EXTRA_INPUT_METHOD_ID);
mInputMethodInfoList = mImm.getInputMethodList(); mInputMethodInfoList = mImm.getInputMethodList();
mCollator = Collator.getInstance();
setPreferenceScreen(createPreferenceHierarchy()); setPreferenceScreen(createPreferenceHierarchy());
} }
@@ -102,14 +102,14 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
.getInstance(getActivity()).refreshAllInputMethodAndSubtypes(); .getInstance(getActivity()).refreshAllInputMethodAndSubtypes();
InputMethodAndSubtypeUtil.loadInputMethodSubtypeList( InputMethodAndSubtypeUtil.loadInputMethodSubtypeList(
this, getContentResolver(), mInputMethodInfoList, mInputMethodAndSubtypePrefsMap); this, getContentResolver(), mInputMethodInfoList, mInputMethodAndSubtypePrefsMap);
updateAutoSelectionCB(); updateAutoSelectionPreferences();
} }
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
// Clear all subtypes of all IMEs to make sure // Clear all subtypes of all IMEs to make sure
clearImplicitlyEnabledSubtypes(null); updateImplicitlyEnabledSubtypes(null /* targetImiId */, false /* check */);
InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(this, getContentResolver(), InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(this, getContentResolver(),
mInputMethodInfoList, mHaveHardKeyboard); mInputMethodInfoList, mHaveHardKeyboard);
} }
@@ -126,29 +126,21 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
// We look for the first preference item in subtype enabler. // We look for the first preference item in subtype enabler.
// The first item is used for turning on/off subtype auto selection. // The first item is used for turning on/off subtype auto selection.
// We are in the subtype enabler and trying selecting subtypes automatically. // We are in the subtype enabler and trying selecting subtypes automatically.
setSubtypeAutoSelectionEnabled(imiId, chkPref.isChecked()); setAutoSelectionSubtypesEnabled(imiId, chkPref.isChecked());
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
} }
final String id = chkPref.getKey(); final String id = chkPref.getKey();
if (chkPref.isChecked()) { if (chkPref.isChecked()) {
InputMethodInfo selImi = null; final InputMethodInfo imi = getInputMethodInfoById(id);
final int N = mInputMethodInfoList.size(); if (imi == null) {
for (int i = 0; i < N; i++) { return super.onPreferenceTreeClick(preferenceScreen, preference);
final InputMethodInfo imi = mInputMethodInfoList.get(i);
if (id.equals(imi.getId())) {
selImi = imi;
if (InputMethodUtils.isSystemIme(imi)) {
InputMethodAndSubtypeUtil.setSubtypesPreferenceEnabled(
this, mInputMethodInfoList, id, true);
// This is a built-in IME, so no need to warn.
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
break;
}
} }
if (selImi == null) { if (InputMethodUtils.isSystemIme(imi)) {
InputMethodAndSubtypeUtil.setSubtypesPreferenceEnabled(
this, mInputMethodInfoList, id, true);
// This is a built-in IME, so no need to warn.
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
chkPref.setChecked(false); chkPref.setChecked(false);
@@ -182,17 +174,28 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
} }
mDialog.setMessage(getResources().getString( mDialog.setMessage(getResources().getString(
R.string.ime_security_warning, R.string.ime_security_warning,
selImi.getServiceInfo().applicationInfo.loadLabel(getPackageManager()))); imi.getServiceInfo().applicationInfo.loadLabel(getPackageManager())));
mDialog.show(); mDialog.show();
} else { } else {
InputMethodAndSubtypeUtil.setSubtypesPreferenceEnabled( InputMethodAndSubtypeUtil.setSubtypesPreferenceEnabled(
this, mInputMethodInfoList, id, false); this, mInputMethodInfoList, id, false);
updateAutoSelectionCB(); updateAutoSelectionPreferences();
} }
} }
return super.onPreferenceTreeClick(preferenceScreen, preference); return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
private InputMethodInfo getInputMethodInfoById(final String imiId) {
final int imiCount = mInputMethodInfoList.size();
for (int index = 0; index < imiCount; ++index) {
final InputMethodInfo imi = mInputMethodInfoList.get(index);
if (imi.getId().equals(imiId)) {
return imi;
}
}
return null;
}
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
@@ -207,10 +210,9 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
final PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity()); final PreferenceScreen root = getPreferenceManager().createPreferenceScreen(getActivity());
final Context context = getActivity(); final Context context = getActivity();
final Collator collator = Collator.getInstance(); final int imiCount = (mInputMethodInfoList == null ? 0 : mInputMethodInfoList.size());
final int N = (mInputMethodInfoList == null ? 0 : mInputMethodInfoList.size()); for (int imiIndex = 0; imiIndex < imiCount; ++imiIndex) {
for (int i = 0; i < N; ++i) { final InputMethodInfo imi = mInputMethodInfoList.get(imiIndex);
final InputMethodInfo imi = mInputMethodInfoList.get(i);
final int subtypeCount = imi.getSubtypeCount(); final int subtypeCount = imi.getSubtypeCount();
if (subtypeCount <= 1) { if (subtypeCount <= 1) {
continue; continue;
@@ -229,116 +231,101 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
keyboardSettingsCategory.setTitle(label); keyboardSettingsCategory.setTitle(label);
keyboardSettingsCategory.setKey(imiId); keyboardSettingsCategory.setKey(imiId);
// TODO: Use toggle Preference if images are ready. // TODO: Use toggle Preference if images are ready.
final CheckBoxPreference autoCB = new CheckBoxPreference(context); final CheckBoxPreference autoSelectionPref = new CheckBoxPreference(context);
mAutoSelectionPrefsMap.put(imiId, autoCB); mAutoSelectionPrefsMap.put(imiId, autoSelectionPref);
keyboardSettingsCategory.addPreference(autoCB); keyboardSettingsCategory.addPreference(autoSelectionPref);
final PreferenceCategory activeInputMethodsCategory = new PreferenceCategory(context); final PreferenceCategory activeInputMethodsCategory = new PreferenceCategory(context);
activeInputMethodsCategory.setTitle(R.string.active_input_method_subtypes); activeInputMethodsCategory.setTitle(R.string.active_input_method_subtypes);
root.addPreference(activeInputMethodsCategory); root.addPreference(activeInputMethodsCategory);
boolean isAutoSubtype = false;
CharSequence autoSubtypeLabel = null; CharSequence autoSubtypeLabel = null;
final ArrayList<Preference> subtypePreferences = new ArrayList<>(); final ArrayList<Preference> subtypePreferences = new ArrayList<>();
if (subtypeCount > 0) { for (int index = 0; index < subtypeCount; ++index) {
for (int j = 0; j < subtypeCount; ++j) { final InputMethodSubtype subtype = imi.getSubtypeAt(index);
final InputMethodSubtype subtype = imi.getSubtypeAt(j); if (subtype.overridesImplicitlyEnabledSubtype()) {
if (subtype.overridesImplicitlyEnabledSubtype()) { if (autoSubtypeLabel == null) {
if (!isAutoSubtype) { autoSubtypeLabel = subtype.getDisplayName(context,
isAutoSubtype = true; imi.getPackageName(), imi.getServiceInfo().applicationInfo);
autoSubtypeLabel = subtype.getDisplayName(context,
imi.getPackageName(), imi.getServiceInfo().applicationInfo);
}
} else {
final CheckBoxPreference chkbxPref = new InputMethodSubtypePreference(
context, subtype, imi);
subtypePreferences.add(chkbxPref);
} }
}
Collections.sort(subtypePreferences, new Comparator<Preference>() {
@Override
public int compare(Preference lhs, Preference rhs) {
if (lhs instanceof InputMethodSubtypePreference) {
return ((InputMethodSubtypePreference)lhs).compareTo(rhs, collator);
}
return lhs.compareTo(rhs);
}
});
for (int j = 0; j < subtypePreferences.size(); ++j) {
activeInputMethodsCategory.addPreference(subtypePreferences.get(j));
}
mInputMethodAndSubtypePrefsMap.put(imiId, subtypePreferences);
}
if (isAutoSubtype) {
if (TextUtils.isEmpty(autoSubtypeLabel)) {
Log.w(TAG, "Title for auto subtype is empty.");
autoCB.setTitle("---");
} else { } else {
autoCB.setTitle(autoSubtypeLabel); 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);
}
mInputMethodAndSubtypePrefsMap.put(imiId, subtypePreferences);
if (TextUtils.isEmpty(autoSubtypeLabel)) {
autoSelectionPref.setTitle(
R.string.use_system_language_to_select_input_method_subtypes);
} else { } else {
autoCB.setTitle(R.string.use_system_language_to_select_input_method_subtypes); autoSelectionPref.setTitle(autoSubtypeLabel);
} }
} }
return root; return root;
} }
private boolean isNoSubtypesExplicitlySelected(String imiId) { private boolean isNoSubtypesExplicitlySelected(final String imiId) {
boolean allSubtypesOff = true;
final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId); final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
for (final Preference pref : subtypePrefs) { for (final Preference pref : subtypePrefs) {
if (pref instanceof CheckBoxPreference && ((CheckBoxPreference)pref).isChecked()) { if (pref instanceof CheckBoxPreference && ((CheckBoxPreference)pref).isChecked()) {
allSubtypesOff = false; return false;
break;
} }
} }
return allSubtypesOff; return true;
} }
private void setSubtypeAutoSelectionEnabled(String imiId, boolean autoSelectionEnabled) { private void setAutoSelectionSubtypesEnabled(final String imiId,
final CheckBoxPreference autoSelectionCB = mAutoSelectionPrefsMap.get(imiId); final boolean autoSelectionEnabled) {
if (autoSelectionCB == null) { final CheckBoxPreference autoSelectionPref = mAutoSelectionPrefsMap.get(imiId);
if (autoSelectionPref == null) {
return; return;
} }
autoSelectionCB.setChecked(autoSelectionEnabled); autoSelectionPref.setChecked(autoSelectionEnabled);
final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId); final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
for (final Preference subtypePref : subtypePrefs) { for (final Preference pref : subtypePrefs) {
if (subtypePref instanceof CheckBoxPreference) { if (pref instanceof CheckBoxPreference) {
// When autoSelectionEnabled is true, all subtype prefs need to be disabled with // 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 // implicitly checked subtypes. In case of false, all subtype prefs need to be
// enabled. // enabled.
subtypePref.setEnabled(!autoSelectionEnabled); pref.setEnabled(!autoSelectionEnabled);
if (autoSelectionEnabled) { if (autoSelectionEnabled) {
((CheckBoxPreference)subtypePref).setChecked(false); ((CheckBoxPreference)pref).setChecked(false);
} }
} }
} }
if (autoSelectionEnabled) { if (autoSelectionEnabled) {
InputMethodAndSubtypeUtil.saveInputMethodSubtypeList( InputMethodAndSubtypeUtil.saveInputMethodSubtypeList(
this, getContentResolver(), mInputMethodInfoList, mHaveHardKeyboard); this, getContentResolver(), mInputMethodInfoList, mHaveHardKeyboard);
setCheckedImplicitlyEnabledSubtypes(imiId); updateImplicitlyEnabledSubtypes(imiId, true /* check */);
} }
} }
private void setCheckedImplicitlyEnabledSubtypes(String targetImiId) { private void updateImplicitlyEnabledSubtypes(final String targetImiId, final boolean check) {
updateImplicitlyEnabledSubtypes(targetImiId, true);
}
private void clearImplicitlyEnabledSubtypes(String targetImiId) {
updateImplicitlyEnabledSubtypes(targetImiId, false);
}
private void updateImplicitlyEnabledSubtypes(String targetImiId, boolean check) {
// When targetImiId is null, apply to all subtypes of all IMEs // When targetImiId is null, apply to all subtypes of all IMEs
for (final InputMethodInfo imi : mInputMethodInfoList) { for (final InputMethodInfo imi : mInputMethodInfoList) {
final String imiId = imi.getId(); final String imiId = imi.getId();
if (targetImiId != null && !targetImiId.equals(imiId)) { if (targetImiId != null && !targetImiId.equals(imiId)) {
continue; continue;
} }
final CheckBoxPreference autoCB = mAutoSelectionPrefsMap.get(imiId); final CheckBoxPreference autoSelectionPref = mAutoSelectionPrefsMap.get(imiId);
// No need to update implicitly enabled subtypes when the user has unchecked the // No need to update implicitly enabled subtypes when the user has unchecked the
// "subtype auto selection". // "subtype auto selection".
if (autoCB == null || !autoCB.isChecked()) { if (autoSelectionPref == null || !autoSelectionPref.isChecked()) {
continue; continue;
} }
final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId); final List<Preference> subtypePrefs = mInputMethodAndSubtypePrefsMap.get(imiId);
@@ -347,17 +334,18 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
if (subtypePrefs == null || implicitlyEnabledSubtypes == null) { if (subtypePrefs == null || implicitlyEnabledSubtypes == null) {
continue; continue;
} }
for (final Preference subtypePref : subtypePrefs) { for (final Preference pref : subtypePrefs) {
if (subtypePref instanceof CheckBoxPreference) { if (!(pref instanceof CheckBoxPreference)) {
final CheckBoxPreference cb = (CheckBoxPreference)subtypePref; continue;
cb.setChecked(false); }
if (check) { final CheckBoxPreference subtypePref = (CheckBoxPreference)pref;
for (final InputMethodSubtype subtype : implicitlyEnabledSubtypes) { subtypePref.setChecked(false);
String implicitlyEnabledSubtypePrefKey = imiId + subtype.hashCode(); if (check) {
if (cb.getKey().equals(implicitlyEnabledSubtypePrefKey)) { for (final InputMethodSubtype subtype : implicitlyEnabledSubtypes) {
cb.setChecked(true); String implicitlyEnabledSubtypePrefKey = imiId + subtype.hashCode();
break; if (subtypePref.getKey().equals(implicitlyEnabledSubtypePrefKey)) {
} subtypePref.setChecked(true);
break;
} }
} }
} }
@@ -365,10 +353,10 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment {
} }
} }
private void updateAutoSelectionCB() { private void updateAutoSelectionPreferences() {
for (final String imiId : mInputMethodAndSubtypePrefsMap.keySet()) { for (final String imiId : mInputMethodAndSubtypePrefsMap.keySet()) {
setSubtypeAutoSelectionEnabled(imiId, isNoSubtypesExplicitlySelected(imiId)); setAutoSelectionSubtypesEnabled(imiId, isNoSubtypesExplicitlySelected(imiId));
} }
setCheckedImplicitlyEnabledSubtypes(null); updateImplicitlyEnabledSubtypes(null /* targetImiId */, true /* check */);
} }
} }