Merge IMMS#mMethod{List,Map} into IMMS#mSettings
With this CL the following fields
InputMethodManagerService#mMethodList
InputMethodManagerService#mMethodMap
will be effectively merged into
InputMethodManagerService#mSettings
as immutable fields so that relevant data objects are always
consistent with each other.
There must be no observable behavior change.
Bug: 309837937
Fix: 309870347
Test: atest CtsInputMethodTestCases
Test: atest FrameworksServicesTests:InputMethodSettingsTest
Test: atest FrameworksServicesTests:InputMethodManagerServiceTests
Test: atest FrameworksInputMethodSystemServerTests
Change-Id: I512519ed83b28adb2878945bc3e6eaff9ba29f5e
diff --git a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
index c76ca2b..fba71fd 100644
--- a/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
+++ b/services/core/java/com/android/server/inputmethod/AdditionalSubtypeUtils.java
@@ -114,7 +114,7 @@
* @param userId The user ID to be associated with.
*/
static void save(ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
- ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ InputMethodMap methodMap, @UserIdInt int userId) {
final File inputMethodDir = getInputMethodDir(userId);
if (allSubtypes.isEmpty()) {
@@ -143,7 +143,7 @@
@VisibleForTesting
static void saveToFile(ArrayMap<String, List<InputMethodSubtype>> allSubtypes,
- ArrayMap<String, InputMethodInfo> methodMap, AtomicFile subtypesFile) {
+ InputMethodMap methodMap, AtomicFile subtypesFile) {
// Safety net for the case that this function is called before methodMap is set.
final boolean isSetMethodMap = methodMap != null && methodMap.size() > 0;
FileOutputStream fos = null;
diff --git a/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java b/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
index 4b85d09..c9a3748 100644
--- a/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
+++ b/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.util.ArrayMap;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
@@ -44,16 +43,15 @@
return mUserId;
}
- HardwareKeyboardShortcutController(
- @NonNull ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ HardwareKeyboardShortcutController(@NonNull InputMethodMap methodMap, @UserIdInt int userId) {
mUserId = userId;
reset(methodMap);
}
@GuardedBy("ImfLock.class")
- void reset(@NonNull ArrayMap<String, InputMethodInfo> methodMap) {
+ void reset(@NonNull InputMethodMap methodMap) {
mSubtypeHandles.clear();
- final InputMethodSettings settings = new InputMethodSettings(methodMap, mUserId);
+ final InputMethodSettings settings = InputMethodSettings.create(methodMap, mUserId);
final List<InputMethodInfo> inputMethods = settings.getEnabledInputMethodListLocked();
for (int i = 0; i < inputMethods.size(); ++i) {
final InputMethodInfo imi = inputMethods.get(i);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
index 542165d..6339686 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodInfoUtils.java
@@ -23,7 +23,6 @@
import android.annotation.Nullable;
import android.content.Context;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Slog;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
@@ -204,7 +203,7 @@
*/
@Nullable
static InputMethodInfo chooseSystemVoiceIme(
- @NonNull ArrayMap<String, InputMethodInfo> methodMap,
+ @NonNull InputMethodMap methodMap,
@Nullable String systemSpeechRecognizerPackageName,
@Nullable String currentDefaultVoiceImeId) {
if (TextUtils.isEmpty(systemSpeechRecognizerPackageName)) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8448fc2..e997fcf 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -314,10 +314,6 @@
@Nullable
private VirtualDeviceManagerInternal mVdmInternal = null;
- // All known input methods.
- final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
- private final ArrayMap<String, InputMethodInfo> mMethodMap = new ArrayMap<>();
-
// Mapping from deviceId to the device-specific imeId for that device.
@GuardedBy("ImfLock.class")
private final SparseArray<String> mVirtualDeviceMethodMap = new SparseArray<>();
@@ -330,7 +326,7 @@
private HardwareKeyboardShortcutController mHardwareKeyboardShortcutController;
/**
- * Tracks how many times {@link #mMethodMap} was updated.
+ * Tracks how many times {@link #mSettings} was updated.
*/
@GuardedBy("ImfLock.class")
private int mMethodMapUpdateCount = 0;
@@ -472,7 +468,7 @@
@GuardedBy("ImfLock.class")
@Nullable
InputMethodInfo queryInputMethodForCurrentUserLocked(@NonNull String imeId) {
- return mMethodMap.get(imeId);
+ return mSettings.getMethodMap().get(imeId);
}
/**
@@ -1265,10 +1261,11 @@
return false;
}
String curInputMethodId = mSettings.getSelectedInputMethod();
- final int numImes = mMethodList.size();
+ final List<InputMethodInfo> methodList = mSettings.getMethodList();
+ final int numImes = methodList.size();
if (curInputMethodId != null) {
for (int i = 0; i < numImes; i++) {
- InputMethodInfo imi = mMethodList.get(i);
+ InputMethodInfo imi = methodList.get(i);
if (imi.getId().equals(curInputMethodId)) {
for (String pkg : packages) {
if (imi.getPackageName().equals(pkg)) {
@@ -1339,7 +1336,7 @@
@Override
public void onPackageDataCleared(String packageName, int uid) {
boolean changed = false;
- for (InputMethodInfo imi : mMethodList) {
+ for (InputMethodInfo imi : mSettings.getMethodList()) {
if (imi.getPackageName().equals(packageName)) {
mAdditionalSubtypeMap.remove(imi.getId());
changed = true;
@@ -1347,7 +1344,8 @@
}
if (changed) {
AdditionalSubtypeUtils.save(
- mAdditionalSubtypeMap, mMethodMap, mSettings.getCurrentUserId());
+ mAdditionalSubtypeMap, mSettings.getMethodMap(),
+ mSettings.getCurrentUserId());
mChangedPackages.add(packageName);
}
}
@@ -1405,10 +1403,11 @@
InputMethodInfo curIm = null;
String curInputMethodId = mSettings.getSelectedInputMethod();
- final int numImes = mMethodList.size();
+ final List<InputMethodInfo> methodList = mSettings.getMethodList();
+ final int numImes = methodList.size();
if (curInputMethodId != null) {
for (int i = 0; i < numImes; i++) {
- InputMethodInfo imi = mMethodList.get(i);
+ InputMethodInfo imi = methodList.get(i);
final String imiId = imi.getId();
if (imiId.equals(curInputMethodId)) {
curIm = imi;
@@ -1426,7 +1425,7 @@
+ imi.getComponent());
mAdditionalSubtypeMap.remove(imi.getId());
AdditionalSubtypeUtils.save(mAdditionalSubtypeMap,
- mMethodMap,
+ mSettings.getMethodMap(),
mSettings.getCurrentUserId());
}
}
@@ -1584,7 +1583,7 @@
if (userId != currentUserId) {
return;
}
- mSettings = new InputMethodSettings(mMethodMap, userId);
+ mSettings = InputMethodSettings.createEmptyMap(userId);
if (mSystemReady) {
// We need to rebuild IMEs.
buildInputMethodListLocked(false /* resetDefaultEnabledIme */);
@@ -1658,14 +1657,15 @@
mLastSwitchUserId = userId;
// mSettings should be created before buildInputMethodListLocked
- mSettings = new InputMethodSettings(mMethodMap, userId);
+ mSettings = InputMethodSettings.createEmptyMap(userId);
AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, userId);
mSwitchingController =
- InputMethodSubtypeSwitchingController.createInstanceLocked(context, mMethodMap,
- userId);
+ InputMethodSubtypeSwitchingController.createInstanceLocked(context,
+ mSettings.getMethodMap(), userId);
mHardwareKeyboardShortcutController =
- new HardwareKeyboardShortcutController(mMethodMap, userId);
+ new HardwareKeyboardShortcutController(mSettings.getMethodMap(),
+ mSettings.getCurrentUserId());
mMenuController = new InputMethodMenuController(this);
mBindingController =
bindingControllerForTesting != null
@@ -1723,7 +1723,8 @@
private void resetDefaultImeLocked(Context context) {
// Do not reset the default (current) IME when it is a 3rd-party IME
String selectedMethodId = getSelectedMethodIdLocked();
- if (selectedMethodId != null && !mMethodMap.get(selectedMethodId).isSystem()) {
+ if (selectedMethodId != null
+ && !mSettings.getMethodMap().get(selectedMethodId).isSystem()) {
return;
}
final List<InputMethodInfo> suitableImes = InputMethodInfoUtils.getDefaultEnabledImes(
@@ -1791,7 +1792,7 @@
// ContentObserver should be registered again when the user is changed
mSettingsObserver.registerContentObserverLocked(newUserId);
- mSettings = new InputMethodSettings(mMethodMap, newUserId);
+ mSettings = InputMethodSettings.createEmptyMap(newUserId);
// Additional subtypes should be reset when the user is changed
AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, newUserId);
final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -2001,9 +2002,9 @@
}
//TODO(b/197848765): This can be optimized by caching multi-user methodMaps/methodList.
//TODO(b/210039666): use cache.
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
- final InputMethodInfo imi = methodMap.get(settings.getSelectedInputMethod());
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
+ final InputMethodInfo imi = settings.getMethodMap().get(
+ settings.getSelectedInputMethod());
return imi != null && imi.supportsStylusHandwriting();
}
}
@@ -2023,23 +2024,19 @@
@GuardedBy("ImfLock.class")
private List<InputMethodInfo> getInputMethodListLocked(@UserIdInt int userId,
@DirectBootAwareness int directBootAwareness, int callingUid) {
- final ArrayList<InputMethodInfo> methodList;
final InputMethodSettings settings;
if (userId == mSettings.getCurrentUserId()
&& directBootAwareness == DirectBootAwareness.AUTO) {
- // Create a copy.
- methodList = new ArrayList<>(mMethodList);
settings = mSettings;
} else {
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- methodList = new ArrayList<>();
final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
new ArrayMap<>();
AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
- methodList, directBootAwareness);
- settings = new InputMethodSettings(methodMap, userId);
+ settings = queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
+ directBootAwareness);
}
+ // Create a copy.
+ final ArrayList<InputMethodInfo> methodList = new ArrayList<>(settings.getMethodList());
// filter caller's access to input methods
methodList.removeIf(imi ->
!canCallerAccessInputMethod(imi.getPackageName(), callingUid, userId, settings));
@@ -2055,8 +2052,7 @@
methodList = mSettings.getEnabledInputMethodListLocked();
settings = mSettings;
} else {
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- settings = new InputMethodSettings(methodMap, userId);
+ settings = queryMethodMapForUser(userId);
methodList = settings.getEnabledInputMethodListLocked();
}
// filter caller's access to input methods
@@ -2120,9 +2116,9 @@
final InputMethodInfo imi;
String selectedMethodId = getSelectedMethodIdLocked();
if (imiId == null && selectedMethodId != null) {
- imi = mMethodMap.get(selectedMethodId);
+ imi = mSettings.getMethodMap().get(selectedMethodId);
} else {
- imi = mMethodMap.get(imiId);
+ imi = mSettings.getMethodMap().get(imiId);
}
if (imi == null || !canCallerAccessInputMethod(
imi.getPackageName(), callingUid, userId, mSettings)) {
@@ -2131,12 +2127,11 @@
return mSettings.getEnabledInputMethodSubtypeListLocked(
imi, allowsImplicitlyEnabledSubtypes);
}
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodInfo imi = methodMap.get(imiId);
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
+ final InputMethodInfo imi = settings.getMethodMap().get(imiId);
if (imi == null) {
return Collections.emptyList();
}
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
if (!canCallerAccessInputMethod(imi.getPackageName(), callingUid, userId, settings)) {
return Collections.emptyList();
}
@@ -2343,7 +2338,7 @@
}
String curId = getCurIdLocked();
- final InputMethodInfo curInputMethodInfo = mMethodMap.get(curId);
+ final InputMethodInfo curInputMethodInfo = mSettings.getMethodMap().get(curId);
final boolean suppressesSpellChecker =
curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker();
final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions =
@@ -2559,7 +2554,7 @@
mVirtualDeviceMethodMap.get(mDeviceIdToShowIme, currentMethodId);
if (Objects.equals(deviceMethodId, currentMethodId)) {
return currentMethodId;
- } else if (!mMethodMap.containsKey(deviceMethodId)) {
+ } else if (!mSettings.getMethodMap().containsKey(deviceMethodId)) {
if (DEBUG) {
Slog.v(TAG, "Disabling IME on virtual device with id " + mDeviceIdToShowIme
+ " because its custom input method is not available: " + deviceMethodId);
@@ -2601,7 +2596,7 @@
if (isSoftInputModeStateVisibleAllowed(unverifiedTargetSdkVersion, startInputFlags)) {
return false;
}
- final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
+ final InputMethodInfo imi = mSettings.getMethodMap().get(selectedMethodId);
if (imi == null) {
return false;
}
@@ -3234,17 +3229,17 @@
// TODO: Instantiate mSwitchingController for each user.
if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
- mSwitchingController.resetCircularListLocked(mMethodMap);
+ mSwitchingController.resetCircularListLocked(mSettings.getMethodMap());
} else {
mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
- mContext, mMethodMap, mSettings.getCurrentUserId());
+ mContext, mSettings.getMethodMap(), mSettings.getCurrentUserId());
}
// TODO: Instantiate mHardwareKeyboardShortcutController for each user.
if (mSettings.getCurrentUserId() == mHardwareKeyboardShortcutController.getUserId()) {
- mHardwareKeyboardShortcutController.reset(mMethodMap);
+ mHardwareKeyboardShortcutController.reset(mSettings.getMethodMap());
} else {
mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
- mMethodMap, mSettings.getCurrentUserId());
+ mSettings.getMethodMap(), mSettings.getCurrentUserId());
}
sendOnNavButtonFlagsChangedLocked();
}
@@ -3268,7 +3263,7 @@
@GuardedBy("ImfLock.class")
void setInputMethodLocked(String id, int subtypeId, int deviceId) {
- InputMethodInfo info = mMethodMap.get(id);
+ InputMethodInfo info = mSettings.getMethodMap().get(id);
if (info == null) {
throw getExceptionForUnknownImeId(id);
}
@@ -4017,7 +4012,7 @@
if (!calledWithValidTokenLocked(token)) {
return;
}
- final InputMethodInfo imi = mMethodMap.get(id);
+ final InputMethodInfo imi = mSettings.getMethodMap().get(id);
if (imi == null || !canCallerAccessInputMethod(
imi.getPackageName(), callingUid, userId, mSettings)) {
throw getExceptionForUnknownImeId(id);
@@ -4035,7 +4030,7 @@
if (!calledWithValidTokenLocked(token)) {
return;
}
- final InputMethodInfo imi = mMethodMap.get(id);
+ final InputMethodInfo imi = mSettings.getMethodMap().get(id);
if (imi == null || !canCallerAccessInputMethod(
imi.getPackageName(), callingUid, userId, mSettings)) {
throw getExceptionForUnknownImeId(id);
@@ -4058,7 +4053,7 @@
final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
final InputMethodInfo lastImi;
if (lastIme != null) {
- lastImi = mMethodMap.get(lastIme.first);
+ lastImi = mSettings.getMethodMap().get(lastIme.first);
} else {
lastImi = null;
}
@@ -4139,7 +4134,8 @@
@GuardedBy("ImfLock.class")
private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme) {
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
- onlyCurrentIme, mMethodMap.get(getSelectedMethodIdLocked()), mCurrentSubtype);
+ onlyCurrentIme, mSettings.getMethodMap().get(getSelectedMethodIdLocked()),
+ mCurrentSubtype);
if (nextSubtype == null) {
return false;
}
@@ -4155,8 +4151,8 @@
return false;
}
final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
- false /* onlyCurrentIme */, mMethodMap.get(getSelectedMethodIdLocked()),
- mCurrentSubtype);
+ false /* onlyCurrentIme */,
+ mSettings.getMethodMap().get(getSelectedMethodIdLocked()), mCurrentSubtype);
return nextSubtype != null;
}
}
@@ -4172,8 +4168,7 @@
return mSettings.getLastInputMethodSubtypeLocked();
}
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
return settings.getLastInputMethodSubtypeLocked();
}
}
@@ -4218,14 +4213,11 @@
return;
}
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
new ArrayMap<>();
AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
- methodList, DirectBootAwareness.AUTO);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
+ final InputMethodSettings settings = queryInputMethodServicesInternal(mContext, userId,
+ additionalSubtypeMap, DirectBootAwareness.AUTO);
settings.setAdditionalInputMethodSubtypes(imiId, toBeAdded, additionalSubtypeMap,
mPackageManagerInternal, callingUid);
}
@@ -4253,8 +4245,7 @@
synchronized (ImfLock.class) {
final boolean currentUser = (mSettings.getCurrentUserId() == userId);
final InputMethodSettings settings = currentUser
- ? mSettings
- : new InputMethodSettings(queryMethodMapForUser(userId), userId);
+ ? mSettings : queryMethodMapForUser(userId);
if (!settings.setEnabledInputMethodSubtypes(imeId, subtypeHashCodes)) {
return;
}
@@ -4626,7 +4617,8 @@
if (mSettings.getCurrentUserId() != mSwitchingController.getUserId()) {
return;
}
- final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
+ final InputMethodInfo imi =
+ mSettings.getMethodMap().get(getSelectedMethodIdLocked());
if (imi != null) {
mSwitchingController.onUserActionLocked(imi, mCurrentSubtype);
}
@@ -4684,7 +4676,7 @@
return;
} else {
// Called with current IME's token.
- if (mMethodMap.get(id) != null
+ if (mSettings.getMethodMap().get(id) != null
&& mSettings.getEnabledInputMethodListWithFilterLocked(
(info) -> info.getId().equals(id)).isEmpty()) {
throw new IllegalStateException("Requested IME is not enabled: " + id);
@@ -4866,7 +4858,8 @@
final List<ImeSubtypeListItem> imList = InputMethodSubtypeSwitchingController
.getSortedInputMethodAndSubtypeList(
showAuxSubtypes, isScreenLocked, true /* forImeMenu */,
- mContext, mMethodMap, mSettings.getCurrentUserId());
+ mContext, mSettings.getMethodMap(),
+ mSettings.getCurrentUserId());
mMenuController.showInputMethodMenuLocked(showAuxSubtypes, displayId,
lastInputMethodId, lastInputMethodSubtypeId, imList);
}
@@ -5062,17 +5055,14 @@
return false;
}
- static void queryInputMethodServicesInternal(Context context,
+ @NonNull
+ static InputMethodSettings queryInputMethodServicesInternal(Context context,
@UserIdInt int userId, ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap,
- ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
@DirectBootAwareness int directBootAwareness) {
final Context userAwareContext = context.getUserId() == userId
? context
: context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
- methodList.clear();
- methodMap.clear();
-
final int directBootAwarenessFlags;
switch (directBootAwareness) {
case DirectBootAwareness.ANY:
@@ -5095,24 +5085,23 @@
new Intent(InputMethod.SERVICE_INTERFACE),
PackageManager.ResolveInfoFlags.of(flags));
- methodList.ensureCapacity(services.size());
- methodMap.ensureCapacity(services.size());
-
// Note: This is a temporary solution for Bug 261723412. If there is any better solution,
// we should remove this data dependency.
final List<String> enabledInputMethodList =
InputMethodUtils.getEnabledInputMethodIdsForFiltering(context, userId);
- filterInputMethodServices(additionalSubtypeMap, methodMap, methodList,
- enabledInputMethodList, userAwareContext, services);
+ final InputMethodMap methodMap = filterInputMethodServices(
+ additionalSubtypeMap, enabledInputMethodList, userAwareContext, services);
+ return InputMethodSettings.create(methodMap, userId);
}
- static void filterInputMethodServices(
+ @NonNull
+ static InputMethodMap filterInputMethodServices(
ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap,
- ArrayMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
List<String> enabledInputMethodList, Context userAwareContext,
List<ResolveInfo> services) {
final ArrayMap<String, Integer> imiPackageCount = new ArrayMap<>();
+ final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>(services.size());
for (int i = 0; i < services.size(); ++i) {
ResolveInfo ri = services.get(i);
@@ -5141,7 +5130,6 @@
imiPackageCount.put(packageName,
1 + imiPackageCount.getOrDefault(packageName, 0));
- methodList.add(imi);
methodMap.put(imi.getId(), imi);
if (DEBUG) {
Slog.d(TAG, "Found an input method " + imi);
@@ -5153,6 +5141,7 @@
Slog.wtf(TAG, "Unable to load input method " + imeId, e);
}
}
+ return InputMethodMap.of(methodMap);
}
@GuardedBy("ImfLock.class")
@@ -5168,8 +5157,8 @@
mMethodMapUpdateCount++;
mMyPackageMonitor.clearKnownImePackageNamesLocked();
- queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(),
- mAdditionalSubtypeMap, mMethodMap, mMethodList, DirectBootAwareness.AUTO);
+ mSettings = queryInputMethodServicesInternal(mContext, mSettings.getCurrentUserId(),
+ mAdditionalSubtypeMap, DirectBootAwareness.AUTO);
// Construct the set of possible IME packages for onPackageChanged() to avoid false
// negatives when the package state remains to be the same but only the component state is
@@ -5200,7 +5189,7 @@
final int numImes = enabledImes.size();
for (int i = 0; i < numImes; ++i) {
final InputMethodInfo imi = enabledImes.get(i);
- if (mMethodList.contains(imi)) {
+ if (mSettings.getMethodMap().containsKey(imi.getId())) {
enabledImeFound = true;
if (!imi.isAuxiliaryIme()) {
enabledNonAuxImeFound = true;
@@ -5224,7 +5213,7 @@
if (resetDefaultEnabledIme || reenableMinimumNonAuxSystemImes) {
final ArrayList<InputMethodInfo> defaultEnabledIme =
- InputMethodInfoUtils.getDefaultEnabledImes(mContext, mMethodList,
+ InputMethodInfoUtils.getDefaultEnabledImes(mContext, mSettings.getMethodList(),
reenableMinimumNonAuxSystemImes);
final int numImes = defaultEnabledIme.size();
for (int i = 0; i < numImes; ++i) {
@@ -5238,7 +5227,7 @@
final String defaultImiId = mSettings.getSelectedInputMethod();
if (!TextUtils.isEmpty(defaultImiId)) {
- if (!mMethodMap.containsKey(defaultImiId)) {
+ if (!mSettings.getMethodMap().containsKey(defaultImiId)) {
Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
if (chooseNewDefaultIMELocked()) {
updateInputMethodsFromSettingsLocked(true);
@@ -5253,23 +5242,23 @@
// TODO: Instantiate mSwitchingController for each user.
if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
- mSwitchingController.resetCircularListLocked(mMethodMap);
+ mSwitchingController.resetCircularListLocked(mSettings.getMethodMap());
} else {
mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
- mContext, mMethodMap, mSettings.getCurrentUserId());
+ mContext, mSettings.getMethodMap(), mSettings.getCurrentUserId());
}
// TODO: Instantiate mHardwareKeyboardShortcutController for each user.
if (mSettings.getCurrentUserId() == mHardwareKeyboardShortcutController.getUserId()) {
- mHardwareKeyboardShortcutController.reset(mMethodMap);
+ mHardwareKeyboardShortcutController.reset(mSettings.getMethodMap());
} else {
mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
- mMethodMap, mSettings.getCurrentUserId());
+ mSettings.getMethodMap(), mSettings.getCurrentUserId());
}
sendOnNavButtonFlagsChangedLocked();
// Notify InputMethodListListeners of the new installed InputMethods.
- final List<InputMethodInfo> inputMethodList = new ArrayList<>(mMethodList);
+ final List<InputMethodInfo> inputMethodList = mSettings.getMethodList();
mHandler.obtainMessage(MSG_DISPATCH_ON_INPUT_METHOD_LIST_UPDATED,
mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
}
@@ -5290,7 +5279,7 @@
mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
final String currentDefaultVoiceImeId = mSettings.getDefaultVoiceInputMethod();
final InputMethodInfo newSystemVoiceIme = InputMethodInfoUtils.chooseSystemVoiceIme(
- mMethodMap, systemSpeechRecognizer, currentDefaultVoiceImeId);
+ mSettings.getMethodMap(), systemSpeechRecognizer, currentDefaultVoiceImeId);
if (newSystemVoiceIme == null) {
if (DEBUG) {
Slog.i(TAG, "Found no valid default Voice IME. If the user is still locked,"
@@ -5402,7 +5391,7 @@
@GuardedBy("ImfLock.class")
private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
- InputMethodInfo imi = mMethodMap.get(newDefaultIme);
+ InputMethodInfo imi = mSettings.getMethodMap().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)) {
@@ -5437,8 +5426,7 @@
return getCurrentInputMethodSubtypeLocked();
}
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
return settings.getCurrentInputMethodSubtypeForNonCurrentUsers();
}
}
@@ -5460,7 +5448,7 @@
return null;
}
final boolean subtypeIsSelected = mSettings.isSubtypeSelected();
- final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
+ final InputMethodInfo imi = mSettings.getMethodMap().get(selectedMethodId);
if (imi == null || imi.getSubtypeCount() == 0) {
return null;
}
@@ -5501,46 +5489,42 @@
*/
@GuardedBy("ImfLock.class")
private InputMethodInfo queryDefaultInputMethodForUserIdLocked(@UserIdInt int userId) {
+ final InputMethodSettings settings;
if (userId == mSettings.getCurrentUserId()) {
- return mMethodMap.get(mSettings.getSelectedInputMethod());
+ settings = mSettings;
+ } else {
+ final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
+ new ArrayMap<>();
+ AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
+ settings = queryInputMethodServicesInternal(mContext, userId,
+ additionalSubtypeMap, DirectBootAwareness.AUTO);
}
-
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
- final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap = new ArrayMap<>();
- AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap, methodMap,
- methodList, DirectBootAwareness.AUTO);
- InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
- return methodMap.get(settings.getSelectedInputMethod());
+ return settings.getMethodMap().get(settings.getSelectedInputMethod());
}
- private ArrayMap<String, InputMethodInfo> queryMethodMapForUser(@UserIdInt int userId) {
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
+ private InputMethodSettings queryMethodMapForUser(@UserIdInt int userId) {
final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
new ArrayMap<>();
AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
- methodMap, methodList, DirectBootAwareness.AUTO);
- return methodMap;
+ return queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
+ DirectBootAwareness.AUTO);
}
@GuardedBy("ImfLock.class")
private boolean switchToInputMethodLocked(String imeId, @UserIdInt int userId) {
if (userId == mSettings.getCurrentUserId()) {
- if (!mMethodMap.containsKey(imeId)
+ if (!mSettings.getMethodMap().containsKey(imeId)
|| !mSettings.getEnabledInputMethodListLocked()
- .contains(mMethodMap.get(imeId))) {
+ .contains(mSettings.getMethodMap().get(imeId))) {
return false; // IME is not found or not enabled.
}
setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID);
return true;
}
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
- if (!methodMap.containsKey(imeId)
- || !settings.getEnabledInputMethodListLocked().contains(methodMap.get(imeId))) {
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
+ if (!settings.getMethodMap().containsKey(imeId)
+ || !settings.getEnabledInputMethodListLocked().contains(
+ settings.getMethodMap().get(imeId))) {
return false; // IME is not found or not enabled.
}
settings.putSelectedInputMethod(imeId);
@@ -5578,7 +5562,8 @@
@GuardedBy("ImfLock.class")
private void switchKeyboardLayoutLocked(int direction) {
- final InputMethodInfo currentImi = mMethodMap.get(getSelectedMethodIdLocked());
+ final InputMethodInfo currentImi = mSettings.getMethodMap().get(
+ getSelectedMethodIdLocked());
if (currentImi == null) {
return;
}
@@ -5590,7 +5575,7 @@
if (nextSubtypeHandle == null) {
return;
}
- final InputMethodInfo nextImi = mMethodMap.get(nextSubtypeHandle.getImeId());
+ final InputMethodInfo nextImi = mSettings.getMethodMap().get(nextSubtypeHandle.getImeId());
if (nextImi == null) {
return;
}
@@ -5670,15 +5655,14 @@
public boolean setInputMethodEnabled(String imeId, boolean enabled, @UserIdInt int userId) {
synchronized (ImfLock.class) {
if (userId == mSettings.getCurrentUserId()) {
- if (!mMethodMap.containsKey(imeId)) {
+ if (!mSettings.getMethodMap().containsKey(imeId)) {
return false; // IME is not found.
}
setInputMethodEnabledLocked(imeId, enabled);
return true;
}
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
- if (!methodMap.containsKey(imeId)) {
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
+ if (!settings.getMethodMap().containsKey(imeId)) {
return false; // IME is not found.
}
if (enabled) {
@@ -5997,10 +5981,11 @@
synchronized (ImfLock.class) {
p.println("Current Input Method Manager state:");
- int numImes = mMethodList.size();
+ final List<InputMethodInfo> methodList = mSettings.getMethodList();
+ int numImes = methodList.size();
p.println(" Input Methods: mMethodMapUpdateCount=" + mMethodMapUpdateCount);
for (int i = 0; i < numImes; i++) {
- InputMethodInfo info = mMethodList.get(i);
+ InputMethodInfo info = methodList.get(i);
p.println(" InputMethod #" + i + ":");
info.dump(p, " ");
}
@@ -6416,16 +6401,15 @@
boolean failedToEnableUnknownIme = false;
boolean previouslyEnabled = false;
if (userId == mSettings.getCurrentUserId()) {
- if (enabled && !mMethodMap.containsKey(imeId)) {
+ if (enabled && !mSettings.getMethodMap().containsKey(imeId)) {
failedToEnableUnknownIme = true;
} else {
previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled);
}
} else {
- final ArrayMap<String, InputMethodInfo> methodMap = queryMethodMapForUser(userId);
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
+ final InputMethodSettings settings = queryMethodMapForUser(userId);
if (enabled) {
- if (!methodMap.containsKey(imeId)) {
+ if (!settings.getMethodMap().containsKey(imeId)) {
failedToEnableUnknownIme = true;
} else {
final String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
@@ -6539,7 +6523,7 @@
// Enable default IMEs, disable others
var toDisable = mSettings.getEnabledInputMethodListLocked();
var defaultEnabled = InputMethodInfoUtils.getDefaultEnabledImes(
- mContext, mMethodList);
+ mContext, mSettings.getMethodList());
toDisable.removeAll(defaultEnabled);
for (InputMethodInfo info : toDisable) {
setInputMethodEnabledLocked(info.getId(), false);
@@ -6558,18 +6542,14 @@
nextIme = mSettings.getSelectedInputMethod();
nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
} else {
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
final ArrayMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
new ArrayMap<>();
AdditionalSubtypeUtils.load(additionalSubtypeMap, userId);
- queryInputMethodServicesInternal(mContext, userId, additionalSubtypeMap,
- methodMap, methodList, DirectBootAwareness.AUTO);
- final InputMethodSettings settings = new InputMethodSettings(
- methodMap, userId);
+ final InputMethodSettings settings = queryInputMethodServicesInternal(
+ mContext, userId, additionalSubtypeMap, DirectBootAwareness.AUTO);
nextEnabledImes = InputMethodInfoUtils.getDefaultEnabledImes(mContext,
- methodList);
+ settings.getMethodList());
nextIme = InputMethodInfoUtils.getMostApplicableDefaultIME(
nextEnabledImes).getId();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMap.java b/services/core/java/com/android/server/inputmethod/InputMethodMap.java
new file mode 100644
index 0000000..a8e5e2e
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMap.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.inputmethod;
+
+import android.annotation.AnyThread;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.view.inputmethod.InputMethodInfo;
+
+import java.util.List;
+
+/**
+ * A map from IME ID to {@link InputMethodInfo}, which is guaranteed to be immutable thus
+ * thread-safe.
+ */
+final class InputMethodMap {
+ private static final ArrayMap<String, InputMethodInfo> EMPTY_MAP =
+ new ArrayMap<>();
+
+ private final ArrayMap<String, InputMethodInfo> mMap;
+
+ static InputMethodMap emptyMap() {
+ return new InputMethodMap(EMPTY_MAP);
+ }
+
+ static InputMethodMap of(@NonNull ArrayMap<String, InputMethodInfo> map) {
+ return new InputMethodMap(map);
+ }
+
+ private InputMethodMap(@NonNull ArrayMap<String, InputMethodInfo> map) {
+ mMap = map.isEmpty() ? EMPTY_MAP : new ArrayMap<>(map);
+ }
+
+ @AnyThread
+ @Nullable
+ InputMethodInfo get(@Nullable String imeId) {
+ return mMap.get(imeId);
+ }
+
+ @AnyThread
+ @NonNull
+ List<InputMethodInfo> values() {
+ return List.copyOf(mMap.values());
+ }
+
+ @AnyThread
+ @Nullable
+ InputMethodInfo valueAt(int index) {
+ return mMap.valueAt(index);
+ }
+
+ @AnyThread
+ boolean containsKey(@Nullable String imeId) {
+ return mMap.containsKey(imeId);
+ }
+
+ @AnyThread
+ @IntRange(from = 0)
+ int size() {
+ return mMap.size();
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
index 9ddb428..c9752fb 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
@@ -16,6 +16,7 @@
package com.android.server.inputmethod;
+import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -58,7 +59,9 @@
private static final char INPUT_METHOD_SUBTYPE_SEPARATOR =
InputMethodUtils.INPUT_METHOD_SUBTYPE_SEPARATOR;
- private final ArrayMap<String, InputMethodInfo> mMethodMap;
+ private final InputMethodMap mMethodMap;
+ private final List<InputMethodInfo> mMethodList;
+
@UserIdInt
private final int mCurrentUserId;
@@ -73,8 +76,17 @@
}
}
- InputMethodSettings(ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ static InputMethodSettings createEmptyMap(@UserIdInt int userId) {
+ return new InputMethodSettings(InputMethodMap.emptyMap(), userId);
+ }
+
+ static InputMethodSettings create(InputMethodMap methodMap, @UserIdInt int userId) {
+ return new InputMethodSettings(methodMap, userId);
+ }
+
+ private InputMethodSettings(InputMethodMap methodMap, @UserIdInt int userId) {
mMethodMap = methodMap;
+ mMethodList = methodMap.values();
mCurrentUserId = userId;
String ime = getSelectedInputMethod();
String defaultDeviceIme = getSelectedDefaultDeviceInputMethod();
@@ -84,6 +96,18 @@
}
}
+ @AnyThread
+ @NonNull
+ InputMethodMap getMethodMap() {
+ return mMethodMap;
+ }
+
+ @AnyThread
+ @NonNull
+ List<InputMethodInfo> getMethodList() {
+ return mMethodList;
+ }
+
private void putString(@NonNull String key, @Nullable String str) {
SecureSettingsWrapper.putString(key, str, mCurrentUserId);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index 834ba20..b37d040 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Printer;
import android.util.Slog;
@@ -158,13 +157,13 @@
static List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
boolean includeAuxiliarySubtypes, boolean isScreenLocked, boolean forImeMenu,
- @NonNull Context context, @NonNull ArrayMap<String, InputMethodInfo> methodMap,
+ @NonNull Context context, @NonNull InputMethodMap methodMap,
@UserIdInt int userId) {
final Context userAwareContext = context.getUserId() == userId
? context
: context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
final String mSystemLocaleStr = SystemLocaleWrapper.get(userId).get(0).toLanguageTag();
- final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);
+ final InputMethodSettings settings = InputMethodSettings.create(methodMap, userId);
final ArrayList<InputMethodInfo> imis = settings.getEnabledInputMethodListLocked();
if (imis.isEmpty()) {
@@ -479,7 +478,7 @@
private ControllerImpl mController;
private InputMethodSubtypeSwitchingController(@NonNull Context context,
- @NonNull ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ @NonNull InputMethodMap methodMap, @UserIdInt int userId) {
mContext = context;
mUserId = userId;
mController = ControllerImpl.createFrom(null,
@@ -491,7 +490,7 @@
@NonNull
public static InputMethodSubtypeSwitchingController createInstanceLocked(
@NonNull Context context,
- @NonNull ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
+ @NonNull InputMethodMap methodMap, @UserIdInt int userId) {
return new InputMethodSubtypeSwitchingController(context, methodMap, userId);
}
@@ -511,8 +510,7 @@
mController.onUserActionLocked(imi, subtype);
}
- public void resetCircularListLocked(
- @NonNull ArrayMap<String, InputMethodInfo> methodMap) {
+ public void resetCircularListLocked(@NonNull InputMethodMap methodMap) {
mController = ControllerImpl.createFrom(mController,
getSortedInputMethodAndSubtypeList(
false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/AdditionalSubtypeUtilsTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/AdditionalSubtypeUtilsTest.java
index 23e3e25..0edb3df 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/AdditionalSubtypeUtilsTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/AdditionalSubtypeUtilsTest.java
@@ -55,7 +55,7 @@
// Save & load.
AtomicFile atomicFile = new AtomicFile(
new File(InstrumentationRegistry.getContext().getCacheDir(), "subtypes.xml"));
- AdditionalSubtypeUtils.saveToFile(allSubtypes, methodMap, atomicFile);
+ AdditionalSubtypeUtils.saveToFile(allSubtypes, InputMethodMap.of(methodMap), atomicFile);
ArrayMap<String, List<InputMethodSubtype>> loadedSubtypes = new ArrayMap<>();
AdditionalSubtypeUtils.loadFromFile(loadedSubtypes, atomicFile);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceRestrictImeAmountTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceRestrictImeAmountTest.java
index 570132f..71752ba 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceRestrictImeAmountTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceRestrictImeAmountTest.java
@@ -126,11 +126,9 @@
List<String> enabledComponents) {
final ArrayMap<String, List<InputMethodSubtype>> emptyAdditionalSubtypeMap =
new ArrayMap<>();
- final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
- final ArrayList<InputMethodInfo> methodList = new ArrayList<>();
- InputMethodManagerService.filterInputMethodServices(emptyAdditionalSubtypeMap, methodMap,
- methodList, enabledComponents, mContext, resolveInfoList);
- return methodList;
+ final InputMethodMap methodMap = InputMethodManagerService.filterInputMethodServices(
+ emptyAdditionalSubtypeMap, enabledComponents, mContext, resolveInfoList);
+ return methodMap.values();
}
private ResolveInfo createFakeSystemResolveInfo(String packageName, String componentName) {
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index ac485be..d81df12 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -796,19 +796,22 @@
{
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(methodMap, null, ""));
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(InputMethodMap.of(methodMap),
+ null, ""));
}
// Returns null when the config value is empty.
{
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(methodMap, "", ""));
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(InputMethodMap.of(methodMap), "",
+ ""));
}
// Returns null when the configured package doesn't have an IME.
{
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(new ArrayMap<>(),
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(
+ InputMethodMap.emptyMap(),
systemIme.getPackageName(), ""));
}
@@ -816,7 +819,8 @@
{
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
- assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(
+ InputMethodMap.of(methodMap),
systemIme.getPackageName(), null));
}
@@ -824,13 +828,15 @@
{
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
- assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(
+ InputMethodMap.of(methodMap),
systemIme.getPackageName(), ""));
}
// Returns null when the current default isn't found.
{
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(new ArrayMap<>(),
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(
+ InputMethodMap.emptyMap(),
systemIme.getPackageName(), systemIme.getId()));
}
@@ -841,7 +847,7 @@
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
methodMap.put(secondIme.getId(), secondIme);
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(InputMethodMap.of(methodMap),
systemIme.getPackageName(), ""));
}
@@ -852,7 +858,8 @@
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
methodMap.put(secondIme.getId(), secondIme);
- assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertEquals(systemIme, InputMethodInfoUtils.chooseSystemVoiceIme(
+ InputMethodMap.of(methodMap),
systemIme.getPackageName(), systemIme.getId()));
}
@@ -862,7 +869,7 @@
final InputMethodInfo nonSystemIme = createFakeInputMethodInfo("NonSystemIme",
"fake.voice0", false /* isSystem */);
methodMap.put(nonSystemIme.getId(), nonSystemIme);
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(InputMethodMap.of(methodMap),
nonSystemIme.getPackageName(), nonSystemIme.getId()));
}
@@ -873,7 +880,7 @@
"FakeDefaultAutoVoiceIme", "fake.voice0", false /* isSystem */);
methodMap.put(systemIme.getId(), systemIme);
methodMap.put(nonSystemIme.getId(), nonSystemIme);
- assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(methodMap,
+ assertNull(InputMethodInfoUtils.chooseSystemVoiceIme(InputMethodMap.of(methodMap),
nonSystemIme.getPackageName(), ""));
}
}