Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6731b32 authored by Geoffrey Boullanger's avatar Geoffrey Boullanger
Browse files

Use the newly introduced MCC to country table, from the time zone mainline module

Bug: 381070025
Flag: com.android.internal.telephony.flags.use_i18n_for_mcc_mapping
Test: atest MccTable still passes with the flag on and off
Change-Id: I296f30866750f14031befd1d9342b255de2659d6
parent 4d4b0806
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -242,7 +242,12 @@ 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"
}
+37 −21
Original line number Diff line number Diff line
@@ -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;

@@ -87,7 +87,6 @@ public final class MccTable {
     *
     * @hide
     */
    @VisibleForTesting
    public static class MccMnc {
        @NonNull
        public final String mcc;
@@ -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();
    }

    /**
@@ -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
@@ -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;
    }
@@ -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.
@@ -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);
+4 −5
Original line number Diff line number Diff line
@@ -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);
@@ -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";
+43 −14
Original line number Diff line number Diff line
@@ -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
@@ -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