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 18package com.android.providers.telephony; 19 20import android.content.ContentProvider; 21import android.content.ContentUris; 22import android.content.ContentValues; 23import android.content.UriMatcher; 24import android.database.sqlite.SQLiteDatabase; 25import android.database.sqlite.SQLiteQueryBuilder; 26import android.database.Cursor; 27import android.database.SQLException; 28import android.net.Uri; 29import android.text.TextUtils; 30import android.util.Log; 31import java.util.HashMap; 32 33import com.android.internal.telephony.HbpcdLookup; 34import com.android.internal.telephony.HbpcdLookup.MccIdd; 35import com.android.internal.telephony.HbpcdLookup.MccLookup; 36import com.android.internal.telephony.HbpcdLookup.MccSidConflicts; 37import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch; 38import com.android.internal.telephony.HbpcdLookup.MccSidRange; 39import com.android.internal.telephony.HbpcdLookup.NanpAreaCode; 40 41public 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 { 75 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD, MCC_IDD); 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. 79 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 80 HbpcdLookup.PATH_MCC_SID_CONFLICT, MCC_SID_CONFLICT); 81 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_SID_RANGE, MCC_SID_RANGE); 82 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_NANP_AREA_CODE, NANP_AREA_CODE); 83 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 84 HbpcdLookup.PATH_ARBITRARY_MCC_SID_MATCH, ARBITRARY_MCC_SID_MATCH); 85 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, HbpcdLookup.PATH_MCC_IDD + "/#", MCC_IDD_ID); 86 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 87 HbpcdLookup.PATH_MCC_LOOKUP_TABLE + "/#", MCC_LOOKUP_TABLE_ID); 88 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 89 HbpcdLookup.PATH_MCC_SID_CONFLICT + "/#", MCC_SID_CONFLICT_ID); 90 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 91 HbpcdLookup.PATH_MCC_SID_RANGE + "/#", MCC_SID_RANGE_ID); 92 sURIMatcher.addURI(HbpcdLookup.AUTHORITY, 93 HbpcdLookup.PATH_NANP_AREA_CODE + "/#", NANP_AREA_CODE_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>(); 98 sIddProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); 99 sIddProjectionMap.put(MccIdd.MCC, MccIdd.MCC); 100 sIddProjectionMap.put(MccIdd.IDD, MccIdd.IDD); 101 102 sLookupProjectionMap = new HashMap<String, String>(); 103 sLookupProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); 104 sLookupProjectionMap.put(MccLookup.MCC, MccLookup.MCC); 105 sLookupProjectionMap.put(MccLookup.COUNTRY_CODE, MccLookup.COUNTRY_CODE); 106 sLookupProjectionMap.put(MccLookup.COUNTRY_NAME, MccLookup.COUNTRY_NAME); 107 sLookupProjectionMap.put(MccLookup.NDD, MccLookup.NDD); 108 sLookupProjectionMap.put(MccLookup.NANPS, MccLookup.NANPS); 109 sLookupProjectionMap.put(MccLookup.GMT_OFFSET_LOW, MccLookup.GMT_OFFSET_LOW); 110 sLookupProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, MccLookup.GMT_OFFSET_HIGH); 111 sLookupProjectionMap.put(MccLookup.GMT_DST_LOW, MccLookup.GMT_DST_LOW); 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 117 sConflictProjectionMap.put(MccLookup.GMT_OFFSET_LOW, 118 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_LOW); 119 sConflictProjectionMap.put(MccLookup.GMT_OFFSET_HIGH, 120 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_OFFSET_HIGH); 121 sConflictProjectionMap.put(MccLookup.GMT_DST_LOW, 122 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_LOW); 123 sConflictProjectionMap.put(MccLookup.GMT_DST_HIGH, 124 TABLE_MCC_LOOKUP_TABLE + "." + MccLookup.GMT_DST_HIGH); 125 sConflictProjectionMap.put(MccSidConflicts.MCC, 126 TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.MCC); 127 sConflictProjectionMap.put(MccSidConflicts.SID_CONFLICT, 128 TABLE_MCC_SID_CONFLICT + "." + MccSidConflicts.SID_CONFLICT); 129 130 sRangeProjectionMap = new HashMap<String, String>(); 131 sRangeProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); 132 sRangeProjectionMap.put(MccSidRange.MCC, MccSidRange.MCC); 133 sRangeProjectionMap.put(MccSidRange.RANGE_LOW, MccSidRange.RANGE_LOW); 134 sRangeProjectionMap.put(MccSidRange.RANGE_HIGH, MccSidRange.RANGE_HIGH); 135 136 sNanpProjectionMap = new HashMap<String, String>(); 137 sNanpProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); 138 sNanpProjectionMap.put(NanpAreaCode.AREA_CODE, NanpAreaCode.AREA_CODE); 139 140 sArbitraryProjectionMap = new HashMap<String, String>(); 141 sArbitraryProjectionMap.put(HbpcdLookup.ID, HbpcdLookup.ID); 142 sArbitraryProjectionMap.put(ArbitraryMccSidMatch.MCC, ArbitraryMccSidMatch.MCC); 143 sArbitraryProjectionMap.put(ArbitraryMccSidMatch.SID, ArbitraryMccSidMatch.SID); 144 } 145 146 private HbpcdLookupDatabaseHelper mDbHelper; 147 148 @Override 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 160 public String getType(Uri uri) { 161 if (DBG) { 162 Log.d(TAG, "getType"); 163 } 164 165 return null; 166 } 167 168 @Override 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 314 public Uri insert(Uri uri, ContentValues values) { 315 throw new UnsupportedOperationException("Failed to insert row into " + uri); 316 } 317 318 @Override 319 public int delete(Uri uri, String selection, String[] selectionArgs) { 320 throw new UnsupportedOperationException("Cannot delete URL: " + uri); 321 } 322 323 @Override 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