OSDN Git Service

Allow the users to disable system IME
authorSatoshi Kataoka <satok@google.com>
Wed, 31 Jul 2013 07:20:29 +0000 (16:20 +0900)
committerSatoshi Kataoka <satok@google.com>
Fri, 2 Aug 2013 11:06:34 +0000 (20:06 +0900)
Bug: 8364845
Change-Id: Icc5173a68fa00b2895c0768ff8f8b9dcf30e6171

src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java
src/com/android/settings/inputmethod/InputMethodPreference.java
src/com/android/settings/inputmethod/InputMethodSettingValuesWrapper.java

index 45b1182..32e8e83 100644 (file)
@@ -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<InputMethodInfo> 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<InputMethodInfo> 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;
index 936b1a6..561302a 100644 (file)
@@ -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);
index e85b3fc..3f7b869 100644 (file)
@@ -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<InputMethodSubtype> 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();
index b14f041..3d8563e 100644 (file)
@@ -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<InputMethodInfo> 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<InputMethodInfo> 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);
     }
 }