Loading core/java/android/view/inputmethod/InputMethodSubtype.java +41 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.inputmethod; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading Loading
core/java/android/view/inputmethod/InputMethodSubtype.java +41 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view.inputmethod; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading
core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java +32 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 { Loading