Add InputMethodSubtype#getCanonicalizedLanguageTag()
This is a preparation for implementing Subtype-keyed physical keyboard layout switching. This CL introduces an @hide method InputMethodSubtype#getCanonicalizedLanguageTag() so that later CLs can be written by obtaining canonicalized BCP 47 Language Tags from InputMethodSubtype. See test cases to see how it works. Bug: 252816846 Test: atest FrameworksCoreTests:InputMethodSubtypeTest Change-Id: I5276642ba83fb708e95591da9bc7fefe2810b170
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view.inputmethod;
|
||||
|
||||
import android.annotation.AnyThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -23,6 +24,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.icu.text.DisplayContext;
|
||||
import android.icu.text.LocaleDisplayNames;
|
||||
import android.icu.util.ULocale;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
@@ -89,6 +91,14 @@ public final class InputMethodSubtype implements Parcelable {
|
||||
private volatile Locale mCachedLocaleObj;
|
||||
private volatile HashMap<String, String> mExtraValueHashMapCache;
|
||||
|
||||
/**
|
||||
* A volatile cache to optimize {@link #getCanonicalizedLanguageTag()}.
|
||||
*
|
||||
* <p>{@code null} means that the initial evaluation is not yet done.</p>
|
||||
*/
|
||||
@Nullable
|
||||
private volatile String mCachedCanonicalizedLanguageTag;
|
||||
|
||||
/**
|
||||
* InputMethodSubtypeBuilder is a builder class of InputMethodSubtype.
|
||||
* This class is designed to be used with
|
||||
@@ -391,6 +401,37 @@ public final class InputMethodSubtype implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a canonicalized BCP 47 Language Tag initialized with {@link #getLocaleObject()}.
|
||||
*
|
||||
* <p>This has an internal cache mechanism. Subsequent calls are in general cheap and fast.</p>
|
||||
*
|
||||
* @return a canonicalized BCP 47 Language Tag initialized with {@link #getLocaleObject()}. An
|
||||
* empty string if {@link #getLocaleObject()} returns {@code null} or an empty
|
||||
* {@link Locale} object.
|
||||
* @hide
|
||||
*/
|
||||
@AnyThread
|
||||
@NonNull
|
||||
public String getCanonicalizedLanguageTag() {
|
||||
final String cachedValue = mCachedCanonicalizedLanguageTag;
|
||||
if (cachedValue != null) {
|
||||
return cachedValue;
|
||||
}
|
||||
|
||||
String result = null;
|
||||
final Locale locale = getLocaleObject();
|
||||
if (locale != null) {
|
||||
final String langTag = locale.toLanguageTag();
|
||||
if (!TextUtils.isEmpty(langTag)) {
|
||||
result = ULocale.createCanonical(ULocale.forLanguageTag(langTag)).toLanguageTag();
|
||||
}
|
||||
}
|
||||
result = TextUtils.emptyIfNull(result);
|
||||
mCachedCanonicalizedLanguageTag = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The mode of the subtype.
|
||||
*/
|
||||
|
||||
@@ -20,8 +20,10 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
|
||||
|
||||
@@ -125,6 +127,36 @@ public class InputMethodSubtypeTest {
|
||||
assertEquals("he", clonedSubtypeHe.getLocale());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanonicalizedLanguageTagObjectCache() {
|
||||
final InputMethodSubtype subtype = createSubtypeUsingLanguageTag("en-US");
|
||||
// Verify that the returned object is cached and any subsequent call should return the same
|
||||
// object, which is strictly guaranteed if the method gets called only on a single thread.
|
||||
assertSame(subtype.getCanonicalizedLanguageTag(), subtype.getCanonicalizedLanguageTag());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanonicalizedLanguageTag() {
|
||||
verifyCanonicalizedLanguageTag("en", "en");
|
||||
verifyCanonicalizedLanguageTag("en-US", "en-US");
|
||||
verifyCanonicalizedLanguageTag("en-Latn-US-t-k0-qwerty", "en-Latn-US-t-k0-qwerty");
|
||||
|
||||
verifyCanonicalizedLanguageTag("en-us", "en-US");
|
||||
verifyCanonicalizedLanguageTag("EN-us", "en-US");
|
||||
|
||||
verifyCanonicalizedLanguageTag(null, "");
|
||||
verifyCanonicalizedLanguageTag("", "");
|
||||
|
||||
verifyCanonicalizedLanguageTag("und", "und");
|
||||
verifyCanonicalizedLanguageTag("apparently invalid language tag!!!", "und");
|
||||
}
|
||||
|
||||
private void verifyCanonicalizedLanguageTag(
|
||||
@Nullable String languageTag, @Nullable String expectedLanguageTag) {
|
||||
final InputMethodSubtype subtype = createSubtypeUsingLanguageTag(languageTag);
|
||||
assertEquals(subtype.getCanonicalizedLanguageTag(), expectedLanguageTag);
|
||||
}
|
||||
|
||||
private static InputMethodSubtype cloneViaParcel(final InputMethodSubtype original) {
|
||||
Parcel parcel = null;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user