• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.ActivityManager;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.content.Context;
24 import android.os.Build;
25 import android.os.SystemProperties;
26 import android.text.TextUtils;
27 import android.timezone.MobileCountries;
28 import android.timezone.TelephonyLookup;
29 import android.timezone.TelephonyNetwork;
30 import android.timezone.TelephonyNetworkFinder;
31 
32 import com.android.internal.annotations.GuardedBy;
33 import com.android.internal.annotations.VisibleForTesting;
34 import com.android.internal.telephony.util.TelephonyUtils;
35 import com.android.telephony.Rlog;
36 
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.Objects;
44 
45 /**
46  * Mobile Country Code
47  *
48  * {@hide}
49  */
50 public final class MccTable {
51     static final String LOG_TAG = "MccTable";
52 
53     @GuardedBy("MccTable.class")
54     private static TelephonyNetworkFinder sTelephonyNetworkFinder;
55 
56     static ArrayList<MccEntry> sTable;
57 
58     @VisibleForTesting
getAllMccEntries()59     public static List<MccEntry> getAllMccEntries() {
60         return new ArrayList<>(sTable);
61     }
62 
63     /**
64      * Container class for mcc and iso. This class implements compareTo so that it can be sorted
65      * by mcc.
66      */
67     public static class MccEntry implements Comparable<MccEntry> {
68         @VisibleForTesting
69         public final int mMcc;
70         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
71                 publicAlternatives = "There is no alternative for {@code MccTable.MccEntry.mIso}, "
72                         + "but it was included in hidden APIs due to a static analysis false "
73                         + "positive and has been made max Q. Please file a bug if you "
74                         + "still require this API.")
75         public final String mIso;
76         final int mSmallestDigitsMnc;
77 
MccEntry(int mcc, String iso, int smallestDigitsMCC)78         MccEntry(int mcc, String iso, int smallestDigitsMCC) {
79             if (iso == null) {
80                 throw new NullPointerException();
81             }
82             mMcc = mcc;
83             mIso = iso;
84             mSmallestDigitsMnc = smallestDigitsMCC;
85         }
86 
87         @Override
compareTo(MccEntry o)88         public int compareTo(MccEntry o) {
89             return mMcc - o.mMcc;
90         }
91     }
92 
93     /**
94      * A combination of MCC and MNC. The MNC is optional and may be null.
95      *
96      * @hide
97      */
98     public static class MccMnc {
99         @NonNull
100         public final String mcc;
101 
102         @Nullable
103         public final String mnc;
104 
105         /**
106          * Splits the supplied String in two: the first three characters are treated as the MCC,
107          * the remaining characters are treated as the MNC.
108          */
109         @Nullable
fromOperatorNumeric(@onNull String operatorNumeric)110         public static MccMnc fromOperatorNumeric(@NonNull String operatorNumeric) {
111             Objects.requireNonNull(operatorNumeric);
112             String mcc;
113             try {
114                 mcc = operatorNumeric.substring(0, 3);
115             } catch (StringIndexOutOfBoundsException e) {
116                 return null;
117             }
118 
119             String mnc;
120             try {
121                 mnc = operatorNumeric.substring(3);
122             } catch (StringIndexOutOfBoundsException e) {
123                 mnc = null;
124             }
125             return new MccMnc(mcc, mnc);
126         }
127 
128         /**
129          * Creates an MccMnc using the supplied values.
130          */
MccMnc(@onNull String mcc, @Nullable String mnc)131         public MccMnc(@NonNull String mcc, @Nullable String mnc) {
132             this.mcc = Objects.requireNonNull(mcc);
133             this.mnc = mnc;
134         }
135 
136         @Override
equals(Object o)137         public boolean equals(Object o) {
138             if (this == o) {
139                 return true;
140             }
141             if (o == null || getClass() != o.getClass()) {
142                 return false;
143             }
144             MccMnc mccMnc = (MccMnc) o;
145             return mcc.equals(mccMnc.mcc)
146                     && Objects.equals(mnc, mccMnc.mnc);
147         }
148 
149         @Override
hashCode()150         public int hashCode() {
151             return Objects.hash(mcc, mnc);
152         }
153 
154         @Override
toString()155         public String toString() {
156             return "MccMnc{"
157                     + "mcc='" + mcc + '\''
158                     + ", mnc='" + mnc + '\''
159                     + '}';
160         }
161     }
162 
163     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
164             publicAlternatives = "There is no alternative for {@code MccTable.entryForMcc}, "
165                     + "but it was included in hidden APIs due to a static analysis false positive "
166                     + "and has been made greylist-max-q. Please file a bug if you still require "
167                     + "this API.")
entryForMcc(int mcc)168     public static MccEntry entryForMcc(int mcc) {
169         MccEntry m = new MccEntry(mcc, "", 0);
170 
171         int index = Collections.binarySearch(sTable, m);
172 
173         if (index < 0) {
174             return null;
175         } else {
176             return sTable.get(index);
177         }
178     }
179 
180     /**
181      * Given a GSM Mobile Country Code, returns a lower-case ISO 3166 alpha-2 country code if
182      * available. Returns empty string if unavailable.
183      */
184     @NonNull
countryCodeForMcc(@onNull String mcc)185     public static String countryCodeForMcc(@NonNull String mcc) {
186         if (mcc == null) {
187             return "";
188         }
189 
190         if (!isNewMccTableEnabled()) {
191             try {
192                 MccEntry entry = entryForMcc(Integer.parseInt(mcc));
193 
194                 if (entry == null) {
195                     return "";
196                 } else {
197                     return entry.mIso;
198                 }
199             } catch (NumberFormatException ex) {
200                 return "";
201             }
202         }
203 
204         TelephonyNetworkFinder telephonyNetworkFinder;
205 
206         synchronized (MccTable.class) {
207             if ((telephonyNetworkFinder = sTelephonyNetworkFinder) == null) {
208                 sTelephonyNetworkFinder = telephonyNetworkFinder =
209                         TelephonyLookup.getInstance().getTelephonyNetworkFinder();
210             }
211         }
212 
213         if (telephonyNetworkFinder == null) {
214             // This should not happen under normal circumstances, only when the data is missing.
215             return "";
216         }
217 
218         MobileCountries mobileCountries = telephonyNetworkFinder.findCountriesByMcc(mcc);
219         if (mobileCountries == null) {
220             return "";
221         }
222 
223         return mobileCountries.getDefaultCountryIsoCode();
224     }
225 
226     /**
227      * Given a combination of MCC and MNC, returns a lower case ISO 3166 alpha-2 country code for
228      * the device's geographical location.
229      *
230      * <p>This can give a better geographical result than {@link #countryCodeForMcc(String)}
231      * (which provides the official "which country is the MCC assigned to?" answer) for cases when
232      * MNC is also available: Sometimes an MCC can be used by multiple countries and the MNC can
233      * help distinguish, or the MCC assigned to a country isn't used for geopolitical reasons.
234      * When the geographical country is needed  (e.g. time zone detection) this version can provide
235      * more pragmatic results than the official MCC-only answer. This method falls back to calling
236      * {@link #countryCodeForMcc(String)} if no special MCC+MNC cases are found.
237      * Returns empty string if no code can be determined.
238      */
239     @NonNull
geoCountryCodeForMccMnc(@onNull MccMnc mccMnc)240     public static String geoCountryCodeForMccMnc(@NonNull MccMnc mccMnc) {
241         String countryCode = null;
242         if (mccMnc.mnc != null) {
243             countryCode = countryCodeForMccMncNoFallback(mccMnc);
244         }
245         if (TextUtils.isEmpty(countryCode)) {
246             // Try the MCC-only fallback.
247             countryCode = countryCodeForMcc(mccMnc.mcc);
248         }
249         return countryCode;
250     }
251 
252     @Nullable
countryCodeForMccMncNoFallback(MccMnc mccMnc)253     private static String countryCodeForMccMncNoFallback(MccMnc mccMnc) {
254         synchronized (MccTable.class) {
255             if (sTelephonyNetworkFinder == null) {
256                 sTelephonyNetworkFinder = TelephonyLookup.getInstance().getTelephonyNetworkFinder();
257             }
258         }
259         if (sTelephonyNetworkFinder == null) {
260             // This should not happen under normal circumstances, only when the data is missing.
261             return null;
262         }
263         TelephonyNetwork network =
264                 sTelephonyNetworkFinder.findNetworkByMccMnc(mccMnc.mcc, mccMnc.mnc);
265         if (network == null) {
266             return null;
267         }
268         return network.getCountryIsoCode();
269     }
270 
271     /**
272      * Given a GSM Mobile Country Code, returns
273      * the smallest number of digits that M if available.
274      * Returns 2 if unavailable.
275      */
276     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
277             publicAlternatives = "There is no alternative for {@code MccTable"
278                     + ".smallestDigitsMccForMnc}, but it was included in hidden APIs due to a "
279                     + "static analysis false positive and has been made max Q. Please "
280                     + "file a bug if you still require this API.")
smallestDigitsMccForMnc(int mcc)281     public static int smallestDigitsMccForMnc(int mcc) {
282         MccEntry entry = entryForMcc(mcc);
283 
284         if (entry == null) {
285             return 2;
286         } else {
287             return entry.mSmallestDigitsMnc;
288         }
289     }
290 
291     /**
292      * Updates MCC and MNC device configuration information for application retrieving
293      * correct version of resources.  If MCC is 0, MCC and MNC will be ignored (not set).
294      * @param context Context to act on.
295      * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
296      */
updateMccMncConfiguration(Context context, String mccmnc)297     public static void updateMccMncConfiguration(Context context, String mccmnc) {
298         Rlog.d(LOG_TAG, "updateMccMncConfiguration mccmnc='" + mccmnc);
299 
300         if (TelephonyUtils.IS_DEBUGGABLE) {
301             String overrideMcc = SystemProperties.get("persist.sys.override_mcc");
302             if (!TextUtils.isEmpty(overrideMcc)) {
303                 mccmnc = overrideMcc;
304                 Rlog.d(LOG_TAG, "updateMccMncConfiguration overriding mccmnc='" + mccmnc + "'");
305             }
306         }
307 
308         if (!TextUtils.isEmpty(mccmnc)) {
309             int mccInt;
310             try {
311                 mccInt = Integer.parseInt(mccmnc.substring(0, 3));
312             } catch (NumberFormatException | StringIndexOutOfBoundsException ex) {
313                 Rlog.e(LOG_TAG, "Error parsing mccmnc: " + mccmnc + ". ex=" + ex);
314                 return;
315             }
316             if (mccInt != 0) {
317                 ActivityManager activityManager = (ActivityManager) context.getSystemService(
318                         Context.ACTIVITY_SERVICE);
319                 if (!activityManager.updateMccMncConfiguration(
320                         mccmnc.substring(0, 3), mccmnc.substring(3))) {
321                     Rlog.d(LOG_TAG, "updateMccMncConfiguration: update mccmnc="
322                             + mccmnc + " failure");
323                 } else {
324                     Rlog.d(LOG_TAG, "updateMccMncConfiguration: update mccmnc="
325                             + mccmnc + " success");
326                 }
327             } else {
328                 Rlog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
329             }
330         }
331     }
332 
333     /**
334      * Maps a given locale to a fallback locale that approximates it. This is a hack.
335      */
336     public static final Map<Locale, Locale> FALLBACKS = new HashMap<Locale, Locale>();
337 
isNewMccTableEnabled()338     public static boolean isNewMccTableEnabled() {
339         return com.android.icu.Flags.telephonyLookupMccExtension()
340                 && com.android.internal.telephony.flags.Flags.useI18nForMccMapping();
341     }
342 
343     static {
344         // If we have English (without a country) explicitly prioritize en_US. http://b/28998094
FALLBACKS.put(Locale.ENGLISH, Locale.US)345         FALLBACKS.put(Locale.ENGLISH, Locale.US);
346     }
347 
348     static {
349         sTable = new ArrayList<MccEntry>(240);
350 
351 
352         /*
353          * The table below is built from two main resources:
354          *
355          * 1) ITU "LIST OF MOBILE COUNTRY OR GEOGRAPHICAL AREA CODES (POSITION ON 1 FEBRUARY 2017)"
356          *    available here: http://handle.itu.int/11.1002/pub/80f1788f-en
357          *
358          *
359          * 2) The ISO 3166 country codes list, available here:
360          *    https://www.iso.org/iso-3166-country-codes.html
361          *
362          * There are entries below that are not found in the ITU documentation and have unclear
363          * origin but have been kept from previous Android releases as their entries do not conflict
364          * with ITU values. These are commented with (*).
365          *
366          * This table has not been verified.
367          */
368 
sTable.add(new MccEntry(202, "gr", 2))369         sTable.add(new MccEntry(202, "gr", 2)); // Greece
sTable.add(new MccEntry(204, "nl", 2))370         sTable.add(new MccEntry(204, "nl", 2)); // Netherlands (Kingdom of the)
sTable.add(new MccEntry(206, "be", 2))371         sTable.add(new MccEntry(206, "be", 2)); // Belgium
sTable.add(new MccEntry(208, "fr", 2))372         sTable.add(new MccEntry(208, "fr", 2)); // France
sTable.add(new MccEntry(212, "mc", 2))373         sTable.add(new MccEntry(212, "mc", 2)); // Monaco (Principality of)
sTable.add(new MccEntry(213, "ad", 2))374         sTable.add(new MccEntry(213, "ad", 2)); // Andorra (Principality of)
sTable.add(new MccEntry(214, "es", 2))375         sTable.add(new MccEntry(214, "es", 2)); // Spain
sTable.add(new MccEntry(216, "hu", 2))376         sTable.add(new MccEntry(216, "hu", 2)); // Hungary (Republic of)
sTable.add(new MccEntry(218, "ba", 2))377         sTable.add(new MccEntry(218, "ba", 2)); // Bosnia and Herzegovina
sTable.add(new MccEntry(219, "hr", 2))378         sTable.add(new MccEntry(219, "hr", 2)); // Croatia (Republic of)
sTable.add(new MccEntry(220, "rs", 2))379         sTable.add(new MccEntry(220, "rs", 2)); // Serbia (Republic of)
sTable.add(new MccEntry(221, "xk", 2))380         sTable.add(new MccEntry(221, "xk", 2)); // Kosovo
sTable.add(new MccEntry(222, "it", 2))381         sTable.add(new MccEntry(222, "it", 2)); // Italy
sTable.add(new MccEntry(225, "va", 2))382         sTable.add(new MccEntry(225, "va", 2)); // Vatican City State
sTable.add(new MccEntry(226, "ro", 2))383         sTable.add(new MccEntry(226, "ro", 2)); // Romania
sTable.add(new MccEntry(228, "ch", 2))384         sTable.add(new MccEntry(228, "ch", 2)); // Switzerland (Confederation of)
sTable.add(new MccEntry(230, "cz", 2))385         sTable.add(new MccEntry(230, "cz", 2)); // Czechia
sTable.add(new MccEntry(231, "sk", 2))386         sTable.add(new MccEntry(231, "sk", 2)); // Slovak Republic
sTable.add(new MccEntry(232, "at", 2))387         sTable.add(new MccEntry(232, "at", 2)); // Austria
sTable.add(new MccEntry(234, "gb", 2))388         sTable.add(new MccEntry(234, "gb", 2)); // United Kingdom of Great Britain and Northern Ireland
sTable.add(new MccEntry(235, "gb", 2))389         sTable.add(new MccEntry(235, "gb", 2)); // United Kingdom of Great Britain and Northern Ireland
sTable.add(new MccEntry(238, "dk", 2))390         sTable.add(new MccEntry(238, "dk", 2)); // Denmark
sTable.add(new MccEntry(240, "se", 2))391         sTable.add(new MccEntry(240, "se", 2)); // Sweden
sTable.add(new MccEntry(242, "no", 2))392         sTable.add(new MccEntry(242, "no", 2)); // Norway
sTable.add(new MccEntry(244, "fi", 2))393         sTable.add(new MccEntry(244, "fi", 2)); // Finland
sTable.add(new MccEntry(246, "lt", 2))394         sTable.add(new MccEntry(246, "lt", 2)); // Lithuania (Republic of)
sTable.add(new MccEntry(247, "lv", 2))395         sTable.add(new MccEntry(247, "lv", 2)); // Latvia (Republic of)
sTable.add(new MccEntry(248, "ee", 2))396         sTable.add(new MccEntry(248, "ee", 2)); // Estonia (Republic of)
sTable.add(new MccEntry(250, "ru", 2))397         sTable.add(new MccEntry(250, "ru", 2)); // Russian Federation
sTable.add(new MccEntry(255, "ua", 2))398         sTable.add(new MccEntry(255, "ua", 2)); // Ukraine
sTable.add(new MccEntry(257, "by", 2))399         sTable.add(new MccEntry(257, "by", 2)); // Belarus (Republic of)
sTable.add(new MccEntry(259, "md", 2))400         sTable.add(new MccEntry(259, "md", 2)); // Moldova (Republic of)
sTable.add(new MccEntry(260, "pl", 2))401         sTable.add(new MccEntry(260, "pl", 2)); // Poland (Republic of)
sTable.add(new MccEntry(262, "de", 2))402         sTable.add(new MccEntry(262, "de", 2)); // Germany (Federal Republic of)
sTable.add(new MccEntry(266, "gi", 2))403         sTable.add(new MccEntry(266, "gi", 2)); // Gibraltar
sTable.add(new MccEntry(268, "pt", 2))404         sTable.add(new MccEntry(268, "pt", 2)); // Portugal
sTable.add(new MccEntry(270, "lu", 2))405         sTable.add(new MccEntry(270, "lu", 2)); // Luxembourg
sTable.add(new MccEntry(272, "ie", 2))406         sTable.add(new MccEntry(272, "ie", 2)); // Ireland
sTable.add(new MccEntry(274, "is", 2))407         sTable.add(new MccEntry(274, "is", 2)); // Iceland
sTable.add(new MccEntry(276, "al", 2))408         sTable.add(new MccEntry(276, "al", 2)); // Albania (Republic of)
sTable.add(new MccEntry(278, "mt", 2))409         sTable.add(new MccEntry(278, "mt", 2)); // Malta
sTable.add(new MccEntry(280, "cy", 2))410         sTable.add(new MccEntry(280, "cy", 2)); // Cyprus (Republic of)
sTable.add(new MccEntry(282, "ge", 2))411         sTable.add(new MccEntry(282, "ge", 2)); // Georgia
sTable.add(new MccEntry(283, "am", 2))412         sTable.add(new MccEntry(283, "am", 2)); // Armenia (Republic of)
sTable.add(new MccEntry(284, "bg", 2))413         sTable.add(new MccEntry(284, "bg", 2)); // Bulgaria (Republic of)
sTable.add(new MccEntry(286, "tr", 2))414         sTable.add(new MccEntry(286, "tr", 2)); // Turkey
sTable.add(new MccEntry(288, "fo", 2))415         sTable.add(new MccEntry(288, "fo", 2)); // Faroe Islands
sTable.add(new MccEntry(289, "ge", 2))416         sTable.add(new MccEntry(289, "ge", 2)); // Abkhazia (Georgia) (*)
sTable.add(new MccEntry(290, "gl", 2))417         sTable.add(new MccEntry(290, "gl", 2)); // Greenland (Denmark)
sTable.add(new MccEntry(292, "sm", 2))418         sTable.add(new MccEntry(292, "sm", 2)); // San Marino (Republic of)
sTable.add(new MccEntry(293, "si", 2))419         sTable.add(new MccEntry(293, "si", 2)); // Slovenia (Republic of)
sTable.add(new MccEntry(294, "mk", 2))420         sTable.add(new MccEntry(294, "mk", 2)); // The Former Yugoslav Republic of Macedonia
sTable.add(new MccEntry(295, "li", 2))421         sTable.add(new MccEntry(295, "li", 2)); // Liechtenstein (Principality of)
sTable.add(new MccEntry(297, "me", 2))422         sTable.add(new MccEntry(297, "me", 2)); // Montenegro
sTable.add(new MccEntry(302, "ca", 3))423         sTable.add(new MccEntry(302, "ca", 3)); // Canada
sTable.add(new MccEntry(308, "pm", 2))424         sTable.add(new MccEntry(308, "pm", 2)); // Saint Pierre and Miquelon (Collectivité territoriale de la République française)
sTable.add(new MccEntry(310, "us", 3))425         sTable.add(new MccEntry(310, "us", 3)); // United States of America
sTable.add(new MccEntry(311, "us", 3))426         sTable.add(new MccEntry(311, "us", 3)); // United States of America
sTable.add(new MccEntry(312, "us", 3))427         sTable.add(new MccEntry(312, "us", 3)); // United States of America
sTable.add(new MccEntry(313, "us", 3))428         sTable.add(new MccEntry(313, "us", 3)); // United States of America
sTable.add(new MccEntry(314, "us", 3))429         sTable.add(new MccEntry(314, "us", 3)); // United States of America
sTable.add(new MccEntry(315, "us", 3))430         sTable.add(new MccEntry(315, "us", 3)); // United States of America
sTable.add(new MccEntry(316, "us", 3))431         sTable.add(new MccEntry(316, "us", 3)); // United States of America
sTable.add(new MccEntry(330, "pr", 2))432         sTable.add(new MccEntry(330, "pr", 2)); // Puerto Rico
sTable.add(new MccEntry(332, "vi", 2))433         sTable.add(new MccEntry(332, "vi", 2)); // United States Virgin Islands
sTable.add(new MccEntry(334, "mx", 3))434         sTable.add(new MccEntry(334, "mx", 3)); // Mexico
sTable.add(new MccEntry(338, "jm", 3))435         sTable.add(new MccEntry(338, "jm", 3)); // Jamaica
sTable.add(new MccEntry(340, "gp", 2))436         sTable.add(new MccEntry(340, "gp", 2)); // Guadeloupe (French Department of)
sTable.add(new MccEntry(342, "bb", 3))437         sTable.add(new MccEntry(342, "bb", 3)); // Barbados
sTable.add(new MccEntry(344, "ag", 3))438         sTable.add(new MccEntry(344, "ag", 3)); // Antigua and Barbuda
sTable.add(new MccEntry(346, "ky", 3))439         sTable.add(new MccEntry(346, "ky", 3)); // Cayman Islands
sTable.add(new MccEntry(348, "vg", 3))440         sTable.add(new MccEntry(348, "vg", 3)); // British Virgin Islands
sTable.add(new MccEntry(350, "bm", 2))441         sTable.add(new MccEntry(350, "bm", 2)); // Bermuda
sTable.add(new MccEntry(352, "gd", 2))442         sTable.add(new MccEntry(352, "gd", 2)); // Grenada
sTable.add(new MccEntry(354, "ms", 2))443         sTable.add(new MccEntry(354, "ms", 2)); // Montserrat
sTable.add(new MccEntry(356, "kn", 2))444         sTable.add(new MccEntry(356, "kn", 2)); // Saint Kitts and Nevis
sTable.add(new MccEntry(358, "lc", 2))445         sTable.add(new MccEntry(358, "lc", 2)); // Saint Lucia
sTable.add(new MccEntry(360, "vc", 2))446         sTable.add(new MccEntry(360, "vc", 2)); // Saint Vincent and the Grenadines
sTable.add(new MccEntry(362, "cw", 2))447         sTable.add(new MccEntry(362, "cw", 2)); // Curaçao
sTable.add(new MccEntry(363, "aw", 2))448         sTable.add(new MccEntry(363, "aw", 2)); // Aruba
sTable.add(new MccEntry(364, "bs", 2))449         sTable.add(new MccEntry(364, "bs", 2)); // Bahamas (Commonwealth of the)
sTable.add(new MccEntry(365, "ai", 3))450         sTable.add(new MccEntry(365, "ai", 3)); // Anguilla
sTable.add(new MccEntry(366, "dm", 2))451         sTable.add(new MccEntry(366, "dm", 2)); // Dominica (Commonwealth of)
sTable.add(new MccEntry(368, "cu", 2))452         sTable.add(new MccEntry(368, "cu", 2)); // Cuba
sTable.add(new MccEntry(370, "do", 2))453         sTable.add(new MccEntry(370, "do", 2)); // Dominican Republic
sTable.add(new MccEntry(372, "ht", 2))454         sTable.add(new MccEntry(372, "ht", 2)); // Haiti (Republic of)
sTable.add(new MccEntry(374, "tt", 2))455         sTable.add(new MccEntry(374, "tt", 2)); // Trinidad and Tobago
sTable.add(new MccEntry(376, "tc", 2))456         sTable.add(new MccEntry(376, "tc", 2)); // Turks and Caicos Islands
sTable.add(new MccEntry(400, "az", 2))457         sTable.add(new MccEntry(400, "az", 2)); // Azerbaijani Republic
sTable.add(new MccEntry(401, "kz", 2))458         sTable.add(new MccEntry(401, "kz", 2)); // Kazakhstan (Republic of)
sTable.add(new MccEntry(402, "bt", 2))459         sTable.add(new MccEntry(402, "bt", 2)); // Bhutan (Kingdom of)
sTable.add(new MccEntry(404, "in", 2))460         sTable.add(new MccEntry(404, "in", 2)); // India (Republic of)
sTable.add(new MccEntry(405, "in", 2))461         sTable.add(new MccEntry(405, "in", 2)); // India (Republic of)
sTable.add(new MccEntry(406, "in", 2))462         sTable.add(new MccEntry(406, "in", 2)); // India (Republic of)
sTable.add(new MccEntry(410, "pk", 2))463         sTable.add(new MccEntry(410, "pk", 2)); // Pakistan (Islamic Republic of)
sTable.add(new MccEntry(412, "af", 2))464         sTable.add(new MccEntry(412, "af", 2)); // Afghanistan
sTable.add(new MccEntry(413, "lk", 2))465         sTable.add(new MccEntry(413, "lk", 2)); // Sri Lanka (Democratic Socialist Republic of)
sTable.add(new MccEntry(414, "mm", 2))466         sTable.add(new MccEntry(414, "mm", 2)); // Myanmar (the Republic of the Union of)
sTable.add(new MccEntry(415, "lb", 2))467         sTable.add(new MccEntry(415, "lb", 2)); // Lebanon
sTable.add(new MccEntry(416, "jo", 2))468         sTable.add(new MccEntry(416, "jo", 2)); // Jordan (Hashemite Kingdom of)
sTable.add(new MccEntry(417, "sy", 2))469         sTable.add(new MccEntry(417, "sy", 2)); // Syrian Arab Republic
sTable.add(new MccEntry(418, "iq", 2))470         sTable.add(new MccEntry(418, "iq", 2)); // Iraq (Republic of)
sTable.add(new MccEntry(419, "kw", 2))471         sTable.add(new MccEntry(419, "kw", 2)); // Kuwait (State of)
sTable.add(new MccEntry(420, "sa", 2))472         sTable.add(new MccEntry(420, "sa", 2)); // Saudi Arabia (Kingdom of)
sTable.add(new MccEntry(421, "ye", 2))473         sTable.add(new MccEntry(421, "ye", 2)); // Yemen (Republic of)
sTable.add(new MccEntry(422, "om", 2))474         sTable.add(new MccEntry(422, "om", 2)); // Oman (Sultanate of)
sTable.add(new MccEntry(423, "ps", 2))475         sTable.add(new MccEntry(423, "ps", 2)); // Palestine (*)
sTable.add(new MccEntry(424, "ae", 2))476         sTable.add(new MccEntry(424, "ae", 2)); // United Arab Emirates
sTable.add(new MccEntry(425, "il", 2))477         sTable.add(new MccEntry(425, "il", 2)); // Israel (State of)
sTable.add(new MccEntry(426, "bh", 2))478         sTable.add(new MccEntry(426, "bh", 2)); // Bahrain (Kingdom of)
sTable.add(new MccEntry(427, "qa", 2))479         sTable.add(new MccEntry(427, "qa", 2)); // Qatar (State of)
sTable.add(new MccEntry(428, "mn", 2))480         sTable.add(new MccEntry(428, "mn", 2)); // Mongolia
sTable.add(new MccEntry(429, "np", 2))481         sTable.add(new MccEntry(429, "np", 2)); // Nepal (Federal Democratic Republic of)
sTable.add(new MccEntry(430, "ae", 2))482         sTable.add(new MccEntry(430, "ae", 2)); // United Arab Emirates
sTable.add(new MccEntry(431, "ae", 2))483         sTable.add(new MccEntry(431, "ae", 2)); // United Arab Emirates
sTable.add(new MccEntry(432, "ir", 2))484         sTable.add(new MccEntry(432, "ir", 2)); // Iran (Islamic Republic of)
sTable.add(new MccEntry(434, "uz", 2))485         sTable.add(new MccEntry(434, "uz", 2)); // Uzbekistan (Republic of)
sTable.add(new MccEntry(436, "tj", 2))486         sTable.add(new MccEntry(436, "tj", 2)); // Tajikistan (Republic of)
sTable.add(new MccEntry(437, "kg", 2))487         sTable.add(new MccEntry(437, "kg", 2)); // Kyrgyz Republic
sTable.add(new MccEntry(438, "tm", 2))488         sTable.add(new MccEntry(438, "tm", 2)); // Turkmenistan
sTable.add(new MccEntry(440, "jp", 2))489         sTable.add(new MccEntry(440, "jp", 2)); // Japan
sTable.add(new MccEntry(441, "jp", 2))490         sTable.add(new MccEntry(441, "jp", 2)); // Japan
sTable.add(new MccEntry(450, "kr", 2))491         sTable.add(new MccEntry(450, "kr", 2)); // Korea (Republic of)
sTable.add(new MccEntry(452, "vn", 2))492         sTable.add(new MccEntry(452, "vn", 2)); // Viet Nam (Socialist Republic of)
sTable.add(new MccEntry(454, "hk", 2))493         sTable.add(new MccEntry(454, "hk", 2)); // Hong Kong, China
sTable.add(new MccEntry(455, "mo", 2))494         sTable.add(new MccEntry(455, "mo", 2)); // Macao, China
sTable.add(new MccEntry(456, "kh", 2))495         sTable.add(new MccEntry(456, "kh", 2)); // Cambodia (Kingdom of)
sTable.add(new MccEntry(457, "la", 2))496         sTable.add(new MccEntry(457, "la", 2)); // Lao People's Democratic Republic
sTable.add(new MccEntry(460, "cn", 2))497         sTable.add(new MccEntry(460, "cn", 2)); // China (People's Republic of)
sTable.add(new MccEntry(461, "cn", 2))498         sTable.add(new MccEntry(461, "cn", 2)); // China (People's Republic of)
sTable.add(new MccEntry(466, "tw", 2))499         sTable.add(new MccEntry(466, "tw", 2)); // Taiwan, China
sTable.add(new MccEntry(467, "kp", 2))500         sTable.add(new MccEntry(467, "kp", 2)); // Democratic People's Republic of Korea
sTable.add(new MccEntry(470, "bd", 2))501         sTable.add(new MccEntry(470, "bd", 2)); // Bangladesh (People's Republic of)
sTable.add(new MccEntry(472, "mv", 2))502         sTable.add(new MccEntry(472, "mv", 2)); // Maldives (Republic of)
sTable.add(new MccEntry(502, "my", 2))503         sTable.add(new MccEntry(502, "my", 2)); // Malaysia
sTable.add(new MccEntry(505, "au", 2))504         sTable.add(new MccEntry(505, "au", 2)); // Australia
sTable.add(new MccEntry(510, "id", 2))505         sTable.add(new MccEntry(510, "id", 2)); // Indonesia (Republic of)
sTable.add(new MccEntry(514, "tl", 2))506         sTable.add(new MccEntry(514, "tl", 2)); // Timor-Leste (Democratic Republic of)
sTable.add(new MccEntry(515, "ph", 2))507         sTable.add(new MccEntry(515, "ph", 2)); // Philippines (Republic of the)
sTable.add(new MccEntry(520, "th", 2))508         sTable.add(new MccEntry(520, "th", 2)); // Thailand
sTable.add(new MccEntry(525, "sg", 2))509         sTable.add(new MccEntry(525, "sg", 2)); // Singapore (Republic of)
sTable.add(new MccEntry(528, "bn", 2))510         sTable.add(new MccEntry(528, "bn", 2)); // Brunei Darussalam
sTable.add(new MccEntry(530, "nz", 2))511         sTable.add(new MccEntry(530, "nz", 2)); // New Zealand
sTable.add(new MccEntry(534, "mp", 2))512         sTable.add(new MccEntry(534, "mp", 2)); // Northern Mariana Islands (Commonwealth of the) (*)
sTable.add(new MccEntry(535, "gu", 2))513         sTable.add(new MccEntry(535, "gu", 2)); // Guam (*)
sTable.add(new MccEntry(536, "nr", 2))514         sTable.add(new MccEntry(536, "nr", 2)); // Nauru (Republic of)
sTable.add(new MccEntry(537, "pg", 2))515         sTable.add(new MccEntry(537, "pg", 2)); // Papua New Guinea
sTable.add(new MccEntry(539, "to", 2))516         sTable.add(new MccEntry(539, "to", 2)); // Tonga (Kingdom of)
sTable.add(new MccEntry(540, "sb", 2))517         sTable.add(new MccEntry(540, "sb", 2)); // Solomon Islands
sTable.add(new MccEntry(541, "vu", 2))518         sTable.add(new MccEntry(541, "vu", 2)); // Vanuatu (Republic of)
sTable.add(new MccEntry(542, "fj", 2))519         sTable.add(new MccEntry(542, "fj", 2)); // Fiji (Republic of)
sTable.add(new MccEntry(543, "wf", 2))520         sTable.add(new MccEntry(543, "wf", 2)); // Wallis and Futuna (Territoire français d'outre-mer)
sTable.add(new MccEntry(544, "as", 2))521         sTable.add(new MccEntry(544, "as", 2)); // American Samoa
sTable.add(new MccEntry(545, "ki", 2))522         sTable.add(new MccEntry(545, "ki", 2)); // Kiribati (Republic of)
sTable.add(new MccEntry(546, "nc", 2))523         sTable.add(new MccEntry(546, "nc", 2)); // New Caledonia (Territoire français d'outre-mer)
sTable.add(new MccEntry(547, "pf", 2))524         sTable.add(new MccEntry(547, "pf", 2)); // French Polynesia (Territoire français d'outre-mer)
sTable.add(new MccEntry(548, "ck", 2))525         sTable.add(new MccEntry(548, "ck", 2)); // Cook Islands
sTable.add(new MccEntry(549, "ws", 2))526         sTable.add(new MccEntry(549, "ws", 2)); // Samoa (Independent State of)
sTable.add(new MccEntry(550, "fm", 2))527         sTable.add(new MccEntry(550, "fm", 2)); // Micronesia (Federated States of)
sTable.add(new MccEntry(551, "mh", 2))528         sTable.add(new MccEntry(551, "mh", 2)); // Marshall Islands (Republic of the)
sTable.add(new MccEntry(552, "pw", 2))529         sTable.add(new MccEntry(552, "pw", 2)); // Palau (Republic of)
sTable.add(new MccEntry(553, "tv", 2))530         sTable.add(new MccEntry(553, "tv", 2)); // Tuvalu
sTable.add(new MccEntry(554, "tk", 2))531         sTable.add(new MccEntry(554, "tk", 2)); // Tokelau
sTable.add(new MccEntry(555, "nu", 2))532         sTable.add(new MccEntry(555, "nu", 2)); // Niue
sTable.add(new MccEntry(602, "eg", 2))533         sTable.add(new MccEntry(602, "eg", 2)); // Egypt (Arab Republic of)
sTable.add(new MccEntry(603, "dz", 2))534         sTable.add(new MccEntry(603, "dz", 2)); // Algeria (People's Democratic Republic of)
sTable.add(new MccEntry(604, "ma", 2))535         sTable.add(new MccEntry(604, "ma", 2)); // Morocco (Kingdom of)
sTable.add(new MccEntry(605, "tn", 2))536         sTable.add(new MccEntry(605, "tn", 2)); // Tunisia
sTable.add(new MccEntry(606, "ly", 2))537         sTable.add(new MccEntry(606, "ly", 2)); // Libya
sTable.add(new MccEntry(607, "gm", 2))538         sTable.add(new MccEntry(607, "gm", 2)); // Gambia (Republic of the)
sTable.add(new MccEntry(608, "sn", 2))539         sTable.add(new MccEntry(608, "sn", 2)); // Senegal (Republic of)
sTable.add(new MccEntry(609, "mr", 2))540         sTable.add(new MccEntry(609, "mr", 2)); // Mauritania (Islamic Republic of)
sTable.add(new MccEntry(610, "ml", 2))541         sTable.add(new MccEntry(610, "ml", 2)); // Mali (Republic of)
sTable.add(new MccEntry(611, "gn", 2))542         sTable.add(new MccEntry(611, "gn", 2)); // Guinea (Republic of)
sTable.add(new MccEntry(612, "ci", 2))543         sTable.add(new MccEntry(612, "ci", 2)); // Côte d'Ivoire (Republic of)
sTable.add(new MccEntry(613, "bf", 2))544         sTable.add(new MccEntry(613, "bf", 2)); // Burkina Faso
sTable.add(new MccEntry(614, "ne", 2))545         sTable.add(new MccEntry(614, "ne", 2)); // Niger (Republic of the)
sTable.add(new MccEntry(615, "tg", 2))546         sTable.add(new MccEntry(615, "tg", 2)); // Togolese Republic
sTable.add(new MccEntry(616, "bj", 2))547         sTable.add(new MccEntry(616, "bj", 2)); // Benin (Republic of)
sTable.add(new MccEntry(617, "mu", 2))548         sTable.add(new MccEntry(617, "mu", 2)); // Mauritius (Republic of)
sTable.add(new MccEntry(618, "lr", 2))549         sTable.add(new MccEntry(618, "lr", 2)); // Liberia (Republic of)
sTable.add(new MccEntry(619, "sl", 2))550         sTable.add(new MccEntry(619, "sl", 2)); // Sierra Leone
sTable.add(new MccEntry(620, "gh", 2))551         sTable.add(new MccEntry(620, "gh", 2)); // Ghana
sTable.add(new MccEntry(621, "ng", 2))552         sTable.add(new MccEntry(621, "ng", 2)); // Nigeria (Federal Republic of)
sTable.add(new MccEntry(622, "td", 2))553         sTable.add(new MccEntry(622, "td", 2)); // Chad (Republic of)
sTable.add(new MccEntry(623, "cf", 2))554         sTable.add(new MccEntry(623, "cf", 2)); // Central African Republic
sTable.add(new MccEntry(624, "cm", 2))555         sTable.add(new MccEntry(624, "cm", 2)); // Cameroon (Republic of)
sTable.add(new MccEntry(625, "cv", 2))556         sTable.add(new MccEntry(625, "cv", 2)); // Cape Verde (Republic of)
sTable.add(new MccEntry(626, "st", 2))557         sTable.add(new MccEntry(626, "st", 2)); // Sao Tome and Principe (Democratic Republic of)
sTable.add(new MccEntry(627, "gq", 2))558         sTable.add(new MccEntry(627, "gq", 2)); // Equatorial Guinea (Republic of)
sTable.add(new MccEntry(628, "ga", 2))559         sTable.add(new MccEntry(628, "ga", 2)); // Gabonese Republic
sTable.add(new MccEntry(629, "cg", 2))560         sTable.add(new MccEntry(629, "cg", 2)); // Congo (Republic of the)
sTable.add(new MccEntry(630, "cd", 2))561         sTable.add(new MccEntry(630, "cd", 2)); // Democratic Republic of the Congo
sTable.add(new MccEntry(631, "ao", 2))562         sTable.add(new MccEntry(631, "ao", 2)); // Angola (Republic of)
sTable.add(new MccEntry(632, "gw", 2))563         sTable.add(new MccEntry(632, "gw", 2)); // Guinea-Bissau (Republic of)
sTable.add(new MccEntry(633, "sc", 2))564         sTable.add(new MccEntry(633, "sc", 2)); // Seychelles (Republic of)
sTable.add(new MccEntry(634, "sd", 2))565         sTable.add(new MccEntry(634, "sd", 2)); // Sudan (Republic of the)
sTable.add(new MccEntry(635, "rw", 2))566         sTable.add(new MccEntry(635, "rw", 2)); // Rwanda (Republic of)
sTable.add(new MccEntry(636, "et", 2))567         sTable.add(new MccEntry(636, "et", 2)); // Ethiopia (Federal Democratic Republic of)
sTable.add(new MccEntry(637, "so", 2))568         sTable.add(new MccEntry(637, "so", 2)); // Somali Democratic Republic
sTable.add(new MccEntry(638, "dj", 2))569         sTable.add(new MccEntry(638, "dj", 2)); // Djibouti (Republic of)
sTable.add(new MccEntry(639, "ke", 2))570         sTable.add(new MccEntry(639, "ke", 2)); // Kenya (Republic of)
sTable.add(new MccEntry(640, "tz", 2))571         sTable.add(new MccEntry(640, "tz", 2)); // Tanzania (United Republic of)
sTable.add(new MccEntry(641, "ug", 2))572         sTable.add(new MccEntry(641, "ug", 2)); // Uganda (Republic of)
sTable.add(new MccEntry(642, "bi", 2))573         sTable.add(new MccEntry(642, "bi", 2)); // Burundi (Republic of)
sTable.add(new MccEntry(643, "mz", 2))574         sTable.add(new MccEntry(643, "mz", 2)); // Mozambique (Republic of)
sTable.add(new MccEntry(645, "zm", 2))575         sTable.add(new MccEntry(645, "zm", 2)); // Zambia (Republic of)
sTable.add(new MccEntry(646, "mg", 2))576         sTable.add(new MccEntry(646, "mg", 2)); // Madagascar (Republic of)
sTable.add(new MccEntry(647, "re", 2))577         sTable.add(new MccEntry(647, "re", 2)); // French Departments and Territories in the Indian Ocean
sTable.add(new MccEntry(648, "zw", 2))578         sTable.add(new MccEntry(648, "zw", 2)); // Zimbabwe (Republic of)
sTable.add(new MccEntry(649, "na", 2))579         sTable.add(new MccEntry(649, "na", 2)); // Namibia (Republic of)
sTable.add(new MccEntry(650, "mw", 2))580         sTable.add(new MccEntry(650, "mw", 2)); // Malawi
sTable.add(new MccEntry(651, "ls", 2))581         sTable.add(new MccEntry(651, "ls", 2)); // Lesotho (Kingdom of)
sTable.add(new MccEntry(652, "bw", 2))582         sTable.add(new MccEntry(652, "bw", 2)); // Botswana (Republic of)
sTable.add(new MccEntry(653, "sz", 2))583         sTable.add(new MccEntry(653, "sz", 2)); // Swaziland (Kingdom of)
sTable.add(new MccEntry(654, "km", 2))584         sTable.add(new MccEntry(654, "km", 2)); // Comoros (Union of the)
sTable.add(new MccEntry(655, "za", 2))585         sTable.add(new MccEntry(655, "za", 2)); // South Africa (Republic of)
sTable.add(new MccEntry(657, "er", 2))586         sTable.add(new MccEntry(657, "er", 2)); // Eritrea
sTable.add(new MccEntry(658, "sh", 2))587         sTable.add(new MccEntry(658, "sh", 2)); // Saint Helena, Ascension and Tristan da Cunha
sTable.add(new MccEntry(659, "ss", 2))588         sTable.add(new MccEntry(659, "ss", 2)); // South Sudan (Republic of)
sTable.add(new MccEntry(702, "bz", 2))589         sTable.add(new MccEntry(702, "bz", 2)); // Belize
sTable.add(new MccEntry(704, "gt", 2))590         sTable.add(new MccEntry(704, "gt", 2)); // Guatemala (Republic of)
sTable.add(new MccEntry(706, "sv", 2))591         sTable.add(new MccEntry(706, "sv", 2)); // El Salvador (Republic of)
sTable.add(new MccEntry(708, "hn", 3))592         sTable.add(new MccEntry(708, "hn", 3)); // Honduras (Republic of)
sTable.add(new MccEntry(710, "ni", 2))593         sTable.add(new MccEntry(710, "ni", 2)); // Nicaragua
sTable.add(new MccEntry(712, "cr", 2))594         sTable.add(new MccEntry(712, "cr", 2)); // Costa Rica
sTable.add(new MccEntry(714, "pa", 2))595         sTable.add(new MccEntry(714, "pa", 2)); // Panama (Republic of)
sTable.add(new MccEntry(716, "pe", 2))596         sTable.add(new MccEntry(716, "pe", 2)); // Peru
sTable.add(new MccEntry(722, "ar", 3))597         sTable.add(new MccEntry(722, "ar", 3)); // Argentine Republic
sTable.add(new MccEntry(724, "br", 2))598         sTable.add(new MccEntry(724, "br", 2)); // Brazil (Federative Republic of)
sTable.add(new MccEntry(730, "cl", 2))599         sTable.add(new MccEntry(730, "cl", 2)); // Chile
sTable.add(new MccEntry(732, "co", 3))600         sTable.add(new MccEntry(732, "co", 3)); // Colombia (Republic of)
sTable.add(new MccEntry(734, "ve", 2))601         sTable.add(new MccEntry(734, "ve", 2)); // Venezuela (Bolivarian Republic of)
sTable.add(new MccEntry(736, "bo", 2))602         sTable.add(new MccEntry(736, "bo", 2)); // Bolivia (Republic of)
sTable.add(new MccEntry(738, "gy", 2))603         sTable.add(new MccEntry(738, "gy", 2)); // Guyana
sTable.add(new MccEntry(740, "ec", 2))604         sTable.add(new MccEntry(740, "ec", 2)); // Ecuador
sTable.add(new MccEntry(742, "gf", 2))605         sTable.add(new MccEntry(742, "gf", 2)); // French Guiana (French Department of)
sTable.add(new MccEntry(744, "py", 2))606         sTable.add(new MccEntry(744, "py", 2)); // Paraguay (Republic of)
sTable.add(new MccEntry(746, "sr", 2))607         sTable.add(new MccEntry(746, "sr", 2)); // Suriname (Republic of)
sTable.add(new MccEntry(748, "uy", 2))608         sTable.add(new MccEntry(748, "uy", 2)); // Uruguay (Eastern Republic of)
sTable.add(new MccEntry(750, "fk", 2))609         sTable.add(new MccEntry(750, "fk", 2)); // Falkland Islands (Malvinas)
610 
611         Collections.sort(sTable);
612     }
613 }
614