diff options
| author | satok <satok@google.com> | 2010-11-11 14:58:11 +0900 |
|---|---|---|
| committer | satok <satok@google.com> | 2010-11-11 17:13:10 +0900 |
| commit | 723a27ef3d7c94fc666abc52e0abd5e8526acb69 (patch) | |
| tree | 40d37ba6b92831acceb6f0402035bb4a7b56d99d /services/java | |
| parent | a6689ddbba5d7d5e9ad7a07ae84a187497f18121 (diff) | |
| download | frameworks_base-723a27ef3d7c94fc666abc52e0abd5e8526acb69.zip frameworks_base-723a27ef3d7c94fc666abc52e0abd5e8526acb69.tar.gz frameworks_base-723a27ef3d7c94fc666abc52e0abd5e8526acb69.tar.bz2 | |
Save the history of InputMethodSubtype for reverting the subtype when IME was changed.
- Re-revert the change https://android-git.corp.google.com/g/#q,78962,n,z
*** If you want to see the diff between reverted change and new change, please see the diff between patch set 1 and the latest patch set
- TODO: Add a public function "switchToLastInputMethod"
Change-Id: Ic85d54b3b68e47a22360acaeb81202a366a34586
Diffstat (limited to 'services/java')
| -rw-r--r-- | services/java/com/android/server/InputMethodManagerService.java | 275 |
1 files changed, 228 insertions, 47 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index d035eb5..0d3cfde 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -116,6 +116,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final long TIME_TO_RECONNECT = 10*1000; private static final int NOT_A_SUBTYPE_ID = -1; + private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID); // If IME doesn't support the system locale, the default subtype will be the first defined one. private static final int DEFAULT_SUBTYPE_ID = 0; @@ -366,9 +367,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!doit) { return true; } - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, ""); - resetSelectedInputMethodSubtype(); + resetSelectedInputMethodAndSubtypeLocked(""); chooseNewDefaultIMELocked(); return true; } @@ -425,9 +424,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub changed = true; curIm = null; Slog.i(TAG, "Unsetting current input method"); - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, ""); - resetSelectedInputMethodSubtype(); + resetSelectedInputMethodAndSubtypeLocked(""); } } } @@ -510,9 +507,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.i(TAG, "No default found, using " + defIm.getId()); } if (defIm != null) { - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId()); - putSelectedInputMethodSubtype(defIm, NOT_A_SUBTYPE_ID); + setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false); } } @@ -994,7 +989,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub synchronized (mMethodMap) { if (mCurMethod != null) { try { - putSelectedInputMethodSubtype(info, subtypeId); + setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true); if (mInputShown) { // If mInputShown is false, there is no IME button on the // system bar. @@ -1014,13 +1009,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final long ident = Binder.clearCallingIdentity(); try { - mCurMethodId = id; // Set a subtype to this input method. // subtypeId the name of a subtype which will be set. - putSelectedInputMethodSubtype(info, subtypeId); - - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, id); + setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false); + // mCurMethodId should be updated after setSelectedInputMethodAndSubtypeLocked() + // because mCurMethodId is stored as a history in + // setSelectedInputMethodAndSubtypeLocked(). + mCurMethodId = id; if (ActivityManagerNative.isSystemReady()) { Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED); @@ -1487,9 +1482,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } InputMethodInfo imi = enabled.get(i); - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.DEFAULT_INPUT_METHOD, imi.getId()); - putSelectedInputMethodSubtype(imi, NOT_A_SUBTYPE_ID); + resetSelectedInputMethodAndSubtypeLocked(imi.getId()); return true; } @@ -1793,11 +1786,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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(); + resetSelectedInputMethodAndSubtypeLocked(enabledInputMethodsList.size() > 0 + ? enabledInputMethodsList.get(0).first : ""); } // Previous state was enabled. return true; @@ -1809,30 +1799,63 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - private void resetSelectedInputMethodSubtype() { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, NOT_A_SUBTYPE_ID); + private void saveCurrentInputMethodAndSubtypeToHistory() { + String subtypeId = NOT_A_SUBTYPE_ID_STR; + if (mCurrentSubtype != null) { + subtypeId = String.valueOf(mCurrentSubtype.hashCode()); + } + mSettings.addSubtypeToHistory(mCurMethodId, subtypeId); } - private void putSelectedInputMethodSubtype(InputMethodInfo imi, int subtypeId) { - final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); - if (subtypeId >= 0 && subtypeId < subtypes.size()) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, - subtypes.get(subtypeId).hashCode()); - mCurrentSubtype = subtypes.get(subtypeId); - } else { - resetSelectedInputMethodSubtype(); + private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId, + boolean setSubtypeOnly) { + // Update the history of InputMethod and Subtype + saveCurrentInputMethodAndSubtypeToHistory(); + + // Set Subtype here + if (imi == null || subtypeId < 0) { + mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); mCurrentSubtype = null; + } else { + final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); + if (subtypeId < subtypes.size()) { + mSettings.putSelectedSubtype(subtypes.get(subtypeId).hashCode()); + mCurrentSubtype = subtypes.get(subtypeId); + } else { + mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); + mCurrentSubtype = null; + } + } + + if (!setSubtypeOnly) { + // Set InputMethod here + mSettings.putSelectedInputMethod(imi != null ? imi.getId() : ""); } } + private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) { + InputMethodInfo imi = mMethodMap.get(newDefaultIme); + int lastSubtypeId = NOT_A_SUBTYPE_ID; + // newDefaultIme is empty when there is no candidate for the selected IME. + if (imi != null && !TextUtils.isEmpty(newDefaultIme)) { + String subtypeHashCode = mSettings.getLastSubtypeForInputMethodLocked(newDefaultIme); + if (subtypeHashCode != null) { + try { + lastSubtypeId = getSubtypeIdFromHashCode( + imi, Integer.valueOf(subtypeHashCode)); + } catch (NumberFormatException e) { + Slog.w(TAG, "HashCode for subtype looks broken: " + subtypeHashCode, e); + } + } + } + setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false); + } + private int getSelectedInputMethodSubtypeId(String id) { InputMethodInfo imi = mMethodMap.get(id); if (imi == null) { return NOT_A_SUBTYPE_ID; } - ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); int subtypeId; try { subtypeId = Settings.Secure.getInt(mContext.getContentResolver(), @@ -1840,9 +1863,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } catch (SettingNotFoundException e) { return NOT_A_SUBTYPE_ID; } + return getSubtypeIdFromHashCode(imi, subtypeId); + } + + private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) { + ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); for (int i = 0; i < subtypes.size(); ++i) { InputMethodSubtype ims = subtypes.get(i); - if (subtypeId == ims.hashCode()) { + if (subtypeHashCode == ims.hashCode()) { return i; } } @@ -1922,10 +1950,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // 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 = + private final TextUtils.SimpleStringSplitter mInputMethodSplitter = new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER); - private final TextUtils.SimpleStringSplitter mStringSemiColonSplitter = + private final TextUtils.SimpleStringSplitter mSubtypeSplitter = new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER); private final ContentResolver mResolver; @@ -1988,16 +2016,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (TextUtils.isEmpty(enabledInputMethodsStr)) { return imsList; } - mStringColonSplitter.setString(enabledInputMethodsStr); - while (mStringColonSplitter.hasNext()) { - String nextImsStr = mStringColonSplitter.next(); - mStringSemiColonSplitter.setString(nextImsStr); - if (mStringSemiColonSplitter.hasNext()) { + mInputMethodSplitter.setString(enabledInputMethodsStr); + while (mInputMethodSplitter.hasNext()) { + String nextImsStr = mInputMethodSplitter.next(); + mSubtypeSplitter.setString(nextImsStr); + if (mSubtypeSplitter.hasNext()) { ArrayList<String> subtypeHashes = new ArrayList<String>(); // The first element is ime id. - String imeId = mStringSemiColonSplitter.next(); - while (mStringSemiColonSplitter.hasNext()) { - subtypeHashes.add(mStringSemiColonSplitter.next()); + String imeId = mSubtypeSplitter.next(); + while (mSubtypeSplitter.hasNext()) { + subtypeHashes.add(mSubtypeSplitter.next()); } imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes)); } @@ -2083,8 +2111,161 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private String getEnabledInputMethodsStr() { mEnabledInputMethodsStrCache = Settings.Secure.getString( mResolver, Settings.Secure.ENABLED_INPUT_METHODS); + if (DEBUG) { + Slog.d(TAG, "getEnabledInputMethodsStr: " + mEnabledInputMethodsStrCache); + } return mEnabledInputMethodsStrCache; } + + private void saveSubtypeHistory( + List<Pair<String, String>> savedImes, String newImeId, String newSubtypeId) { + StringBuilder builder = new StringBuilder(); + boolean isImeAdded = false; + if (!TextUtils.isEmpty(newImeId) && !TextUtils.isEmpty(newSubtypeId)) { + builder.append(newImeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append( + newSubtypeId); + isImeAdded = true; + } + for (Pair<String, String> ime: savedImes) { + String imeId = ime.first; + String subtypeId = ime.second; + if (TextUtils.isEmpty(subtypeId)) { + subtypeId = NOT_A_SUBTYPE_ID_STR; + } + if (isImeAdded) { + builder.append(INPUT_METHOD_SEPARATER); + } else { + isImeAdded = true; + } + builder.append(imeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append( + subtypeId); + } + // Remove the last INPUT_METHOD_SEPARATER + putSubtypeHistoryStr(builder.toString()); + } + + public void addSubtypeToHistory(String imeId, String subtypeId) { + List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); + for (Pair<String, String> ime: subtypeHistory) { + if (ime.first.equals(imeId)) { + if (DEBUG) { + Slog.v(TAG, "Subtype found in the history: " + imeId + + ime.second); + } + // We should break here + subtypeHistory.remove(ime); + break; + } + } + saveSubtypeHistory(subtypeHistory, imeId, subtypeId); + } + + private void putSubtypeHistoryStr(String str) { + if (DEBUG) { + Slog.d(TAG, "putSubtypeHistoryStr: " + str); + } + Settings.Secure.putString( + mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, str); + } + + public Pair<String, String> getLastInputMethodAndSubtypeLocked() { + // Gets the first one from the history + return getLastSubtypeForInputMethodLockedInternal(null); + } + + public String getLastSubtypeForInputMethodLocked(String imeId) { + Pair<String, String> ime = getLastSubtypeForInputMethodLockedInternal(imeId); + if (ime != null) { + return ime.second; + } else { + return null; + } + } + + private Pair<String, String> getLastSubtypeForInputMethodLockedInternal(String imeId) { + List<Pair<String, ArrayList<String>>> enabledImes = + getEnabledInputMethodsAndSubtypeListLocked(); + List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); + for (Pair<String, String> imeAndSubtype: subtypeHistory) { + final String imeInTheHistory = imeAndSubtype.first; + // If imeId is empty, returns the first IME and subtype in the history + if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) { + final String subtypeInTheHistory = imeAndSubtype.second; + final String subtypeHashCode = getEnabledSubtypeForInputMethodAndSubtypeLocked( + enabledImes, imeInTheHistory, subtypeInTheHistory); + if (!TextUtils.isEmpty(subtypeHashCode)) { + if (DEBUG) { + Slog.d(TAG, "Enabled subtype found in the history:" + subtypeHashCode); + } + return new Pair<String, String>(imeInTheHistory, subtypeHashCode); + } + } + } + if (DEBUG) { + Slog.d(TAG, "No enabled IME found in the history"); + } + return null; + } + + private String getEnabledSubtypeForInputMethodAndSubtypeLocked(List<Pair<String, + ArrayList<String>>> enabledImes, String imeId, String subtypeHashCode) { + for (Pair<String, ArrayList<String>> enabledIme: enabledImes) { + if (enabledIme.first.equals(imeId)) { + for (String s: enabledIme.second) { + if (s.equals(subtypeHashCode)) { + // If both imeId and subtypeId are enabled, return subtypeId. + return s; + } + } + // If imeId was enabled but subtypeId was disabled. + return NOT_A_SUBTYPE_ID_STR; + } + } + // If both imeId and subtypeId are disabled, return null + return null; + } + + private List<Pair<String, String>> loadInputMethodAndSubtypeHistoryLocked() { + ArrayList<Pair<String, String>> imsList = new ArrayList<Pair<String, String>>(); + final String subtypeHistoryStr = getSubtypeHistoryStr(); + if (TextUtils.isEmpty(subtypeHistoryStr)) { + return imsList; + } + mInputMethodSplitter.setString(subtypeHistoryStr); + while (mInputMethodSplitter.hasNext()) { + String nextImsStr = mInputMethodSplitter.next(); + mSubtypeSplitter.setString(nextImsStr); + if (mSubtypeSplitter.hasNext()) { + String subtypeId = NOT_A_SUBTYPE_ID_STR; + // The first element is ime id. + String imeId = mSubtypeSplitter.next(); + while (mSubtypeSplitter.hasNext()) { + subtypeId = mSubtypeSplitter.next(); + break; + } + imsList.add(new Pair<String, String>(imeId, subtypeId)); + } + } + return imsList; + } + + private String getSubtypeHistoryStr() { + if (DEBUG) { + Slog.d(TAG, "getSubtypeHistoryStr: " + Settings.Secure.getString( + mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY)); + } + return Settings.Secure.getString( + mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY); + } + + public void putSelectedInputMethod(String imeId) { + Settings.Secure.putString(mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, imeId); + } + + public void putSelectedSubtype(int subtypeId) { + Settings.Secure.putInt( + mResolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtypeId); + } } // ---------------------------------------------------------------------- |
