• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
55 package com.android.providers.telephony;
56 
57 import android.content.ContentValues;
58 import android.content.Context;
59 import android.content.res.Resources;
60 import android.content.res.XmlResourceParser;
61 import android.database.Cursor;
62 import android.database.SQLException;
63 import android.database.sqlite.SQLiteDatabase;
64 import android.database.sqlite.SQLiteOpenHelper;
65 import android.database.sqlite.SQLiteQueryBuilder;
66 import android.util.Log;
67 import android.util.Xml;
68 import com.android.internal.util.XmlUtils;
69 
70 import org.xmlpull.v1.XmlPullParser;
71 import org.xmlpull.v1.XmlPullParserException;
72 
73 import java.io.IOException;
74 
75 import com.android.internal.telephony.HbpcdLookup;
76 import com.android.internal.telephony.HbpcdLookup.MccIdd;
77 import com.android.internal.telephony.HbpcdLookup.MccLookup;
78 import com.android.internal.telephony.HbpcdLookup.MccSidConflicts;
79 import com.android.internal.telephony.HbpcdLookup.MccSidRange;
80 import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch;
81 import com.android.internal.telephony.HbpcdLookup.NanpAreaCode;
82 
83 public 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      */
HbpcdLookupDatabaseHelper(Context context)98     public HbpcdLookupDatabaseHelper(Context context) {
99         super(context, DATABASE_NAME, null, DATABASE_VERSION);
100 
101         mContext = context;
102     }
103 
104     @Override
onCreate(SQLiteDatabase db)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
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)149     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
150         // do nothing
151     }
152 
initDatabase(SQLiteDatabase db)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 
loadTable(SQLiteDatabase db, XmlPullParser parser, String tableName)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 
getTableMccIddRow(XmlPullParser parser)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 
getTableMccLookupTableRow(XmlPullParser parser)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 
getTableMccSidConflictRow(XmlPullParser parser)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 
getTableMccSidRangeRow(XmlPullParser parser)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 
getTableNanpAreaCodeRow(XmlPullParser parser)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 
getTableArbitraryMccSidMatch(XmlPullParser parser)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