From 8203a5c485c001313005fcc6f4351a6b606ede3e Mon Sep 17 00:00:00 2001 From: Shu Chen Date: Thu, 10 Nov 2022 09:56:13 +0800 Subject: [PATCH] Adds the new API - InputMethodSubtypeBuilder#setPhysicalKeyboardHint. So that the system can automatically configure the physical keyboard for the subtypes. Bug: 253535881 Test: tests passed. Change-Id: I50ba87afbaceadf11aa9891ac12e5c0eb277bb30 --- core/api/current.txt | 5 ++ .../view/inputmethod/InputMethodInfo.java | 8 ++ .../view/inputmethod/InputMethodSubtype.java | 57 +++++++++++++ core/res/res/values/attrs.xml | 11 +++ core/res/res/values/public-staging.xml | 2 + .../inputmethod/AdditionalSubtypeUtils.java | 55 ++++++++---- .../AdditionalSubtypeUtilsTest.java | 84 +++++++++++++++++++ 7 files changed, 208 insertions(+), 14 deletions(-) create mode 100644 services/tests/servicestests/src/com/android/server/inputmethod/AdditionalSubtypeUtilsTest.java diff --git a/core/api/current.txt b/core/api/current.txt index a7bca5a9e09cb..23e1a76a072d5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -1174,6 +1174,8 @@ package android { field public static final int persistentDrawingCache = 16842990; // 0x10100ee field public static final int persistentWhenFeatureAvailable = 16844131; // 0x1010563 field @Deprecated public static final int phoneNumber = 16843111; // 0x1010167 + field public static final int physicalKeyboardHintLanguageTag; + field public static final int physicalKeyboardHintLayoutType; field public static final int pivotX = 16843189; // 0x10101b5 field public static final int pivotY = 16843190; // 0x10101b6 field public static final int pointerIcon = 16844041; // 0x1010509 @@ -54395,6 +54397,8 @@ package android.view.inputmethod { method public String getMode(); method @NonNull public CharSequence getNameOverride(); method public int getNameResId(); + method @Nullable public android.icu.util.ULocale getPhysicalKeyboardHintLanguageTag(); + method @NonNull public String getPhysicalKeyboardHintLayoutType(); method public boolean isAsciiCapable(); method public boolean isAuxiliary(); method public boolean overridesImplicitlyEnabledSubtype(); @@ -54409,6 +54413,7 @@ package android.view.inputmethod { method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean); method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLanguageTag(String); method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean); + method @NonNull public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setPhysicalKeyboardHint(@Nullable android.icu.util.ULocale, @NonNull String); method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(String); method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeIconResId(int); method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeId(int); diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index d7c18462077d6..b7da73247efd5 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -34,6 +34,7 @@ import android.content.res.Resources.NotFoundException; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.icu.util.ULocale; import android.inputmethodservice.InputMethodService; import android.os.Parcel; import android.os.Parcelable; @@ -266,11 +267,18 @@ public final class InputMethodInfo implements Parcelable { } final TypedArray a = res.obtainAttributes( attrs, com.android.internal.R.styleable.InputMethod_Subtype); + String pkLanguageTag = a.getString(com.android.internal.R.styleable + .InputMethod_Subtype_physicalKeyboardHintLanguageTag); + String pkLayoutType = a.getString(com.android.internal.R.styleable + .InputMethod_Subtype_physicalKeyboardHintLayoutType); final InputMethodSubtype subtype = new InputMethodSubtypeBuilder() .setSubtypeNameResId(a.getResourceId(com.android.internal.R.styleable .InputMethod_Subtype_label, 0)) .setSubtypeIconResId(a.getResourceId(com.android.internal.R.styleable .InputMethod_Subtype_icon, 0)) + .setPhysicalKeyboardHint( + pkLanguageTag == null ? null : new ULocale(pkLanguageTag), + pkLayoutType == null ? "" : pkLayoutType) .setLanguageTag(a.getString(com.android.internal.R.styleable .InputMethod_Subtype_languageTag)) .setSubtypeLocale(a.getString(com.android.internal.R.styleable diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java index 6a02198394abf..e73e7a358b61b 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtype.java +++ b/core/java/android/view/inputmethod/InputMethodSubtype.java @@ -39,6 +39,7 @@ import java.util.HashSet; import java.util.IllegalFormatException; import java.util.List; import java.util.Locale; +import java.util.Objects; /** * This class is used to specify meta information of a subtype contained in an input method editor @@ -87,6 +88,8 @@ public final class InputMethodSubtype implements Parcelable { private final int mSubtypeIconResId; private final int mSubtypeNameResId; private final CharSequence mSubtypeNameOverride; + private final String mPkLanguageTag; + private final String mPkLayoutType; private final int mSubtypeId; private final String mSubtypeLocale; private final String mSubtypeLanguageTag; @@ -189,6 +192,30 @@ public final class InputMethodSubtype implements Parcelable { } private CharSequence mSubtypeNameOverride = ""; + /** + * Sets the physical keyboard hint information, such as language and layout. + * + * The system can use the hint information to automatically configure the physical keyboard + * for the subtype. + * + * @param languageTag is the preferred physical keyboard BCP-47 language tag. This is used + * to match the keyboardLocale attribute in the physical keyboard definition. If it's + * {@code null}, the subtype's language tag will be used. + * @param layoutType is the preferred physical keyboard layout, which is used to match the + * keyboardLayoutType attribute in the physical keyboard definition. See + * {@link android.hardware.input.InputManager#ACTION_QUERY_KEYBOARD_LAYOUTS}. + */ + @NonNull + public InputMethodSubtypeBuilder setPhysicalKeyboardHint(@Nullable ULocale languageTag, + @NonNull String layoutType) { + Objects.requireNonNull(layoutType, "layoutType cannot be null"); + mPkLanguageTag = languageTag == null ? "" : languageTag.toLanguageTag(); + mPkLayoutType = layoutType; + return this; + } + private String mPkLanguageTag = ""; + private String mPkLayoutType = ""; + /** * @param subtypeId is the unique ID for this subtype. The input method framework keeps * track of enabled subtypes by ID. When the IME package gets upgraded, enabled IDs will @@ -322,6 +349,8 @@ public final class InputMethodSubtype implements Parcelable { private InputMethodSubtype(InputMethodSubtypeBuilder builder) { mSubtypeNameResId = builder.mSubtypeNameResId; mSubtypeNameOverride = builder.mSubtypeNameOverride; + mPkLanguageTag = builder.mPkLanguageTag; + mPkLayoutType = builder.mPkLayoutType; mSubtypeIconResId = builder.mSubtypeIconResId; mSubtypeLocale = builder.mSubtypeLocale; mSubtypeLanguageTag = builder.mSubtypeLanguageTag; @@ -346,6 +375,10 @@ public final class InputMethodSubtype implements Parcelable { mSubtypeNameResId = source.readInt(); CharSequence cs = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); mSubtypeNameOverride = cs != null ? cs : ""; + s = source.readString8(); + mPkLanguageTag = s != null ? s : ""; + s = source.readString8(); + mPkLayoutType = s != null ? s : ""; mSubtypeIconResId = source.readInt(); s = source.readString(); mSubtypeLocale = s != null ? s : ""; @@ -377,6 +410,28 @@ public final class InputMethodSubtype implements Parcelable { return mSubtypeNameOverride; } + /** + * Returns the physical keyboard BCP-47 language tag. + * + * @attr ref android.R.styleable#InputMethod_Subtype_physicalKeyboardHintLanguageTag + * @see InputMethodSubtypeBuilder#setPhysicalKeyboardHint + */ + @Nullable + public ULocale getPhysicalKeyboardHintLanguageTag() { + return TextUtils.isEmpty(mPkLanguageTag) ? null : ULocale.forLanguageTag(mPkLanguageTag); + } + + /** + * Returns the physical keyboard layout type string. + * + * @attr ref android.R.styleable#InputMethod_Subtype_physicalKeyboardHintLayoutType + * @see InputMethodSubtypeBuilder#setPhysicalKeyboardHint + */ + @NonNull + public String getPhysicalKeyboardHintLayoutType() { + return mPkLayoutType; + } + /** * @return Resource ID of the subtype icon drawable. */ @@ -729,6 +784,8 @@ public final class InputMethodSubtype implements Parcelable { public void writeToParcel(Parcel dest, int parcelableFlags) { dest.writeInt(mSubtypeNameResId); TextUtils.writeToParcel(mSubtypeNameOverride, dest, parcelableFlags); + dest.writeString8(mPkLanguageTag); + dest.writeString8(mPkLayoutType); dest.writeInt(mSubtypeIconResId); dest.writeString(mSubtypeLocale); dest.writeString(mSubtypeLanguageTag); diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c8b0601621ed8..1072f57e7928a 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -3812,6 +3812,17 @@ + + + +