Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.telephony;
     18 
     19 import android.app.ActivityManagerNative;
     20 import android.app.AlarmManager;
     21 import android.content.Context;
     22 import android.content.res.Configuration;
     23 import android.net.wifi.WifiManager;
     24 import android.os.RemoteException;
     25 import android.os.SystemProperties;
     26 import android.provider.Settings;
     27 import android.text.TextUtils;
     28 import android.util.Log;
     29 
     30 import java.util.Arrays;
     31 
     32 /**
     33  * The table below is built from two resources:
     34  *
     35  * 1) ITU "Mobile Network Code (MNC) for the international
     36  *   identification plan for mobile terminals and mobile users"
     37  *   which is available as an annex to the ITU operational bulletin
     38  *   available here: http://www.itu.int/itu-t/bulletin/annex.html
     39  *
     40  * 2) The ISO 3166 country codes list, available here:
     41  *    http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
     42  *
     43  * This table was verified (28 Aug 2009) against
     44  * http://en.wikipedia.org/wiki/List_of_mobile_country_codes with the
     45  * only unresolved discrepancy being that this list has an extra entry
     46  * (461) for China.
     47  *
     48  * TODO: Complete the mappings for timezones and language/locale codes.
     49  *
     50  * The actual table data used in the Java code is generated from the
     51  * below Python code for efficiency.  The information is expected to
     52  * be static, but if changes are required, the table in the python
     53  * code can be modified and the trailing code run to re-generate the
     54  * tables that are to be used by Java.
     55 
     56 mcc_table = [
     57   (202, 'gr', 2, 'Greece'),
     58   (204, 'nl', 2, 'Europe/Amsterdam', 'nl', 13, 'Netherlands (Kingdom of the)'),
     59   (206, 'be', 2, 'Belgium'),
     60   (208, 'fr', 2, 'Europe/Paris', 'fr', 'France'),
     61   (212, 'mc', 2, 'Monaco (Principality of)'),
     62   (213, 'ad', 2, 'Andorra (Principality of)'),
     63   (214, 'es', 2, 'Europe/Madrid', 'es', 'Spain'),
     64   (216, 'hu', 2, 'Hungary (Republic of)'),
     65   (218, 'ba', 2, 'Bosnia and Herzegovina'),
     66   (219, 'hr', 2, 'Croatia (Republic of)'),
     67   (220, 'rs', 2, 'Serbia and Montenegro'),
     68   (222, 'it', 2, 'Europe/Rome', 'it', 'Italy'),
     69   (225, 'va', 2, 'Europe/Rome', 'it', 'Vatican City State'),
     70   (226, 'ro', 2, 'Romania'),
     71   (228, 'ch', 2, 'Europe/Zurich', 'de', 'Switzerland (Confederation of)'),
     72   (230, 'cz', 2, 'Europe/Prague', 'cs', 13, 'Czech Republic'),
     73   (231, 'sk', 2, 'Slovak Republic'),
     74   (232, 'at', 2, 'Europe/Vienna', 'de', 13, 'Austria'),
     75   (234, 'gb', 2, 'Europe/London', 'en', 13, 'United Kingdom of Great Britain and Northern Ireland'),
     76   (235, 'gb', 2, 'Europe/London', 'en', 13, 'United Kingdom of Great Britain and Northern Ireland'),
     77   (238, 'dk', 2, 'Denmark'),
     78   (240, 'se', 2, 'Sweden'),
     79   (242, 'no', 2, 'Norway'),
     80   (244, 'fi', 2, 'Finland'),
     81   (246, 'lt', 2, 'Lithuania (Republic of)'),
     82   (247, 'lv', 2, 'Latvia (Republic of)'),
     83   (248, 'ee', 2, 'Estonia (Republic of)'),
     84   (250, 'ru', 2, 'Russian Federation'),
     85   (255, 'ua', 2, 'Ukraine'),
     86   (257, 'by', 2, 'Belarus (Republic of)'),
     87   (259, 'md', 2, 'Moldova (Republic of)'),
     88   (260, 'pl', 2, 'Europe/Warsaw', 'Poland (Republic of)'),
     89   (262, 'de', 2, 'Europe/Berlin', 'de', 13, 'Germany (Federal Republic of)'),
     90   (266, 'gi', 2, 'Gibraltar'),
     91   (268, 'pt', 2, 'Portugal'),
     92   (270, 'lu', 2, 'Luxembourg'),
     93   (272, 'ie', 2, 'Europe/Dublin', 'en', 'Ireland'),
     94   (274, 'is', 2, 'Iceland'),
     95   (276, 'al', 2, 'Albania (Republic of)'),
     96   (278, 'mt', 2, 'Malta'),
     97   (280, 'cy', 2, 'Cyprus (Republic of)'),
     98   (282, 'ge', 2, 'Georgia'),
     99   (283, 'am', 2, 'Armenia (Republic of)'),
    100   (284, 'bg', 2, 'Bulgaria (Republic of)'),
    101   (286, 'tr', 2, 'Turkey'),
    102   (288, 'fo', 2, 'Faroe Islands'),
    103   (289, 'ge', 2, 'Abkhazia (Georgia)'),
    104   (290, 'gl', 2, 'Greenland (Denmark)'),
    105   (292, 'sm', 2, 'San Marino (Republic of)'),
    106   (293, 'sl', 2, 'Slovenia (Republic of)'),
    107   (294, 'mk', 2, 'The Former Yugoslav Republic of Macedonia'),
    108   (295, 'li', 2, 'Liechtenstein (Principality of)'),
    109   (297, 'me', 2, 'Montenegro (Republic of)'),
    110   (302, 'ca', 3, '', '', 11, 'Canada'),
    111   (308, 'pm', 2, 'Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)'),
    112   (310, 'us', 3, '', 'en', 11, 'United States of America'),
    113   (311, 'us', 3, '', 'en', 11, 'United States of America'),
    114   (312, 'us', 3, '', 'en', 11, 'United States of America'),
    115   (313, 'us', 3, '', 'en', 11, 'United States of America'),
    116   (314, 'us', 3, '', 'en', 11, 'United States of America'),
    117   (315, 'us', 3, '', 'en', 11, 'United States of America'),
    118   (316, 'us', 3, '', 'en', 11, 'United States of America'),
    119   (330, 'pr', 2, 'Puerto Rico'),
    120   (332, 'vi', 2, 'United States Virgin Islands'),
    121   (334, 'mx', 3, 'Mexico'),
    122   (338, 'jm', 3, 'Jamaica'),
    123   (340, 'gp', 2, 'Guadeloupe (French Department of)'),
    124   (342, 'bb', 3, 'Barbados'),
    125   (344, 'ag', 3, 'Antigua and Barbuda'),
    126   (346, 'ky', 3, 'Cayman Islands'),
    127   (348, 'vg', 3, 'British Virgin Islands'),
    128   (350, 'bm', 2, 'Bermuda'),
    129   (352, 'gd', 2, 'Grenada'),
    130   (354, 'ms', 2, 'Montserrat'),
    131   (356, 'kn', 2, 'Saint Kitts and Nevis'),
    132   (358, 'lc', 2, 'Saint Lucia'),
    133   (360, 'vc', 2, 'Saint Vincent and the Grenadines'),
    134   (362, 'nl', 2, 'Netherlands Antilles'),
    135   (363, 'aw', 2, 'Aruba'),
    136   (364, 'bs', 2, 'Bahamas (Commonwealth of the)'),
    137   (365, 'ai', 3, 'Anguilla'),
    138   (366, 'dm', 2, 'Dominica (Commonwealth of)'),
    139   (368, 'cu', 2, 'Cuba'),
    140   (370, 'do', 2, 'Dominican Republic'),
    141   (372, 'ht', 2, 'Haiti (Republic of)'),
    142   (374, 'tt', 2, 'Trinidad and Tobago'),
    143   (376, 'tc', 2, 'Turks and Caicos Islands'),
    144   (400, 'az', 2, 'Azerbaijani Republic'),
    145   (401, 'kz', 2, 'Kazakhstan (Republic of)'),
    146   (402, 'bt', 2, 'Bhutan (Kingdom of)'),
    147   (404, 'in', 2, 'India (Republic of)'),
    148   (405, 'in', 2, 'India (Republic of)'),
    149   (410, 'pk', 2, 'Pakistan (Islamic Republic of)'),
    150   (412, 'af', 2, 'Afghanistan'),
    151   (413, 'lk', 2, 'Sri Lanka (Democratic Socialist Republic of)'),
    152   (414, 'mm', 2, 'Myanmar (Union of)'),
    153   (415, 'lb', 2, 'Lebanon'),
    154   (416, 'jo', 2, 'Jordan (Hashemite Kingdom of)'),
    155   (417, 'sy', 2, 'Syrian Arab Republic'),
    156   (418, 'iq', 2, 'Iraq (Republic of)'),
    157   (419, 'kw', 2, 'Kuwait (State of)'),
    158   (420, 'sa', 2, 'Saudi Arabia (Kingdom of)'),
    159   (421, 'ye', 2, 'Yemen (Republic of)'),
    160   (422, 'om', 2, 'Oman (Sultanate of)'),
    161   (423, 'ps', 2, 'Palestine'),
    162   (424, 'ae', 2, 'United Arab Emirates'),
    163   (425, 'il', 2, 'Israel (State of)'),
    164   (426, 'bh', 2, 'Bahrain (Kingdom of)'),
    165   (427, 'qa', 2, 'Qatar (State of)'),
    166   (428, 'mn', 2, 'Mongolia'),
    167   (429, 'np', 2, 'Nepal'),
    168   (430, 'ae', 2, 'United Arab Emirates'),
    169   (431, 'ae', 2, 'United Arab Emirates'),
    170   (432, 'ir', 2, 'Iran (Islamic Republic of)'),
    171   (434, 'uz', 2, 'Uzbekistan (Republic of)'),
    172   (436, 'tj', 2, 'Tajikistan (Republic of)'),
    173   (437, 'kg', 2, 'Kyrgyz Republic'),
    174   (438, 'tm', 2, 'Turkmenistan'),
    175   (440, 'jp', 2, 'Asia/Tokyo', 'ja', 14, 'Japan'),
    176   (441, 'jp', 2, 'Asia/Tokyo', 'ja', 14, 'Japan'),
    177   (450, 'kr', 2, 'Asia/Seoul', 'ko', 13, 'Korea (Republic of)'),
    178   (452, 'vn', 2, 'Viet Nam (Socialist Republic of)'),
    179   (454, 'hk', 2, '"Hong Kong, China"'),
    180   (455, 'mo', 2, '"Macao, China"'),
    181   (456, 'kh', 2, 'Cambodia (Kingdom of)'),
    182   (457, 'la', 2, "Lao People's Democratic Republic"),
    183   (460, 'cn', 2, "Asia/Beijing", 'zh', 13, "China (People's Republic of)"),
    184   (461, 'cn', 2, "Asia/Beijing", 'zh', 13, "China (People's Republic of)"),
    185   (466, 'tw', 2, "Taiwan (Republic of China)"),
    186   (467, 'kp', 2, "Democratic People's Republic of Korea"),
    187   (470, 'bd', 2, "Bangladesh (People's Republic of)"),
    188   (472, 'mv', 2, 'Maldives (Republic of)'),
    189   (502, 'my', 2, 'Malaysia'),
    190   (505, 'au', 2, 'Australia/Sydney', 'en', 11, 'Australia'),
    191   (510, 'id', 2, 'Indonesia (Republic of)'),
    192   (514, 'tl', 2, 'Democratic Republic of Timor-Leste'),
    193   (515, 'ph', 2, 'Philippines (Republic of the)'),
    194   (520, 'th', 2, 'Thailand'),
    195   (525, 'sg', 2, 'Asia/Singapore', 'en', 11, 'Singapore (Republic of)'),
    196   (528, 'bn', 2, 'Brunei Darussalam'),
    197   (530, 'nz', 2, 'Pacific/Auckland', 'en', 'New Zealand'),
    198   (534, 'mp', 2, 'Northern Mariana Islands (Commonwealth of the)'),
    199   (535, 'gu', 2, 'Guam'),
    200   (536, 'nr', 2, 'Nauru (Republic of)'),
    201   (537, 'pg', 2, 'Papua New Guinea'),
    202   (539, 'to', 2, 'Tonga (Kingdom of)'),
    203   (540, 'sb', 2, 'Solomon Islands'),
    204   (541, 'vu', 2, 'Vanuatu (Republic of)'),
    205   (542, 'fj', 2, 'Fiji (Republic of)'),
    206   (543, 'wf', 2, "Wallis and Futuna (Territoire franais d'outre-mer)"),
    207   (544, 'as', 2, 'American Samoa'),
    208   (545, 'ki', 2, 'Kiribati (Republic of)'),
    209   (546, 'nc', 2, "New Caledonia (Territoire franais d'outre-mer)"),
    210   (547, 'pf', 2, "French Polynesia (Territoire franais d'outre-mer)"),
    211   (548, 'ck', 2, 'Cook Islands'),
    212   (549, 'ws', 2, 'Samoa (Independent State of)'),
    213   (550, 'fm', 2, 'Micronesia (Federated States of)'),
    214   (551, 'mh', 2, 'Marshall Islands (Republic of the)'),
    215   (552, 'pw', 2, 'Palau (Republic of)'),
    216   (602, 'eg', 2, 'Egypt (Arab Republic of)'),
    217   (603, 'dz', 2, "Algeria (People's Democratic Republic of)"),
    218   (604, 'ma', 2, 'Morocco (Kingdom of)'),
    219   (605, 'tn', 2, 'Tunisia'),
    220   (606, 'ly', 2, "Libya (Socialist People's Libyan Arab Jamahiriya)"),
    221   (607, 'gm', 2, 'Gambia (Republic of the)'),
    222   (608, 'sn', 2, 'Senegal (Republic of)'),
    223   (609, 'mr', 2, 'Mauritania (Islamic Republic of)'),
    224   (610, 'ml', 2, 'Mali (Republic of)'),
    225   (611, 'gn', 2, 'Guinea (Republic of)'),
    226   (612, 'ci', 2, "Cte d'Ivoire (Republic of)"),
    227   (613, 'bf', 2, 'Burkina Faso'),
    228   (614, 'ne', 2, 'Niger (Republic of the)'),
    229   (615, 'tg', 2, 'Togolese Republic'),
    230   (616, 'bj', 2, 'Benin (Republic of)'),
    231   (617, 'mu', 2, 'Mauritius (Republic of)'),
    232   (618, 'lr', 2, 'Liberia (Republic of)'),
    233   (619, 'sl', 2, 'Sierra Leone'),
    234   (620, 'gh', 2, 'Ghana'),
    235   (621, 'ng', 2, 'Nigeria (Federal Republic of)'),
    236   (622, 'td', 2, 'Chad (Republic of)'),
    237   (623, 'cf', 2, 'Central African Republic'),
    238   (624, 'cm', 2, 'Cameroon (Republic of)'),
    239   (625, 'cv', 2, 'Cape Verde (Republic of)'),
    240   (626, 'st', 2, 'Sao Tome and Principe (Democratic Republic of)'),
    241   (627, 'gq', 2, 'Equatorial Guinea (Republic of)'),
    242   (628, 'ga', 2, 'Gabonese Republic'),
    243   (629, 'cg', 2, 'Congo (Republic of the)'),
    244   (630, 'cg', 2, 'Democratic Republic of the Congo'),
    245   (631, 'ao', 2, 'Angola (Republic of)'),
    246   (632, 'gw', 2, 'Guinea-Bissau (Republic of)'),
    247   (633, 'sc', 2, 'Seychelles (Republic of)'),
    248   (634, 'sd', 2, 'Sudan (Republic of the)'),
    249   (635, 'rw', 2, 'Rwanda (Republic of)'),
    250   (636, 'et', 2, 'Ethiopia (Federal Democratic Republic of)'),
    251   (637, 'so', 2, 'Somali Democratic Republic'),
    252   (638, 'dj', 2, 'Djibouti (Republic of)'),
    253   (639, 'ke', 2, 'Kenya (Republic of)'),
    254   (640, 'tz', 2, 'Tanzania (United Republic of)'),
    255   (641, 'ug', 2, 'Uganda (Republic of)'),
    256   (642, 'bi', 2, 'Burundi (Republic of)'),
    257   (643, 'mz', 2, 'Mozambique (Republic of)'),
    258   (645, 'zm', 2, 'Zambia (Republic of)'),
    259   (646, 'mg', 2, 'Madagascar (Republic of)'),
    260   (647, 're', 2, 'Reunion (French Department of)'),
    261   (648, 'zw', 2, 'Zimbabwe (Republic of)'),
    262   (649, 'na', 2, 'Namibia (Republic of)'),
    263   (650, 'mw', 2, 'Malawi'),
    264   (651, 'ls', 2, 'Lesotho (Kingdom of)'),
    265   (652, 'bw', 2, 'Botswana (Republic of)'),
    266   (653, 'sz', 2, 'Swaziland (Kingdom of)'),
    267   (654, 'km', 2, 'Comoros (Union of the)'),
    268   (655, 'za', 2, 'Africa/Johannesburg', 'en', 'South Africa (Republic of)'),
    269   (657, 'er', 2, 'Eritrea'),
    270   (702, 'bz', 2, 'Belize'),
    271   (704, 'gt', 2, 'Guatemala (Republic of)'),
    272   (706, 'sv', 2, 'El Salvador (Republic of)'),
    273   (708, 'hn', 3, 'Honduras (Republic of)'),
    274   (710, 'ni', 2, 'Nicaragua'),
    275   (712, 'cr', 2, 'Costa Rica'),
    276   (714, 'pa', 2, 'Panama (Republic of)'),
    277   (716, 'pe', 2, 'Peru'),
    278   (722, 'ar', 3, 'Argentine Republic'),
    279   (724, 'br', 2, 'Brazil (Federative Republic of)'),
    280   (730, 'cl', 2, 'Chile'),
    281   (732, 'co', 3, 'Colombia (Republic of)'),
    282   (734, 've', 2, 'Venezuela (Bolivarian Republic of)'),
    283   (736, 'bo', 2, 'Bolivia (Republic of)'),
    284   (738, 'gy', 2, 'Guyana'),
    285   (740, 'ec', 2, 'Ecuador'),
    286   (742, 'gf', 2, 'French Guiana (French Department of)'),
    287   (744, 'py', 2, 'Paraguay (Republic of)'),
    288   (746, 'sr', 2, 'Suriname (Republic of)'),
    289   (748, 'uy', 2, 'Uruguay (Eastern Republic of)'),
    290   (750, 'fk', 2, 'Falkland Islands (Malvinas)')]
    291 
    292 get_mcc = lambda elt: elt[0]
    293 get_iso = lambda elt: elt[1]
    294 get_sd = lambda elt: elt[2]
    295 get_tz = lambda elt: len(elt) > 4 and elt[3] or ''
    296 get_lang = lambda elt: len(elt) > 5 and elt[4] or ''
    297 get_wifi = lambda elt: len(elt) > 6 and elt[5] or 0
    298 
    299 mcc_codes = ['0x%04x' % get_mcc(elt) for elt in mcc_table]
    300 tz_set = sorted(x for x in set(get_tz(elt) for elt in mcc_table))
    301 lang_set = sorted(x for x in set(get_lang(elt) for elt in mcc_table))
    302 
    303 def mk_ind_code(elt):
    304   iso = get_iso(elt)
    305   iso_code = ((ord(iso[0]) << 8) | ord(iso[1])) & 0xFFFF # 16 bits
    306   wifi = get_wifi(elt) & 0x000F                          #  4 bits
    307   sd = get_sd(elt) & 0x0003                              #  2 bits
    308   tz_ind = tz_set.index(get_tz(elt)) & 0x001F            #  5 bits
    309   lang_ind = lang_set.index(get_lang(elt)) & 0x000F      #  4 bits
    310   return (iso_code << 16) | (wifi << 11) | (sd << 9) | (tz_ind << 4) | lang_ind
    311 
    312 ind_codes = ['0x%08x' % mk_ind_code(elt) for elt in mcc_table]
    313 
    314 def fmt_list(title, l, batch_sz):
    315   sl = []
    316   for i in range(len(l) / batch_sz + (len(l) % batch_sz and 1 or 0)):
    317     j = i * batch_sz
    318     sl.append((' ' * 8) + ', '.join(l[j:j + batch_sz]))
    319   return '    private static final %s = {\n' % title + ',\n'.join(sl) + '\n    };\n'
    320 
    321 def do_autogen_comment(extra_desc=[]):
    322   print '    /' + '**\n    * AUTO GENERATED (by the Python code above)'
    323   for line in extra_desc:
    324     print '    * %s' % line
    325   print '    *' + '/'
    326 
    327 do_autogen_comment()
    328 print fmt_list('String[] TZ_STRINGS', ['"%s"' % x for x in tz_set], 1)
    329 do_autogen_comment()
    330 print fmt_list('String[] LANG_STRINGS', ['"%s"' % x for x in lang_set], 10)
    331 do_autogen_comment(['This table is a list of MCC codes.  The index in this table',
    332                     'of a given MCC code is the index of extra information about',
    333                     'that MCC in the IND_CODES table.'])
    334 print fmt_list('short[] MCC_CODES', mcc_codes, 10)
    335 do_autogen_comment(['The values in this table are broken down as follows (msb to lsb):',
    336                     '    iso country code 16 bits',
    337                     '    (unused)          1 bit',
    338                     '    wifi channel      4 bits',
    339                     '    smalled digit     2 bits',
    340                     '    default timezone  5 bits',
    341                     '    default language  4 bits'])
    342 print fmt_list('int[] IND_CODES', ind_codes, 6)
    343 
    344 def parse_ind_code(ind):
    345   mcc = eval(mcc_codes[ind])
    346   code = eval(ind_codes[ind])
    347   iso_lsb = int((code >> 16) & 0x00FF)
    348   iso_msb = int((code >> 24) & 0x00FF)
    349   iso = '%s%s' % (chr(iso_msb), chr(iso_lsb))
    350   wifi = int((code >> 11) & 0x000F)
    351   sd = int((code >> 9) & 0x0003)
    352   tz_ind = (code >> 4) & 0x001F
    353   lang_ind = (code >> 0) & 0x000F
    354   return (mcc, iso, sd, tz_set[tz_ind], lang_set[lang_ind], wifi)
    355 
    356 fmt_str = 'mcc = %s, iso = %s, sd = %s, tz = %s, lang = %s, wifi = %s'
    357 orig_table = [fmt_str % (get_mcc(elt), get_iso(elt), get_sd(elt),
    358                          get_tz(elt), get_lang(elt), get_wifi(elt))
    359               for elt in mcc_table]
    360 derived_table = [fmt_str % parse_ind_code(i) for i in range(len(ind_codes))]
    361 for i in range(len(orig_table)):
    362   if orig_table[i] == derived_table[i]: continue
    363   print 'MISMATCH ERROR : ', orig_table[i], " != ", derived_table[i]
    364 
    365 */
    366 
    367 /**
    368  * Mobile Country Code
    369  *
    370  * {@hide}
    371  */
    372 public final class MccTable
    373 {
    374     /**
    375      * AUTO GENERATED (by the Python code above)
    376      */
    377     private static final String[] TZ_STRINGS = {
    378         "",
    379         "Africa/Johannesburg",
    380         "Asia/Beijing",
    381         "Asia/Seoul",
    382         "Asia/Singapore",
    383         "Asia/Tokyo",
    384         "Australia/Sydney",
    385         "Europe/Amsterdam",
    386         "Europe/Berlin",
    387         "Europe/Dublin",
    388         "Europe/London",
    389         "Europe/Madrid",
    390         "Europe/Paris",
    391         "Europe/Prague",
    392         "Europe/Rome",
    393         "Europe/Vienna",
    394         "Europe/Warsaw",
    395         "Europe/Zurich",
    396         "Pacific/Auckland"
    397     };
    398 
    399     /**
    400      * AUTO GENERATED (by the Python code above)
    401      */
    402     private static final String[] LANG_STRINGS = {
    403         "", "cs", "de", "en", "es", "fr", "it", "ja", "ko", "nl",
    404         "zh"
    405     };
    406 
    407     /**
    408      * AUTO GENERATED (by the Python code above)
    409      * This table is a list of MCC codes.  The index in this table
    410      * of a given MCC code is the index of extra information about
    411      * that MCC in the IND_CODES table.
    412      */
    413     private static final short[] MCC_CODES = {
    414         0x00ca, 0x00cc, 0x00ce, 0x00d0, 0x00d4, 0x00d5, 0x00d6, 0x00d8, 0x00da, 0x00db,
    415         0x00dc, 0x00de, 0x00e1, 0x00e2, 0x00e4, 0x00e6, 0x00e7, 0x00e8, 0x00ea, 0x00eb,
    416         0x00ee, 0x00f0, 0x00f2, 0x00f4, 0x00f6, 0x00f7, 0x00f8, 0x00fa, 0x00ff, 0x0101,
    417         0x0103, 0x0104, 0x0106, 0x010a, 0x010c, 0x010e, 0x0110, 0x0112, 0x0114, 0x0116,
    418         0x0118, 0x011a, 0x011b, 0x011c, 0x011e, 0x0120, 0x0121, 0x0122, 0x0124, 0x0125,
    419         0x0126, 0x0127, 0x0129, 0x012e, 0x0134, 0x0136, 0x0137, 0x0138, 0x0139, 0x013a,
    420         0x013b, 0x013c, 0x014a, 0x014c, 0x014e, 0x0152, 0x0154, 0x0156, 0x0158, 0x015a,
    421         0x015c, 0x015e, 0x0160, 0x0162, 0x0164, 0x0166, 0x0168, 0x016a, 0x016b, 0x016c,
    422         0x016d, 0x016e, 0x0170, 0x0172, 0x0174, 0x0176, 0x0178, 0x0190, 0x0191, 0x0192,
    423         0x0194, 0x0195, 0x019a, 0x019c, 0x019d, 0x019e, 0x019f, 0x01a0, 0x01a1, 0x01a2,
    424         0x01a3, 0x01a4, 0x01a5, 0x01a6, 0x01a7, 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac,
    425         0x01ad, 0x01ae, 0x01af, 0x01b0, 0x01b2, 0x01b4, 0x01b5, 0x01b6, 0x01b8, 0x01b9,
    426         0x01c2, 0x01c4, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01cc, 0x01cd, 0x01d2, 0x01d3,
    427         0x01d6, 0x01d8, 0x01f6, 0x01f9, 0x01fe, 0x0202, 0x0203, 0x0208, 0x020d, 0x0210,
    428         0x0212, 0x0216, 0x0217, 0x0218, 0x0219, 0x021b, 0x021c, 0x021d, 0x021e, 0x021f,
    429         0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x025a,
    430         0x025b, 0x025c, 0x025d, 0x025e, 0x025f, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264,
    431         0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e,
    432         0x026f, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278,
    433         0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, 0x0280, 0x0281, 0x0282,
    434         0x0283, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d,
    435         0x028e, 0x028f, 0x0291, 0x02be, 0x02c0, 0x02c2, 0x02c4, 0x02c6, 0x02c8, 0x02ca,
    436         0x02cc, 0x02d2, 0x02d4, 0x02da, 0x02dc, 0x02de, 0x02e0, 0x02e2, 0x02e4, 0x02e6,
    437         0x02e8, 0x02ea, 0x02ec, 0x02ee
    438     };
    439 
    440     /**
    441      * AUTO GENERATED (by the Python code above)
    442      * The values in this table are broken down as follows (msb to lsb):
    443      *     iso country code 16 bits
    444      *     (unused)          1 bit
    445      *     wifi channel      4 bits
    446      *     smalled digit     2 bits
    447      *     default timezone  5 bits
    448      *     default language  4 bits
    449      */
    450     private static final int[] IND_CODES = {
    451         0x67720400, 0x6e6c6c79, 0x62650400, 0x667204c5, 0x6d630400, 0x61640400,
    452         0x657304b4, 0x68750400, 0x62610400, 0x68720400, 0x72730400, 0x697404e6,
    453         0x766104e6, 0x726f0400, 0x63680512, 0x637a6cd1, 0x736b0400, 0x61746cf2,
    454         0x67626ca3, 0x67626ca3, 0x646b0400, 0x73650400, 0x6e6f0400, 0x66690400,
    455         0x6c740400, 0x6c760400, 0x65650400, 0x72750400, 0x75610400, 0x62790400,
    456         0x6d640400, 0x706c0500, 0x64656c82, 0x67690400, 0x70740400, 0x6c750400,
    457         0x69650493, 0x69730400, 0x616c0400, 0x6d740400, 0x63790400, 0x67650400,
    458         0x616d0400, 0x62670400, 0x74720400, 0x666f0400, 0x67650400, 0x676c0400,
    459         0x736d0400, 0x736c0400, 0x6d6b0400, 0x6c690400, 0x6d650400, 0x63615e00,
    460         0x706d0400, 0x75735e03, 0x75735e03, 0x75735e03, 0x75735e03, 0x75735e03,
    461         0x75735e03, 0x75735e03, 0x70720400, 0x76690400, 0x6d780600, 0x6a6d0600,
    462         0x67700400, 0x62620600, 0x61670600, 0x6b790600, 0x76670600, 0x626d0400,
    463         0x67640400, 0x6d730400, 0x6b6e0400, 0x6c630400, 0x76630400, 0x6e6c0400,
    464         0x61770400, 0x62730400, 0x61690600, 0x646d0400, 0x63750400, 0x646f0400,
    465         0x68740400, 0x74740400, 0x74630400, 0x617a0400, 0x6b7a0400, 0x62740400,
    466         0x696e0400, 0x696e0400, 0x706b0400, 0x61660400, 0x6c6b0400, 0x6d6d0400,
    467         0x6c620400, 0x6a6f0400, 0x73790400, 0x69710400, 0x6b770400, 0x73610400,
    468         0x79650400, 0x6f6d0400, 0x70730400, 0x61650400, 0x696c0400, 0x62680400,
    469         0x71610400, 0x6d6e0400, 0x6e700400, 0x61650400, 0x61650400, 0x69720400,
    470         0x757a0400, 0x746a0400, 0x6b670400, 0x746d0400, 0x6a707457, 0x6a707457,
    471         0x6b726c38, 0x766e0400, 0x686b0400, 0x6d6f0400, 0x6b680400, 0x6c610400,
    472         0x636e6c2a, 0x636e6c2a, 0x74770400, 0x6b700400, 0x62640400, 0x6d760400,
    473         0x6d790400, 0x61755c63, 0x69640400, 0x746c0400, 0x70680400, 0x74680400,
    474         0x73675c43, 0x626e0400, 0x6e7a0523, 0x6d700400, 0x67750400, 0x6e720400,
    475         0x70670400, 0x746f0400, 0x73620400, 0x76750400, 0x666a0400, 0x77660400,
    476         0x61730400, 0x6b690400, 0x6e630400, 0x70660400, 0x636b0400, 0x77730400,
    477         0x666d0400, 0x6d680400, 0x70770400, 0x65670400, 0x647a0400, 0x6d610400,
    478         0x746e0400, 0x6c790400, 0x676d0400, 0x736e0400, 0x6d720400, 0x6d6c0400,
    479         0x676e0400, 0x63690400, 0x62660400, 0x6e650400, 0x74670400, 0x626a0400,
    480         0x6d750400, 0x6c720400, 0x736c0400, 0x67680400, 0x6e670400, 0x74640400,
    481         0x63660400, 0x636d0400, 0x63760400, 0x73740400, 0x67710400, 0x67610400,
    482         0x63670400, 0x63670400, 0x616f0400, 0x67770400, 0x73630400, 0x73640400,
    483         0x72770400, 0x65740400, 0x736f0400, 0x646a0400, 0x6b650400, 0x747a0400,
    484         0x75670400, 0x62690400, 0x6d7a0400, 0x7a6d0400, 0x6d670400, 0x72650400,
    485         0x7a770400, 0x6e610400, 0x6d770400, 0x6c730400, 0x62770400, 0x737a0400,
    486         0x6b6d0400, 0x7a610413, 0x65720400, 0x627a0400, 0x67740400, 0x73760400,
    487         0x686e0600, 0x6e690400, 0x63720400, 0x70610400, 0x70650400, 0x61720600,
    488         0x62720400, 0x636c0400, 0x636f0600, 0x76650400, 0x626f0400, 0x67790400,
    489         0x65630400, 0x67660400, 0x70790400, 0x73720400, 0x75790400, 0x666b0400
    490     };
    491 
    492     static final String LOG_TAG = "MccTable";
    493 
    494     /**
    495      * Given a Mobile Country Code, returns a default time zone ID
    496      * if available.  Returns null if unavailable.
    497      */
    498     public static String defaultTimeZoneForMcc(int mcc) {
    499         int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
    500         if (index < 0) {
    501             return null;
    502         }
    503         int indCode = IND_CODES[index];
    504         int tzInd = (indCode >>> 4) & 0x001F;
    505         String tz = TZ_STRINGS[tzInd];
    506         if (tz == "") {
    507             return null;
    508         }
    509         return tz;
    510     }
    511 
    512     /**
    513      * Given a Mobile Country Code, returns an ISO two-character
    514      * country code if available.  Returns "" if unavailable.
    515      */
    516     public static String countryCodeForMcc(int mcc) {
    517         int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
    518         if (index < 0) {
    519             return "";
    520         }
    521         int indCode = IND_CODES[index];
    522         byte[] iso = {(byte)((indCode >>> 24) & 0x00FF), (byte)((indCode >>> 16) & 0x00FF)};
    523         return new String(iso);
    524     }
    525 
    526     /**
    527      * Given a GSM Mobile Country Code, returns an ISO 2-3 character
    528      * language code if available.  Returns null if unavailable.
    529      */
    530     public static String defaultLanguageForMcc(int mcc) {
    531         int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
    532         if (index < 0) {
    533             return null;
    534         }
    535         int indCode = IND_CODES[index];
    536         int langInd = indCode & 0x000F;
    537         String lang = LANG_STRINGS[langInd];
    538         if (lang == "") {
    539             return null;
    540         }
    541         return lang;
    542     }
    543 
    544     /**
    545      * Given a GSM Mobile Country Code, returns the corresponding
    546      * smallest number of digits field.  Returns 2 if unavailable.
    547      */
    548     public static int smallestDigitsMccForMnc(int mcc) {
    549         int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
    550         if (index < 0) {
    551             return 2;
    552         }
    553         int indCode = IND_CODES[index];
    554         int smDig = (indCode >>> 9) & 0x0003;
    555         return smDig;
    556     }
    557 
    558     /**
    559      * Given a GSM Mobile Country Code, returns the number of wifi
    560      * channels allowed in that country.  Returns 0 if unavailable.
    561      */
    562     public static int wifiChannelsForMcc(int mcc) {
    563         int index = Arrays.binarySearch(MCC_CODES, (short)mcc);
    564         if (index < 0) {
    565             return 0;
    566         }
    567         int indCode = IND_CODES[index];
    568         int wifi = (indCode >>> 11) & 0x000F;
    569         return wifi;
    570     }
    571 
    572     /**
    573      * Updates MCC and MNC device configuration information for application retrieving
    574      * correct version of resources.  If either MCC or MNC is 0, they will be ignored (not set).
    575      * @param phone PhoneBae to act on.
    576      * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
    577      */
    578     public static void updateMccMncConfiguration(PhoneBase phone, String mccmnc) {
    579         if (!TextUtils.isEmpty(mccmnc)) {
    580             int mcc, mnc;
    581 
    582             try {
    583                 mcc = Integer.parseInt(mccmnc.substring(0,3));
    584                 mnc = Integer.parseInt(mccmnc.substring(3));
    585             } catch (NumberFormatException e) {
    586                 Log.e(LOG_TAG, "Error parsing IMSI");
    587                 return;
    588             }
    589 
    590             Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
    591 
    592             if (mcc != 0) {
    593                 setTimezoneFromMccIfNeeded(phone, mcc);
    594                 setLocaleFromMccIfNeeded(phone, mcc);
    595                 setWifiChannelsFromMcc(phone, mcc);
    596             }
    597             try {
    598                 Configuration config = ActivityManagerNative.getDefault().getConfiguration();
    599                 if (mcc != 0) {
    600                     config.mcc = mcc;
    601                 }
    602                 if (mnc != 0) {
    603                     config.mnc = mnc;
    604                 }
    605                 ActivityManagerNative.getDefault().updateConfiguration(config);
    606             } catch (RemoteException e) {
    607                 Log.e(LOG_TAG, "Can't update configuration", e);
    608             }
    609         }
    610     }
    611 
    612     /**
    613      * If the timezone is not already set, set it based on the MCC of the SIM.
    614      * @param phone PhoneBase to act on (get context from).
    615      * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
    616      */
    617     private static void setTimezoneFromMccIfNeeded(PhoneBase phone, int mcc) {
    618         String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
    619         if (timezone == null || timezone.length() == 0) {
    620             String zoneId = defaultTimeZoneForMcc(mcc);
    621             if (zoneId != null && zoneId.length() > 0) {
    622                 Context context = phone.getContext();
    623                 // Set time zone based on MCC
    624                 AlarmManager alarm =
    625                         (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    626                 alarm.setTimeZone(zoneId);
    627                 Log.d(LOG_TAG, "timezone set to "+zoneId);
    628             }
    629         }
    630     }
    631 
    632     /**
    633      * If the locale is not already set, set it based on the MCC of the SIM.
    634      * @param phone PhoneBase to act on.
    635      * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
    636      */
    637     private static void setLocaleFromMccIfNeeded(PhoneBase phone, int mcc) {
    638         String language = MccTable.defaultLanguageForMcc(mcc);
    639         String country = MccTable.countryCodeForMcc(mcc);
    640 
    641         Log.d(LOG_TAG, "locale set to "+language+"_"+country);
    642         phone.setSystemLocale(language, country);
    643     }
    644 
    645     /**
    646      * If the number of allowed wifi channels has not been set, set it based on
    647      * the MCC of the SIM.
    648      * @param phone PhoneBase to act on (get context from).
    649      * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
    650      */
    651     private static void setWifiChannelsFromMcc(PhoneBase phone, int mcc) {
    652         int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
    653         if (wifiChannels != 0) {
    654             Context context = phone.getContext();
    655             Log.d(LOG_TAG, "WIFI_NUM_ALLOWED_CHANNELS set to " + wifiChannels);
    656             WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    657             //persist
    658             wM.setNumAllowedChannels(wifiChannels, true);
    659         }
    660     }
    661 }
    662