HbpcdLookupDatabaseHelper.java revision 6e3c0dc4e12bf48543af8df85f3452985e0043ed
1/*
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}
365