diff options
| author | satok <satok@google.com> | 2010-09-29 11:52:06 +0900 |
|---|---|---|
| committer | satok <satok@google.com> | 2010-10-05 14:51:31 +0900 |
| commit | d87c2594c688b4ed8fc9c14053abfbc5ea87fb5e (patch) | |
| tree | 2696f96d97e80803e0abf9e246f319a42e728458 /services/java/com/android/server/InputMethodManagerService.java | |
| parent | 2fe9a8f6f6a5264597a9dbed2fb2e02d84853189 (diff) | |
Add utility of enabled InputMethod settings to InputMethodManagerService
- Add setter of enabled InputMethodSubtypes
- Enabled InputMethods are saved as follows:
-- enabled_inputmethod0;enabled_subtype0;enabled_subtype1:enabled_inputmethod1
- TODO: Fix Settings application to parse new Enabled InputMethod string.
-- Currently IMMS doesn't save InputMethodSubtypes so this will not break Settings application.
Change-Id: Icd0f13de396ce286ff6563e8c2775d53bcdacbf3
Diffstat (limited to 'services/java/com/android/server/InputMethodManagerService.java')
| -rw-r--r-- | services/java/com/android/server/InputMethodManagerService.java | 319 |
1 files changed, 201 insertions, 118 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index de283754ec59..9a5423c0c889 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -117,6 +117,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final Context mContext; final Handler mHandler; + final InputMethodSettings mSettings; final SettingsObserver mSettingsObserver; final StatusBarManagerService mStatusBar; final IWindowManager mIWindowManager; @@ -126,13 +127,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // All known input methods. mMethodMap also serves as the global // lock for this class. - final ArrayList<InputMethodInfo> mMethodList - = new ArrayList<InputMethodInfo>(); - final HashMap<String, InputMethodInfo> mMethodMap - = new HashMap<String, InputMethodInfo>(); - - final TextUtils.SimpleStringSplitter mStringColonSplitter - = new TextUtils.SimpleStringSplitter(':'); + final ArrayList<InputMethodInfo> mMethodList = new ArrayList<InputMethodInfo>(); + final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<String, InputMethodInfo>(); class SessionState { final ClientState client; @@ -483,27 +479,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mStatusBar = statusBar; statusBar.setIconVisibility("ime", false); + // mSettings should be created before buildInputMethodListLocked + mSettings = new InputMethodSettings(context.getContentResolver(), mMethodMap, mMethodList); buildInputMethodListLocked(mMethodList, mMethodMap); + mSettings.enableAllIMEsIfThereIsNoEnabledIME(); - final String enabledStr = Settings.Secure.getString( - mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS); - Slog.i(TAG, "Enabled input methods: " + enabledStr); - final String defaultIme = Settings.Secure.getString(mContext - .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - if (enabledStr == null || TextUtils.isEmpty(defaultIme)) { - Slog.i(TAG, "Enabled input methods or default IME has not been set, enabling all"); + if (TextUtils.isEmpty(Settings.Secure.getString( + mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD))) { InputMethodInfo defIm = null; - StringBuilder sb = new StringBuilder(256); - final int N = mMethodList.size(); - for (int i=0; i<N; i++) { - InputMethodInfo imi = mMethodList.get(i); - Slog.i(TAG, "Adding: " + imi.getId()); - if (i > 0) sb.append(':'); - sb.append(imi.getId()); + for (InputMethodInfo imi: mMethodList) { if (defIm == null && imi.getIsDefaultResourceId() != 0) { try { - Resources res = mContext.createPackageContext( + Resources res = context.createPackageContext( imi.getPackageName(), 0).getResources(); if (res.getBoolean(imi.getIsDefaultResourceId())) { defIm = imi; @@ -514,12 +501,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } } - if (defIm == null && N > 0) { + if (defIm == null && mMethodList.size() > 0) { defIm = mMethodList.get(0); Slog.i(TAG, "No default found, using " + defIm.getId()); } - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS, sb.toString()); if (defIm != null) { Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId()); @@ -567,31 +552,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub public List<InputMethodInfo> getEnabledInputMethodList() { synchronized (mMethodMap) { - return getEnabledInputMethodListLocked(); + return mSettings.getEnabledInputMethodListLocked(); } } - List<InputMethodInfo> getEnabledInputMethodListLocked() { - final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>(); - - final String enabledStr = Settings.Secure.getString( - mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS); - if (enabledStr != null) { - final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; - splitter.setString(enabledStr); - - while (splitter.hasNext()) { - InputMethodInfo info = mMethodMap.get(splitter.next()); - if (info != null) { - res.add(info); - } - } - } - - return res; - } - public void addClient(IInputMethodClient client, IInputContext inputContext, int uid, int pid) { synchronized (mMethodMap) { @@ -1471,7 +1435,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } private boolean chooseNewDefaultIMELocked() { - List<InputMethodInfo> enabled = getEnabledInputMethodListLocked(); + List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked(); if (enabled != null && enabled.size() > 0) { // We'd prefer to fall back on a system IME, since that is safer. int i=enabled.size(); @@ -1650,7 +1614,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub hideInputMethodMenu(); } }; - + TypedArray a = context.obtainStyledAttributes(null, com.android.internal.R.styleable.DialogPreference, com.android.internal.R.attr.alertDialogStyle, 0); @@ -1664,7 +1628,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub .setIcon(a.getDrawable( com.android.internal.R.styleable.DialogPreference_dialogTitle)); a.recycle(); - + mDialogBuilder.setSingleChoiceItems(mItems, checkedItem, new AlertDialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { @@ -1738,81 +1702,45 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Make sure this is a valid input method. InputMethodInfo imm = mMethodMap.get(id); if (imm == null) { - if (imm == null) { - throw new IllegalArgumentException("Unknown id: " + mCurMethodId); - } + throw new IllegalArgumentException("Unknown id: " + mCurMethodId); } - StringBuilder builder = new StringBuilder(256); + List<Pair<String, ArrayList<String>>> enabledInputMethodsList = mSettings + .getEnabledInputMethodsAndSubtypeListLocked(); - boolean removed = false; - String firstId = null; - - // Look through the currently enabled input methods. - String enabledStr = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS); - if (enabledStr != null) { - final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter; - splitter.setString(enabledStr); - while (splitter.hasNext()) { - String curId = splitter.next(); - if (curId.equals(id)) { - if (enabled) { - // We are enabling this input method, but it is - // already enabled. Nothing to do. The previous - // state was enabled. - return true; - } - // We are disabling this input method, and it is - // currently enabled. Skip it to remove from the - // new list. - removed = true; - } else if (!enabled) { - // We are building a new list of input methods that - // doesn't contain the given one. - if (firstId == null) firstId = curId; - if (builder.length() > 0) builder.append(':'); - builder.append(curId); + if (enabled) { + for (Pair<String, ArrayList<String>> pair: enabledInputMethodsList) { + if (pair.first.equals(id)) { + // We are enabling this input method, but it is already enabled. + // Nothing to do. The previous state was enabled. + return true; } } - } - - if (!enabled) { - if (!removed) { - // We are disabling the input method but it is already - // disabled. Nothing to do. The previous state was - // disabled. + mSettings.appendAndPutEnabledInputMethodLocked(id, false); + // Previous state was disabled. + return false; + } else { + StringBuilder builder = new StringBuilder(); + if (mSettings.buildAndPutEnabledInputMethodsStrRemovingIdLocked( + builder, enabledInputMethodsList, id)) { + // Disabled input method is currently selected, switch to another one. + String selId = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.DEFAULT_INPUT_METHOD); + if (id.equals(selId)) { + Settings.Secure.putString( + mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD, + enabledInputMethodsList.size() > 0 + ? enabledInputMethodsList.get(0).first : ""); + resetSelectedInputMethodSubtype(); + } + // Previous state was enabled. + return true; + } else { + // We are disabling the input method but it is already disabled. + // Nothing to do. The previous state was disabled. return false; } - // Update the setting with the new list of input methods. - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS, builder.toString()); - // We the disabled input method is currently selected, switch - // to another one. - String selId = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD); - if (id.equals(selId)) { - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, - firstId != null ? firstId : ""); - resetSelectedInputMethodSubtype(); - } - // Previous state was enabled. - return true; - } - - // Add in the newly enabled input method. - if (enabledStr == null || enabledStr.length() == 0) { - enabledStr = id; - } else { - enabledStr = enabledStr + ':' + id; } - - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_INPUT_METHODS, enabledStr); - - // Previous state was disabled. - return false; } private void resetSelectedInputMethodSubtype() { @@ -1862,6 +1790,161 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mCurrentSubtype; } + /** + * Utility class for putting and getting settings for InputMethod + * TODO: Move all putters and getters of settings to this class. + */ + private static class InputMethodSettings { + // The string for enabled input method is saved as follows: + // example: ("ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0") + private static final char INPUT_METHOD_SEPARATER = ':'; + private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';'; + private final TextUtils.SimpleStringSplitter mStringColonSplitter = + new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER); + + private final TextUtils.SimpleStringSplitter mStringSemiColonSplitter = + new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER); + + private final ContentResolver mResolver; + private final HashMap<String, InputMethodInfo> mMethodMap; + private final ArrayList<InputMethodInfo> mMethodList; + + private String mEnabledInputMethodsStrCache; + + private static void buildEnabledInputMethodsSettingString( + StringBuilder builder, Pair<String, ArrayList<String>> pair) { + String id = pair.first; + ArrayList<String> subtypes = pair.second; + builder.append(id); + if (subtypes.size() > 0) { + builder.append(subtypes.get(0)); + for (int i = 1; i < subtypes.size(); ++i) { + builder.append(INPUT_METHOD_SUBTYPE_SEPARATER).append(subtypes.get(i)); + } + } + } + + public InputMethodSettings( + ContentResolver resolver, HashMap<String, InputMethodInfo> methodMap, + ArrayList<InputMethodInfo> methodList) { + mResolver = resolver; + mMethodMap = methodMap; + mMethodList = methodList; + } + + public List<InputMethodInfo> getEnabledInputMethodListLocked() { + return createEnabledInputMethodListLocked( + getEnabledInputMethodsAndSubtypeListLocked()); + } + + // At the initial boot, the settings for input methods are not set, + // so we need to enable IME in that case. + public void enableAllIMEsIfThereIsNoEnabledIME() { + if (TextUtils.isEmpty(getEnabledInputMethodsStr())) { + StringBuilder sb = new StringBuilder(); + final int N = mMethodList.size(); + for (int i = 0; i < N; i++) { + InputMethodInfo imi = mMethodList.get(i); + Slog.i(TAG, "Adding: " + imi.getId()); + if (i > 0) sb.append(':'); + sb.append(imi.getId()); + } + putEnabledInputMethodsStr(sb.toString()); + } + } + + public List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() { + ArrayList<Pair<String, ArrayList<String>>> imsList + = new ArrayList<Pair<String, ArrayList<String>>>(); + final String enabledInputMethodsStr = getEnabledInputMethodsStr(); + if (TextUtils.isEmpty(enabledInputMethodsStr)) { + return imsList; + } + mStringColonSplitter.setString(enabledInputMethodsStr); + while (mStringColonSplitter.hasNext()) { + String nextImsStr = mStringColonSplitter.next(); + mStringSemiColonSplitter.setString(nextImsStr); + if (mStringSemiColonSplitter.hasNext()) { + ArrayList<String> subtypeHashes = new ArrayList<String>(); + // The first element is ime id. + String imeId = mStringSemiColonSplitter.next(); + while (mStringSemiColonSplitter.hasNext()) { + subtypeHashes.add(mStringSemiColonSplitter.next()); + } + imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes)); + } + } + return imsList; + } + + public void appendAndPutEnabledInputMethodLocked(String id, boolean reloadInputMethodStr) { + if (reloadInputMethodStr) { + getEnabledInputMethodsStr(); + } + if (TextUtils.isEmpty(mEnabledInputMethodsStrCache)) { + // Add in the newly enabled input method. + putEnabledInputMethodsStr(id); + } else { + putEnabledInputMethodsStr( + mEnabledInputMethodsStrCache + INPUT_METHOD_SEPARATER + id); + } + } + + /** + * Build and put a string of EnabledInputMethods with removing specified Id. + * @return the specified id was removed or not. + */ + public boolean buildAndPutEnabledInputMethodsStrRemovingIdLocked( + StringBuilder builder, List<Pair<String, ArrayList<String>>> imsList, String id) { + boolean isRemoved = false; + boolean needsAppendSeparator = false; + for (Pair<String, ArrayList<String>> ims: imsList) { + String curId = ims.first; + if (curId.equals(id)) { + // We are disabling this input method, and it is + // currently enabled. Skip it to remove from the + // new list. + isRemoved = true; + } else { + if (needsAppendSeparator) { + builder.append(INPUT_METHOD_SEPARATER); + } else { + needsAppendSeparator = true; + } + buildEnabledInputMethodsSettingString(builder, ims); + } + } + if (isRemoved) { + // Update the setting with the new list of input methods. + putEnabledInputMethodsStr(builder.toString()); + } + return isRemoved; + } + + private List<InputMethodInfo> createEnabledInputMethodListLocked( + List<Pair<String, ArrayList<String>>> imsList) { + final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>(); + for (Pair<String, ArrayList<String>> ims: imsList) { + InputMethodInfo info = mMethodMap.get(ims.first); + if (info != null) { + res.add(info); + } + } + return res; + } + + private void putEnabledInputMethodsStr(String str) { + Settings.Secure.putString(mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str); + mEnabledInputMethodsStrCache = str; + } + + private String getEnabledInputMethodsStr() { + mEnabledInputMethodsStrCache = Settings.Secure.getString( + mResolver, Settings.Secure.ENABLED_INPUT_METHODS); + return mEnabledInputMethodsStrCache; + } + } + // ---------------------------------------------------------------------- @Override |
