Make additional IME Subtype ID persistent.

It turns out that IME subtypes specified to
InputMethodManager#setAdditionalInputMethodSubtypes() are stored in the
presistent storate without subtype IDs.  As a result, when the system is
rebooted, the system would no longer consider those additional subtypes
as enabled due to subtype ID mismatch, until the IME re-adds those
additional subtypes again with the original subtype IDs.

Bug: 28104337
Change-Id: I1445213e0b83d76631a839b974ec1ab9b28ad7d2
This commit is contained in:
Yohei Yukawa
2016-04-11 02:29:35 -07:00
parent cf45224a81
commit 66baf69042
2 changed files with 39 additions and 10 deletions

View File

@@ -68,6 +68,7 @@ public final class InputMethodSubtype implements Parcelable {
// TODO: remove this
private static final String EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME =
"UntranslatableReplacementStringInSubtypeName";
private static final int SUBTYPE_ID_NONE = 0;
private final boolean mIsAuxiliary;
private final boolean mOverridesImplicitlyEnabledSubtype;
@@ -157,13 +158,13 @@ public final class InputMethodSubtype implements Parcelable {
* track of enabled subtypes by ID. When the IME package gets upgraded, enabled IDs will
* stay enabled even if other attributes are different. If the ID is unspecified or 0,
* Arrays.hashCode(new Object[] {locale, mode, extraValue,
* isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead.
* isAuxiliary, overridesImplicitlyEnabledSubtype, isAsciiCapable}) will be used instead.
*/
public InputMethodSubtypeBuilder setSubtypeId(int subtypeId) {
mSubtypeId = subtypeId;
return this;
}
private int mSubtypeId = 0;
private int mSubtypeId = SUBTYPE_ID_NONE;
/**
* @param subtypeLocale is the locale supported by this subtype.
@@ -268,7 +269,7 @@ public final class InputMethodSubtype implements Parcelable {
* subtypes by ID. When the IME package gets upgraded, enabled IDs will stay enabled even if
* other attributes are different. If the ID is unspecified or 0,
* Arrays.hashCode(new Object[] {locale, mode, extraValue,
* isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead.
* isAuxiliary, overridesImplicitlyEnabledSubtype, isAsciiCapable}) will be used instead.
*/
public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, int id) {
@@ -293,9 +294,12 @@ public final class InputMethodSubtype implements Parcelable {
mIsAsciiCapable = builder.mIsAsciiCapable;
// If hashCode() of this subtype is 0 and you want to specify it as an id of this subtype,
// just specify 0 as this subtype's id. Then, this subtype's id is treated as 0.
mSubtypeHashCode = mSubtypeId != 0 ? mSubtypeId : hashCodeInternal(mSubtypeLocale,
mSubtypeMode, mSubtypeExtraValue, mIsAuxiliary, mOverridesImplicitlyEnabledSubtype,
mIsAsciiCapable);
if (mSubtypeId != SUBTYPE_ID_NONE) {
mSubtypeHashCode = mSubtypeId;
} else {
mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue,
mIsAuxiliary, mOverridesImplicitlyEnabledSubtype, mIsAsciiCapable);
}
}
InputMethodSubtype(Parcel source) {
@@ -501,6 +505,22 @@ public final class InputMethodSubtype implements Parcelable {
return mSubtypeHashCode;
}
/**
* @hide
* @return {@code true} if a valid subtype ID exists.
*/
public final boolean hasSubtypeId() {
return mSubtypeId != SUBTYPE_ID_NONE;
}
/**
* @hide
* @return subtype ID. {@code 0} means that not subtype ID is specified.
*/
public final int getSubtypeId() {
return mSubtypeId;
}
@Override
public boolean equals(Object o) {
if (o instanceof InputMethodSubtype) {

View File

@@ -3648,6 +3648,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private static final String ATTR_ID = "id";
private static final String ATTR_LABEL = "label";
private static final String ATTR_ICON = "icon";
private static final String ATTR_IME_SUBTYPE_ID = "subtypeId";
private static final String ATTR_IME_SUBTYPE_LOCALE = "imeSubtypeLocale";
private static final String ATTR_IME_SUBTYPE_LANGUAGE_TAG = "languageTag";
private static final String ATTR_IME_SUBTYPE_MODE = "imeSubtypeMode";
@@ -3741,6 +3742,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
for (int i = 0; i < N; ++i) {
final InputMethodSubtype subtype = subtypesList.get(i);
out.startTag(null, NODE_SUBTYPE);
if (subtype.hasSubtypeId()) {
out.attribute(null, ATTR_IME_SUBTYPE_ID,
String.valueOf(subtype.getSubtypeId()));
}
out.attribute(null, ATTR_ICON, String.valueOf(subtype.getIconResId()));
out.attribute(null, ATTR_LABEL, String.valueOf(subtype.getNameResId()));
out.attribute(null, ATTR_IME_SUBTYPE_LOCALE, subtype.getLocale());
@@ -3819,7 +3824,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
parser.getAttributeValue(null, ATTR_IS_AUXILIARY)));
final boolean isAsciiCapable = "1".equals(String.valueOf(
parser.getAttributeValue(null, ATTR_IS_ASCII_CAPABLE)));
final InputMethodSubtype subtype = new InputMethodSubtypeBuilder()
final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder()
.setSubtypeNameResId(label)
.setSubtypeIconResId(icon)
.setSubtypeLocale(imeSubtypeLocale)
@@ -3827,9 +3832,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
.setSubtypeMode(imeSubtypeMode)
.setSubtypeExtraValue(imeSubtypeExtraValue)
.setIsAuxiliary(isAuxiliary)
.setIsAsciiCapable(isAsciiCapable)
.build();
tempSubtypesArray.add(subtype);
.setIsAsciiCapable(isAsciiCapable);
final String subtypeIdString =
parser.getAttributeValue(null, ATTR_IME_SUBTYPE_ID);
if (subtypeIdString != null) {
builder.setSubtypeId(Integer.valueOf(subtypeIdString));
}
tempSubtypesArray.add(builder.build());
}
}
} catch (XmlPullParserException | IOException | NumberFormatException e) {