Loading flags/misc.aconfig +8 −3 Original line number Diff line number Diff line Loading @@ -242,9 +242,14 @@ flag { namespace: "telephony" description: "Make No Emergency Wifi Calling Do Not Ask Again text translatable" bug:"382006472" metadata { purpose: PURPOSE_BUGFIX } # OWNER=jackyu,boullanger TARGET=25Q3 flag { name: "use_i18n_for_mcc_mapping" namespace: "telephony" description: "Use the newly introduced MCC to country table, from the time zone mainline module" bug:"381070025" } # # OWNER=nharold TARGET=25Q4 Loading src/java/com/android/internal/telephony/MccTable.java +37 −21 Original line number Diff line number Diff line Loading @@ -24,12 +24,12 @@ import android.content.Context; import android.os.Build; import android.os.SystemProperties; import android.text.TextUtils; import android.timezone.MobileCountries; import android.timezone.TelephonyLookup; import android.timezone.TelephonyNetwork; import android.timezone.TelephonyNetworkFinder; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; Loading Loading @@ -87,7 +87,6 @@ public final class MccTable { * * @hide */ @VisibleForTesting public static class MccMnc { @NonNull public final String mcc; Loading Loading @@ -174,29 +173,42 @@ public final class MccTable { * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if * available. Returns empty string if unavailable. */ @UnsupportedAppUsage @NonNull public static String countryCodeForMcc(int mcc) { MccEntry entry = entryForMcc(mcc); public static String countryCodeForMcc(@NonNull String mcc) { if (!isNewMccTableEnabled()) { try { MccEntry entry = entryForMcc(Integer.parseInt(mcc)); if (entry == null) { return ""; } else { return entry.mIso; } } catch (NumberFormatException ex) { return ""; } } /** * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if * available. Returns empty string if unavailable. */ @NonNull public static String countryCodeForMcc(@NonNull String mcc) { try { return countryCodeForMcc(Integer.parseInt(mcc)); } catch (NumberFormatException ex) { TelephonyNetworkFinder telephonyNetworkFinder; synchronized (MccTable.class) { if ((telephonyNetworkFinder = sTelephonyNetworkFinder) == null) { sTelephonyNetworkFinder = telephonyNetworkFinder = TelephonyLookup.getInstance().getTelephonyNetworkFinder(); } } if (telephonyNetworkFinder == null) { // This should not happen under normal circumstances, only when the data is missing. return ""; } MobileCountries mobileCountries = telephonyNetworkFinder.findCountriesByMcc(mcc); if (mobileCountries == null) { return ""; } return mobileCountries.getDefaultCountryIsoCode(); } /** Loading @@ -209,7 +221,7 @@ public final class MccTable { * help distinguish, or the MCC assigned to a country isn't used for geopolitical reasons. * When the geographical country is needed (e.g. time zone detection) this version can provide * more pragmatic results than the official MCC-only answer. This method falls back to calling * {@link #countryCodeForMcc(int)} if no special MCC+MNC cases are found. * {@link #countryCodeForMcc(String)} if no special MCC+MNC cases are found. * Returns empty string if no code can be determined. */ @NonNull Loading @@ -220,7 +232,7 @@ public final class MccTable { } if (TextUtils.isEmpty(countryCode)) { // Try the MCC-only fallback. countryCode = MccTable.countryCodeForMcc(mccMnc.mcc); countryCode = countryCodeForMcc(mccMnc.mcc); } return countryCode; } Loading @@ -244,7 +256,6 @@ public final class MccTable { return network.getCountryIsoCode(); } /** * Given a GSM Mobile Country Code, returns * the smallest number of digits that M if available. Loading Loading @@ -312,6 +323,11 @@ public final class MccTable { */ public static final Map<Locale, Locale> FALLBACKS = new HashMap<Locale, Locale>(); public static boolean isNewMccTableEnabled() { return com.android.icu.Flags.telephonyLookupMccExtension() && com.android.internal.telephony.flags.Flags.useI18nForMccMapping(); } static { // If we have English (without a country) explicitly prioritize en_US. http://b/28998094 FALLBACKS.put(Locale.ENGLISH, Locale.US); Loading src/java/com/android/internal/telephony/util/LocaleUtils.java +4 −5 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ public class LocaleUtils { public static Locale getLocaleFromMcc(Context context, int mcc, String simLanguage) { boolean hasSimLanguage = !TextUtils.isEmpty(simLanguage); String language = hasSimLanguage ? simLanguage : defaultLanguageForMcc(mcc); String country = MccTable.countryCodeForMcc(mcc); String country = MccTable.countryCodeForMcc(String.valueOf(mcc)); Rlog.d(LOG_TAG, "getLocaleFromMcc(" + language + ", " + country + ", " + mcc); final Locale locale = getLocaleForLanguageCountry(context, language, country); Loading Loading @@ -155,14 +155,13 @@ public class LocaleUtils { * Returns null if unavailable. */ public static String defaultLanguageForMcc(int mcc) { MccTable.MccEntry entry = MccTable.entryForMcc(mcc); if (entry == null) { String country = MccTable.countryCodeForMcc(String.valueOf(mcc)); if (country.isEmpty()) { Rlog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): no country for mcc"); return null; } final String country = entry.mIso; // Choose English as the default language for India. if ("in".equals(country)) { return "en"; Loading tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java +43 −14 Original line number Diff line number Diff line Loading @@ -17,40 +17,69 @@ package com.android.internal.telephony; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import android.content.Context; import android.platform.test.annotations.UsesFlags; import android.platform.test.flag.junit.FlagsParameterization; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import com.android.internal.telephony.MccTable.MccMnc; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.LocaleUtils; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.List; import java.util.Locale; @RunWith(Parameterized.class) @UsesFlags({ com.android.internal.telephony.flags.Flags.class, com.android.icu.Flags.class }) public class MccTableTest { @ClassRule public static final SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule(); @Parameterized.Parameters(name = "{0}") public static List<FlagsParameterization> getParams() { return FlagsParameterization.allCombinationsOf( Flags.FLAG_USE_I18N_FOR_MCC_MAPPING, com.android.icu.Flags.FLAG_TELEPHONY_LOOKUP_MCC_EXTENSION); } @Rule public final SetFlagsRule mSetFlagsRule; public MccTableTest(FlagsParameterization flags) { mSetFlagsRule = mSetFlagsClassRule.createSetFlagsRule(flags); } @SmallTest @Test public void testCountryCodeForMcc() throws Exception { checkMccLookupWithNoMnc("lu", 270); checkMccLookupWithNoMnc("gr", 202); checkMccLookupWithNoMnc("fk", 750); checkMccLookupWithNoMnc("mg", 646); checkMccLookupWithNoMnc("us", 314); checkMccLookupWithNoMnc("", 300); // mcc not defined, hence default checkMccLookupWithNoMnc("", 0); // mcc not defined, hence default checkMccLookupWithNoMnc("", 2000); // mcc not defined, hence default checkMccLookupWithNoMnc("lu", "270"); checkMccLookupWithNoMnc("gr", "202"); checkMccLookupWithNoMnc("fk", "750"); checkMccLookupWithNoMnc("mg", "646"); checkMccLookupWithNoMnc("us", "314"); checkMccLookupWithNoMnc("", "300"); // mcc not defined, hence default checkMccLookupWithNoMnc("", "0"); // mcc not defined, hence default checkMccLookupWithNoMnc("", "2000"); // mcc not defined, hence default } private void checkMccLookupWithNoMnc(String expectedCountryIsoCode, int mcc) { assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc)); private void checkMccLookupWithNoMnc(String expectedCountryIsoCode, String mcc) { assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc)); assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc("" + mcc)); assertEquals(expectedCountryIsoCode, MccTable.geoCountryCodeForMccMnc(new MccMnc("" + mcc, "999"))); MccTable.geoCountryCodeForMccMnc(new MccMnc(mcc, "999"))); } @SmallTest Loading @@ -69,9 +98,9 @@ public class MccTableTest { assertEquals("nl", LocaleUtils.defaultLanguageForMcc(204)); assertEquals("is", LocaleUtils.defaultLanguageForMcc(274)); // mcc not defined, hence default assertEquals(null, LocaleUtils.defaultLanguageForMcc(0)); assertNull(LocaleUtils.defaultLanguageForMcc(0)); // mcc not defined, hence default assertEquals(null, LocaleUtils.defaultLanguageForMcc(2000)); assertNull(LocaleUtils.defaultLanguageForMcc(2000)); } @SmallTest Loading Loading
flags/misc.aconfig +8 −3 Original line number Diff line number Diff line Loading @@ -242,9 +242,14 @@ flag { namespace: "telephony" description: "Make No Emergency Wifi Calling Do Not Ask Again text translatable" bug:"382006472" metadata { purpose: PURPOSE_BUGFIX } # OWNER=jackyu,boullanger TARGET=25Q3 flag { name: "use_i18n_for_mcc_mapping" namespace: "telephony" description: "Use the newly introduced MCC to country table, from the time zone mainline module" bug:"381070025" } # # OWNER=nharold TARGET=25Q4 Loading
src/java/com/android/internal/telephony/MccTable.java +37 −21 Original line number Diff line number Diff line Loading @@ -24,12 +24,12 @@ import android.content.Context; import android.os.Build; import android.os.SystemProperties; import android.text.TextUtils; import android.timezone.MobileCountries; import android.timezone.TelephonyLookup; import android.timezone.TelephonyNetwork; import android.timezone.TelephonyNetworkFinder; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; Loading Loading @@ -87,7 +87,6 @@ public final class MccTable { * * @hide */ @VisibleForTesting public static class MccMnc { @NonNull public final String mcc; Loading Loading @@ -174,29 +173,42 @@ public final class MccTable { * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if * available. Returns empty string if unavailable. */ @UnsupportedAppUsage @NonNull public static String countryCodeForMcc(int mcc) { MccEntry entry = entryForMcc(mcc); public static String countryCodeForMcc(@NonNull String mcc) { if (!isNewMccTableEnabled()) { try { MccEntry entry = entryForMcc(Integer.parseInt(mcc)); if (entry == null) { return ""; } else { return entry.mIso; } } catch (NumberFormatException ex) { return ""; } } /** * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if * available. Returns empty string if unavailable. */ @NonNull public static String countryCodeForMcc(@NonNull String mcc) { try { return countryCodeForMcc(Integer.parseInt(mcc)); } catch (NumberFormatException ex) { TelephonyNetworkFinder telephonyNetworkFinder; synchronized (MccTable.class) { if ((telephonyNetworkFinder = sTelephonyNetworkFinder) == null) { sTelephonyNetworkFinder = telephonyNetworkFinder = TelephonyLookup.getInstance().getTelephonyNetworkFinder(); } } if (telephonyNetworkFinder == null) { // This should not happen under normal circumstances, only when the data is missing. return ""; } MobileCountries mobileCountries = telephonyNetworkFinder.findCountriesByMcc(mcc); if (mobileCountries == null) { return ""; } return mobileCountries.getDefaultCountryIsoCode(); } /** Loading @@ -209,7 +221,7 @@ public final class MccTable { * help distinguish, or the MCC assigned to a country isn't used for geopolitical reasons. * When the geographical country is needed (e.g. time zone detection) this version can provide * more pragmatic results than the official MCC-only answer. This method falls back to calling * {@link #countryCodeForMcc(int)} if no special MCC+MNC cases are found. * {@link #countryCodeForMcc(String)} if no special MCC+MNC cases are found. * Returns empty string if no code can be determined. */ @NonNull Loading @@ -220,7 +232,7 @@ public final class MccTable { } if (TextUtils.isEmpty(countryCode)) { // Try the MCC-only fallback. countryCode = MccTable.countryCodeForMcc(mccMnc.mcc); countryCode = countryCodeForMcc(mccMnc.mcc); } return countryCode; } Loading @@ -244,7 +256,6 @@ public final class MccTable { return network.getCountryIsoCode(); } /** * Given a GSM Mobile Country Code, returns * the smallest number of digits that M if available. Loading Loading @@ -312,6 +323,11 @@ public final class MccTable { */ public static final Map<Locale, Locale> FALLBACKS = new HashMap<Locale, Locale>(); public static boolean isNewMccTableEnabled() { return com.android.icu.Flags.telephonyLookupMccExtension() && com.android.internal.telephony.flags.Flags.useI18nForMccMapping(); } static { // If we have English (without a country) explicitly prioritize en_US. http://b/28998094 FALLBACKS.put(Locale.ENGLISH, Locale.US); Loading
src/java/com/android/internal/telephony/util/LocaleUtils.java +4 −5 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ public class LocaleUtils { public static Locale getLocaleFromMcc(Context context, int mcc, String simLanguage) { boolean hasSimLanguage = !TextUtils.isEmpty(simLanguage); String language = hasSimLanguage ? simLanguage : defaultLanguageForMcc(mcc); String country = MccTable.countryCodeForMcc(mcc); String country = MccTable.countryCodeForMcc(String.valueOf(mcc)); Rlog.d(LOG_TAG, "getLocaleFromMcc(" + language + ", " + country + ", " + mcc); final Locale locale = getLocaleForLanguageCountry(context, language, country); Loading Loading @@ -155,14 +155,13 @@ public class LocaleUtils { * Returns null if unavailable. */ public static String defaultLanguageForMcc(int mcc) { MccTable.MccEntry entry = MccTable.entryForMcc(mcc); if (entry == null) { String country = MccTable.countryCodeForMcc(String.valueOf(mcc)); if (country.isEmpty()) { Rlog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): no country for mcc"); return null; } final String country = entry.mIso; // Choose English as the default language for India. if ("in".equals(country)) { return "en"; Loading
tests/telephonytests/src/com/android/internal/telephony/MccTableTest.java +43 −14 Original line number Diff line number Diff line Loading @@ -17,40 +17,69 @@ package com.android.internal.telephony; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import android.content.Context; import android.platform.test.annotations.UsesFlags; import android.platform.test.flag.junit.FlagsParameterization; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import com.android.internal.telephony.MccTable.MccMnc; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.util.LocaleUtils; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.List; import java.util.Locale; @RunWith(Parameterized.class) @UsesFlags({ com.android.internal.telephony.flags.Flags.class, com.android.icu.Flags.class }) public class MccTableTest { @ClassRule public static final SetFlagsRule.ClassRule mSetFlagsClassRule = new SetFlagsRule.ClassRule(); @Parameterized.Parameters(name = "{0}") public static List<FlagsParameterization> getParams() { return FlagsParameterization.allCombinationsOf( Flags.FLAG_USE_I18N_FOR_MCC_MAPPING, com.android.icu.Flags.FLAG_TELEPHONY_LOOKUP_MCC_EXTENSION); } @Rule public final SetFlagsRule mSetFlagsRule; public MccTableTest(FlagsParameterization flags) { mSetFlagsRule = mSetFlagsClassRule.createSetFlagsRule(flags); } @SmallTest @Test public void testCountryCodeForMcc() throws Exception { checkMccLookupWithNoMnc("lu", 270); checkMccLookupWithNoMnc("gr", 202); checkMccLookupWithNoMnc("fk", 750); checkMccLookupWithNoMnc("mg", 646); checkMccLookupWithNoMnc("us", 314); checkMccLookupWithNoMnc("", 300); // mcc not defined, hence default checkMccLookupWithNoMnc("", 0); // mcc not defined, hence default checkMccLookupWithNoMnc("", 2000); // mcc not defined, hence default checkMccLookupWithNoMnc("lu", "270"); checkMccLookupWithNoMnc("gr", "202"); checkMccLookupWithNoMnc("fk", "750"); checkMccLookupWithNoMnc("mg", "646"); checkMccLookupWithNoMnc("us", "314"); checkMccLookupWithNoMnc("", "300"); // mcc not defined, hence default checkMccLookupWithNoMnc("", "0"); // mcc not defined, hence default checkMccLookupWithNoMnc("", "2000"); // mcc not defined, hence default } private void checkMccLookupWithNoMnc(String expectedCountryIsoCode, int mcc) { assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc)); private void checkMccLookupWithNoMnc(String expectedCountryIsoCode, String mcc) { assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc(mcc)); assertEquals(expectedCountryIsoCode, MccTable.countryCodeForMcc("" + mcc)); assertEquals(expectedCountryIsoCode, MccTable.geoCountryCodeForMccMnc(new MccMnc("" + mcc, "999"))); MccTable.geoCountryCodeForMccMnc(new MccMnc(mcc, "999"))); } @SmallTest Loading @@ -69,9 +98,9 @@ public class MccTableTest { assertEquals("nl", LocaleUtils.defaultLanguageForMcc(204)); assertEquals("is", LocaleUtils.defaultLanguageForMcc(274)); // mcc not defined, hence default assertEquals(null, LocaleUtils.defaultLanguageForMcc(0)); assertNull(LocaleUtils.defaultLanguageForMcc(0)); // mcc not defined, hence default assertEquals(null, LocaleUtils.defaultLanguageForMcc(2000)); assertNull(LocaleUtils.defaultLanguageForMcc(2000)); } @SmallTest Loading