MccTable.java revision a081eb7d8c7dabf82f6dcc1dcf78d4525200645a
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 17package com.android.internal.telephony; 18 19import android.app.ActivityManagerNative; 20import android.app.AlarmManager; 21import android.content.Context; 22import android.content.res.Configuration; 23import android.net.wifi.WifiManager; 24import android.os.Build; 25import android.os.RemoteException; 26import android.os.SystemProperties; 27import android.provider.Settings; 28import android.telephony.TelephonyManager; 29import android.text.TextUtils; 30import android.util.Slog; 31 32import java.util.ArrayList; 33import java.util.Arrays; 34import java.util.Collections; 35import java.util.List; 36import java.util.Locale; 37import libcore.icu.ICU; 38import libcore.icu.TimeZoneNames; 39 40/** 41 * Mobile Country Code 42 * 43 * {@hide} 44 */ 45public final class MccTable { 46 static final String LOG_TAG = "MccTable"; 47 48 static ArrayList<MccEntry> sTable; 49 50 static class MccEntry implements Comparable<MccEntry> { 51 final int mMcc; 52 final String mIso; 53 final int mSmallestDigitsMnc; 54 55 MccEntry(int mnc, String iso, int smallestDigitsMCC) { 56 if (iso == null) { 57 throw new NullPointerException(); 58 } 59 mMcc = mnc; 60 mIso = iso; 61 mSmallestDigitsMnc = smallestDigitsMCC; 62 } 63 64 @Override 65 public int compareTo(MccEntry o) { 66 return mMcc - o.mMcc; 67 } 68 } 69 70 private static MccEntry entryForMcc(int mcc) { 71 MccEntry m = new MccEntry(mcc, "", 0); 72 73 int index = Collections.binarySearch(sTable, m); 74 75 if (index < 0) { 76 return null; 77 } else { 78 return sTable.get(index); 79 } 80 } 81 82 /** 83 * Returns a default time zone ID for the given MCC. 84 * @param mcc Mobile Country Code 85 * @return default TimeZone ID, or null if not specified 86 */ 87 public static String defaultTimeZoneForMcc(int mcc) { 88 MccEntry entry = entryForMcc(mcc); 89 if (entry == null) { 90 return null; 91 } 92 Locale locale = new Locale("", entry.mIso); 93 String[] tz = TimeZoneNames.forLocale(locale); 94 if (tz.length == 0) return null; 95 return tz[0]; 96 } 97 98 /** 99 * Given a GSM Mobile Country Code, returns 100 * an ISO two-character country code if available. 101 * Returns "" if unavailable. 102 */ 103 public static String countryCodeForMcc(int mcc) { 104 MccEntry entry = entryForMcc(mcc); 105 106 if (entry == null) { 107 return ""; 108 } else { 109 return entry.mIso; 110 } 111 } 112 113 /** 114 * Given a GSM Mobile Country Code, returns 115 * an ISO 2-3 character language code if available. 116 * Returns null if unavailable. 117 */ 118 public static String defaultLanguageForMcc(int mcc) { 119 MccEntry entry = entryForMcc(mcc); 120 if (entry == null) { 121 Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): no country for mcc"); 122 return null; 123 } 124 125 // Ask CLDR for the language this country uses... 126 Locale likelyLocale = ICU.addLikelySubtags(new Locale("und", entry.mIso)); 127 String likelyLanguage = likelyLocale.getLanguage(); 128 Slog.d(LOG_TAG, "defaultLanguageForMcc(" + mcc + "): country " + entry.mIso + " uses " + 129 likelyLanguage); 130 return likelyLanguage; 131 } 132 133 /** 134 * Given a GSM Mobile Country Code, returns 135 * the smallest number of digits that M if available. 136 * Returns 2 if unavailable. 137 */ 138 public static int smallestDigitsMccForMnc(int mcc) { 139 MccEntry entry = entryForMcc(mcc); 140 141 if (entry == null) { 142 return 2; 143 } else { 144 return entry.mSmallestDigitsMnc; 145 } 146 } 147 148 /** 149 * Updates MCC and MNC device configuration information for application retrieving 150 * correct version of resources. If MCC is 0, MCC and MNC will be ignored (not set). 151 * @param context Context to act on. 152 * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end 153 * @param fromServiceState true if coming from the radio service state, false if from SIM 154 */ 155 public static void updateMccMncConfiguration(Context context, String mccmnc, 156 boolean fromServiceState) { 157 Slog.d(LOG_TAG, "updateMccMncConfiguration mccmnc='" + mccmnc + "' fromServiceState=" + fromServiceState); 158 159 if (Build.IS_DEBUGGABLE) { 160 String overrideMcc = SystemProperties.get("persist.sys.override_mcc"); 161 if (!TextUtils.isEmpty(overrideMcc)) { 162 mccmnc = overrideMcc; 163 Slog.d(LOG_TAG, "updateMccMncConfiguration overriding mccmnc='" + mccmnc + "'"); 164 } 165 } 166 167 if (!TextUtils.isEmpty(mccmnc)) { 168 int mcc, mnc; 169 170 String defaultMccMnc = TelephonyManager.getDefault().getSimOperatorNumeric(); 171 Slog.d(LOG_TAG, "updateMccMncConfiguration defaultMccMnc=" + defaultMccMnc); 172 //Update mccmnc only for default subscription in case of MultiSim. 173// if (!defaultMccMnc.equals(mccmnc)) { 174// Slog.d(LOG_TAG, "Not a Default subscription, ignoring mccmnc config update."); 175// return; 176// } 177 178 try { 179 mcc = Integer.parseInt(mccmnc.substring(0,3)); 180 mnc = Integer.parseInt(mccmnc.substring(3)); 181 } catch (NumberFormatException e) { 182 Slog.e(LOG_TAG, "Error parsing IMSI: " + mccmnc); 183 return; 184 } 185 186 Slog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc); 187 188 Locale locale = null; 189 if (mcc != 0) { 190 setTimezoneFromMccIfNeeded(context, mcc); 191 locale = getLocaleFromMcc(context, mcc); 192 } 193 if (fromServiceState) { 194 setWifiCountryCodeFromMcc(context, mcc); 195 } else { 196 // from SIM 197 try { 198 Configuration config = new Configuration(); 199 boolean updateConfig = false; 200 if (mcc != 0) { 201 config.mcc = mcc; 202 config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc; 203 updateConfig = true; 204 } 205 if (locale != null) { 206 config.setLocale(locale); 207 updateConfig = true; 208 } 209 if (updateConfig) { 210 Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config); 211 ActivityManagerNative.getDefault().updateConfiguration(config); 212 } else { 213 Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update"); 214 } 215 } catch (RemoteException e) { 216 Slog.e(LOG_TAG, "Can't update configuration", e); 217 } 218 } 219 } else { 220 if (fromServiceState) { 221 // an empty mccmnc means no signal - tell wifi we don't know 222 setWifiCountryCodeFromMcc(context, 0); 223 } 224 } 225 } 226 227 // Bug 19232829: It is possible to get through provisioning without setting up a persistent 228 // locale value. We don't modify the locale if the device has completed "provisioning" because 229 // we don't want to change the locale if the user inserts a new SIM or a new version of Android 230 // is better at recognizing MCC values than an older version. 231 private static boolean canUpdateLocale(Context context) { 232 return !(userHasPersistedLocale() || isDeviceProvisioned(context)); 233 } 234 235 private static boolean userHasPersistedLocale() { 236 String persistSysLanguage = SystemProperties.get("persist.sys.language", ""); 237 String persistSysCountry = SystemProperties.get("persist.sys.country", ""); 238 return !(persistSysLanguage.isEmpty() && persistSysCountry.isEmpty()); 239 } 240 241 private static boolean isDeviceProvisioned(Context context) { 242 try { 243 return Settings.Global.getInt( 244 context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED) != 0; 245 } catch (Settings.SettingNotFoundException e) { 246 return false; 247 } 248 } 249 250 /** 251 * Return Locale for the language and country or null if no good match. 252 * 253 * @param context Context to act on. 254 * @param language Two character language code desired 255 * @param country Two character country code desired 256 * 257 * @return Locale or null if no appropriate value 258 */ 259 private static Locale getLocaleForLanguageCountry(Context context, String language, 260 String country) { 261 if (language == null) { 262 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: skipping no language"); 263 return null; // no match possible 264 } 265 if (country == null) { 266 country = ""; // The Locale constructor throws if passed null. 267 } 268 269 // Check whether a developer is trying to test an arbitrary MCC. 270 boolean debuggingMccOverride = isDebuggingMccOverride(); 271 272 // If this is a regular user and they already have a persisted locale, we're done. 273 if (!(debuggingMccOverride || canUpdateLocale(context))) { 274 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: not permitted to update locale"); 275 return null; 276 } 277 278 // Find the best match we actually have a localization for. 279 // TODO: this should really follow the CLDR chain of parent locales! 280 final Locale target = new Locale(language, country); 281 try { 282 String[] localeArray = context.getAssets().getLocales(); 283 List<String> locales = new ArrayList<>(Arrays.asList(localeArray)); 284 285 // Even in developer mode, you don't want the pseudolocales. 286 locales.remove("ar-XB"); 287 locales.remove("en-XA"); 288 289 Locale firstMatch = null; 290 for (String locale : locales) { 291 final Locale l = Locale.forLanguageTag(locale.replace('_', '-')); 292 293 // Only consider locales with both language and country. 294 if (l == null || "und".equals(l.getLanguage()) || 295 l.getLanguage().isEmpty() || l.getCountry().isEmpty()) { 296 continue; 297 } 298 if (l.getLanguage().equals(target.getLanguage())) { 299 // If we got a perfect match, we're done. 300 if (l.getCountry().equals(target.getCountry())) { 301 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got perfect match: " + 302 l.toLanguageTag()); 303 return l; 304 } 305 // Otherwise somewhat arbitrarily take the first locale for the language, 306 // unless we get a perfect match later. Note that these come back in no 307 // particular order, so there's no reason to think the first match is 308 // a particularly good match. 309 if (firstMatch == null) { 310 firstMatch = l; 311 } 312 } 313 } 314 315 // We didn't find the exact locale, so return whichever locale we saw first where 316 // the language matched (if any). 317 if (firstMatch != null) { 318 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got a language-only match: " + 319 firstMatch.toLanguageTag()); 320 return firstMatch; 321 } else { 322 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: no locales for language " + 323 language); 324 } 325 } catch (Exception e) { 326 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: exception", e); 327 } 328 329 return null; 330 } 331 332 private static boolean isDebuggingMccOverride() { 333 if (Build.IS_DEBUGGABLE) { 334 String overrideMcc = SystemProperties.get("persist.sys.override_mcc", ""); 335 if (!overrideMcc.isEmpty()) { 336 return true; 337 } 338 } 339 return false; 340 } 341 342 /** 343 * Utility code to set the system locale if it's not set already 344 * @param context Context to act on. 345 * @param language Two character language code desired 346 * @param country Two character country code desired 347 * 348 * {@hide} 349 */ 350 public static void setSystemLocale(Context context, String language, String country) { 351 Locale locale = getLocaleForLanguageCountry(context, language, country); 352 if (locale != null) { 353 Configuration config = new Configuration(); 354 config.setLocale(locale); 355 config.userSetLocale = false; 356 Slog.d(LOG_TAG, "setSystemLocale: updateLocale config=" + config); 357 try { 358 ActivityManagerNative.getDefault().updateConfiguration(config); 359 } catch (RemoteException e) { 360 Slog.d(LOG_TAG, "setSystemLocale exception", e); 361 } 362 } else { 363 Slog.d(LOG_TAG, "setSystemLocale: no locale"); 364 } 365 } 366 367 /** 368 * If the timezone is not already set, set it based on the MCC of the SIM. 369 * @param context Context to act on. 370 * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA) 371 */ 372 private static void setTimezoneFromMccIfNeeded(Context context, int mcc) { 373 String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY); 374 if (timezone == null || timezone.length() == 0) { 375 String zoneId = defaultTimeZoneForMcc(mcc); 376 if (zoneId != null && zoneId.length() > 0) { 377 // Set time zone based on MCC 378 AlarmManager alarm = 379 (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 380 alarm.setTimeZone(zoneId); 381 Slog.d(LOG_TAG, "timezone set to "+zoneId); 382 } 383 } 384 } 385 386 /** 387 * Get Locale based on the MCC of the SIM. 388 * @param context Context to act on. 389 * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA) 390 * 391 * @return locale for the mcc or null if none 392 */ 393 private static Locale getLocaleFromMcc(Context context, int mcc) { 394 String language = MccTable.defaultLanguageForMcc(mcc); 395 String country = MccTable.countryCodeForMcc(mcc); 396 397 Slog.d(LOG_TAG, "getLocaleFromMcc to " + language + "_" + country + " mcc=" + mcc); 398 return getLocaleForLanguageCountry(context, language, country); 399 } 400 401 /** 402 * Set the country code for wifi. This sets allowed wifi channels based on the 403 * country of the carrier we see. If we can't see any, reset to 0 so we don't 404 * broadcast on forbidden channels. 405 * @param context Context to act on. 406 * @param mcc Mobile Country Code of the operator. 0 if not known 407 */ 408 private static void setWifiCountryCodeFromMcc(Context context, int mcc) { 409 String country = MccTable.countryCodeForMcc(mcc); 410 Slog.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country); 411 WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 412 //persist 413 wM.setCountryCode(country, true); 414 } 415 416 static { 417 sTable = new ArrayList<MccEntry>(240); 418 419 420 /* 421 * The table below is built from two resources: 422 * 423 * 1) ITU "Mobile Network Code (MNC) for the international 424 * identification plan for mobile terminals and mobile users" 425 * which is available as an annex to the ITU operational bulletin 426 * available here: http://www.itu.int/itu-t/bulletin/annex.html 427 * 428 * 2) The ISO 3166 country codes list, available here: 429 * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html 430 * 431 * This table has not been verified. 432 */ 433 434 sTable.add(new MccEntry(202,"gr",2)); //Greece 435 sTable.add(new MccEntry(204,"nl",2)); //Netherlands (Kingdom of the) 436 sTable.add(new MccEntry(206,"be",2)); //Belgium 437 sTable.add(new MccEntry(208,"fr",2)); //France 438 sTable.add(new MccEntry(212,"mc",2)); //Monaco (Principality of) 439 sTable.add(new MccEntry(213,"ad",2)); //Andorra (Principality of) 440 sTable.add(new MccEntry(214,"es",2)); //Spain 441 sTable.add(new MccEntry(216,"hu",2)); //Hungary (Republic of) 442 sTable.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina 443 sTable.add(new MccEntry(219,"hr",2)); //Croatia (Republic of) 444 sTable.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro 445 sTable.add(new MccEntry(222,"it",2)); //Italy 446 sTable.add(new MccEntry(225,"va",2)); //Vatican City State 447 sTable.add(new MccEntry(226,"ro",2)); //Romania 448 sTable.add(new MccEntry(228,"ch",2)); //Switzerland (Confederation of) 449 sTable.add(new MccEntry(230,"cz",2)); //Czech Republic 450 sTable.add(new MccEntry(231,"sk",2)); //Slovak Republic 451 sTable.add(new MccEntry(232,"at",2)); //Austria 452 sTable.add(new MccEntry(234,"gb",2)); //United Kingdom of Great Britain and Northern Ireland 453 sTable.add(new MccEntry(235,"gb",2)); //United Kingdom of Great Britain and Northern Ireland 454 sTable.add(new MccEntry(238,"dk",2)); //Denmark 455 sTable.add(new MccEntry(240,"se",2)); //Sweden 456 sTable.add(new MccEntry(242,"no",2)); //Norway 457 sTable.add(new MccEntry(244,"fi",2)); //Finland 458 sTable.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of) 459 sTable.add(new MccEntry(247,"lv",2)); //Latvia (Republic of) 460 sTable.add(new MccEntry(248,"ee",2)); //Estonia (Republic of) 461 sTable.add(new MccEntry(250,"ru",2)); //Russian Federation 462 sTable.add(new MccEntry(255,"ua",2)); //Ukraine 463 sTable.add(new MccEntry(257,"by",2)); //Belarus (Republic of) 464 sTable.add(new MccEntry(259,"md",2)); //Moldova (Republic of) 465 sTable.add(new MccEntry(260,"pl",2)); //Poland (Republic of) 466 sTable.add(new MccEntry(262,"de",2)); //Germany (Federal Republic of) 467 sTable.add(new MccEntry(266,"gi",2)); //Gibraltar 468 sTable.add(new MccEntry(268,"pt",2)); //Portugal 469 sTable.add(new MccEntry(270,"lu",2)); //Luxembourg 470 sTable.add(new MccEntry(272,"ie",2)); //Ireland 471 sTable.add(new MccEntry(274,"is",2)); //Iceland 472 sTable.add(new MccEntry(276,"al",2)); //Albania (Republic of) 473 sTable.add(new MccEntry(278,"mt",2)); //Malta 474 sTable.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of) 475 sTable.add(new MccEntry(282,"ge",2)); //Georgia 476 sTable.add(new MccEntry(283,"am",2)); //Armenia (Republic of) 477 sTable.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of) 478 sTable.add(new MccEntry(286,"tr",2)); //Turkey 479 sTable.add(new MccEntry(288,"fo",2)); //Faroe Islands 480 sTable.add(new MccEntry(289,"ge",2)); //Abkhazia (Georgia) 481 sTable.add(new MccEntry(290,"gl",2)); //Greenland (Denmark) 482 sTable.add(new MccEntry(292,"sm",2)); //San Marino (Republic of) 483 sTable.add(new MccEntry(293,"si",2)); //Slovenia (Republic of) 484 sTable.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia 485 sTable.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of) 486 sTable.add(new MccEntry(297,"me",2)); //Montenegro (Republic of) 487 sTable.add(new MccEntry(302,"ca",3)); //Canada 488 sTable.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise) 489 sTable.add(new MccEntry(310,"us",3)); //United States of America 490 sTable.add(new MccEntry(311,"us",3)); //United States of America 491 sTable.add(new MccEntry(312,"us",3)); //United States of America 492 sTable.add(new MccEntry(313,"us",3)); //United States of America 493 sTable.add(new MccEntry(314,"us",3)); //United States of America 494 sTable.add(new MccEntry(315,"us",3)); //United States of America 495 sTable.add(new MccEntry(316,"us",3)); //United States of America 496 sTable.add(new MccEntry(330,"pr",2)); //Puerto Rico 497 sTable.add(new MccEntry(332,"vi",2)); //United States Virgin Islands 498 sTable.add(new MccEntry(334,"mx",3)); //Mexico 499 sTable.add(new MccEntry(338,"jm",3)); //Jamaica 500 sTable.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of) 501 sTable.add(new MccEntry(342,"bb",3)); //Barbados 502 sTable.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda 503 sTable.add(new MccEntry(346,"ky",3)); //Cayman Islands 504 sTable.add(new MccEntry(348,"vg",3)); //British Virgin Islands 505 sTable.add(new MccEntry(350,"bm",2)); //Bermuda 506 sTable.add(new MccEntry(352,"gd",2)); //Grenada 507 sTable.add(new MccEntry(354,"ms",2)); //Montserrat 508 sTable.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis 509 sTable.add(new MccEntry(358,"lc",2)); //Saint Lucia 510 sTable.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines 511 sTable.add(new MccEntry(362,"ai",2)); //Netherlands Antilles 512 sTable.add(new MccEntry(363,"aw",2)); //Aruba 513 sTable.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the) 514 sTable.add(new MccEntry(365,"ai",3)); //Anguilla 515 sTable.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of) 516 sTable.add(new MccEntry(368,"cu",2)); //Cuba 517 sTable.add(new MccEntry(370,"do",2)); //Dominican Republic 518 sTable.add(new MccEntry(372,"ht",2)); //Haiti (Republic of) 519 sTable.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago 520 sTable.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands 521 sTable.add(new MccEntry(400,"az",2)); //Azerbaijani Republic 522 sTable.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of) 523 sTable.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of) 524 sTable.add(new MccEntry(404,"in",2)); //India (Republic of) 525 sTable.add(new MccEntry(405,"in",2)); //India (Republic of) 526 sTable.add(new MccEntry(406,"in",2)); //India (Republic of) 527 sTable.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of) 528 sTable.add(new MccEntry(412,"af",2)); //Afghanistan 529 sTable.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of) 530 sTable.add(new MccEntry(414,"mm",2)); //Myanmar (Union of) 531 sTable.add(new MccEntry(415,"lb",2)); //Lebanon 532 sTable.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of) 533 sTable.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic 534 sTable.add(new MccEntry(418,"iq",2)); //Iraq (Republic of) 535 sTable.add(new MccEntry(419,"kw",2)); //Kuwait (State of) 536 sTable.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of) 537 sTable.add(new MccEntry(421,"ye",2)); //Yemen (Republic of) 538 sTable.add(new MccEntry(422,"om",2)); //Oman (Sultanate of) 539 sTable.add(new MccEntry(423,"ps",2)); //Palestine 540 sTable.add(new MccEntry(424,"ae",2)); //United Arab Emirates 541 sTable.add(new MccEntry(425,"il",2)); //Israel (State of) 542 sTable.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of) 543 sTable.add(new MccEntry(427,"qa",2)); //Qatar (State of) 544 sTable.add(new MccEntry(428,"mn",2)); //Mongolia 545 sTable.add(new MccEntry(429,"np",2)); //Nepal 546 sTable.add(new MccEntry(430,"ae",2)); //United Arab Emirates 547 sTable.add(new MccEntry(431,"ae",2)); //United Arab Emirates 548 sTable.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of) 549 sTable.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of) 550 sTable.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of) 551 sTable.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic 552 sTable.add(new MccEntry(438,"tm",2)); //Turkmenistan 553 sTable.add(new MccEntry(440,"jp",2)); //Japan 554 sTable.add(new MccEntry(441,"jp",2)); //Japan 555 sTable.add(new MccEntry(450,"kr",2)); //Korea (Republic of) 556 sTable.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of) 557 sTable.add(new MccEntry(454,"hk",2)); //"Hong Kong, China" 558 sTable.add(new MccEntry(455,"mo",2)); //"Macao, China" 559 sTable.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of) 560 sTable.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic 561 sTable.add(new MccEntry(460,"cn",2)); //China (People's Republic of) 562 sTable.add(new MccEntry(461,"cn",2)); //China (People's Republic of) 563 sTable.add(new MccEntry(466,"tw",2)); //"Taiwan, China" 564 sTable.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea 565 sTable.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of) 566 sTable.add(new MccEntry(472,"mv",2)); //Maldives (Republic of) 567 sTable.add(new MccEntry(502,"my",2)); //Malaysia 568 sTable.add(new MccEntry(505,"au",2)); //Australia 569 sTable.add(new MccEntry(510,"id",2)); //Indonesia (Republic of) 570 sTable.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste 571 sTable.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the) 572 sTable.add(new MccEntry(520,"th",2)); //Thailand 573 sTable.add(new MccEntry(525,"sg",2)); //Singapore (Republic of) 574 sTable.add(new MccEntry(528,"bn",2)); //Brunei Darussalam 575 sTable.add(new MccEntry(530,"nz",2)); //New Zealand 576 sTable.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the) 577 sTable.add(new MccEntry(535,"gu",2)); //Guam 578 sTable.add(new MccEntry(536,"nr",2)); //Nauru (Republic of) 579 sTable.add(new MccEntry(537,"pg",2)); //Papua New Guinea 580 sTable.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of) 581 sTable.add(new MccEntry(540,"sb",2)); //Solomon Islands 582 sTable.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of) 583 sTable.add(new MccEntry(542,"fj",2)); //Fiji (Republic of) 584 sTable.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer) 585 sTable.add(new MccEntry(544,"as",2)); //American Samoa 586 sTable.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of) 587 sTable.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer) 588 sTable.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer) 589 sTable.add(new MccEntry(548,"ck",2)); //Cook Islands 590 sTable.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of) 591 sTable.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of) 592 sTable.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the) 593 sTable.add(new MccEntry(552,"pw",2)); //Palau (Republic of) 594 sTable.add(new MccEntry(553,"tv",2)); //Tuvalu 595 sTable.add(new MccEntry(555,"nu",2)); //Niue 596 sTable.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of) 597 sTable.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of) 598 sTable.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of) 599 sTable.add(new MccEntry(605,"tn",2)); //Tunisia 600 sTable.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya) 601 sTable.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the) 602 sTable.add(new MccEntry(608,"sn",2)); //Senegal (Republic of) 603 sTable.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of) 604 sTable.add(new MccEntry(610,"ml",2)); //Mali (Republic of) 605 sTable.add(new MccEntry(611,"gn",2)); //Guinea (Republic of) 606 sTable.add(new MccEntry(612,"ci",2)); //Côte d'Ivoire (Republic of) 607 sTable.add(new MccEntry(613,"bf",2)); //Burkina Faso 608 sTable.add(new MccEntry(614,"ne",2)); //Niger (Republic of the) 609 sTable.add(new MccEntry(615,"tg",2)); //Togolese Republic 610 sTable.add(new MccEntry(616,"bj",2)); //Benin (Republic of) 611 sTable.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of) 612 sTable.add(new MccEntry(618,"lr",2)); //Liberia (Republic of) 613 sTable.add(new MccEntry(619,"sl",2)); //Sierra Leone 614 sTable.add(new MccEntry(620,"gh",2)); //Ghana 615 sTable.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of) 616 sTable.add(new MccEntry(622,"td",2)); //Chad (Republic of) 617 sTable.add(new MccEntry(623,"cf",2)); //Central African Republic 618 sTable.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of) 619 sTable.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of) 620 sTable.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of) 621 sTable.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of) 622 sTable.add(new MccEntry(628,"ga",2)); //Gabonese Republic 623 sTable.add(new MccEntry(629,"cg",2)); //Congo (Republic of the) 624 sTable.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo 625 sTable.add(new MccEntry(631,"ao",2)); //Angola (Republic of) 626 sTable.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of) 627 sTable.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of) 628 sTable.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the) 629 sTable.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of) 630 sTable.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of) 631 sTable.add(new MccEntry(637,"so",2)); //Somali Democratic Republic 632 sTable.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of) 633 sTable.add(new MccEntry(639,"ke",2)); //Kenya (Republic of) 634 sTable.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of) 635 sTable.add(new MccEntry(641,"ug",2)); //Uganda (Republic of) 636 sTable.add(new MccEntry(642,"bi",2)); //Burundi (Republic of) 637 sTable.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of) 638 sTable.add(new MccEntry(645,"zm",2)); //Zambia (Republic of) 639 sTable.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of) 640 sTable.add(new MccEntry(647,"re",2)); //Reunion (French Department of) 641 sTable.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of) 642 sTable.add(new MccEntry(649,"na",2)); //Namibia (Republic of) 643 sTable.add(new MccEntry(650,"mw",2)); //Malawi 644 sTable.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of) 645 sTable.add(new MccEntry(652,"bw",2)); //Botswana (Republic of) 646 sTable.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of) 647 sTable.add(new MccEntry(654,"km",2)); //Comoros (Union of the) 648 sTable.add(new MccEntry(655,"za",2)); //South Africa (Republic of) 649 sTable.add(new MccEntry(657,"er",2)); //Eritrea 650 sTable.add(new MccEntry(658,"sh",2)); //Saint Helena, Ascension and Tristan da Cunha 651 sTable.add(new MccEntry(659,"ss",2)); //South Sudan (Republic of) 652 sTable.add(new MccEntry(702,"bz",2)); //Belize 653 sTable.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of) 654 sTable.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of) 655 sTable.add(new MccEntry(708,"hn",3)); //Honduras (Republic of) 656 sTable.add(new MccEntry(710,"ni",2)); //Nicaragua 657 sTable.add(new MccEntry(712,"cr",2)); //Costa Rica 658 sTable.add(new MccEntry(714,"pa",2)); //Panama (Republic of) 659 sTable.add(new MccEntry(716,"pe",2)); //Peru 660 sTable.add(new MccEntry(722,"ar",3)); //Argentine Republic 661 sTable.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of) 662 sTable.add(new MccEntry(730,"cl",2)); //Chile 663 sTable.add(new MccEntry(732,"co",3)); //Colombia (Republic of) 664 sTable.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of) 665 sTable.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of) 666 sTable.add(new MccEntry(738,"gy",2)); //Guyana 667 sTable.add(new MccEntry(740,"ec",2)); //Ecuador 668 sTable.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of) 669 sTable.add(new MccEntry(744,"py",2)); //Paraguay (Republic of) 670 sTable.add(new MccEntry(746,"sr",2)); //Suriname (Republic of) 671 sTable.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of) 672 sTable.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas) 673 //table.add(new MccEntry(901,"",2)); //"International Mobile, shared code" 674 675 Collections.sort(sTable); 676 } 677} 678