diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 45b118284d9..32e8e839cfe 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -40,6 +40,7 @@ import android.os.Handler; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; @@ -49,6 +50,7 @@ import android.text.TextUtils; import android.view.InputDevice; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import android.widget.BaseAdapter; import java.util.ArrayList; import java.util.Collections; @@ -88,11 +90,20 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment private InputMethodManager mImm; private boolean mIsOnlyImeSettings; private Handler mHandler; - @SuppressWarnings("unused") private SettingsObserver mSettingsObserver; private Intent mIntentWaitingForResult; private InputMethodSettingValuesWrapper mInputMethodSettingValues; + private final OnPreferenceChangeListener mOnImePreferenceChangedListener = + new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference arg0, Object arg1) { + ((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged(); + updateInputMethodPreferenceViews(); + return true; + } + }; + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -153,19 +164,22 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment mKeyboardSettingsCategory.addPreference(currentIme); } - mInputMethodPreferenceList.clear(); - final List imis = mInputMethodSettingValues.getInputMethodList(); - final int N = (imis == null ? 0 : imis.size()); - for (int i = 0; i < N; ++i) { - final InputMethodInfo imi = imis.get(i); - final InputMethodPreference pref = getInputMethodPreference(imi, N); - mInputMethodPreferenceList.add(pref); - } - - if (!mInputMethodPreferenceList.isEmpty()) { - Collections.sort(mInputMethodPreferenceList); + synchronized (mInputMethodPreferenceList) { + mInputMethodPreferenceList.clear(); + final List imis = mInputMethodSettingValues.getInputMethodList(); + final int N = (imis == null ? 0 : imis.size()); for (int i = 0; i < N; ++i) { - mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i)); + final InputMethodInfo imi = imis.get(i); + final InputMethodPreference pref = getInputMethodPreference(imi); + pref.setOnImePreferenceChangeListener(mOnImePreferenceChangedListener); + mInputMethodPreferenceList.add(pref); + } + + if (!mInputMethodPreferenceList.isEmpty()) { + Collections.sort(mInputMethodPreferenceList); + for (int i = 0; i < N; ++i) { + mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i)); + } } } @@ -299,7 +313,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment InputMethodAndSubtypeUtil.loadInputMethodSubtypeList( this, getContentResolver(), mInputMethodSettingValues.getInputMethodList(), null); - updateActiveInputMethodsSummary(); + updateInputMethodPreferenceViews(); } @Override @@ -409,10 +423,12 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment return false; } - private void updateActiveInputMethodsSummary() { - for (Preference pref : mInputMethodPreferenceList) { - if (pref instanceof InputMethodPreference) { - ((InputMethodPreference)pref).updateSummary(); + private void updateInputMethodPreferenceViews() { + synchronized (mInputMethodPreferenceList) { + for (Preference pref : mInputMethodPreferenceList) { + if (pref instanceof InputMethodPreference) { + ((InputMethodPreference) pref).updatePreferenceViews(); + } } } updateCurrentImeName(); @@ -433,7 +449,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } } - private InputMethodPreference getInputMethodPreference(InputMethodInfo imi, int imiSize) { + private InputMethodPreference getInputMethodPreference(InputMethodInfo imi) { final PackageManager pm = getPackageManager(); final CharSequence label = imi.loadLabel(pm); // IME settings @@ -447,7 +463,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } // Add a check box for enabling/disabling IME - InputMethodPreference pref = new InputMethodPreference(this, intent, mImm, imi, imiSize); + final InputMethodPreference pref = + new InputMethodPreference(this, intent, mImm, imi); pref.setKey(imi.getId()); pref.setTitle(label); return pref; diff --git a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java index 936b1a6d582..561302ab35a 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java +++ b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java @@ -20,10 +20,6 @@ import com.android.internal.inputmethod.InputMethodUtils; import com.android.settings.SettingsPreferenceFragment; import android.content.ContentResolver; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.res.Resources; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceScreen; @@ -32,13 +28,11 @@ import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import android.util.Log; import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; public class InputMethodAndSubtypeUtil { @@ -49,7 +43,6 @@ public class InputMethodAndSubtypeUtil { private static final char INPUT_METHOD_SEPARATER = ':'; private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';'; private static final int NOT_A_SUBTYPE_ID = -1; - private static final Locale ENGLISH_LOCALE = new Locale("en"); private static final TextUtils.SimpleStringSplitter sStringInputMethodSplitter = new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER); diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java index e85b3fca0b6..3f7b8691e0f 100644 --- a/src/com/android/settings/inputmethod/InputMethodPreference.java +++ b/src/com/android/settings/inputmethod/InputMethodPreference.java @@ -24,6 +24,7 @@ import com.android.settings.Utils; import android.app.AlertDialog; import android.app.Fragment; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; @@ -52,8 +53,8 @@ public class InputMethodPreference extends CheckBoxPreference { private final SettingsPreferenceFragment mFragment; private final InputMethodInfo mImi; private final InputMethodManager mImm; + private final boolean mIsValidSystemNonAuxAsciiCapableIme; private final Intent mSettingsIntent; - private final boolean mAlwaysChecked; private final boolean mIsSystemIme; private final Collator mCollator; @@ -62,6 +63,7 @@ public class InputMethodPreference extends CheckBoxPreference { private TextView mTitleText; private TextView mSummaryText; private View mInputMethodPref; + private OnPreferenceChangeListener mOnImePreferenceChangeListener; private final OnClickListener mPrefOnclickListener = new OnClickListener() { @Override @@ -82,7 +84,7 @@ public class InputMethodPreference extends CheckBoxPreference { }; public InputMethodPreference(SettingsPreferenceFragment fragment, Intent settingsIntent, - InputMethodManager imm, InputMethodInfo imi, int imiCount) { + InputMethodManager imm, InputMethodInfo imi) { super(fragment.getActivity(), null, R.style.InputMethodPreferenceStyle); setLayoutResource(R.layout.preference_inputmethod); setWidgetLayoutResource(R.layout.preference_inputmethod_widget); @@ -90,15 +92,12 @@ public class InputMethodPreference extends CheckBoxPreference { mSettingsIntent = settingsIntent; mImm = imm; mImi = imi; - updateSummary(); - mAlwaysChecked = InputMethodSettingValuesWrapper.getInstance( - fragment.getActivity()).isAlwaysCheckedIme( - imi, fragment.getActivity()); mIsSystemIme = InputMethodUtils.isSystemIme(imi); - if (mAlwaysChecked) { - setEnabled(false); - } mCollator = Collator.getInstance(fragment.getResources().getConfiguration().locale); + final Context context = fragment.getActivity(); + mIsValidSystemNonAuxAsciiCapableIme = InputMethodSettingValuesWrapper + .getInstance(context).isValidSystemNonAuxAsciiCapableIme(imi, context); + updatePreferenceViews(); } @Override @@ -158,9 +157,8 @@ public class InputMethodPreference extends CheckBoxPreference { } if (mSettingsIntent == null) { mInputMethodSettingsButton.setVisibility(View.GONE); - } else { - updatePreferenceViews(); } + updatePreferenceViews(); } @Override @@ -169,7 +167,16 @@ public class InputMethodPreference extends CheckBoxPreference { updatePreferenceViews(); } - private void updatePreferenceViews() { + public void updatePreferenceViews() { + final boolean isAlwaysChecked = + InputMethodSettingValuesWrapper.getInstance(getContext()).isAlwaysCheckedIme( + mImi, getContext()); + if (isAlwaysChecked) { + super.setChecked(true); + super.setEnabled(false); + } else { + super.setEnabled(true); + } final boolean checked = isChecked(); if (mInputMethodSettingsButton != null) { mInputMethodSettingsButton.setEnabled(checked); @@ -194,6 +201,7 @@ public class InputMethodPreference extends CheckBoxPreference { mInputMethodPref.setBackgroundColor(0); } } + updateSummary(); } public static boolean startFragment( @@ -211,7 +219,7 @@ public class InputMethodPreference extends CheckBoxPreference { } } - public String getSummaryString() { + private String getSummaryString() { final StringBuilder builder = new StringBuilder(); final List subtypes = mImm.getEnabledInputMethodSubtypeList(mImi, true); for (InputMethodSubtype subtype : subtypes) { @@ -225,7 +233,7 @@ public class InputMethodPreference extends CheckBoxPreference { return builder.toString(); } - public void updateSummary() { + private void updateSummary() { final String summary = getSummaryString(); if (TextUtils.isEmpty(summary)) { return; @@ -238,17 +246,21 @@ public class InputMethodPreference extends CheckBoxPreference { * @param checked whether to check the box * @param save whether to save IME settings */ - public void setChecked(boolean checked, boolean save) { + private void setChecked(boolean checked, boolean save) { + final boolean wasChecked = isChecked(); super.setChecked(checked); if (save) { saveImeSettings(); + InputMethodSettingValuesWrapper.getInstance( + getContext()).refreshAllInputMethodAndSubtypes(); + if (wasChecked != checked && mOnImePreferenceChangeListener != null) { + mOnImePreferenceChangeListener.onPreferenceChange(this, checked); + } } - updateSummary(); } - @Override - public void setChecked(boolean checked) { - setChecked(checked, false); + public void setOnImePreferenceChangeListener(OnPreferenceChangeListener listener) { + mOnImePreferenceChangeListener = listener; } private void showSecurityWarnDialog(InputMethodInfo imi, final InputMethodPreference chkPref) { @@ -285,8 +297,8 @@ public class InputMethodPreference extends CheckBoxPreference { return super.compareTo(p); } final InputMethodPreference imp = (InputMethodPreference) p; - final boolean priority0 = mIsSystemIme && mAlwaysChecked; - final boolean priority1 = imp.mIsSystemIme && imp.mAlwaysChecked; + final boolean priority0 = mIsSystemIme && mIsValidSystemNonAuxAsciiCapableIme; + final boolean priority1 = imp.mIsSystemIme && imp.mIsValidSystemNonAuxAsciiCapableIme; if (priority0 == priority1) { final CharSequence t0 = getTitle(); final CharSequence t1 = imp.getTitle(); diff --git a/src/com/android/settings/inputmethod/InputMethodSettingValuesWrapper.java b/src/com/android/settings/inputmethod/InputMethodSettingValuesWrapper.java index b14f041898e..3d8563ee3e5 100644 --- a/src/com/android/settings/inputmethod/InputMethodSettingValuesWrapper.java +++ b/src/com/android/settings/inputmethod/InputMethodSettingValuesWrapper.java @@ -109,24 +109,67 @@ public class InputMethodSettingValuesWrapper { } public boolean isAlwaysCheckedIme(InputMethodInfo imi, Context context) { - if (getInputMethodList().size() <= 1) { - return true; + synchronized (mMethodMap) { + if (mSettings.getEnabledInputMethodListLocked().size() <= 1) { + return true; + } } + + final int enabledValidSystemNonAuxAsciiCapableImeCount = + getEnabledValidSystemNonAuxAsciiCapableImeCount(context); + if (enabledValidSystemNonAuxAsciiCapableImeCount > 1) { + return false; + } + + if (enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabledImi(imi)) { + return false; + } + if (!InputMethodUtils.isSystemIme(imi)) { return false; } return isValidSystemNonAuxAsciiCapableIme(imi, context); } - private static boolean isValidSystemNonAuxAsciiCapableIme( - InputMethodInfo imi, Context context) { + private int getEnabledValidSystemNonAuxAsciiCapableImeCount(Context context) { + int count = 0; + final List enabledImis; + synchronized(mMethodMap) { + enabledImis = mSettings.getEnabledInputMethodListLocked(); + } + for (final InputMethodInfo imi : enabledImis) { + if (isValidSystemNonAuxAsciiCapableIme(imi, context)) { + ++count; + } + } + if (count == 0) { + Log.w(TAG, "No \"enabledValidSystemNonAuxAsciiCapableIme\"s found."); + } + return count; + } + + private boolean isEnabledImi(InputMethodInfo imi) { + final List enabledImis; + synchronized(mMethodMap) { + enabledImis = mSettings.getEnabledInputMethodListLocked(); + } + for (final InputMethodInfo tempImi : enabledImis) { + if (tempImi.getId().equals(imi.getId())) { + return true; + } + } + return false; + } + + public static boolean isValidSystemNonAuxAsciiCapableIme(InputMethodInfo imi, + Context context) { if (imi.isAuxiliaryIme()) { return false; } if (InputMethodUtils.isValidSystemDefaultIme(true /* isSystemReady */, imi, context)) { return true; } - return InputMethodUtils.containsSubtypeOf( - imi, ENGLISH_LOCALE.getLanguage(), null /* mode */); + return InputMethodUtils.containsSubtypeOf(imi, ENGLISH_LOCALE.getLanguage(), + InputMethodUtils.SUBTYPE_MODE_KEYBOARD); } }