summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java37
-rw-r--r--core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java28
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java34
3 files changed, 56 insertions, 43 deletions
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index efa3167..495d5c6 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -37,6 +37,10 @@ import java.util.TreeMap;
/**
* InputMethodSubtypeSwitchingController controls the switching behavior of the subtypes.
+ * <p>
+ * This class is designed to be used from and only from {@link InputMethodManagerService} by using
+ * {@link InputMethodManagerService#mMethodMap} as a global lock.
+ * </p>
*/
public class InputMethodSubtypeSwitchingController {
private static final String TAG = InputMethodSubtypeSwitchingController.class.getSimpleName();
@@ -207,12 +211,11 @@ public class InputMethodSubtypeSwitchingController {
}
}
- private final Object mLock = new Object();
private final InputMethodSettings mSettings;
private InputMethodAndSubtypeList mSubtypeList;
@VisibleForTesting
- public static ImeSubtypeListItem getNextInputMethodImpl(List<ImeSubtypeListItem> imList,
+ public static ImeSubtypeListItem getNextInputMethodLockedImpl(List<ImeSubtypeListItem> imList,
boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
if (imi == null) {
return null;
@@ -256,34 +259,34 @@ public class InputMethodSubtypeSwitchingController {
return null;
}
- public InputMethodSubtypeSwitchingController(InputMethodSettings settings) {
+ private InputMethodSubtypeSwitchingController(InputMethodSettings settings, Context context) {
mSettings = settings;
+ resetCircularListLocked(context);
+ }
+
+ public static InputMethodSubtypeSwitchingController createInstanceLocked(
+ InputMethodSettings settings, Context context) {
+ return new InputMethodSubtypeSwitchingController(settings, context);
}
// TODO: write unit tests for this method and the logic that determines the next subtype
- public void onCommitText(InputMethodInfo imi, InputMethodSubtype subtype) {
+ public void onCommitTextLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
// TODO: Implement this.
}
public void resetCircularListLocked(Context context) {
- synchronized(mLock) {
- mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
- }
+ mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
}
- public ImeSubtypeListItem getNextInputMethod(
+ public ImeSubtypeListItem getNextInputMethodLocked(
boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
- synchronized(mLock) {
- return getNextInputMethodImpl(mSubtypeList.getSortedInputMethodAndSubtypeList(),
- onlyCurrentIme, imi, subtype);
- }
+ return getNextInputMethodLockedImpl(mSubtypeList.getSortedInputMethodAndSubtypeList(),
+ onlyCurrentIme, imi, subtype);
}
- public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean showSubtypes,
+ public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(boolean showSubtypes,
boolean inputShown, boolean isScreenLocked) {
- synchronized(mLock) {
- return mSubtypeList.getSortedInputMethodAndSubtypeList(
- showSubtypes, inputShown, isScreenLocked);
- }
+ return mSubtypeList.getSortedInputMethodAndSubtypeList(
+ showSubtypes, inputShown, isScreenLocked);
}
}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java
index 2a4d921..0f343b1 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeSwitchingControllerTest.java
@@ -105,44 +105,44 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
// "switchAwareLatinIme/en_US" -> "switchAwareLatinIme/es_US"
currentIme = imList.get(0);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(1), nextIme);
// "switchAwareLatinIme/es_US" -> "switchAwareLatinIme/fr"
currentIme = imList.get(1);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(2), nextIme);
// "switchAwareLatinIme/fr" -> "switchAwareJapaneseIme/ja_JP"
currentIme = imList.get(2);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(5), nextIme);
// "switchAwareJapaneseIme/ja_JP" -> "switchAwareLatinIme/en_US"
currentIme = imList.get(5);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(0), nextIme);
// "nonSwitchAwareLatinIme/en_UK" -> "nonSwitchAwareLatinIme/hi"
currentIme = imList.get(3);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(4), nextIme);
// "nonSwitchAwareLatinIme/hi" -> "nonSwitchAwareJapaneseIme/ja_JP"
currentIme = imList.get(4);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(6), nextIme);
// "nonSwitchAwareJapaneseIme/ja_JP" -> "nonSwitchAwareLatinIme/en_UK"
currentIme = imList.get(6);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(3), nextIme);
@@ -158,46 +158,46 @@ public class InputMethodSubtypeSwitchingControllerTest extends InstrumentationTe
// "switchAwareLatinIme/en_US" -> "switchAwareLatinIme/es_US"
currentIme = imList.get(0);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(1), nextIme);
// "switchAwareLatinIme/es_US" -> "switchAwareLatinIme/fr"
currentIme = imList.get(1);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(2), nextIme);
// "switchAwareLatinIme/fr" -> "switchAwareLatinIme/en_US"
currentIme = imList.get(2);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(0), nextIme);
// "nonSwitchAwareLatinIme/en_UK" -> "nonSwitchAwareLatinIme/hi"
currentIme = imList.get(3);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(4), nextIme);
// "nonSwitchAwareLatinIme/hi" -> "switchAwareLatinIme/en_UK"
currentIme = imList.get(4);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertEquals(imList.get(3), nextIme);
// "switchAwareJapaneseIme/ja_JP" -> null
currentIme = imList.get(5);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertNull(nextIme);
// "nonSwitchAwareJapaneseIme/ja_JP" -> null
currentIme = imList.get(6);
- nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodImpl(
+ nextIme = InputMethodSubtypeSwitchingController.getNextInputMethodLockedImpl(
imList, ONLY_CURRENT_IME, currentIme.mImi, createDummySubtype(
currentIme.mSubtypeName.toString()));
assertNull(nextIme);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 2d270e7..fb69c86 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -692,8 +692,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
updateCurrentProfileIds();
mFileManager = new InputMethodFileManager(mMethodMap, userId);
- mSwitchingController = new InputMethodSubtypeSwitchingController(mSettings);
- mSwitchingController.resetCircularListLocked(context);
+ synchronized (mMethodMap) {
+ mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
+ mSettings, context);
+ }
// Just checking if defaultImiId is empty or not
final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -702,17 +704,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
mImeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
- buildInputMethodListLocked(mMethodList, mMethodMap,
- !mImeSelectedOnBoot /* resetDefaultEnabledIme */);
+ synchronized (mMethodMap) {
+ buildInputMethodListLocked(mMethodList, mMethodMap,
+ !mImeSelectedOnBoot /* resetDefaultEnabledIme */);
+ }
mSettings.enableAllIMEsIfThereIsNoEnabledIME();
if (!mImeSelectedOnBoot) {
Slog.w(TAG, "No IME selected. Choose the most applicable IME.");
- resetDefaultImeLocked(context);
+ synchronized (mMethodMap) {
+ resetDefaultImeLocked(context);
+ }
}
mSettingsObserver = new SettingsObserver(mHandler);
- updateFromSettingsLocked(true);
+ synchronized (mMethodMap) {
+ updateFromSettingsLocked(true);
+ }
// IMMS wants to receive Intent.ACTION_LOCALE_CHANGED in order to update the current IME
// according to the new system locale.
@@ -2174,7 +2182,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return false;
}
synchronized (mMethodMap) {
- final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
+ final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype);
if (nextSubtype == null) {
return false;
@@ -2190,7 +2198,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return false;
}
synchronized (mMethodMap) {
- final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
+ final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
if (nextSubtype == null) {
return false;
@@ -2273,9 +2281,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) {
Slog.d(TAG, "Got the notification of commitText");
}
- final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
- if (imi != null) {
- mSwitchingController.onCommitText(imi, mCurrentSubtype);
+ synchronized (mMethodMap) {
+ final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+ if (imi != null) {
+ mSwitchingController.onCommitTextLocked(imi, mCurrentSubtype);
+ }
}
}
@@ -2698,7 +2708,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
hideInputMethodMenuLocked();
final List<ImeSubtypeListItem> imList =
- mSwitchingController.getSortedInputMethodAndSubtypeList(
+ mSwitchingController.getSortedInputMethodAndSubtypeListLocked(
showSubtypes, mInputShown, isScreenLocked);
if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {