summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Chang <vichang@google.com>2024-03-25 09:57:00 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-03-25 09:57:00 +0000
commit47f6622c6f7bf81544eacecf2c2a3e0c6f18dceb (patch)
tree1aad8edba999f07816cbef316e48dc4c17a7681d
parent836300c33304e880b5d193a63a215e79350e2939 (diff)
parentc033ce976de907a9e866bb2a4f2c3604b24a5cbe (diff)
downloadbase-47f6622c6f7bf81544eacecf2c2a3e0c6f18dceb.tar.gz
Merge "Update LocaleUtils.filterByLanguage due to addLikelySubtags change" into main
-rw-r--r--core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java6
-rw-r--r--services/core/java/com/android/server/inputmethod/LocaleUtils.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java23
3 files changed, 47 insertions, 10 deletions
diff --git a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
index de7244d49834..71c068d7ad46 100644
--- a/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateIntervalFormatTest.java
@@ -149,7 +149,7 @@ public class DateIntervalFormatTest {
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("19.–22.01.2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
- assertEquals("19.01. – 22.04.2009",
+ assertEquals("19.01.\u2009–\u200922.04.2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * MONTH,
FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE));
assertEquals("19.01.2009\u2009\u2013\u200909.02.2012",
@@ -220,10 +220,10 @@ public class DateIntervalFormatTest {
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, 0));
assertEquals("19.–22. Jan. 2009", formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
- assertEquals("Mo., 19. – Do., 22. Jan. 2009",
+ assertEquals("Mo., 19.\u2009–\u2009Do., 22. Jan. 2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY,
FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
- assertEquals("Montag, 19. – Donnerstag, 22. Januar 2009",
+ assertEquals("Montag, 19.\u2009–\u2009Donnerstag, 22. Januar 2009",
formatDateRange(de_DE, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
assertEquals("19. Januar\u2009\u2013\u200922. April 2009",
diff --git a/services/core/java/com/android/server/inputmethod/LocaleUtils.java b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
index 7d090dbcc5d8..b1348b3c785f 100644
--- a/services/core/java/com/android/server/inputmethod/LocaleUtils.java
+++ b/services/core/java/com/android/server/inputmethod/LocaleUtils.java
@@ -46,29 +46,44 @@ final class LocaleUtils {
* @param desired The locale preferred by user.
* @return A score based on the locale matching for the default subtype enabling.
*/
- @IntRange(from = 1, to = 3)
+ @IntRange(from = 1, to = 4)
private static byte calculateMatchingSubScore(@NonNull final ULocale supported,
@NonNull final ULocale desired) {
// Assuming supported/desired is fully expanded.
if (supported.equals(desired)) {
- return 3; // Exact match.
+ return 4; // Exact match.
}
+ // addLikelySubtags is a maximization process as per
+ // https://www.unicode.org/reports/tr35/#Likely_Subtags
+ ULocale maxDesired = ULocale.addLikelySubtags(desired);
+
// Skip language matching since it was already done in calculateMatchingScore.
final String supportedScript = supported.getScript();
- if (supportedScript.isEmpty() || !supportedScript.equals(desired.getScript())) {
+ if (supportedScript.isEmpty() || !supportedScript.equals(maxDesired.getScript())) {
// TODO: Need subscript matching. For example, Hanb should match with Bopo.
return 1;
}
final String supportedCountry = supported.getCountry();
- if (supportedCountry.isEmpty() || !supportedCountry.equals(desired.getCountry())) {
+ if (supportedCountry.isEmpty() || !supportedCountry.equals(maxDesired.getCountry())) {
return 2;
}
// Ignore others e.g. variants, extensions.
- return 3;
+
+ // Since addLikelySubtags can canonicalize subtags, e.g. the deprecated country codes
+ // an locale with an identical script and country before addLikelySubtags is in favour,
+ // and a score of 4 is returned.
+ String desiredScript = desired.getScript();
+ String desiredCountry = desired.getCountry();
+ if ((desiredScript.isEmpty() || desiredScript.equals(maxDesired.getScript()))
+ && (desiredCountry.isEmpty() || desiredCountry.equals(maxDesired.getCountry()))) {
+ return 4;
+ } else {
+ return 3;
+ }
}
private static final class ScoreEntry implements Comparable<ScoreEntry> {
@@ -180,8 +195,7 @@ final class LocaleUtils {
ULocale.forLocale(preferredLocale));
}
score[j] = calculateMatchingSubScore(
- preferredULocaleCache[j],
- ULocale.addLikelySubtags(ULocale.forLocale(locale)));
+ preferredULocaleCache[j], ULocale.forLocale(locale));
if (canSkip && score[j] != 0) {
canSkip = false;
}
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
index 255cb6499d8a..26a2bee8cf68 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/LocaleUtilsTest.java
@@ -357,6 +357,29 @@ public class LocaleUtilsTest {
assertEquals(1, dest.size());
assertEquals(availableLocales.get(0), dest.get(0)); // "sr-Latn-RS"
}
+ // Locale with deprecated subtag, e.g. CS for Serbia and Montenegro, should not win
+ // even if the other available locale doesn't have explicit script / country.
+ // On Android, users don't normally use deprecated subtags unless the application requests.
+ {
+ final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-RS");
+ final ArrayList<Locale> availableLocales = new ArrayList<>();
+ availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS"));
+ availableLocales.add(Locale.forLanguageTag("sr-RS"));
+ final ArrayList<Locale> dest = new ArrayList<>();
+ LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest);
+ assertEquals(1, dest.size());
+ assertEquals(availableLocales.get(1), dest.get(0)); // "sr-RS"
+ }
+ {
+ final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-RS");
+ final ArrayList<Locale> availableLocales = new ArrayList<>();
+ availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS"));
+ availableLocales.add(Locale.forLanguageTag("sr"));
+ final ArrayList<Locale> dest = new ArrayList<>();
+ LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest);
+ assertEquals(1, dest.size());
+ assertEquals(availableLocales.get(1), dest.get(0)); // "sr"
+ }
}
@Test