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