Loading core/java/android/view/inputmethod/InputMethodInfo.java +22 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -431,6 +432,14 @@ public final class InputMethodInfo implements Parcelable { * @hide */ public InputMethodInfo(InputMethodInfo source) { this(source, Collections.emptyList()); } /** * @hide */ public InputMethodInfo(@NonNull InputMethodInfo source, @NonNull List<InputMethodSubtype> additionalSubtypes) { mId = source.mId; mSettingsActivityName = source.mSettingsActivityName; mLanguageSettingsActivityName = source.mLanguageSettingsActivityName; Loading @@ -445,7 +454,19 @@ public final class InputMethodInfo implements Parcelable { mIsVrOnly = source.mIsVrOnly; mIsVirtualDeviceOnly = source.mIsVirtualDeviceOnly; mService = source.mService; if (additionalSubtypes.isEmpty()) { mSubtypes = source.mSubtypes; } else { final ArrayList<InputMethodSubtype> subtypes = source.mSubtypes.toList(); final int additionalSubtypeCount = additionalSubtypes.size(); for (int i = 0; i < additionalSubtypeCount; ++i) { final InputMethodSubtype additionalSubtype = additionalSubtypes.get(i); if (!subtypes.contains(additionalSubtype)) { subtypes.add(additionalSubtype); } } mSubtypes = new InputMethodSubtypeArray(subtypes); } mHandledConfigChanges = source.mHandledConfigChanges; mSupportsStylusHandwriting = source.mSupportsStylusHandwriting; mSupportsConnectionlessStylusHandwriting = source.mSupportsConnectionlessStylusHandwriting; Loading core/java/android/view/inputmethod/InputMethodSubtypeArray.java +13 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.Slog; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; Loading Loading @@ -162,6 +163,18 @@ public class InputMethodSubtypeArray { return instance[index]; } /** * @return A list of {@link InputMethodInfo} copied from this array. */ @NonNull public ArrayList<InputMethodSubtype> toList() { final ArrayList<InputMethodSubtype> list = new ArrayList<>(mCount); for (int i = 0; i < mCount; ++i) { list.add(get(i)); } return list; } /** * Return the number of {@link InputMethodSubtype} objects. */ Loading services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -1024,8 +1024,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } private void onFinishPackageChangesInternal() { synchronized (ImfLock.class) { final int userId = getChangingUserId(); // Instantiating InputMethodInfo requires disk I/O. // Do them before acquiring the lock to minimize the chances of ANR (b/340221861). final var newMethodMapWithoutAdditionalSubtypes = queryInputMethodServicesInternal(mContext, userId, AdditionalSubtypeMap.EMPTY_MAP, DirectBootAwareness.AUTO) .getMethodMap(); synchronized (ImfLock.class) { final boolean isCurrentUser = (userId == mCurrentUserId); final AdditionalSubtypeMap additionalSubtypeMap = AdditionalSubtypeMapRepository.get(userId); Loading Loading @@ -1077,9 +1085,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. && !(additionalSubtypeChanged || shouldRebuildInputMethodListLocked())) { return; } final InputMethodSettings newSettings = queryInputMethodServicesInternal(mContext, userId, newAdditionalSubtypeMap, DirectBootAwareness.AUTO); final var newMethodMap = newMethodMapWithoutAdditionalSubtypes .applyAdditionalSubtypes(newAdditionalSubtypeMap); final InputMethodSettings newSettings = InputMethodSettings.create(newMethodMap, userId); InputMethodSettingsRepository.put(userId, newSettings); if (!isCurrentUser) { return; Loading services/core/java/com/android/server/inputmethod/InputMethodMap.java +24 −0 Original line number Diff line number Diff line Loading @@ -75,4 +75,28 @@ final class InputMethodMap { int size() { return mMap.size(); } @AnyThread @NonNull public InputMethodMap applyAdditionalSubtypes( @NonNull AdditionalSubtypeMap additionalSubtypeMap) { if (additionalSubtypeMap.isEmpty()) { return this; } final int size = size(); final ArrayMap<String, InputMethodInfo> newMethodMap = new ArrayMap<>(size); boolean updated = false; for (int i = 0; i < size; ++i) { final var imi = valueAt(i); final var imeId = imi.getId(); final var newAdditionalSubtypes = additionalSubtypeMap.get(imeId); if (newAdditionalSubtypes == null || newAdditionalSubtypes.isEmpty()) { newMethodMap.put(imi.getId(), imi); } else { newMethodMap.put(imi.getId(), new InputMethodInfo(imi, newAdditionalSubtypes)); updated = true; } } return updated ? InputMethodMap.of(newMethodMap) : this; } } Loading
core/java/android/view/inputmethod/InputMethodInfo.java +22 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Loading Loading @@ -431,6 +432,14 @@ public final class InputMethodInfo implements Parcelable { * @hide */ public InputMethodInfo(InputMethodInfo source) { this(source, Collections.emptyList()); } /** * @hide */ public InputMethodInfo(@NonNull InputMethodInfo source, @NonNull List<InputMethodSubtype> additionalSubtypes) { mId = source.mId; mSettingsActivityName = source.mSettingsActivityName; mLanguageSettingsActivityName = source.mLanguageSettingsActivityName; Loading @@ -445,7 +454,19 @@ public final class InputMethodInfo implements Parcelable { mIsVrOnly = source.mIsVrOnly; mIsVirtualDeviceOnly = source.mIsVirtualDeviceOnly; mService = source.mService; if (additionalSubtypes.isEmpty()) { mSubtypes = source.mSubtypes; } else { final ArrayList<InputMethodSubtype> subtypes = source.mSubtypes.toList(); final int additionalSubtypeCount = additionalSubtypes.size(); for (int i = 0; i < additionalSubtypeCount; ++i) { final InputMethodSubtype additionalSubtype = additionalSubtypes.get(i); if (!subtypes.contains(additionalSubtype)) { subtypes.add(additionalSubtype); } } mSubtypes = new InputMethodSubtypeArray(subtypes); } mHandledConfigChanges = source.mHandledConfigChanges; mSupportsStylusHandwriting = source.mSupportsStylusHandwriting; mSupportsConnectionlessStylusHandwriting = source.mSupportsConnectionlessStylusHandwriting; Loading
core/java/android/view/inputmethod/InputMethodSubtypeArray.java +13 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.Slog; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; Loading Loading @@ -162,6 +163,18 @@ public class InputMethodSubtypeArray { return instance[index]; } /** * @return A list of {@link InputMethodInfo} copied from this array. */ @NonNull public ArrayList<InputMethodSubtype> toList() { final ArrayList<InputMethodSubtype> list = new ArrayList<>(mCount); for (int i = 0; i < mCount; ++i) { list.add(get(i)); } return list; } /** * Return the number of {@link InputMethodSubtype} objects. */ Loading
services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -1024,8 +1024,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } private void onFinishPackageChangesInternal() { synchronized (ImfLock.class) { final int userId = getChangingUserId(); // Instantiating InputMethodInfo requires disk I/O. // Do them before acquiring the lock to minimize the chances of ANR (b/340221861). final var newMethodMapWithoutAdditionalSubtypes = queryInputMethodServicesInternal(mContext, userId, AdditionalSubtypeMap.EMPTY_MAP, DirectBootAwareness.AUTO) .getMethodMap(); synchronized (ImfLock.class) { final boolean isCurrentUser = (userId == mCurrentUserId); final AdditionalSubtypeMap additionalSubtypeMap = AdditionalSubtypeMapRepository.get(userId); Loading Loading @@ -1077,9 +1085,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. && !(additionalSubtypeChanged || shouldRebuildInputMethodListLocked())) { return; } final InputMethodSettings newSettings = queryInputMethodServicesInternal(mContext, userId, newAdditionalSubtypeMap, DirectBootAwareness.AUTO); final var newMethodMap = newMethodMapWithoutAdditionalSubtypes .applyAdditionalSubtypes(newAdditionalSubtypeMap); final InputMethodSettings newSettings = InputMethodSettings.create(newMethodMap, userId); InputMethodSettingsRepository.put(userId, newSettings); if (!isCurrentUser) { return; Loading
services/core/java/com/android/server/inputmethod/InputMethodMap.java +24 −0 Original line number Diff line number Diff line Loading @@ -75,4 +75,28 @@ final class InputMethodMap { int size() { return mMap.size(); } @AnyThread @NonNull public InputMethodMap applyAdditionalSubtypes( @NonNull AdditionalSubtypeMap additionalSubtypeMap) { if (additionalSubtypeMap.isEmpty()) { return this; } final int size = size(); final ArrayMap<String, InputMethodInfo> newMethodMap = new ArrayMap<>(size); boolean updated = false; for (int i = 0; i < size; ++i) { final var imi = valueAt(i); final var imeId = imi.getId(); final var newAdditionalSubtypes = additionalSubtypeMap.get(imeId); if (newAdditionalSubtypes == null || newAdditionalSubtypes.isEmpty()) { newMethodMap.put(imi.getId(), imi); } else { newMethodMap.put(imi.getId(), new InputMethodInfo(imi, newAdditionalSubtypes)); updated = true; } } return updated ? InputMethodMap.of(newMethodMap) : this; } }