blob: ceaed4c814890c04a03ba93f5d5ad9eb57f8818c [file] [log] [blame]
Steven Liu6e3c0dc2014-06-30 14:31:50 -05001/*
2**
3** Copyright (C) 2014, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18/*
19 * This class is used to create, load tables for HBPCD
20 * HBPCD means 'Handset Based Plus Code Dialing', for CDMA network, most of network
21 * couldn't handle international dialing number with '+', it need to be converted
22 * to a IDD (International Direct Dialing) number, and some CDMA network won't
23 * broadcast operator numeric, we need CDMA system ID and timezone etc. information
24 * to get right MCC part of numeric, MNC part of numeric has no way to get in this
25 * case, but for HBPCD, the MCC is enough.
26 *
27 * Table TABLE_MCC_LOOKUP_TABLE
28 * This table has country name, country code, time zones for each MCC
29 *
30 * Table TABLE_MCC_IDD
31 * This table has the IDDs for each MCC, some countries have multiple IDDs.
32 *
33 * Table TABLE_MCC_SID_RANGE
34 * This table are SIDs assigned to each MCC
35 *
36 * Table TABLE_MCC_SID_CONFLICT
37 * This table shows those SIDs are assigned to more than 1 MCC entry,
38 * if the SID is here, it means the SID couldn't be matched to a single MCC,
39 * it need to check the time zone and SID in TABLE_MCC_LOOKUP_TABLE to get
40 * right MCC.
41 *
42 * Table TABLE_ARBITRARY_MCC_SID_MATCH
43 * The SID listed in this table technically have operators in multiple MCC,
44 * but conveniently only have *active* operators in a single MCC allowing a
45 * unique SID->MCC lookup. Lookup by Timezone however would be complicatedi
46 * as there will be multiple matches, and those matched entries have same
47 * time zone, which can not tell which MCC is right. Conventionaly it is known
48 * that SID is used only by the *active* operators in that MCC.
49 *
50 * Table TABLE_NANP_AREA_CODE
51 * This table has NANP(North America Number Planning) area code, this is used
52 * to check if a dialing number is a NANP number.
53 */
54
55package com.android.providers.telephony;
56
57import android.content.ContentValues;
58import android.content.Context;
59import android.content.res.Resources;
60import android.content.res.XmlResourceParser;
61import android.database.Cursor;
62import android.database.SQLException;
63import android.database.sqlite.SQLiteDatabase;
64import android.database.sqlite.SQLiteOpenHelper;
65import android.database.sqlite.SQLiteQueryBuilder;
66import android.util.Log;
67import android.util.Xml;
68import com.android.internal.util.XmlUtils;
69
70import org.xmlpull.v1.XmlPullParser;
71import org.xmlpull.v1.XmlPullParserException;
72
73import java.io.IOException;
74
75import com.android.internal.telephony.HbpcdLookup;
76import com.android.internal.telephony.HbpcdLookup.MccIdd;
77import com.android.internal.telephony.HbpcdLookup.MccLookup;
78import com.android.internal.telephony.HbpcdLookup.MccSidConflicts;
79import com.android.internal.telephony.HbpcdLookup.MccSidRange;
80import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch;
81import com.android.internal.telephony.HbpcdLookup.NanpAreaCode;
82
83public class HbpcdLookupDatabaseHelper extends SQLiteOpenHelper {
84 private static final String TAG = "HbpcdLockupDatabaseHelper";
85 private static final boolean DBG = true;
86
87 private static final String DATABASE_NAME = "HbpcdLookup.db";
88 private static final int DATABASE_VERSION = 1;
89
90 // Context to access resources with
91 private Context mContext;
92
93 /**
94 * DatabaseHelper helper class for loading apns into a database.
95 *
96 * @param context of the user.
97 */
98 public HbpcdLookupDatabaseHelper(Context context) {
99 super(context, DATABASE_NAME, null, DATABASE_VERSION);
100
101 mContext = context;
102 }
103
104 @Override
105 public void onCreate(SQLiteDatabase db) {
106 //set up the database schema
107 // 1 MCC may has more IDDs
108 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_MCC_IDD +
109 "(_id INTEGER PRIMARY KEY," +
110 "MCC INTEGER," +
111 "IDD TEXT);");
112
113 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_MCC_LOOKUP_TABLE +
114 "(_id INTEGER PRIMARY KEY," +
115 "MCC INTEGER," +
116 "Country_Code TEXT," +
117 "Country_Name TEXT," +
118 "NDD TEXT," +
119 "NANPS BOOLEAN," +
120 "GMT_Offset_Low REAL," +
121 "GMT_Offset_High REAL," +
122 "GMT_DST_Low REAL," +
123 "GMT_DST_High REAL);");
124
125 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_MCC_SID_CONFLICT +
126 "(_id INTEGER PRIMARY KEY," +
127 "MCC INTEGER," +
128 "SID_Conflict INTEGER);");
129
130 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_MCC_SID_RANGE +
131 "(_id INTEGER PRIMARY KEY," +
132 "MCC INTEGER," +
133 "SID_Range_Low INTEGER," +
134 "SID_Range_High INTEGER);");
135
136 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_NANP_AREA_CODE +
137 "(_id INTEGER PRIMARY KEY," +
138 "AREA_CODE INTEGER UNIQUE);");
139
140 db.execSQL("CREATE TABLE " + HbpcdLookupProvider.TABLE_ARBITRARY_MCC_SID_MATCH +
141 "(_id INTEGER PRIMARY KEY," +
142 "MCC INTEGER," +
143 "SID INTEGER UNIQUE);");
144
145 initDatabase(db);
146 }
147
148 @Override
149 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
150 // do nothing
151 }
152
153 private void initDatabase (SQLiteDatabase db) {
154 // Read internal data from xml
155 Resources r = mContext.getResources();
156 XmlResourceParser parser = r.getXml(R.xml.hbpcd_lookup_tables);
157
158 if (parser == null) {
159 Log.e (TAG, "error to load the HBPCD resource");
160 } else {
161 try {
162 db.beginTransaction();
163 XmlUtils.beginDocument(parser, "hbpcd_info");
164
165 int eventType = parser.getEventType();
166 String tagName = parser.getName();
167
168 while (eventType != XmlPullParser.END_DOCUMENT) {
169 if (eventType == XmlPullParser.START_TAG
170 && tagName.equalsIgnoreCase("table")) {
171 String tableName = parser.getAttributeValue(null, "name");
172 loadTable(db, parser, tableName);
173 }
174 parser.next();
175 eventType = parser.getEventType();
176 tagName = parser.getName();
177 }
178 db.setTransactionSuccessful();
179 } catch (XmlPullParserException e) {
180 Log.e (TAG, "Got XmlPullParserException when load hbpcd info");
181 } catch (IOException e) {
182 Log.e (TAG, "Got IOException when load hbpcd info");
183 } catch (SQLException e) {
184 Log.e (TAG, "Got SQLException when load hbpcd info");
185 } finally {
186 db.endTransaction();
187 parser.close();
188 }
189 }
190 }
191
192 private void loadTable(SQLiteDatabase db, XmlPullParser parser, String tableName)
193 throws XmlPullParserException, IOException {
194 int eventType = parser.getEventType();
195 String tagName = parser.getName();
196 while (!(eventType == XmlPullParser.END_TAG
197 && tagName.equalsIgnoreCase("table"))) {
198 ContentValues row = null;
199 if (tableName.equalsIgnoreCase(HbpcdLookupProvider.TABLE_MCC_IDD)) {
200 row = getTableMccIddRow(parser);
201 } else if (tableName.equalsIgnoreCase(HbpcdLookupProvider.TABLE_MCC_LOOKUP_TABLE)) {
202 row = getTableMccLookupTableRow(parser);
203 } else if (tableName.equalsIgnoreCase(HbpcdLookupProvider.TABLE_MCC_SID_CONFLICT)) {
204 row = getTableMccSidConflictRow(parser);
205 } else if (tableName.equalsIgnoreCase(HbpcdLookupProvider.TABLE_MCC_SID_RANGE)) {
206 row = getTableMccSidRangeRow(parser);
207 } else if (tableName.equalsIgnoreCase(HbpcdLookupProvider.TABLE_NANP_AREA_CODE)) {
208 row = getTableNanpAreaCodeRow(parser);
209 } else if (tableName.equalsIgnoreCase(
210 HbpcdLookupProvider.TABLE_ARBITRARY_MCC_SID_MATCH)) {
211 row = getTableArbitraryMccSidMatch(parser);
212 } else {
213 Log.e(TAG, "unrecognized table name" + tableName);
214 break;
215 }
216 if (row != null) {
217 db.insert(tableName, null, row);
218 }
219 parser.next();
220 eventType = parser.getEventType();
221 tagName = parser.getName();
222 }
223 }
224
225 private ContentValues getTableMccIddRow(XmlPullParser parser)
226 throws XmlPullParserException, IOException {
227 int eventType = parser.getEventType();
228 String tagName = parser.getName();
229 ContentValues row = new ContentValues();
230
231 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
232 if (eventType == XmlPullParser.START_TAG) {
233 if (tagName.equalsIgnoreCase(MccIdd.MCC)) {
234 row.put(MccIdd.MCC, Integer.parseInt(parser.nextText()));
235 } else if (tagName.equalsIgnoreCase(MccIdd.IDD)) {
236 row.put(MccIdd.IDD, parser.nextText());
237 }
238 }
239 parser.next();
240 eventType = parser.getEventType();
241 tagName = parser.getName();
242 }
243 return row;
244 }
245
246 private ContentValues getTableMccLookupTableRow(XmlPullParser parser)
247 throws XmlPullParserException, IOException {
248 int eventType = parser.getEventType();
249 String tagName = parser.getName();
250 ContentValues row = new ContentValues();
251
252 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
253 if (eventType == XmlPullParser.START_TAG) {
254 if (tagName.equalsIgnoreCase(MccLookup.MCC)) {
255 row.put(MccLookup.MCC, Integer.parseInt(parser.nextText()));
256 } else if (tagName.equalsIgnoreCase(MccLookup.COUNTRY_CODE)) {
257 row.put(MccLookup.COUNTRY_CODE, Integer.parseInt(parser.nextText()));
258 } else if (tagName.equalsIgnoreCase(MccLookup.COUNTRY_NAME)) {
259 row.put(MccLookup.COUNTRY_NAME, parser.nextText());
260 } else if (tagName.equalsIgnoreCase(MccLookup.NDD)) {
261 row.put(MccLookup.NDD, parser.nextText());
262 } else if (tagName.equalsIgnoreCase(MccLookup.NANPS)) {
263 row.put(MccLookup.NANPS, Boolean.parseBoolean(parser.nextText()));
264 } else if (tagName.equalsIgnoreCase(MccLookup.GMT_OFFSET_LOW)) {
265 row.put(MccLookup.GMT_OFFSET_LOW, Float.parseFloat(parser.nextText()));
266 } else if (tagName.equalsIgnoreCase(MccLookup.GMT_OFFSET_HIGH)) {
267 row.put(MccLookup.GMT_OFFSET_HIGH, Float.parseFloat(parser.nextText()));
268 } else if (tagName.equalsIgnoreCase(MccLookup.GMT_DST_LOW)) {
269 row.put(MccLookup.GMT_DST_LOW, Float.parseFloat(parser.nextText()));
270 } else if (tagName.equalsIgnoreCase(MccLookup.GMT_DST_HIGH)) {
271 row.put(MccLookup.GMT_DST_HIGH, Float.parseFloat(parser.nextText()));
272 }
273 }
274 parser.next();
275 eventType = parser.getEventType();
276 tagName = parser.getName();
277 }
278 return row;
279 }
280
281 private ContentValues getTableMccSidConflictRow(XmlPullParser parser)
282 throws XmlPullParserException, IOException {
283 int eventType = parser.getEventType();
284 String tagName = parser.getName();
285 ContentValues row = new ContentValues();
286
287 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
288 if (eventType == XmlPullParser.START_TAG) {
289 if (tagName.equalsIgnoreCase(MccSidConflicts.MCC)) {
290 row.put(MccSidConflicts.MCC, Integer.parseInt(parser.nextText()));
291 } else if (tagName.equalsIgnoreCase(MccSidConflicts.SID_CONFLICT)) {
292 row.put(MccSidConflicts.SID_CONFLICT, Integer.parseInt(parser.nextText()));
293 }
294 }
295 parser.next();
296 eventType = parser.getEventType();
297 tagName = parser.getName();
298 }
299 return row;
300 }
301
302 private ContentValues getTableMccSidRangeRow(XmlPullParser parser)
303 throws XmlPullParserException, IOException {
304 int eventType = parser.getEventType();
305 String tagName = parser.getName();
306 ContentValues row = new ContentValues();
307
308 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
309 if (eventType == XmlPullParser.START_TAG) {
310 if (tagName.equalsIgnoreCase(MccSidRange.MCC)) {
311 row.put(MccSidRange.MCC, Integer.parseInt(parser.nextText()));
312 } else if (tagName.equalsIgnoreCase(MccSidRange.RANGE_LOW)) {
313 row.put(MccSidRange.RANGE_LOW, Integer.parseInt(parser.nextText()));
314 } else if (tagName.equalsIgnoreCase(MccSidRange.RANGE_HIGH)) {
315 row.put(MccSidRange.RANGE_HIGH, Integer.parseInt(parser.nextText()));
316 }
317 }
318 parser.next();
319 eventType = parser.getEventType();
320 tagName = parser.getName();
321 }
322 return row;
323 }
324
325 private ContentValues getTableNanpAreaCodeRow(XmlPullParser parser)
326 throws XmlPullParserException, IOException {
327 int eventType = parser.getEventType();
328 String tagName = parser.getName();
329 ContentValues row = new ContentValues();
330
331 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
332 if (eventType == XmlPullParser.START_TAG) {
333 if (tagName.equalsIgnoreCase(NanpAreaCode.AREA_CODE)) {
334 row.put(NanpAreaCode.AREA_CODE, Integer.parseInt(parser.nextText()));
335 }
336 }
337 parser.next();
338 eventType = parser.getEventType();
339 tagName = parser.getName();
340 }
341 return row;
342 }
343
344 private ContentValues getTableArbitraryMccSidMatch(XmlPullParser parser)
345 throws XmlPullParserException, IOException {
346 int eventType = parser.getEventType();
347 String tagName = parser.getName();
348 ContentValues row = new ContentValues();
349
350 while (!(eventType == XmlPullParser.END_TAG && tagName.equalsIgnoreCase("row"))) {
351 if (eventType == XmlPullParser.START_TAG) {
352 if (tagName.equalsIgnoreCase(ArbitraryMccSidMatch.MCC)) {
353 row.put(ArbitraryMccSidMatch.MCC, Integer.parseInt(parser.nextText()));
354 } else if (tagName.equalsIgnoreCase(ArbitraryMccSidMatch.SID)) {
355 row.put(ArbitraryMccSidMatch.SID, Integer.parseInt(parser.nextText()));
356 }
357 }
358 parser.next();
359 eventType = parser.getEventType();
360 tagName = parser.getName();
361 }
362 return row;
363 }
364}