10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.ActivityManagerNative;
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.app.AlarmManager;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.Context;
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.content.res.Configuration;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.net.wifi.WifiManager;
24e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Savilleimport android.os.Build;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.RemoteException;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.os.SystemProperties;
27a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.TelephonyManager;
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils;
29e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Savilleimport android.util.Slog;
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList;
32f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughesimport java.util.Arrays;
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Collections;
3410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamathimport java.util.HashMap;
35f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughesimport java.util.List;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Locale;
3710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamathimport java.util.Map;
3810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
39ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughesimport libcore.icu.ICU;
40e452cb2aa9236ebecb090e03a469fa68aef8d497Elliott Hughesimport libcore.icu.TimeZoneNames;
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Mobile Country Code
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
47ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughespublic final class MccTable {
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static final String LOG_TAG = "MccTable";
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
5022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    static ArrayList<MccEntry> sTable;
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
52ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes    static class MccEntry implements Comparable<MccEntry> {
53ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        final int mMcc;
54ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        final String mIso;
55ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        final int mSmallestDigitsMnc;
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        MccEntry(int mnc, String iso, int smallestDigitsMCC) {
58ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes            if (iso == null) {
59ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes                throw new NullPointerException();
60ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes            }
6122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mMcc = mnc;
6222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mIso = iso;
6322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            mSmallestDigitsMnc = smallestDigitsMCC;
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
66cbaa45bbf2cab852b6c9c3a887e9f803d4e857eaWink Saville        @Override
67ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        public int compareTo(MccEntry o) {
6822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return mMcc - o.mMcc;
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
72ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes    private static MccEntry entryForMcc(int mcc) {
73ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        MccEntry m = new MccEntry(mcc, "", 0);
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
75ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        int index = Collections.binarySearch(sTable, m);
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (index < 0) {
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
8022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return sTable.get(index);
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns a default time zone ID for the given MCC.
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param mcc Mobile Country Code
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @return default TimeZone ID, or null if not specified
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static String defaultTimeZoneForMcc(int mcc) {
90ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        MccEntry entry = entryForMcc(mcc);
91ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        if (entry == null) {
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
94ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        Locale locale = new Locale("", entry.mIso);
95ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        String[] tz = TimeZoneNames.forLocale(locale);
96ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        if (tz.length == 0) return null;
97ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        return tz[0];
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Given a GSM Mobile Country Code, returns
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an ISO two-character country code if available.
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns "" if unavailable.
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
105ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes    public static String countryCodeForMcc(int mcc) {
106ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        MccEntry entry = entryForMcc(mcc);
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (entry == null) {
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return "";
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return entry.mIso;
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Given a GSM Mobile Country Code, returns
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * an ISO 2-3 character language code if available.
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns null if unavailable.
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public static String defaultLanguageForMcc(int mcc) {
121ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        MccEntry entry = entryForMcc(mcc);
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (entry == null) {
123ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes            Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): no country for mcc");
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return null;
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
126ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes
127ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        // Ask CLDR for the language this country uses...
128ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        Locale likelyLocale = ICU.addLikelySubtags(new Locale("und", entry.mIso));
129ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        String likelyLanguage = likelyLocale.getLanguage();
130ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): country " + entry.mIso + " uses " +
131ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes               likelyLanguage);
132ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        return likelyLanguage;
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Given a GSM Mobile Country Code, returns
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * the smallest number of digits that M if available.
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Returns 2 if unavailable.
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
140ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes    public static int smallestDigitsMccForMnc(int mcc) {
141ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        MccEntry entry = entryForMcc(mcc);
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (entry == null) {
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            return 2;
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } else {
14622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            return entry.mSmallestDigitsMnc;
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * Updates MCC and MNC device configuration information for application retrieving
152e64327265b40cbc52e6c07381bc0a80d7e031018Mattias Petersson     * correct version of resources.  If MCC is 0, MCC and MNC will be ignored (not set).
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param context Context to act on.
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
155b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt     * @param fromServiceState true if coming from the radio service state, false if from SIM
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
157b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt    public static void updateMccMncConfiguration(Context context, String mccmnc,
158b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            boolean fromServiceState) {
159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Slog.d(LOG_TAG, "updateMccMncConfiguration mccmnc='" + mccmnc + "' fromServiceState=" + fromServiceState);
160ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes
161ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        if (Build.IS_DEBUGGABLE) {
162ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes            String overrideMcc = SystemProperties.get("persist.sys.override_mcc");
1630dec178a402be98dd0e68bb063f1e4294cbd1d58Bing Gao            if (!TextUtils.isEmpty(overrideMcc)) {
164ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes                mccmnc = overrideMcc;
165ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes                Slog.d(LOG_TAG, "updateMccMncConfiguration overriding mccmnc='" + mccmnc + "'");
166ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes            }
167ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes        }
168ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (!TextUtils.isEmpty(mccmnc)) {
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            int mcc, mnc;
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
172e70617d81dcd42350a737b11c25532e1d43df4ffLegler Wu            String defaultMccMnc = TelephonyManager.getDefault().getSimOperatorNumeric();
173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            Slog.d(LOG_TAG, "updateMccMncConfiguration defaultMccMnc=" + defaultMccMnc);
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //Update mccmnc only for default subscription in case of MultiSim.
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville//            if (!defaultMccMnc.equals(mccmnc)) {
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville//                Slog.d(LOG_TAG, "Not a Default subscription, ignoring mccmnc config update.");
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville//                return;
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville//            }
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            try {
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mcc = Integer.parseInt(mccmnc.substring(0,3));
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                mnc = Integer.parseInt(mccmnc.substring(3));
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } catch (NumberFormatException e) {
184ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes                Slog.e(LOG_TAG, "Error parsing IMSI: " + mccmnc);
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
188e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville            Slog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (mcc != 0) {
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                setTimezoneFromMccIfNeeded(context, mcc);
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
192b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            if (fromServiceState) {
193b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                setWifiCountryCodeFromMcc(context, mcc);
194b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            } else {
195b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                // from SIM
196b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                try {
197b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    Configuration config = new Configuration();
198b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    boolean updateConfig = false;
199b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    if (mcc != 0) {
200b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        config.mcc = mcc;
201b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc;
202b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        updateConfig = true;
203b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    }
204a727251af66b94f38e269321bb153ca98d21c944Narayan Kamath
205b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    if (updateConfig) {
206b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config);
207b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        ActivityManagerNative.getDefault().updateConfiguration(config);
208b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    } else {
209b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                        Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
210b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    }
211b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                } catch (RemoteException e) {
212b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                    Slog.e(LOG_TAG, "Can't update configuration", e);
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
214b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            }
215b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        } else {
216b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt            if (fromServiceState) {
217b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                // an empty mccmnc means no signal - tell wifi we don't know
218b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt                setWifiCountryCodeFromMcc(context, 0);
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
22410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * Maps a given locale to a fallback locale that approximates it. This is a hack.
22510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     */
22610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    private static final Map<Locale, Locale> FALLBACKS = new HashMap<Locale, Locale>();
22710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
22810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    static {
22910788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        FALLBACKS.put(Locale.CANADA, Locale.US);
23010788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    }
23110788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
23210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    /**
23310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * Find the best match we actually have a localization for. This function assumes we
23410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * couldn't find an exact match.
23510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     *
23610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * TODO: This should really follow the CLDR chain of parent locales! That might be a bit
23710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * of a problem because we don't really have an en-001 locale on android.
23810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     */
23910788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    private static Locale chooseBestFallback(Locale target, List<Locale> candidates) {
24010788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        if (candidates.isEmpty()) {
24110788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            return null;
24210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        }
24310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
24410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        Locale fallback = target;
24510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        while ((fallback = FALLBACKS.get(fallback)) != null) {
24610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            if (candidates.contains(fallback)) {
24710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath                return fallback;
24810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            }
24910788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        }
25010788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
25110788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // Somewhat arbitrarily take the first locale for the language,
25210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // unless we get a perfect match later. Note that these come back in no
25310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // particular order, so there's no reason to think the first match is
25410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // a particularly good match.
25510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        return candidates.get(0);
25610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    }
25710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
25810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    /**
259e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     * Return Locale for the language and country or null if no good match.
260e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     *
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param context Context to act on.
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param language Two character language code desired
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param country Two character country code desired
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     *
265e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     * @return Locale or null if no appropriate value
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
267ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes    private static Locale getLocaleForLanguageCountry(Context context, String language,
268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String country) {
269f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes        if (language == null) {
270e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville            Slog.d(LOG_TAG, "getLocaleForLanguageCountry: skipping no language");
271e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville            return null; // no match possible
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
273f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes        if (country == null) {
274f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            country = ""; // The Locale constructor throws if passed null.
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
276f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes
277f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes        final Locale target = new Locale(language, country);
278f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes        try {
279f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            String[] localeArray = context.getAssets().getLocales();
280f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            List<String> locales = new ArrayList<>(Arrays.asList(localeArray));
281f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes
282f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            // Even in developer mode, you don't want the pseudolocales.
283f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            locales.remove("ar-XB");
284f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            locales.remove("en-XA");
285f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes
28610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            List<Locale> languageMatches = new ArrayList<>();
287f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            for (String locale : locales) {
288f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
289f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes
290f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                // Only consider locales with both language and country.
291f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                if (l == null || "und".equals(l.getLanguage()) ||
292f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                        l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
293f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                    continue;
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
295f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                if (l.getLanguage().equals(target.getLanguage())) {
296f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                    // If we got a perfect match, we're done.
297f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                    if (l.getCountry().equals(target.getCountry())) {
298f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                        Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got perfect match: " +
299f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                               l.toLanguageTag());
300f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                        return l;
301f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                    }
30210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
30310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath                    // We've only matched the language, not the country.
30410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath                    languageMatches.add(l);
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
307f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes
30810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            Locale bestMatch = chooseBestFallback(target, languageMatches);
30910788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            if (bestMatch != null) {
310f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got a language-only match: " +
31110788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath                       bestMatch.toLanguageTag());
31210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath                return bestMatch;
313f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            } else {
314f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                Slog.d(LOG_TAG, "getLocaleForLanguageCountry: no locales for language " +
315f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes                       language);
316f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            }
317f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes        } catch (Exception e) {
318f62253c8dc91e37068dade8e40aac427ece7d57bElliott Hughes            Slog.d(LOG_TAG, "getLocaleForLanguageCountry: exception", e);
319e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville        }
320c25bcac2c4c8754faae69efe2fc5c407f66a9240Narayan Kamath
321c25bcac2c4c8754faae69efe2fc5c407f66a9240Narayan Kamath        return null;
322e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville    }
323e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * If the timezone is not already set, set it based on the MCC of the SIM.
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param context Context to act on.
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static void setTimezoneFromMccIfNeeded(Context context, int mcc) {
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (timezone == null || timezone.length() == 0) {
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            String zoneId = defaultTimeZoneForMcc(mcc);
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (zoneId != null && zoneId.length() > 0) {
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                // Set time zone based on MCC
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                AlarmManager alarm =
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                alarm.setTimeZone(zoneId);
338e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville                Slog.d(LOG_TAG, "timezone set to "+zoneId);
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /**
344e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     * Get Locale based on the MCC of the SIM.
34510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     *
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param context Context to act on.
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
34810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath     * @param simLanguage (nullable) the language from the SIM records (if present).
349e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     *
350e3f6e6a186ac6efe15faa0aa9f1df0333e114ed7Wink Saville     * @return locale for the mcc or null if none
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville     */
35210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath    public static Locale getLocaleFromMcc(Context context, int mcc, String simLanguage) {
35310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        String language = (simLanguage == null) ? MccTable.defaultLanguageForMcc(mcc) : simLanguage;
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String country = MccTable.countryCodeForMcc(mcc);
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
35610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        Slog.d(LOG_TAG, "getLocaleFromMcc(" + language + ", " + country + ", " + mcc);
35710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        final Locale locale = getLocaleForLanguageCountry(context, language, country);
35810788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
35910788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // If we couldn't find a locale that matches the SIM language, give it a go again
36010788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        // with the "likely" language for the given country.
36110788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        if (locale == null && simLanguage != null) {
36210788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            language = MccTable.defaultLanguageForMcc(mcc);
36310788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            Slog.d(LOG_TAG, "[retry ] getLocaleFromMcc(" + language + ", " + country + ", " + mcc);
36410788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath            return getLocaleForLanguageCountry(context, null, country);
36510788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        }
36610788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath
36710788a883039603f3fd154cae6b760a54a83d86cNarayan Kamath        return locale;
3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
370e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt    /**
371b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt     * Set the country code for wifi.  This sets allowed wifi channels based on the
372b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt     * country of the carrier we see.  If we can't see any, reset to 0 so we don't
373b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt     * broadcast on forbidden channels.
374e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt     * @param context Context to act on.
375b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt     * @param mcc Mobile Country Code of the operator.  0 if not known
376e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt     */
377e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt    private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
378e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt        String country = MccTable.countryCodeForMcc(mcc);
379b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        Slog.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
380b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
381b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        //persist
382b0b637dbf2a67c0e7eee917c0809f1cc54983986Robert Greenwalt        wM.setCountryCode(country, true);
383e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt    }
384e0695876e8a7084cf4eaa8e6c71808f238a853a7Robert Greenwalt
3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    static {
38622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        sTable = new ArrayList<MccEntry>(240);
3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        /*
3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * The table below is built from two resources:
3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *
3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * 1) ITU "Mobile Network Code (MNC) for the international
3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *   identification plan for mobile terminals and mobile users"
3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *   which is available as an annex to the ITU operational bulletin
3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *   available here: http://www.itu.int/itu-t/bulletin/annex.html
3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *
3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * 2) The ISO 3166 country codes list, available here:
3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *    http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         *
4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         * This table has not been verified.
4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville         */
4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
40322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(202,"gr",2));	//Greece
404ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(204,"nl",2));	//Netherlands (Kingdom of the)
40522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(206,"be",2));	//Belgium
406ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(208,"fr",2));	//France
40722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(212,"mc",2));	//Monaco (Principality of)
40822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(213,"ad",2));	//Andorra (Principality of)
409ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(214,"es",2));	//Spain
410ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(216,"hu",2));	//Hungary (Republic of)
41122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(218,"ba",2));	//Bosnia and Herzegovina
412ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(219,"hr",2));	//Croatia (Republic of)
41322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(220,"rs",2));	//Serbia and Montenegro
414ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(222,"it",2));	//Italy
415ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(225,"va",2));	//Vatican City State
41622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(226,"ro",2));	//Romania
417ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(228,"ch",2));	//Switzerland (Confederation of)
418ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(230,"cz",2));	//Czech Republic
41922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(231,"sk",2));	//Slovak Republic
420ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(232,"at",2));	//Austria
421ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(234,"gb",2));	//United Kingdom of Great Britain and Northern Ireland
422ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(235,"gb",2));	//United Kingdom of Great Britain and Northern Ireland
42322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(238,"dk",2));	//Denmark
424ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(240,"se",2));	//Sweden
42522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(242,"no",2));	//Norway
42622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(244,"fi",2));	//Finland
42722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(246,"lt",2));	//Lithuania (Republic of)
42822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(247,"lv",2));	//Latvia (Republic of)
42922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(248,"ee",2));	//Estonia (Republic of)
43022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(250,"ru",2));	//Russian Federation
43122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(255,"ua",2));	//Ukraine
43222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(257,"by",2));	//Belarus (Republic of)
43322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(259,"md",2));	//Moldova (Republic of)
43422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(260,"pl",2));	//Poland (Republic of)
435ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(262,"de",2));	//Germany (Federal Republic of)
43622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(266,"gi",2));	//Gibraltar
43722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(268,"pt",2));	//Portugal
43822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(270,"lu",2));	//Luxembourg
439ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(272,"ie",2));	//Ireland
44022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(274,"is",2));	//Iceland
44122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(276,"al",2));	//Albania (Republic of)
44222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(278,"mt",2));	//Malta
44322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(280,"cy",2));	//Cyprus (Republic of)
44422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(282,"ge",2));	//Georgia
44522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(283,"am",2));	//Armenia (Republic of)
44622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(284,"bg",2));	//Bulgaria (Republic of)
44722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(286,"tr",2));	//Turkey
44822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(288,"fo",2));	//Faroe Islands
44922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sTable.add(new MccEntry(289,"ge",2));    //Abkhazia (Georgia)
45022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(290,"gl",2));	//Greenland (Denmark)
45122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(292,"sm",2));	//San Marino (Republic of)
45222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(293,"si",2));	//Slovenia (Republic of)
45322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sTable.add(new MccEntry(294,"mk",2));   //The Former Yugoslav Republic of Macedonia
45422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(295,"li",2));	//Liechtenstein (Principality of)
45522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sTable.add(new MccEntry(297,"me",2));    //Montenegro (Republic of)
456ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(302,"ca",3));	//Canada
45722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(308,"pm",2));	//Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
458ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(310,"us",3));	//United States of America
459ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(311,"us",3));	//United States of America
460ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(312,"us",3));	//United States of America
461ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(313,"us",3));	//United States of America
462ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(314,"us",3));	//United States of America
463ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(315,"us",3));	//United States of America
464ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(316,"us",3));	//United States of America
46522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(330,"pr",2));	//Puerto Rico
46622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(332,"vi",2));	//United States Virgin Islands
46722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(334,"mx",3));	//Mexico
46822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(338,"jm",3));	//Jamaica
46922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(340,"gp",2));	//Guadeloupe (French Department of)
47022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(342,"bb",3));	//Barbados
47122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(344,"ag",3));	//Antigua and Barbuda
47222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(346,"ky",3));	//Cayman Islands
47322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(348,"vg",3));	//British Virgin Islands
47422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(350,"bm",2));	//Bermuda
47522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(352,"gd",2));	//Grenada
47622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(354,"ms",2));	//Montserrat
47722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(356,"kn",2));	//Saint Kitts and Nevis
47822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(358,"lc",2));	//Saint Lucia
47922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(360,"vc",2));	//Saint Vincent and the Grenadines
48022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(362,"ai",2));	//Netherlands Antilles
48122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(363,"aw",2));	//Aruba
48222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(364,"bs",2));	//Bahamas (Commonwealth of the)
48322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(365,"ai",3));	//Anguilla
48422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(366,"dm",2));	//Dominica (Commonwealth of)
48522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(368,"cu",2));	//Cuba
48622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(370,"do",2));	//Dominican Republic
48722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(372,"ht",2));	//Haiti (Republic of)
48822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(374,"tt",2));	//Trinidad and Tobago
48922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(376,"tc",2));	//Turks and Caicos Islands
49022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(400,"az",2));	//Azerbaijani Republic
49122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(401,"kz",2));	//Kazakhstan (Republic of)
49222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(402,"bt",2));	//Bhutan (Kingdom of)
49322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(404,"in",2));	//India (Republic of)
49422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(405,"in",2));	//India (Republic of)
495ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(406,"in",2));	//India (Republic of)
49622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(410,"pk",2));	//Pakistan (Islamic Republic of)
49722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(412,"af",2));	//Afghanistan
49822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(413,"lk",2));	//Sri Lanka (Democratic Socialist Republic of)
49922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(414,"mm",2));	//Myanmar (Union of)
50022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(415,"lb",2));	//Lebanon
50122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(416,"jo",2));	//Jordan (Hashemite Kingdom of)
50222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(417,"sy",2));	//Syrian Arab Republic
50322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(418,"iq",2));	//Iraq (Republic of)
50422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(419,"kw",2));	//Kuwait (State of)
50522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(420,"sa",2));	//Saudi Arabia (Kingdom of)
50622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(421,"ye",2));	//Yemen (Republic of)
50722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(422,"om",2));	//Oman (Sultanate of)
50822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                sTable.add(new MccEntry(423,"ps",2));    //Palestine
50922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(424,"ae",2));	//United Arab Emirates
51022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(425,"il",2));	//Israel (State of)
51122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(426,"bh",2));	//Bahrain (Kingdom of)
51222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(427,"qa",2));	//Qatar (State of)
51322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(428,"mn",2));	//Mongolia
51422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(429,"np",2));	//Nepal
51522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(430,"ae",2));	//United Arab Emirates
51622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(431,"ae",2));	//United Arab Emirates
51722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(432,"ir",2));	//Iran (Islamic Republic of)
51822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(434,"uz",2));	//Uzbekistan (Republic of)
51922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(436,"tj",2));	//Tajikistan (Republic of)
52022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(437,"kg",2));	//Kyrgyz Republic
52122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(438,"tm",2));	//Turkmenistan
522ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(440,"jp",2));	//Japan
523ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(441,"jp",2));	//Japan
524ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(450,"kr",2));	//Korea (Republic of)
52522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(452,"vn",2));	//Viet Nam (Socialist Republic of)
52622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(454,"hk",2));	//"Hong Kong, China"
52722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(455,"mo",2));	//"Macao, China"
52822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(456,"kh",2));	//Cambodia (Kingdom of)
52922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(457,"la",2));	//Lao People's Democratic Republic
530ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(460,"cn",2));	//China (People's Republic of)
531ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(461,"cn",2));	//China (People's Republic of)
53288c4df5614b61958aa0995eba7fd0ad6eaae2b50Jack Yu		sTable.add(new MccEntry(466,"tw",2));	//Taiwan
53322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(467,"kp",2));	//Democratic People's Republic of Korea
53422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(470,"bd",2));	//Bangladesh (People's Republic of)
53522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(472,"mv",2));	//Maldives (Republic of)
53622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(502,"my",2));	//Malaysia
537ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(505,"au",2));	//Australia
53822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(510,"id",2));	//Indonesia (Republic of)
53922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(514,"tl",2));	//Democratic Republic of Timor-Leste
54022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(515,"ph",2));	//Philippines (Republic of the)
54122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(520,"th",2));	//Thailand
542ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(525,"sg",2));	//Singapore (Republic of)
54322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(528,"bn",2));	//Brunei Darussalam
544ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(530,"nz",2));	//New Zealand
54522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(534,"mp",2));	//Northern Mariana Islands (Commonwealth of the)
54622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(535,"gu",2));	//Guam
54722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(536,"nr",2));	//Nauru (Republic of)
54822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(537,"pg",2));	//Papua New Guinea
54922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(539,"to",2));	//Tonga (Kingdom of)
55022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(540,"sb",2));	//Solomon Islands
55122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(541,"vu",2));	//Vanuatu (Republic of)
55222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(542,"fj",2));	//Fiji (Republic of)
55322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(543,"wf",2));	//Wallis and Futuna (Territoire franais d'outre-mer)
55422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(544,"as",2));	//American Samoa
55522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(545,"ki",2));	//Kiribati (Republic of)
55622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(546,"nc",2));	//New Caledonia (Territoire franais d'outre-mer)
55722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(547,"pf",2));	//French Polynesia (Territoire franais d'outre-mer)
55822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(548,"ck",2));	//Cook Islands
55922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(549,"ws",2));	//Samoa (Independent State of)
56022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(550,"fm",2));	//Micronesia (Federated States of)
56122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(551,"mh",2));	//Marshall Islands (Republic of the)
56222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(552,"pw",2));	//Palau (Republic of)
563ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(553,"tv",2));	//Tuvalu
564ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(555,"nu",2));	//Niue
56522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(602,"eg",2));	//Egypt (Arab Republic of)
56622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(603,"dz",2));	//Algeria (People's Democratic Republic of)
56722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(604,"ma",2));	//Morocco (Kingdom of)
56822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(605,"tn",2));	//Tunisia
56922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(606,"ly",2));	//Libya (Socialist People's Libyan Arab Jamahiriya)
57022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(607,"gm",2));	//Gambia (Republic of the)
57122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(608,"sn",2));	//Senegal (Republic of)
57222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(609,"mr",2));	//Mauritania (Islamic Republic of)
57322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(610,"ml",2));	//Mali (Republic of)
57422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(611,"gn",2));	//Guinea (Republic of)
575ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(612,"ci",2));	//Côte d'Ivoire (Republic of)
57622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(613,"bf",2));	//Burkina Faso
57722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(614,"ne",2));	//Niger (Republic of the)
57822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(615,"tg",2));	//Togolese Republic
57922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(616,"bj",2));	//Benin (Republic of)
58022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(617,"mu",2));	//Mauritius (Republic of)
58122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(618,"lr",2));	//Liberia (Republic of)
58222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(619,"sl",2));	//Sierra Leone
58322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(620,"gh",2));	//Ghana
58422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(621,"ng",2));	//Nigeria (Federal Republic of)
58522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(622,"td",2));	//Chad (Republic of)
58622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(623,"cf",2));	//Central African Republic
58722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(624,"cm",2));	//Cameroon (Republic of)
58822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(625,"cv",2));	//Cape Verde (Republic of)
58922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(626,"st",2));	//Sao Tome and Principe (Democratic Republic of)
59022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(627,"gq",2));	//Equatorial Guinea (Republic of)
59122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(628,"ga",2));	//Gabonese Republic
59222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(629,"cg",2));	//Congo (Republic of the)
59388c4df5614b61958aa0995eba7fd0ad6eaae2b50Jack Yu		sTable.add(new MccEntry(630,"cd",2));	//Democratic Republic of the Congo
59422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(631,"ao",2));	//Angola (Republic of)
59522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(632,"gw",2));	//Guinea-Bissau (Republic of)
59622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(633,"sc",2));	//Seychelles (Republic of)
59722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(634,"sd",2));	//Sudan (Republic of the)
59822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(635,"rw",2));	//Rwanda (Republic of)
59922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(636,"et",2));	//Ethiopia (Federal Democratic Republic of)
60022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(637,"so",2));	//Somali Democratic Republic
60122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(638,"dj",2));	//Djibouti (Republic of)
60222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(639,"ke",2));	//Kenya (Republic of)
60322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(640,"tz",2));	//Tanzania (United Republic of)
60422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(641,"ug",2));	//Uganda (Republic of)
60522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(642,"bi",2));	//Burundi (Republic of)
60622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(643,"mz",2));	//Mozambique (Republic of)
60722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(645,"zm",2));	//Zambia (Republic of)
60822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(646,"mg",2));	//Madagascar (Republic of)
60922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(647,"re",2));	//Reunion (French Department of)
61022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(648,"zw",2));	//Zimbabwe (Republic of)
61122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(649,"na",2));	//Namibia (Republic of)
61222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(650,"mw",2));	//Malawi
61322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(651,"ls",2));	//Lesotho (Kingdom of)
61422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(652,"bw",2));	//Botswana (Republic of)
61522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(653,"sz",2));	//Swaziland (Kingdom of)
61622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(654,"km",2));	//Comoros (Union of the)
617ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(655,"za",2));	//South Africa (Republic of)
61822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(657,"er",2));	//Eritrea
619ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(658,"sh",2));	//Saint Helena, Ascension and Tristan da Cunha
620ef43e2415dd9e668f05d692dc540d200063e9e6cElliott Hughes		sTable.add(new MccEntry(659,"ss",2));	//South Sudan (Republic of)
62122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(702,"bz",2));	//Belize
62222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(704,"gt",2));	//Guatemala (Republic of)
62322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(706,"sv",2));	//El Salvador (Republic of)
62422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(708,"hn",3));	//Honduras (Republic of)
62522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(710,"ni",2));	//Nicaragua
62622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(712,"cr",2));	//Costa Rica
62722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(714,"pa",2));	//Panama (Republic of)
62822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(716,"pe",2));	//Peru
62922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(722,"ar",3));	//Argentine Republic
63022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(724,"br",2));	//Brazil (Federative Republic of)
63122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(730,"cl",2));	//Chile
63222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(732,"co",3));	//Colombia (Republic of)
63322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(734,"ve",2));	//Venezuela (Bolivarian Republic of)
63422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(736,"bo",2));	//Bolivia (Republic of)
63522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(738,"gy",2));	//Guyana
63622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(740,"ec",2));	//Ecuador
63722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(742,"gf",2));	//French Guiana (French Department of)
63822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(744,"py",2));	//Paraguay (Republic of)
63922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(746,"sr",2));	//Suriname (Republic of)
64022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(748,"uy",2));	//Uruguay (Eastern Republic of)
64122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville		sTable.add(new MccEntry(750,"fk",2));	//Falkland Islands (Malvinas)
6420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //table.add(new MccEntry(901,"",2));	//"International Mobile, shared code"
6430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
64422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        Collections.sort(sTable);
6450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
6460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
647