OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / telephony / java / com / android / internal / telephony / MccTable.java
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 }