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 package com.android.providers.telephony; 19 20 import android.content.ContentProvider; 21 import android.content.ContentUris; 22 import android.content.ContentValues; 23 import android.content.UriMatcher; 24 import android.database.sqlite.SQLiteDatabase; 25 import android.database.sqlite.SQLiteQueryBuilder; 26 import android.database.Cursor; 27 import android.database.SQLException; 28 import android.net.Uri; 29 import android.text.TextUtils; 30 import android.util.Log; 31 import java.util.HashMap; 32 33 import com.android.internal.telephony.HbpcdLookup; 34 import com.android.internal.telephony.HbpcdLookup.MccIdd; 35 import com.android.internal.telephony.HbpcdLookup.MccLookup; 36 import com.android.internal.telephony.HbpcdLookup.MccSidConflicts; 37 import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch; 38 import com.android.internal.telephony.HbpcdLookup.MccSidRange; 39 import com.android.internal.telephony.HbpcdLookup.NanpAreaCode; 40 41 public class HbpcdLookupProvider extends ContentProvider { 42 private static boolean DBG = false; 43 private static final String TAG = "HbpcdLookupProvider"; 44 45 public static final String TABLE_MCC_IDD = "mcc_idd"; 46 public static final String TABLE_MCC_LOOKUP_TABLE = "mcc_lookup_table"; 47 public static final String TABLE_MCC_SID_CONFLICT = "mcc_sid_conflict"; 48 public static final String TABLE_MCC_SID_RANGE = "mcc_sid_range"; 49 public static final String TABLE_NANP_AREA_CODE = "nanp_area_code"; 50 public static final String TABLE_ARBITRARY_MCC_SID_MATCH= "arbitrary_mcc_sid_match"; 51 52 private static final int MCC_IDD = 1; 53 private static final int MCC_LOOKUP_TABLE = 2; 54 private static final int MCC_SID_CONFLICT = 3; 55 private static final int MCC_SID_RANGE = 4; 56 private static final int NANP_AREA_CODE = 5; 57 private static final int ARBITRARY_MCC_SID_MATCH = 6; 58 private static final int MCC_IDD_ID = 8; 59 private static final int MCC_LOOKUP_TABLE_ID = 9; 60 private static final int MCC_SID_CONFLICT_ID = 10; 61 private static final int MCC_SID_RANGE_ID = 11; 62 private static final int NANP_AREA_CODE_ID = 12; 63 private static final int ARBITRARY_MCC_SID_MATCH_ID = 13; 64 65 private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); 66 67 private static final HashMap<String, String> sIddProjectionMap; 68 private static final HashMap<String, String> sLookupProjectionMap; 69 private static final HashMap<String, String> sConflictProjectionMap; 70 private static final HashMap<String, String> sRangeProjectionMap; 71 private static final HashMap<String, String> sNanpProjectionMap; 72 private static final HashMap<String, String> sArbitraryProjectionMap; 73 74 static { sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD, MCC_IDD)75 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD, MCC_IDD); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_LOOKUP_TABLE, MCC_LOOKUP_TABLE)76 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 77 HbpcdLookup.PATH_MCC_LOOKUP_TABLE, MCC_LOOKUP_TABLE); 78 // following URI is a joint table of MCC_LOOKUP_TABLE and MCC_SID_CONFLIct. sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_CONFLICT, MCC_SID_CONFLICT)79 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 80 HbpcdLookup.PATH_MCC_SID_CONFLICT, MCC_SID_CONFLICT); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_RANGE, MCC_SID_RANGE)81 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_RANGE, MCC_SID_RANGE); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_NANP_AREA_CODE, NANP_AREA_CODE)82 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_NANP_AREA_CODE, NANP_AREA_CODE); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_ARBITRARY_MCC_SID_MATCH, ARBITRARY_MCC_SID_MATCH)83 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 84 HbpcdLookup.PATH_ARBITRARY_MCC_SID_MATCH, ARBITRARY_MCC_SID_MATCH); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD + "/#", MCC_IDD_ID)85 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD + "/#", MCC_IDD_ID); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_LOOKUP_TABLE + "/#", MCC_LOOKUP_TABLE_ID)86 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 87 HbpcdLookup.PATH_MCC_LOOKUP_TABLE + "/#", MCC_LOOKUP_TABLE_ID); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_CONFLICT + "/#", MCC_SID_CONFLICT_ID)88 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 89 HbpcdLookup.PATH_MCC_SID_CONFLICT + "/#", MCC_SID_CONFLICT_ID); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_RANGE + "/#", MCC_SID_RANGE_ID)90 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 91 HbpcdLookup.PATH_MCC_SID_RANGE + "/#", MCC_SID_RANGE_ID); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_NANP_AREA_CODE + "/#", NANP_AREA_CODE_ID)92 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 93 HbpcdLookup.PATH_NANP_AREA_CODE + "/#", NANP_AREA_CODE_ID); sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_ARBITRARY_MCC_SID_MATCH + "/#", ARBITRARY_MCC_SID_MATCH_ID)94 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 95 HbpcdLookup.PATH_ARBITRARY_MCC_SID_MATCH + "/#", ARBITRARY_MCC_SID_MATCH_ID); 96 97 sIddProjectionMap = new HashMap<String, String>(); sIddProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID)98 sIddProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); sIddProjectionMap.put(MccIdd.MCC, MccIdd.MCC)99 sIddProjectionMap.put(MccIdd.MCC, MccIdd.MCC); sIddProjectionMap.put(MccIdd.IDD, MccIdd.IDD)100 sIddProjectionMap.put(MccIdd.IDD, MccIdd.IDD); 101 102 sLookupProjectionMap = new HashMap<String, String>(); sLookupProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID)103 sLookupProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); sLookupProjectionMap.put(MccLookup.MCC, MccLookup.MCC)104 sLookupProjectionMap.put(MccLookup.MCC, MccLookup.MCC); sLookupProjectionMap.put(MccLookup.COUNTRY_CODE, MccLookup.COUNTRY_CODE)105 sLookupProjectionMap.put(MccLookup.COUNTRY_CODE, MccLookup.COUNTRY_CODE); sLookupProjectionMap.put(MccLookup.COUNTRY_NAME, MccLookup.COUNTRY_NAME)106 sLookupProjectionMap.put(MccLookup.COUNTRY_NAME, MccLookup.COUNTRY_NAME); sLookupProjectionMap.put(MccLookup.NDD, MccLookup.NDD)107 sLookupProjectionMap.put(MccLookup.NDD, MccLookup.NDD); sLookupProjectionMap.put(MccLookup.NANPS, MccLookup.NANPS)108 sLookupProjectionMap.put(MccLookup.NANPS, MccLookup.NANPS); sLookupProjectionMap.put(MccLookup.GMT_OFFSET_LOW, MccLookup.GMT_OFFSET_LOW)109 sLookupProjectionMap.put(MccLookup.GMT_OFFSET_LOW, MccLookup.GMT_OFFSET_LOW); sLookupProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, MccLookup.GMT_OFFSET_HIGH)110 sLookupProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, MccLookup.GMT_OFFSET_HIGH); sLookupProjectionMap.put(MccLookup.GMT_DST_LOW, MccLookup.GMT_DST_LOW)111 sLookupProjectionMap.put(MccLookup.GMT_DST_LOW, MccLookup.GMT_DST_LOW); sLookupProjectionMap.put(MccLookup.GMT_DST_HIGH, MccLookup.GMT_DST_HIGH)112 sLookupProjectionMap.put(MccLookup.GMT_DST_HIGH, MccLookup.GMT_DST_HIGH); 113 114 // when we do query, we will join it with MccLookup table 115 sConflictProjectionMap = new HashMap<String, String>(); 116 // MccLookup.MCC is duped to MccSidConflicts.MCC sConflictProjectionMap.put(MccLookup.GMT_OFFSET_LOW, TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_LOW)117 sConflictProjectionMap.put(MccLookup.GMT_OFFSET_LOW, 118 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_LOW); sConflictProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_HIGH)119 sConflictProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, 120 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_HIGH); sConflictProjectionMap.put(MccLookup.GMT_DST_LOW, TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_LOW)121 sConflictProjectionMap.put(MccLookup.GMT_DST_LOW, 122 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_LOW); sConflictProjectionMap.put(MccLookup.GMT_DST_HIGH, TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_HIGH)123 sConflictProjectionMap.put(MccLookup.GMT_DST_HIGH, 124 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_HIGH); sConflictProjectionMap.put(MccSidConflicts.MCC, TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.MCC)125 sConflictProjectionMap.put(MccSidConflicts.MCC, 126 TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.MCC); sConflictProjectionMap.put(MccSidConflicts.SID_CONFLICT, TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.SID_CONFLICT)127 sConflictProjectionMap.put(MccSidConflicts.SID_CONFLICT, 128 TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.SID_CONFLICT); 129 130 sRangeProjectionMap = new HashMap<String, String>(); sRangeProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID)131 sRangeProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); sRangeProjectionMap.put(MccSidRange.MCC, MccSidRange.MCC)132 sRangeProjectionMap.put(MccSidRange.MCC, MccSidRange.MCC); sRangeProjectionMap.put(MccSidRange.RANGE_LOW, MccSidRange.RANGE_LOW)133 sRangeProjectionMap.put(MccSidRange.RANGE_LOW, MccSidRange.RANGE_LOW); sRangeProjectionMap.put(MccSidRange.RANGE_HIGH, MccSidRange.RANGE_HIGH)134 sRangeProjectionMap.put(MccSidRange.RANGE_HIGH, MccSidRange.RANGE_HIGH); 135 136 sNanpProjectionMap = new HashMap<String, String>(); sNanpProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID)137 sNanpProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); sNanpProjectionMap.put(NanpAreaCode.AREA_CODE, NanpAreaCode.AREA_CODE)138 sNanpProjectionMap.put(NanpAreaCode.AREA_CODE, NanpAreaCode.AREA_CODE); 139 140 sArbitraryProjectionMap = new HashMap<String, String>(); sArbitraryProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID)141 sArbitraryProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); sArbitraryProjectionMap.put(ArbitraryMccSidMatch.MCC, ArbitraryMccSidMatch.MCC)142 sArbitraryProjectionMap.put(ArbitraryMccSidMatch.MCC, ArbitraryMccSidMatch.MCC); sArbitraryProjectionMap.put(ArbitraryMccSidMatch.SID, ArbitraryMccSidMatch.SID)143 sArbitraryProjectionMap.put(ArbitraryMccSidMatch.SID, ArbitraryMccSidMatch.SID); 144 } 145 146 private HbpcdLookupDatabaseHelper mDbHelper; 147 148 @Override onCreate()149 public boolean onCreate() { 150 if (DBG) { 151 Log.d(TAG, "onCreate"); 152 } 153 mDbHelper = new HbpcdLookupDatabaseHelper(getContext()); 154 155 mDbHelper.getReadableDatabase(); 156 return true; 157 } 158 159 @Override getType(Uri uri)160 public String getType(Uri uri) { 161 if (DBG) { 162 Log.d(TAG, "getType"); 163 } 164 165 return null; 166 } 167 168 @Override query(Uri uri, String[] projectionIn, String selection, String[] selectionArgs, String sortOrder)169 public Cursor query(Uri uri, String[] projectionIn, String selection, 170 String[] selectionArgs, String sortOrder) { 171 SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 172 String orderBy = null; 173 String groupBy = null; 174 boolean useDefaultOrder = TextUtils.isEmpty(sortOrder); 175 176 int match = sURIMatcher.match(uri); 177 switch (match) { 178 case MCC_IDD: { 179 qb.setTables(TABLE_MCC_IDD); 180 qb.setProjectionMap(sIddProjectionMap); 181 if (useDefaultOrder) { 182 orderBy = MccIdd.DEFAULT_SORT_ORDER; 183 } 184 break; 185 } 186 case MCC_LOOKUP_TABLE: { 187 qb.setTables(TABLE_MCC_LOOKUP_TABLE); 188 qb.setProjectionMap(sLookupProjectionMap); 189 if (useDefaultOrder) { 190 orderBy = MccLookup.DEFAULT_SORT_ORDER; 191 } 192 groupBy = MccLookup.COUNTRY_NAME; 193 break; 194 } 195 case MCC_SID_CONFLICT: { 196 StringBuilder joinT = new StringBuilder(); 197 joinT.append(TABLE_MCC_LOOKUP_TABLE); 198 joinT.append(" INNER JOIN "); 199 joinT.append(TABLE_MCC_SID_CONFLICT); 200 joinT.append(" ON ("); 201 joinT.append(TABLE_MCC_LOOKUP_TABLE); // table name 202 joinT.append("."); 203 joinT.append(MccLookup.MCC); // column name 204 joinT.append(" = "); 205 joinT.append(TABLE_MCC_SID_CONFLICT); // table name 206 joinT.append("."); 207 joinT.append(MccSidConflicts.MCC); //column name 208 joinT.append(")"); 209 qb.setTables(joinT.toString()); 210 qb.setProjectionMap(sConflictProjectionMap); 211 break; 212 } 213 case MCC_SID_RANGE: { 214 qb.setTables(TABLE_MCC_SID_RANGE); 215 qb.setProjectionMap(sRangeProjectionMap); 216 if (useDefaultOrder) { 217 orderBy = MccIdd.DEFAULT_SORT_ORDER; 218 } 219 break; 220 } 221 case NANP_AREA_CODE: { 222 qb.setTables(TABLE_NANP_AREA_CODE); 223 qb.setProjectionMap(sNanpProjectionMap); 224 if (useDefaultOrder) { 225 orderBy = NanpAreaCode.DEFAULT_SORT_ORDER; 226 } 227 break; 228 } 229 case ARBITRARY_MCC_SID_MATCH: { 230 qb.setTables(TABLE_ARBITRARY_MCC_SID_MATCH); 231 qb.setProjectionMap(sArbitraryProjectionMap); 232 if (useDefaultOrder) { 233 orderBy = ArbitraryMccSidMatch.DEFAULT_SORT_ORDER; 234 } 235 break; 236 } 237 case MCC_IDD_ID: { 238 qb.setTables(TABLE_MCC_IDD); 239 qb.setProjectionMap(sIddProjectionMap); 240 qb.appendWhere(TABLE_MCC_IDD + "._id="); 241 qb.appendWhere(uri.getPathSegments().get(1)); 242 if (useDefaultOrder) { 243 orderBy = MccIdd.DEFAULT_SORT_ORDER; 244 } 245 break; 246 } 247 case MCC_LOOKUP_TABLE_ID: { 248 qb.setTables(TABLE_MCC_LOOKUP_TABLE); 249 qb.setProjectionMap(sLookupProjectionMap); 250 qb.appendWhere(TABLE_MCC_LOOKUP_TABLE + "._id="); 251 qb.appendWhere(uri.getPathSegments().get(1)); 252 if (useDefaultOrder) { 253 orderBy = MccLookup.DEFAULT_SORT_ORDER; 254 } 255 break; 256 } 257 case MCC_SID_CONFLICT_ID: { 258 qb.setTables(TABLE_MCC_SID_CONFLICT); 259 qb.appendWhere(TABLE_MCC_SID_CONFLICT + "._id="); 260 qb.appendWhere(uri.getPathSegments().get(1)); 261 if (useDefaultOrder) { 262 orderBy = MccSidConflicts.DEFAULT_SORT_ORDER; 263 } 264 break; 265 } 266 case MCC_SID_RANGE_ID: { 267 qb.setTables(TABLE_MCC_SID_RANGE); 268 qb.setProjectionMap(sRangeProjectionMap); 269 qb.appendWhere(TABLE_MCC_SID_RANGE + "._id="); 270 qb.appendWhere(uri.getPathSegments().get(1)); 271 if (useDefaultOrder) { 272 orderBy = MccIdd.DEFAULT_SORT_ORDER; 273 } 274 break; 275 } 276 case NANP_AREA_CODE_ID: { 277 qb.setTables(TABLE_NANP_AREA_CODE); 278 qb.setProjectionMap(sNanpProjectionMap); 279 qb.appendWhere(TABLE_NANP_AREA_CODE + "._id="); 280 qb.appendWhere(uri.getPathSegments().get(1)); 281 if (useDefaultOrder) { 282 orderBy = NanpAreaCode.DEFAULT_SORT_ORDER; 283 } 284 break; 285 } 286 case ARBITRARY_MCC_SID_MATCH_ID: { 287 qb.setTables(TABLE_ARBITRARY_MCC_SID_MATCH); 288 qb.setProjectionMap(sArbitraryProjectionMap); 289 qb.appendWhere(TABLE_ARBITRARY_MCC_SID_MATCH + "._id="); 290 qb.appendWhere(uri.getPathSegments().get(1)); 291 if (useDefaultOrder) { 292 orderBy = ArbitraryMccSidMatch.DEFAULT_SORT_ORDER; 293 } 294 break; 295 } 296 default: 297 throw new IllegalArgumentException("Unknown URI " + uri); 298 } 299 300 if (!useDefaultOrder) { 301 orderBy = sortOrder; 302 } 303 304 SQLiteDatabase db = mDbHelper.getReadableDatabase(); 305 Cursor c = qb.query(db, projectionIn, selection, selectionArgs, groupBy, null, orderBy); 306 if (c != null) { 307 c.setNotificationUri(getContext().getContentResolver(), uri); 308 } 309 310 return c; 311 } 312 313 @Override insert(Uri uri, ContentValues values)314 public Uri insert(Uri uri, ContentValues values) { 315 throw new UnsupportedOperationException("Failed to insert row into " + uri); 316 } 317 318 @Override delete(Uri uri, String selection, String[] selectionArgs)319 public int delete(Uri uri, String selection, String[] selectionArgs) { 320 throw new UnsupportedOperationException("Cannot delete URL: " + uri); 321 } 322 323 @Override update(Uri uri, ContentValues values, String selection, String[] selectionArgs)324 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 325 int count = 0; 326 final SQLiteDatabase db = mDbHelper.getWritableDatabase(); 327 328 final int match= sURIMatcher.match(uri); 329 switch (match) { 330 case MCC_LOOKUP_TABLE: 331 count = db.update(TABLE_MCC_LOOKUP_TABLE, values, selection, selectionArgs); 332 break; 333 default: 334 throw new UnsupportedOperationException("Cannot update URL: " + uri); 335 } 336 337 return count; 338 } 339 } 340