diff options
Diffstat (limited to 'services/java/com/android/server/InputMethodManagerService.java')
-rw-r--r-- | services/java/com/android/server/InputMethodManagerService.java | 138 |
1 files changed, 105 insertions, 33 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 8e3b825..a49ccf7 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -1142,6 +1142,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (mCurToken != null) { try { if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken); + if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0) { + // The current IME is shown. Hence an IME switch (transition) is happening. + mWindowManagerService.saveLastInputMethodWindowForTransition(); + } mIWindowManager.removeWindowToken(mCurToken); } catch (RemoteException e) { } @@ -2410,17 +2414,63 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - private static class ImeSubtypeListItem { + private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> { public final CharSequence mImeName; public final CharSequence mSubtypeName; public final InputMethodInfo mImi; public final int mSubtypeId; + private final boolean mIsSystemLocale; + private final boolean mIsSystemLanguage; + public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName, - InputMethodInfo imi, int subtypeId) { + InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) { mImeName = imeName; mSubtypeName = subtypeName; mImi = imi; mSubtypeId = subtypeId; + if (TextUtils.isEmpty(subtypeLocale)) { + mIsSystemLocale = false; + mIsSystemLanguage = false; + } else { + mIsSystemLocale = subtypeLocale.equals(systemLocale); + mIsSystemLanguage = mIsSystemLocale + || subtypeLocale.startsWith(systemLocale.substring(0, 2)); + } + } + + @Override + public int compareTo(ImeSubtypeListItem other) { + if (TextUtils.isEmpty(mImeName)) { + return 1; + } + if (TextUtils.isEmpty(other.mImeName)) { + return -1; + } + if (!TextUtils.equals(mImeName, other.mImeName)) { + return mImeName.toString().compareTo(other.mImeName.toString()); + } + if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) { + return 0; + } + if (mIsSystemLocale) { + return -1; + } + if (other.mIsSystemLocale) { + return 1; + } + if (mIsSystemLanguage) { + return -1; + } + if (other.mIsSystemLanguage) { + return 1; + } + if (TextUtils.isEmpty(mSubtypeName)) { + return 1; + } + if (TextUtils.isEmpty(other.mSubtypeName)) { + return -1; + } + return mSubtypeName.toString().compareTo(other.mSubtypeName.toString()); } } @@ -2619,7 +2669,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return getSubtypeIdFromHashCode(imi, subtypeId); } - private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) { + private static boolean isValidSubtypeId(InputMethodInfo imi, int subtypeHashCode) { + return getSubtypeIdFromHashCode(imi, subtypeHashCode) != NOT_A_SUBTYPE_ID; + } + + private static int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) { if (imi != null) { final int subtypeCount = imi.getSubtypeCount(); for (int i = 0; i < subtypeCount; ++i) { @@ -2844,6 +2898,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ @Override public InputMethodSubtype getCurrentInputMethodSubtype() { + if (mCurMethodId == null) { + return null; + } boolean subtypeIsSelected = false; try { subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(), @@ -2851,36 +2908,35 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } catch (SettingNotFoundException e) { } synchronized (mMethodMap) { - if (!subtypeIsSelected || mCurrentSubtype == null) { - String lastInputMethodId = Settings.Secure.getString( - mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId); + final InputMethodInfo imi = mMethodMap.get(mCurMethodId); + if (imi == null || imi.getSubtypeCount() == 0) { + return null; + } + if (!subtypeIsSelected || mCurrentSubtype == null + || !isValidSubtypeId(imi, mCurrentSubtype.hashCode())) { + int subtypeId = getSelectedInputMethodSubtypeId(mCurMethodId); if (subtypeId == NOT_A_SUBTYPE_ID) { - InputMethodInfo imi = mMethodMap.get(lastInputMethodId); - if (imi != null) { - // If there are no selected subtypes, the framework will try to find - // the most applicable subtype from explicitly or implicitly enabled - // subtypes. - List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes = - getEnabledInputMethodSubtypeList(imi, true); - // If there is only one explicitly or implicitly enabled subtype, - // just returns it. - if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) { - mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0); - } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) { + // If there are no selected subtypes, the framework will try to find + // the most applicable subtype from explicitly or implicitly enabled + // subtypes. + List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes = + getEnabledInputMethodSubtypeList(imi, true); + // If there is only one explicitly or implicitly enabled subtype, + // just returns it. + if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) { + mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0); + } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) { + mCurrentSubtype = findLastResortApplicableSubtypeLocked( + mRes, explicitlyOrImplicitlyEnabledSubtypes, + SUBTYPE_MODE_KEYBOARD, null, true); + if (mCurrentSubtype == null) { mCurrentSubtype = findLastResortApplicableSubtypeLocked( - mRes, explicitlyOrImplicitlyEnabledSubtypes, - SUBTYPE_MODE_KEYBOARD, null, true); - if (mCurrentSubtype == null) { - mCurrentSubtype = findLastResortApplicableSubtypeLocked( - mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null, - true); - } + mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null, + true); } } } else { - mCurrentSubtype = - getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId); + mCurrentSubtype = getSubtypes(imi).get(subtypeId); } } return mCurrentSubtype; @@ -2946,10 +3002,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final Context mContext; private final PackageManager mPm; private final InputMethodManagerService mImms; + private final String mSystemLocaleStr; public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) { mContext = context; mPm = context.getPackageManager(); mImms = imms; + mSystemLocaleStr = + imms.mLastSystemLocale != null ? imms.mLastSystemLocale.toString() : ""; } private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis = @@ -2979,7 +3038,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } final int N = imList.size(); final int currentSubtypeId = subtype != null - ? mImms.getSubtypeIdFromHashCode(imi, subtype.hashCode()) + ? getSubtypeIdFromHashCode(imi, subtype.hashCode()) : NOT_A_SUBTYPE_ID; for (int i = 0; i < N; ++i) { final ImeSubtypeListItem isli = imList.get(i); @@ -3037,7 +3096,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub subtype.overridesImplicitlyEnabledSubtype() ? null : subtype.getDisplayName(mContext, imi.getPackageName(), imi.getServiceInfo().applicationInfo); - imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j)); + imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j, + subtype.getLocale(), mSystemLocaleStr)); // Removing this subtype from enabledSubtypeSet because we no longer // need to add an entry of this subtype to imList to avoid duplicated @@ -3046,9 +3106,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } } else { - imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID)); + imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID, + null, mSystemLocaleStr)); } } + Collections.sort(imList); return imList; } } @@ -3356,10 +3418,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub for (Pair<String, ArrayList<String>> enabledIme: enabledImes) { if (enabledIme.first.equals(imeId)) { final ArrayList<String> explicitlyEnabledSubtypes = enabledIme.second; + final InputMethodInfo imi = mMethodMap.get(imeId); if (explicitlyEnabledSubtypes.size() == 0) { // If there are no explicitly enabled subtypes, applicable subtypes are // enabled implicitly. - InputMethodInfo imi = mMethodMap.get(imeId); // If IME is enabled and no subtypes are enabled, applicable subtypes // are enabled implicitly, so needs to treat them to be enabled. if (imi != null && imi.getSubtypeCount() > 0) { @@ -3379,7 +3441,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub for (String s: explicitlyEnabledSubtypes) { if (s.equals(subtypeHashCode)) { // If both imeId and subtypeId are enabled, return subtypeId. - return s; + try { + final int hashCode = Integer.valueOf(subtypeHashCode); + // Check whether the subtype id is valid or not + if (isValidSubtypeId(imi, hashCode)) { + return s; + } else { + return NOT_A_SUBTYPE_ID_STR; + } + } catch (NumberFormatException e) { + return NOT_A_SUBTYPE_ID_STR; + } } } } |