1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.providers.telephony; 18 19 import android.content.ContentValues; 20 import android.content.pm.PackageManager; 21 import android.content.pm.ProviderInfo; 22 import android.content.res.Resources; 23 import android.database.Cursor; 24 import android.database.SQLException; 25 import android.telephony.TelephonyManager; 26 import android.test.mock.MockContentResolver; 27 import android.test.mock.MockContext; 28 import android.text.TextUtils; 29 import android.util.Log; 30 31 import androidx.test.filters.SmallTest; 32 33 import junit.framework.TestCase; 34 35 import org.junit.Test; 36 37 /** 38 * Tests for testing CRUD operations of CarrierProvider. 39 * Uses TelephonyProviderTestable to set up in-memory database 40 * 41 * Build, install and run the tests by running the commands below: 42 * runtest --path <dir or file> 43 * runtest --path <dir or file> --test-method <testMethodName> 44 * e.g.) 45 * runtest --path tests/src/com/android/providers/telephony/CarrierProviderTest.java \ 46 * --test-method testInsertCarriers 47 */ 48 public class CarrierProviderTest extends TestCase { 49 50 private static final String TAG = "CarrierProviderTest"; 51 52 private MockContextWithProvider mContext; 53 private MockContentResolver mContentResolver; 54 private CarrierProviderTestable mCarrierProviderTestable; 55 56 public static final int test_type = 1; 57 public static final String test_mnc = "MNC001"; 58 public static final String test_mnc2 = "MNC002"; 59 public static final String test_mcc = "MCC005"; 60 public static final String test_key1 = "PUBKEY1"; 61 public static final String test_key2 = "PUBKEY2"; 62 public static final String test_key_identifier_data = "key_identifier1"; 63 public static final long test_key_expiration = 1496795015L; 64 public static final int TEST_CARRIER_ID_1 = 1; 65 public static final int TEST_CARRIER_ID_2 = 2; 66 67 /** 68 * This is used to give the CarrierProviderTest a mocked context which takes a 69 * CarrierProvider and attaches it to the ContentResolver. 70 */ 71 private class MockContextWithProvider extends MockContext { 72 private final MockContentResolver mResolver; 73 MockContextWithProvider(CarrierProvider carrierProvider)74 public MockContextWithProvider(CarrierProvider carrierProvider) { 75 mResolver = new MockContentResolver(); 76 77 ProviderInfo providerInfo = new ProviderInfo(); 78 providerInfo.authority = CarrierProvider.PROVIDER_NAME; 79 80 // Add context to given telephonyProvider 81 carrierProvider.attachInfoForTesting(this, providerInfo); 82 Log.d(TAG, "MockContextWithProvider: carrierProvider.getContext(): " 83 + carrierProvider.getContext()); 84 85 // Add given telephonyProvider to mResolver, so that mResolver can send queries 86 // to the provider. 87 mResolver.addProvider(CarrierProvider.PROVIDER_NAME, carrierProvider); 88 Log.d(TAG, "MockContextWithProvider: Add carrierProvider to mResolver"); 89 } 90 91 @Override getSystemService(String name)92 public Object getSystemService(String name) { 93 Log.d(TAG, "getSystemService: returning null"); 94 return null; 95 } 96 97 @Override getResources()98 public Resources getResources() { 99 Log.d(TAG, "getResources: returning null"); 100 return null; 101 } 102 103 @Override getContentResolver()104 public MockContentResolver getContentResolver() { 105 return mResolver; 106 } 107 108 // Gives permission to write to the APN table within the MockContext 109 @Override checkCallingOrSelfPermission(String permission)110 public int checkCallingOrSelfPermission(String permission) { 111 if (TextUtils.equals(permission, "android.permission.WRITE_APN_SETTINGS")) { 112 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 113 + ", returning PackageManager.PERMISSION_GRANTED"); 114 return PackageManager.PERMISSION_GRANTED; 115 } else { 116 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 117 + ", returning PackageManager.PERMISSION_DENIED"); 118 return PackageManager.PERMISSION_DENIED; 119 } 120 } 121 } 122 123 @Override setUp()124 protected void setUp() throws Exception { 125 super.setUp(); 126 mCarrierProviderTestable = new CarrierProviderTestable(); 127 mContext = new MockContextWithProvider(mCarrierProviderTestable); 128 mContentResolver = (MockContentResolver) mContext.getContentResolver(); 129 } 130 131 @Override tearDown()132 protected void tearDown() throws Exception { 133 super.tearDown(); 134 mCarrierProviderTestable.closeDatabase(); 135 } 136 137 /** 138 * Test inserting values in carrier key table. 139 */ 140 @Test 141 @SmallTest testInsertCertificates()142 public void testInsertCertificates() { 143 int count = -1; 144 ContentValues contentValues = new ContentValues(); 145 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 146 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 147 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 148 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 149 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 150 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 151 contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration); 152 153 try { 154 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 155 } catch (Exception e) { 156 Log.d(TAG, "Error inserting certificates:" + e); 157 } 158 try { 159 Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI, 160 new String[]{"count(*) AS count"}, 161 null, 162 null, 163 null); 164 countCursor.moveToFirst(); 165 count = countCursor.getInt(0); 166 } catch (Exception e) { 167 Log.d(TAG, "Exception in getting count:" + e); 168 } 169 assertEquals(1, count); 170 } 171 172 /** 173 * Test update & query. 174 */ 175 @Test 176 @SmallTest testUpdateCertificates()177 public void testUpdateCertificates() { 178 String key = null; 179 ContentValues contentValues = new ContentValues(); 180 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 181 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 182 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 183 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 184 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 185 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 186 contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration); 187 188 try { 189 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 190 } catch (Exception e) { 191 Log.d(TAG, "Error inserting certificates:" + e); 192 } 193 194 try { 195 ContentValues updatedValues = new ContentValues(); 196 updatedValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2); 197 mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues, 198 "mcc=? and mnc=? and carrier_id=? and key_type=?", 199 new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1), 200 String.valueOf(test_type)}); 201 } catch (Exception e) { 202 Log.d(TAG, "Error updating values:" + e); 203 } 204 205 try { 206 String[] columns ={CarrierDatabaseHelper.PUBLIC_KEY}; 207 Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns, 208 "mcc=? and mnc=? and carrier_id=? and key_type=?", 209 new String[]{test_mcc, test_mnc, Integer.toString(TEST_CARRIER_ID_1), 210 String.valueOf(test_type)}, null); 211 findEntry.moveToFirst(); 212 key = findEntry.getString(0); 213 } catch (Exception e) { 214 Log.d(TAG, "Query failed:" + e); 215 } 216 assertEquals(key, test_key2); 217 } 218 219 /** 220 * Test inserting multiple certs 221 */ 222 @Test 223 @SmallTest testMultipleCertificates()224 public void testMultipleCertificates() { 225 int count = -1; 226 ContentValues contentValues = new ContentValues(); 227 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 228 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 229 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 230 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 231 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 232 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 233 234 ContentValues contentValuesNew = new ContentValues(); 235 contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 236 contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc); 237 contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc2); 238 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 239 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 240 contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key2.getBytes()); 241 242 try { 243 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 244 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew); 245 } catch (Exception e) { 246 System.out.println("Error inserting certificates:: " + e); 247 } 248 249 try { 250 Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI, 251 new String[]{"count(*) AS count"}, 252 null, 253 null, 254 null); 255 countCursor.moveToFirst(); 256 count = countCursor.getInt(0); 257 } catch (Exception e) { 258 Log.d(TAG, "Exception in getting count:" + e); 259 } 260 assertEquals(2, count); 261 } 262 263 /** 264 * Test inserting cert with same MCC and MNC but with diff carrier ID 265 */ 266 @Test 267 @SmallTest testMnoandMvnoCertificates()268 public void testMnoandMvnoCertificates() { 269 int count = -1; 270 ContentValues contentValues = new ContentValues(); 271 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 272 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 273 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 274 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 275 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 276 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 277 278 ContentValues contentValuesNew = new ContentValues(); 279 contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 280 contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc); 281 contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc); 282 contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2); 283 contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 284 contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 285 286 try { 287 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 288 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew); 289 } catch (Exception e) { 290 System.out.println("Error inserting certificates:: " + e); 291 } 292 293 try { 294 Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI, 295 new String[]{"count(*) AS count"}, 296 null, 297 null, 298 null); 299 countCursor.moveToFirst(); 300 count = countCursor.getInt(0); 301 } catch (Exception e) { 302 Log.d(TAG, "Exception in getting count:" + e); 303 } 304 assertEquals(2, count); 305 } 306 307 /** 308 * once upgrade to version 3, carrierId = -1 309 * After upgrade, it triggers for new download with correct carrierId 310 * This test case will test writing the new entry, even old entry for same 311 * operator is already existed 312 */ 313 @Test 314 @SmallTest testOldAndNewDBEntries()315 public void testOldAndNewDBEntries() { 316 int count = -1; 317 ContentValues contentValues = new ContentValues(); 318 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 319 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 320 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 321 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID); 322 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 323 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 324 325 ContentValues contentValuesNew = new ContentValues(); 326 contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 327 contentValuesNew.put(CarrierDatabaseHelper.MCC, test_mcc); 328 contentValuesNew.put(CarrierDatabaseHelper.MNC, test_mnc); 329 contentValuesNew.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_2); 330 contentValuesNew.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 331 contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 332 333 try { 334 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 335 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew); 336 } catch (Exception e) { 337 System.out.println("Error inserting certificates:: " + e); 338 } 339 340 try { 341 Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI, 342 new String[]{"count(*) AS count"}, 343 null, 344 null, 345 null); 346 countCursor.moveToFirst(); 347 count = countCursor.getInt(0); 348 } catch (Exception e) { 349 Log.d(TAG, "Exception in getting count:" + e); 350 } 351 assertEquals(2, count); 352 } 353 354 /** 355 * Test inserting duplicate values in carrier key table. Ensure that a SQLException is thrown. 356 */ 357 @Test(expected = SQLException.class) testDuplicateFailure()358 public void testDuplicateFailure() { 359 ContentValues contentValues = new ContentValues(); 360 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 361 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 362 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 363 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 364 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 365 366 try { 367 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 368 } catch (Exception e) { 369 Log.d(TAG, "Error inserting certificates:: " + e); 370 } 371 try { 372 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 373 } catch (Exception e) { 374 Log.d(TAG, "Error inserting certificates:: " + e); 375 } 376 } 377 378 /** 379 * Test delete. 380 */ 381 @Test 382 @SmallTest testDelete()383 public void testDelete() { 384 int numRowsDeleted = -1; 385 ContentValues contentValues = new ContentValues(); 386 contentValues.put(CarrierDatabaseHelper.KEY_TYPE, test_type); 387 contentValues.put(CarrierDatabaseHelper.MCC, test_mcc); 388 contentValues.put(CarrierDatabaseHelper.MNC, test_mnc); 389 contentValues.put(CarrierDatabaseHelper.CARRIER_ID, TEST_CARRIER_ID_1); 390 contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, test_key_identifier_data); 391 contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, test_key1.getBytes()); 392 contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, test_key_expiration); 393 394 try { 395 mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues); 396 } catch (Exception e) { 397 Log.d(TAG, "Error inserting certificates:" + e); 398 } 399 400 try { 401 String whereClause = "mcc=? and mnc=? and carrier_id=?"; 402 String[] whereArgs = new String[]{test_mcc, test_mnc, Integer.toString( 403 TEST_CARRIER_ID_1)}; 404 numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause, 405 whereArgs); 406 } catch (Exception e) { 407 Log.d(TAG, "Error updating values:" + e); 408 } 409 assertEquals(numRowsDeleted, 1); 410 } 411 412 } 413