1 /* 2 * Copyright (C) 2016 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 static org.mockito.ArgumentMatchers.anyInt; 20 import static org.mockito.ArgumentMatchers.anyString; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.eq; 23 import static org.mockito.Mockito.mock; 24 25 26 import android.Manifest; 27 import android.content.ContentUris; 28 import android.content.ContentValues; 29 import android.content.Context; 30 import android.content.SharedPreferences; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ProviderInfo; 33 import android.content.res.Resources; 34 import android.database.ContentObserver; 35 import android.database.Cursor; 36 import android.net.Uri; 37 import android.os.Process; 38 import android.provider.Telephony; 39 import android.provider.Telephony.Carriers; 40 import android.provider.Telephony.SimInfo; 41 import android.telephony.SubscriptionManager; 42 import android.telephony.TelephonyManager; 43 import android.test.mock.MockContentResolver; 44 import android.test.mock.MockContext; 45 import android.test.suitebuilder.annotation.SmallTest; 46 import android.text.TextUtils; 47 import android.util.Log; 48 49 import androidx.test.InstrumentationRegistry; 50 51 import junit.framework.TestCase; 52 53 import org.junit.Test; 54 import org.mockito.ArgumentMatchers; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 import java.lang.reflect.Field; 59 import java.util.Arrays; 60 import java.util.List; 61 import java.util.stream.IntStream; 62 63 /** 64 * Tests for testing CRUD operations of TelephonyProvider. 65 * Uses a MockContentResolver to get permission WRITE_APN_SETTINGS in order to test insert/delete 66 * Uses TelephonyProviderTestable to set up in-memory database 67 * 68 * Build, install and run the tests by running the commands below: 69 * runtest --path <dir or file> 70 * runtest --path <dir or file> --test-method <testMethodName> 71 * e.g.) 72 * runtest --path tests/src/com/android/providers/telephony/TelephonyProviderTest.java \ 73 * --test-method testInsertCarriers 74 */ 75 public class TelephonyProviderTest extends TestCase { 76 private static final String TAG = "TelephonyProviderTest"; 77 78 private MockContextWithProvider mContext; 79 private MockContentResolver mContentResolver; 80 private TelephonyProviderTestable mTelephonyProviderTestable; 81 82 private int notifyChangeCount; 83 private int notifyChangeRestoreCount; 84 private int notifyWfcCount; 85 private int notifyWfcCountWithTestSubId; 86 87 private static final String TEST_SUBID = "1"; 88 private static final String TEST_OPERATOR = "123456"; 89 private static final String TEST_MCC = "123"; 90 private static final String TEST_MNC = "456"; 91 private static final String TEST_SPN = TelephonyProviderTestable.TEST_SPN; 92 private static final int TEST_CARRIERID = 1; 93 94 // Used to test the path for URL_TELEPHONY_USING_SUBID with subid 1 95 private static final Uri CONTENT_URI_WITH_SUBID = Uri.parse( 96 "content://telephony/carriers/subId/" + TEST_SUBID); 97 98 // Used to test the "restore to default" 99 private static final Uri URL_RESTOREAPN_USING_SUBID = Uri.parse( 100 "content://telephony/carriers/restore/subId/" + TEST_SUBID); 101 // Used to test the preferred apn 102 private static final Uri URL_PREFERAPN_USING_SUBID = Uri.parse( 103 "content://telephony/carriers/preferapn/subId/" + TEST_SUBID); 104 private static final Uri URL_WFC_ENABLED_USING_SUBID = Uri.parse( 105 "content://telephony/siminfo/" + TEST_SUBID); 106 private static final Uri URL_SIM_APN_LIST = Uri.parse( 107 "content://telephony/carriers/sim_apn_list"); 108 109 private static final String COLUMN_APN_ID = "apn_id"; 110 111 // Constants for DPC related tests. 112 private static final Uri URI_DPC = Uri.parse("content://telephony/carriers/dpc"); 113 private static final Uri URI_TELEPHONY = Carriers.CONTENT_URI; 114 private static final Uri URI_FILTERED = Uri.parse("content://telephony/carriers/filtered"); 115 private static final Uri URI_ENFORCE_MANAGED= Uri.parse("content://telephony/carriers/enforce_managed"); 116 private static final String ENFORCED_KEY = "enforced"; 117 118 /** 119 * This is used to give the TelephonyProviderTest a mocked context which takes a 120 * TelephonyProvider and attaches it to the ContentResolver with telephony authority. 121 * The mocked context also gives WRITE_APN_SETTINGS permissions 122 */ 123 private class MockContextWithProvider extends MockContext { 124 private final MockContentResolver mResolver; 125 private TelephonyManager mTelephonyManager = mock(TelephonyManager.class); 126 127 private final List<String> GRANTED_PERMISSIONS = Arrays.asList( 128 Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.WRITE_APN_SETTINGS, 129 Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 130 MockContextWithProvider(TelephonyProvider telephonyProvider)131 public MockContextWithProvider(TelephonyProvider telephonyProvider) { 132 mResolver = new MockContentResolver() { 133 @Override 134 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 135 int userHandle) { 136 notifyChangeCount++; 137 if (URL_RESTOREAPN_USING_SUBID.equals(uri)) { 138 notifyChangeRestoreCount++; 139 } else if (SubscriptionManager.WFC_ENABLED_CONTENT_URI.equals(uri)) { 140 notifyWfcCount++; 141 } else if (URL_WFC_ENABLED_USING_SUBID.equals(uri)) { 142 notifyWfcCountWithTestSubId++; 143 } 144 } 145 }; 146 147 // return test subId 0 for all operators 148 doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(anyInt()); 149 150 doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); 151 doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(); 152 doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimCarrierId(); 153 154 // Add authority="telephony" to given telephonyProvider 155 ProviderInfo providerInfo = new ProviderInfo(); 156 providerInfo.authority = "telephony"; 157 158 // Add context to given telephonyProvider 159 telephonyProvider.attachInfoForTesting(this, providerInfo); 160 Log.d(TAG, "MockContextWithProvider: telephonyProvider.getContext(): " 161 + telephonyProvider.getContext()); 162 163 // Add given telephonyProvider to mResolver with authority="telephony" so that 164 // mResolver can send queries to mTelephonyProvider 165 mResolver.addProvider("telephony", telephonyProvider); 166 Log.d(TAG, "MockContextWithProvider: Add telephonyProvider to mResolver"); 167 } 168 169 @Override getSystemService(String name)170 public Object getSystemService(String name) { 171 if (name.equals(Context.TELEPHONY_SERVICE)) { 172 Log.d(TAG, "getSystemService: returning mock TM"); 173 return mTelephonyManager; 174 } else { 175 Log.d(TAG, "getSystemService: returning null"); 176 return null; 177 } 178 } 179 180 @Override getSystemServiceName(Class<?> serviceClass)181 public String getSystemServiceName(Class<?> serviceClass) { 182 if (serviceClass.equals(TelephonyManager.class)) { 183 return Context.TELEPHONY_SERVICE; 184 } else { 185 Log.d(TAG, "getSystemServiceName: returning null"); 186 return null; 187 } 188 } 189 190 @Override getResources()191 public Resources getResources() { 192 Log.d(TAG, "getResources: returning null"); 193 return null; 194 } 195 196 @Override getContentResolver()197 public MockContentResolver getContentResolver() { 198 return mResolver; 199 } 200 201 @Override getSharedPreferences(String name, int mode)202 public SharedPreferences getSharedPreferences(String name, int mode) { 203 return InstrumentationRegistry.getContext().getSharedPreferences(name, mode); 204 } 205 206 // Gives permission to write to the APN table within the MockContext 207 @Override checkCallingOrSelfPermission(String permission)208 public int checkCallingOrSelfPermission(String permission) { 209 if (GRANTED_PERMISSIONS.contains(permission)) { 210 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 211 + ", returning PackageManager.PERMISSION_GRANTED"); 212 return PackageManager.PERMISSION_GRANTED; 213 } else { 214 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 215 + ", returning PackageManager.PERMISSION_DENIED"); 216 return PackageManager.PERMISSION_DENIED; 217 } 218 } 219 } 220 221 @Override setUp()222 protected void setUp() throws Exception { 223 super.setUp(); 224 MockitoAnnotations.initMocks(this); 225 mTelephonyProviderTestable = new TelephonyProviderTestable(); 226 mContext = new MockContextWithProvider(mTelephonyProviderTestable); 227 mContentResolver = (MockContentResolver) mContext.getContentResolver(); 228 notifyChangeCount = 0; 229 notifyChangeRestoreCount = 0; 230 } 231 232 @Override tearDown()233 protected void tearDown() throws Exception { 234 super.tearDown(); 235 mTelephonyProviderTestable.closeDatabase(); 236 } 237 238 /** 239 * Test bulk inserting, querying; 240 * Verify that the inserted values match the result of the query. 241 */ 242 @Test 243 @SmallTest testBulkInsertCarriers()244 public void testBulkInsertCarriers() { 245 // insert 2 test contentValues 246 ContentValues contentValues = new ContentValues(); 247 final String insertApn = "exampleApnName"; 248 final String insertName = "exampleName"; 249 final Integer insertCurrent = 1; 250 final String insertNumeric = TEST_OPERATOR; 251 contentValues.put(Carriers.APN, insertApn); 252 contentValues.put(Carriers.NAME, insertName); 253 contentValues.put(Carriers.CURRENT, insertCurrent); 254 contentValues.put(Carriers.NUMERIC, insertNumeric); 255 256 ContentValues contentValues2 = new ContentValues(); 257 final String insertApn2 = "exampleApnName2"; 258 final String insertName2 = "exampleName2"; 259 final Integer insertCurrent2 = 1; 260 final String insertNumeric2 = "789123"; 261 contentValues2.put(Carriers.APN, insertApn2); 262 contentValues2.put(Carriers.NAME, insertName2); 263 contentValues2.put(Carriers.CURRENT, insertCurrent2); 264 contentValues2.put(Carriers.NUMERIC, insertNumeric2); 265 266 Log.d(TAG, "testInsertCarriers: Bulk inserting contentValues=" + contentValues 267 + ", " + contentValues2); 268 ContentValues[] values = new ContentValues[]{ contentValues, contentValues2 }; 269 int rows = mContentResolver.bulkInsert(Carriers.CONTENT_URI, values); 270 assertEquals(2, rows); 271 assertEquals(1, notifyChangeCount); 272 273 // get values in table 274 final String[] testProjection = 275 { 276 Carriers.APN, 277 Carriers.NAME, 278 Carriers.CURRENT, 279 }; 280 final String selection = Carriers.NUMERIC + "=?"; 281 String[] selectionArgs = { insertNumeric }; 282 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 283 + "\ntestInsertCarriers selection: " + selection 284 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 285 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, 286 testProjection, selection, selectionArgs, null); 287 288 // verify that inserted values match results of query 289 assertNotNull(cursor); 290 assertEquals(1, cursor.getCount()); 291 cursor.moveToFirst(); 292 final String resultApn = cursor.getString(0); 293 final String resultName = cursor.getString(1); 294 final Integer resultCurrent = cursor.getInt(2); 295 assertEquals(insertApn, resultApn); 296 assertEquals(insertName, resultName); 297 assertEquals(insertCurrent, resultCurrent); 298 } 299 300 /** 301 * Test inserting, querying, and deleting values in carriers table. 302 * Verify that the inserted values match the result of the query and are deleted. 303 */ 304 @Test 305 @SmallTest testInsertCarriers()306 public void testInsertCarriers() { 307 doSimpleTestForUri(Carriers.CONTENT_URI); 308 } 309 310 /** 311 * Test migrating int-based MCC/MNCs over to Strings in the sim info table 312 */ 313 @Test 314 @SmallTest testMccMncMigration()315 public void testMccMncMigration() { 316 CarrierIdProviderTestable carrierIdProvider = new CarrierIdProviderTestable(); 317 carrierIdProvider.initializeForTesting(mContext); 318 mContentResolver.addProvider(Telephony.CarrierId.All.CONTENT_URI.getAuthority(), 319 carrierIdProvider); 320 // Insert a few values into the carrier ID db 321 List<String> mccMncs = Arrays.asList("99910", "999110", "999060", "99905"); 322 ContentValues[] carrierIdMccMncs = mccMncs.stream() 323 .map((mccMnc) -> { 324 ContentValues cv = new ContentValues(1); 325 cv.put(Telephony.CarrierId.All.MCCMNC, mccMnc); 326 return cv; 327 }).toArray(ContentValues[]::new); 328 mContentResolver.bulkInsert(Telephony.CarrierId.All.CONTENT_URI, carrierIdMccMncs); 329 330 // Populate the sim info db with int-format entries 331 ContentValues[] existingSimInfoEntries = IntStream.range(0, mccMncs.size()) 332 .mapToObj((idx) -> { 333 int mcc = Integer.valueOf(mccMncs.get(idx).substring(0, 3)); 334 int mnc = Integer.valueOf(mccMncs.get(idx).substring(3)); 335 ContentValues cv = new ContentValues(4); 336 cv.put(SubscriptionManager.MCC, mcc); 337 cv.put(SubscriptionManager.MNC, mnc); 338 cv.put(SubscriptionManager.ICC_ID, String.valueOf(idx)); 339 cv.put(SubscriptionManager.CARD_ID, String.valueOf(idx)); 340 return cv; 341 }).toArray(ContentValues[]::new); 342 343 mContentResolver.bulkInsert(SimInfo.CONTENT_URI, existingSimInfoEntries); 344 345 // Run the upgrade helper on all the sim info entries. 346 String[] proj = {SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, 347 SubscriptionManager.MCC, SubscriptionManager.MNC, 348 SubscriptionManager.MCC_STRING, SubscriptionManager.MNC_STRING}; 349 try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj, 350 null, null, null)) { 351 while (c.moveToNext()) { 352 TelephonyProvider.fillInMccMncStringAtCursor(mContext, 353 mTelephonyProviderTestable.getWritableDatabase(), c); 354 } 355 } 356 357 // Loop through and make sure that everything got filled in correctly. 358 try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj, 359 null, null, null)) { 360 while (c.moveToNext()) { 361 String mcc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MCC_STRING)); 362 String mnc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MNC_STRING)); 363 assertTrue(mccMncs.contains(mcc + mnc)); 364 } 365 } 366 } 367 368 /** 369 * Test updating values in carriers table. Verify that when update hits a conflict using URL_ID 370 * we merge the rows. 371 */ 372 @Test 373 @SmallTest testUpdateConflictingCarriers()374 public void testUpdateConflictingCarriers() { 375 // insert 2 test contentValues 376 ContentValues contentValues = new ContentValues(); 377 final String insertApn = "exampleApnName"; 378 final String insertName = "exampleName"; 379 final String insertNumeric = TEST_OPERATOR; 380 final String insertMcc = TEST_MCC; 381 final String insertMnc = TEST_MNC; 382 contentValues.put(Carriers.APN, insertApn); 383 contentValues.put(Carriers.NAME, insertName); 384 contentValues.put(Carriers.NUMERIC, insertNumeric); 385 contentValues.put(Carriers.MCC, insertMcc); 386 contentValues.put(Carriers.MNC, insertMnc); 387 388 ContentValues contentValues2 = new ContentValues(); 389 final String insertName2 = "exampleName2"; 390 contentValues2.put(Carriers.NAME, insertName2); 391 392 Uri row1 = mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 393 Uri row2 = mContentResolver.insert(Carriers.CONTENT_URI, contentValues2); 394 395 // use URL_ID to update row2 apn so it conflicts with row1 396 Log.d(TAG, "testUpdateConflictingCarriers: update row2=" + row2); 397 contentValues.put(Carriers.NAME, insertName2); 398 mContentResolver.update(row2, contentValues, null, null); 399 400 // verify that only 1 APN now exists and it has the fields from row1 and row2 401 final String[] testProjection = 402 { 403 Carriers.APN, 404 Carriers.NAME, 405 Carriers.NUMERIC, 406 Carriers.MCC, 407 Carriers.MNC 408 }; 409 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, null, null, 410 null); 411 assertNotNull(cursor); 412 assertEquals(1, cursor.getCount()); 413 cursor.moveToFirst(); 414 assertEquals(insertApn, cursor.getString(0 /* APN */)); 415 assertEquals(insertName2, cursor.getString(1 /* NAME */)); 416 assertEquals(insertNumeric, cursor.getString(2 /* NUMERIC */)); 417 assertEquals(insertMcc, cursor.getString(3 /* MCC */)); 418 assertEquals(insertMnc, cursor.getString(4 /* MNC */)); 419 } 420 421 /** 422 * Test inserting, querying, and deleting values in carriers table. 423 * Verify that the inserted values match the result of the query and are deleted. 424 */ 425 @Test 426 @SmallTest testInsertCarriersWithSubId()427 public void testInsertCarriersWithSubId() { 428 doSimpleTestForUri(CONTENT_URI_WITH_SUBID); 429 } 430 doSimpleTestForUri(Uri uri)431 private void doSimpleTestForUri(Uri uri) { 432 // insert test contentValues 433 ContentValues contentValues = new ContentValues(); 434 final String insertApn = "exampleApnName"; 435 final String insertName = "exampleName"; 436 final String insertNumeric = TEST_OPERATOR; 437 contentValues.put(Carriers.APN, insertApn); 438 contentValues.put(Carriers.NAME, insertName); 439 contentValues.put(Carriers.NUMERIC, insertNumeric); 440 441 Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues); 442 mContentResolver.insert(uri, contentValues); 443 444 // get values in table 445 final String[] testProjection = 446 { 447 Carriers.APN, 448 Carriers.NAME, 449 }; 450 final String selection = Carriers.NUMERIC + "=?"; 451 String[] selectionArgs = { insertNumeric }; 452 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 453 + "\ntestInsertCarriers selection: " + selection 454 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 455 Cursor cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 456 457 // verify that inserted values match results of query 458 assertNotNull(cursor); 459 assertEquals(1, cursor.getCount()); 460 cursor.moveToFirst(); 461 final String resultApn = cursor.getString(0); 462 final String resultName = cursor.getString(1); 463 assertEquals(insertApn, resultApn); 464 assertEquals(insertName, resultName); 465 466 // delete test content 467 final String selectionToDelete = Carriers.NUMERIC + "=?"; 468 String[] selectionArgsToDelete = { insertNumeric }; 469 Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete 470 + "testInsertCarriers selectionArgs: " + selectionArgs); 471 int numRowsDeleted = mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete); 472 assertEquals(1, numRowsDeleted); 473 474 // verify that deleted values are gone 475 cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 476 assertEquals(0, cursor.getCount()); 477 } 478 479 @Test 480 @SmallTest testOwnedBy()481 public void testOwnedBy() { 482 // insert test contentValues 483 ContentValues contentValues = new ContentValues(); 484 final String insertApn = "exampleApnName"; 485 final String insertName = "exampleName"; 486 final String insertNumeric = TEST_OPERATOR; 487 final Integer insertOwnedBy = Carriers.OWNED_BY_OTHERS; 488 contentValues.put(Carriers.APN, insertApn); 489 contentValues.put(Carriers.NAME, insertName); 490 contentValues.put(Carriers.NUMERIC, insertNumeric); 491 contentValues.put(Carriers.OWNED_BY, insertOwnedBy); 492 493 Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues); 494 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 495 496 // get values in table 497 final String[] testProjection = 498 { 499 Carriers.APN, 500 Carriers.NAME, 501 Carriers.OWNED_BY, 502 }; 503 final String selection = Carriers.NUMERIC + "=?"; 504 String[] selectionArgs = { insertNumeric }; 505 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 506 + "\ntestInsertCarriers selection: " + selection 507 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 508 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, 509 testProjection, selection, selectionArgs, null); 510 511 // verify that inserted values match results of query 512 assertNotNull(cursor); 513 assertEquals(1, cursor.getCount()); 514 cursor.moveToFirst(); 515 final String resultApn = cursor.getString(0); 516 final String resultName = cursor.getString(1); 517 final Integer resultOwnedBy = cursor.getInt(2); 518 assertEquals(insertApn, resultApn); 519 assertEquals(insertName, resultName); 520 // Verify that OWNED_BY is force set to OWNED_BY_OTHERS when inserted with general uri 521 assertEquals(insertOwnedBy, resultOwnedBy); 522 523 // delete test content 524 final String selectionToDelete = Carriers.NUMERIC + "=?"; 525 String[] selectionArgsToDelete = { insertNumeric }; 526 Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete 527 + "testInsertCarriers selectionArgs: " + selectionArgs); 528 int numRowsDeleted = mContentResolver.delete(Carriers.CONTENT_URI, 529 selectionToDelete, selectionArgsToDelete); 530 assertEquals(1, numRowsDeleted); 531 532 // verify that deleted values are gone 533 cursor = mContentResolver.query(Carriers.CONTENT_URI, 534 testProjection, selection, selectionArgs, null); 535 assertEquals(0, cursor.getCount()); 536 } 537 538 /** 539 * Test inserting, querying, and deleting values in carriers table. 540 * Verify that the inserted values match the result of the query and are deleted. 541 */ 542 @Test 543 @SmallTest testSimTable()544 public void testSimTable() { 545 // insert test contentValues 546 ContentValues contentValues = new ContentValues(); 547 final int insertSubId = 11; 548 final String insertDisplayName = "exampleDisplayName"; 549 final String insertCarrierName = "exampleCarrierName"; 550 final String insertIccId = "exampleIccId"; 551 final String insertCardId = "exampleCardId"; 552 final int insertProfileClass = SubscriptionManager.PROFILE_CLASS_DEFAULT; 553 contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId); 554 contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName); 555 contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName); 556 contentValues.put(SubscriptionManager.ICC_ID, insertIccId); 557 contentValues.put(SubscriptionManager.CARD_ID, insertCardId); 558 contentValues.put(SubscriptionManager.PROFILE_CLASS, insertProfileClass); 559 560 Log.d(TAG, "testSimTable Inserting contentValues: " + contentValues); 561 mContentResolver.insert(SimInfo.CONTENT_URI, contentValues); 562 563 // get values in table 564 final String[] testProjection = 565 { 566 SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, 567 SubscriptionManager.CARRIER_NAME, 568 SubscriptionManager.CARD_ID, 569 SubscriptionManager.PROFILE_CLASS, 570 }; 571 final String selection = SubscriptionManager.DISPLAY_NAME + "=?"; 572 String[] selectionArgs = { insertDisplayName }; 573 Log.d(TAG,"\ntestSimTable selection: " + selection 574 + "\ntestSimTable selectionArgs: " + selectionArgs.toString()); 575 Cursor cursor = mContentResolver.query(SimInfo.CONTENT_URI, 576 testProjection, selection, selectionArgs, null); 577 578 // verify that inserted values match results of query 579 assertNotNull(cursor); 580 assertEquals(1, cursor.getCount()); 581 cursor.moveToFirst(); 582 final int resultSubId = cursor.getInt(0); 583 final String resultCarrierName = cursor.getString(1); 584 final String resultCardId = cursor.getString(2); 585 final int resultProfileClass = cursor.getInt(3); 586 assertEquals(insertSubId, resultSubId); 587 assertEquals(insertCarrierName, resultCarrierName); 588 assertEquals(insertCardId, resultCardId); 589 assertEquals(insertProfileClass, resultProfileClass); 590 591 // delete test content 592 final String selectionToDelete = SubscriptionManager.DISPLAY_NAME + "=?"; 593 String[] selectionArgsToDelete = { insertDisplayName }; 594 Log.d(TAG, "testSimTable deleting selection: " + selectionToDelete 595 + "testSimTable selectionArgs: " + selectionArgs); 596 int numRowsDeleted = mContentResolver.delete(SimInfo.CONTENT_URI, 597 selectionToDelete, selectionArgsToDelete); 598 assertEquals(1, numRowsDeleted); 599 600 // verify that deleted values are gone 601 cursor = mContentResolver.query(SimInfo.CONTENT_URI, 602 testProjection, selection, selectionArgs, null); 603 assertEquals(0, cursor.getCount()); 604 } 605 parseIdFromInsertedUri(Uri uri)606 private int parseIdFromInsertedUri(Uri uri) throws NumberFormatException { 607 return (uri != null) ? Integer.parseInt(uri.getLastPathSegment()) : -1; 608 } 609 insertApnRecord(Uri uri, String apn, String name, int current, String numeric)610 private int insertApnRecord(Uri uri, String apn, String name, int current, String numeric) { 611 ContentValues contentValues = new ContentValues(); 612 contentValues.put(Carriers.APN, apn); 613 contentValues.put(Carriers.NAME, name); 614 contentValues.put(Carriers.CURRENT, current); 615 contentValues.put(Carriers.NUMERIC, numeric); 616 Uri resultUri = mContentResolver.insert(uri, contentValues); 617 return parseIdFromInsertedUri(resultUri); 618 } 619 620 /** 621 * Test URL_ENFORCE_MANAGED and URL_FILTERED works correctly. 622 * Verify that when enforce is set true via URL_ENFORCE_MANAGED, only DPC records are returned 623 * for URL_FILTERED and URL_FILTERED_ID. 624 * Verify that when enforce is set false via URL_ENFORCE_MANAGED, only non-DPC records 625 * are returned for URL_FILTERED and URL_FILTERED_ID. 626 */ 627 @Test 628 @SmallTest testEnforceManagedUri()629 public void testEnforceManagedUri() { 630 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 631 632 final int current = 1; 633 final String numeric = TEST_OPERATOR; 634 635 // Insert DPC record. 636 final String dpcRecordApn = "exampleApnNameDPC"; 637 final String dpcRecordName = "exampleNameDPC"; 638 final int dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 639 current, numeric); 640 641 // Insert non-DPC record. 642 final String othersRecordApn = "exampleApnNameOTHERS"; 643 final String othersRecordName = "exampleNameDPOTHERS"; 644 final int othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 645 current, numeric); 646 647 // Set enforced = false. 648 ContentValues enforceManagedValue = new ContentValues(); 649 enforceManagedValue.put(ENFORCED_KEY, false); 650 Log.d(TAG, "testEnforceManagedUri Updating enforced = false: " 651 + enforceManagedValue); 652 mContentResolver.update(URI_ENFORCE_MANAGED, enforceManagedValue, "", new String[]{}); 653 654 // Verify that enforced is set to false in TelephonyProvider. 655 Cursor enforceCursor = mContentResolver.query(URI_ENFORCE_MANAGED, 656 null, null, null, null); 657 assertNotNull(enforceCursor); 658 assertEquals(1, enforceCursor.getCount()); 659 enforceCursor.moveToFirst(); 660 assertEquals(0, enforceCursor.getInt(0)); 661 662 // Verify URL_FILTERED query only returns non-DPC record. 663 final String[] testProjection = 664 { 665 Carriers._ID, 666 Carriers.OWNED_BY 667 }; 668 final String selection = Carriers.NUMERIC + "=?"; 669 final String[] selectionArgs = { numeric }; 670 final Cursor cursorNotEnforced = mContentResolver.query(URI_FILTERED, 671 testProjection, selection, selectionArgs, null); 672 assertNotNull(cursorNotEnforced); 673 assertEquals(1, cursorNotEnforced.getCount()); 674 cursorNotEnforced.moveToFirst(); 675 assertEquals(othersRecordId, cursorNotEnforced.getInt(0)); 676 assertEquals(Carriers.OWNED_BY_OTHERS, cursorNotEnforced.getInt(1)); 677 678 // Verify that URL_FILTERED_ID cannot get DPC record. 679 Cursor cursorNotEnforcedDpc = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 680 Integer.toString(dpcRecordId)), null, null, null, null); 681 assertNotNull(cursorNotEnforcedDpc); 682 assertTrue(cursorNotEnforcedDpc.getCount() == 0); 683 // Verify that URL_FILTERED_ID can get non-DPC record. 684 Cursor cursorNotEnforcedOthers = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 685 Integer.toString(othersRecordId)), null, null, null, null); 686 assertNotNull(cursorNotEnforcedOthers); 687 assertTrue(cursorNotEnforcedOthers.getCount() == 1); 688 689 // Set enforced = true. 690 enforceManagedValue.put(ENFORCED_KEY, true); 691 Log.d(TAG, "testEnforceManagedUri Updating enforced = true: " 692 + enforceManagedValue); 693 mContentResolver.update(URI_ENFORCE_MANAGED, enforceManagedValue, "", new String[]{}); 694 695 // Verify that enforced is set to true in TelephonyProvider. 696 enforceCursor = mContentResolver.query(URI_ENFORCE_MANAGED, 697 null, null, null, null); 698 assertNotNull(enforceCursor); 699 assertEquals(1, enforceCursor.getCount()); 700 enforceCursor.moveToFirst(); 701 assertEquals(1, enforceCursor.getInt(0)); 702 703 // Verify URL_FILTERED query only returns DPC record. 704 final Cursor cursorEnforced = mContentResolver.query(URI_FILTERED, 705 testProjection, selection, selectionArgs, null); 706 assertNotNull(cursorEnforced); 707 assertEquals(1, cursorEnforced.getCount()); 708 cursorEnforced.moveToFirst(); 709 assertEquals(dpcRecordId, cursorEnforced.getInt(0)); 710 assertEquals(Carriers.OWNED_BY_DPC, cursorEnforced.getInt(1)); 711 712 // Verify that URL_FILTERED_ID can get DPC record. 713 cursorNotEnforcedDpc = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 714 Integer.toString(dpcRecordId)), null, null, null, null); 715 assertNotNull(cursorNotEnforcedDpc); 716 assertTrue(cursorNotEnforcedDpc.getCount() == 1); 717 // Verify that URL_FILTERED_ID cannot get non-DPC record. 718 cursorNotEnforcedOthers = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 719 Integer.toString(othersRecordId)), null, null, null, null); 720 assertNotNull(cursorNotEnforcedOthers); 721 assertTrue(cursorNotEnforcedOthers.getCount() == 0); 722 723 // Delete testing records. 724 int numRowsDeleted = mContentResolver.delete(URI_TELEPHONY, selection, selectionArgs); 725 assertEquals(1, numRowsDeleted); 726 727 numRowsDeleted = mContentResolver.delete( 728 ContentUris.withAppendedId(URI_DPC, dpcRecordId), "", null); 729 assertEquals(1, numRowsDeleted); 730 } 731 queryFullTestApnRecord(Uri uri, String numeric)732 private Cursor queryFullTestApnRecord(Uri uri, String numeric) { 733 final String selection = Carriers.NUMERIC + "=?"; 734 String[] selectionArgs = { numeric }; 735 final String[] testProjection = 736 { 737 Carriers._ID, 738 Carriers.APN, 739 Carriers.NAME, 740 Carriers.CURRENT, 741 Carriers.OWNED_BY, 742 }; 743 return mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 744 } 745 746 @Test 747 @SmallTest 748 /** 749 * Test URL_TELEPHONY cannot insert, query, update or delete DPC records. 750 */ testTelephonyUriDpcRecordAccessControl()751 public void testTelephonyUriDpcRecordAccessControl() { 752 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 753 754 final int current = 1; 755 final String numeric = TEST_OPERATOR; 756 final String selection = Carriers.NUMERIC + "=?"; 757 final String[] selectionArgs = { numeric }; 758 759 // Insert DPC record. 760 final String dpcRecordApn = "exampleApnNameDPC"; 761 final String dpcRecordName = "exampleNameDPC"; 762 final int dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 763 current, numeric); 764 765 // Insert non-DPC record. 766 final String othersRecordApn = "exampleApnNameOTHERS"; 767 final String othersRecordName = "exampleNameDPOTHERS"; 768 final int othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 769 current, numeric); 770 771 // Verify URL_TELEPHONY query only returns non-DPC record. 772 final Cursor cursorTelephony = queryFullTestApnRecord(URI_TELEPHONY, numeric); 773 assertNotNull(cursorTelephony); 774 assertEquals(1, cursorTelephony.getCount()); 775 cursorTelephony.moveToFirst(); 776 assertApnEquals(cursorTelephony, othersRecordId, othersRecordApn, othersRecordName, 777 current, Carriers.OWNED_BY_OTHERS); 778 779 // Verify URI_TELEPHONY updates only non-DPC records. 780 ContentValues contentValuesOthersUpdate = new ContentValues(); 781 final String othersRecordUpdatedApn = "exampleApnNameOTHERSUpdated"; 782 final String othersRecordUpdatedName = "exampleNameOTHERSpdated"; 783 contentValuesOthersUpdate.put(Carriers.APN, othersRecordUpdatedApn); 784 contentValuesOthersUpdate.put(Carriers.NAME, othersRecordUpdatedName); 785 786 final int updateCount = mContentResolver.update(URI_TELEPHONY, contentValuesOthersUpdate, 787 selection, selectionArgs); 788 assertEquals(1, updateCount); 789 final Cursor cursorNonDPCUpdate = queryFullTestApnRecord(URI_TELEPHONY, numeric); 790 final Cursor cursorDPCUpdate = queryFullTestApnRecord(URI_DPC, numeric); 791 792 // Verify that non-DPC records are updated. 793 assertNotNull(cursorNonDPCUpdate); 794 assertEquals(1, cursorNonDPCUpdate.getCount()); 795 cursorNonDPCUpdate.moveToFirst(); 796 assertApnEquals(cursorNonDPCUpdate, othersRecordId, othersRecordUpdatedApn, 797 othersRecordUpdatedName); 798 799 // Verify that DPC records are not updated. 800 assertNotNull(cursorDPCUpdate); 801 assertEquals(1, cursorDPCUpdate.getCount()); 802 cursorDPCUpdate.moveToFirst(); 803 assertApnEquals(cursorDPCUpdate, dpcRecordId, dpcRecordApn, dpcRecordName); 804 805 // Verify URI_TELEPHONY deletes only non-DPC records. 806 int numRowsDeleted = mContentResolver.delete(URI_TELEPHONY, selection, selectionArgs); 807 assertEquals(1, numRowsDeleted); 808 final Cursor cursorTelephonyRemaining = queryFullTestApnRecord(URI_TELEPHONY, numeric); 809 assertNotNull(cursorTelephonyRemaining); 810 assertEquals(0, cursorTelephonyRemaining.getCount()); 811 final Cursor cursorDPCDeleted = queryFullTestApnRecord(URI_DPC, numeric); 812 assertNotNull(cursorDPCDeleted); 813 assertEquals(1, cursorDPCDeleted.getCount()); 814 815 // Delete remaining test records. 816 numRowsDeleted = mContentResolver.delete( 817 ContentUris.withAppendedId(URI_DPC, dpcRecordId), "", null); 818 assertEquals(1, numRowsDeleted); 819 } 820 821 /** 822 * Test URL_DPC cannot insert or query non-DPC records. 823 * Test URL_DPC_ID cannot update or delete non-DPC records. 824 */ 825 @Test 826 @SmallTest testDpcUri()827 public void testDpcUri() { 828 int dpcRecordId = 0, othersRecordId = 0; 829 try { 830 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 831 832 final int current = 1; 833 final String numeric = TEST_OPERATOR; 834 835 // Insert DPC record. 836 final String dpcRecordApn = "exampleApnNameDPC"; 837 final String dpcRecordName = "exampleNameDPC"; 838 dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 839 current, numeric); 840 841 // Insert non-DPC record. 842 final String othersRecordApn = "exampleApnNameOTHERS"; 843 final String othersRecordName = "exampleNameDPOTHERS"; 844 othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 845 current, numeric); 846 847 Log.d(TAG, "testDPCIdUri Id for inserted DPC record: " + dpcRecordId); 848 Log.d(TAG, "testDPCIdUri Id for inserted non-DPC record: " + othersRecordId); 849 850 // Verify that URI_DPC query only returns DPC records. 851 final Cursor cursorDPC = queryFullTestApnRecord(URI_DPC, numeric); 852 assertNotNull(cursorDPC); 853 assertEquals(1, cursorDPC.getCount()); 854 cursorDPC.moveToFirst(); 855 assertApnEquals(cursorDPC, dpcRecordId, dpcRecordApn, dpcRecordName, current, 856 Carriers.OWNED_BY_DPC); 857 858 // Verify that URI_DPC_ID updates only DPC records. 859 ContentValues contentValuesDpcUpdate = new ContentValues(); 860 final String dpcRecordUpdatedApn = "exampleApnNameDPCUpdated"; 861 final String dpcRecordUpdatedName = "exampleNameDPCUpdated"; 862 contentValuesDpcUpdate.put(Carriers.APN, dpcRecordUpdatedApn); 863 contentValuesDpcUpdate.put(Carriers.NAME, dpcRecordUpdatedName); 864 final int updateCount = mContentResolver.update( 865 ContentUris.withAppendedId(URI_DPC, dpcRecordId), 866 contentValuesDpcUpdate, null, null); 867 assertEquals(1, updateCount); 868 final Cursor cursorNonDPCUpdate = queryFullTestApnRecord(URI_TELEPHONY, numeric); 869 final Cursor cursorDPCUpdate = queryFullTestApnRecord(URI_DPC, numeric); 870 871 // Verify that non-DPC records are not updated. 872 assertNotNull(cursorNonDPCUpdate); 873 assertEquals(1, cursorNonDPCUpdate.getCount()); 874 cursorNonDPCUpdate.moveToFirst(); 875 assertApnEquals(cursorNonDPCUpdate, othersRecordId, othersRecordApn, othersRecordName); 876 877 // Verify that DPC records are updated. 878 assertNotNull(cursorDPCUpdate); 879 assertEquals(1, cursorDPCUpdate.getCount()); 880 cursorDPCUpdate.moveToFirst(); 881 assertApnEquals(cursorDPCUpdate, dpcRecordId, dpcRecordUpdatedApn, 882 dpcRecordUpdatedName); 883 884 // Test URI_DPC_ID deletes only DPC records. 885 int numRowsDeleted = mContentResolver.delete( 886 ContentUris.withAppendedId(URI_DPC, dpcRecordId), null, null); 887 assertEquals(1, numRowsDeleted); 888 numRowsDeleted = mContentResolver.delete( 889 ContentUris.withAppendedId(URI_DPC, dpcRecordId), null, null); 890 assertEquals(0, numRowsDeleted); 891 892 } finally { 893 // Delete remaining test records. 894 int numRowsDeleted = mContentResolver.delete( 895 ContentUris.withAppendedId(URI_TELEPHONY, othersRecordId), null, null); 896 assertEquals(1, numRowsDeleted); 897 } 898 } 899 assertApnEquals(Cursor cursor, Object... values)900 private void assertApnEquals(Cursor cursor, Object... values) { 901 assertTrue(values.length <= cursor.getColumnCount()); 902 for (int i = 0; i < values.length; i ++) { 903 if (values[i] instanceof Integer) { 904 assertEquals(values[i], cursor.getInt(i)); 905 } else if (values[i] instanceof String) { 906 assertEquals(values[i], cursor.getString(i)); 907 } else { 908 fail("values input type not correct"); 909 } 910 } 911 } 912 913 /** 914 * Test URL_DPC does not change database on conflict for insert and update. 915 */ 916 @Test 917 @SmallTest testDpcUriOnConflict()918 public void testDpcUriOnConflict() { 919 int dpcRecordId1 = 0, dpcRecordId2 = 0; 920 try { 921 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 922 923 final int current = 1; 924 final String numeric = TEST_OPERATOR; 925 926 // Insert DPC record 1. 927 final String dpcRecordApn1 = "exampleApnNameDPC"; 928 final String dpcRecordName = "exampleNameDPC"; 929 dpcRecordId1 = insertApnRecord(URI_DPC, dpcRecordApn1, dpcRecordName, 930 current, numeric); 931 Log.d(TAG, "testDpcUriOnConflict Id for DPC record 1: " + dpcRecordId1); 932 933 // Insert conflicting DPC record. 934 final String dpcRecordNameConflict = "exampleNameDPCConflict"; 935 final int dpcRecordIdConflict = insertApnRecord(URI_DPC, dpcRecordApn1, 936 dpcRecordNameConflict, current, numeric); 937 938 // Verity that conflicting DPC record is not inserted. 939 assertEquals(-1, dpcRecordIdConflict); 940 // Verify that APN 1 is not replaced or updated. 941 Cursor cursorDPC1 = queryFullTestApnRecord(URI_DPC, numeric); 942 assertNotNull(cursorDPC1); 943 assertEquals(1, cursorDPC1.getCount()); 944 cursorDPC1.moveToFirst(); 945 assertApnEquals(cursorDPC1, dpcRecordId1, dpcRecordApn1, dpcRecordName, current, 946 Carriers.OWNED_BY_DPC); 947 948 // Insert DPC record 2. 949 final String dpcRecordApn2 = "exampleApnNameDPC2"; 950 dpcRecordId2 = insertApnRecord(URI_DPC, dpcRecordApn2, dpcRecordName, 951 current, numeric); 952 Log.d(TAG, "testDpcUriOnConflict Id for DPC record 2: " + dpcRecordId2); 953 954 // Update DPC record 2 to the values of DPC record 1. 955 ContentValues contentValuesDpcUpdate = new ContentValues(); 956 contentValuesDpcUpdate.put(Carriers.APN, dpcRecordApn1); 957 contentValuesDpcUpdate.put(Carriers.NAME, dpcRecordNameConflict); 958 final int updateCount = mContentResolver.update( 959 ContentUris.withAppendedId(URI_DPC, dpcRecordId2), 960 contentValuesDpcUpdate, null, null); 961 962 // Verify that database is not updated. 963 assertEquals(0, updateCount); 964 Cursor cursorDPC2 = queryFullTestApnRecord(URI_DPC, numeric); 965 assertNotNull(cursorDPC2); 966 assertEquals(2, cursorDPC2.getCount()); 967 cursorDPC2.moveToFirst(); 968 assertApnEquals(cursorDPC2, dpcRecordId1, dpcRecordApn1, dpcRecordName, current, 969 Carriers.OWNED_BY_DPC); 970 cursorDPC2.moveToNext(); 971 assertApnEquals(cursorDPC2, dpcRecordId2, dpcRecordApn2, dpcRecordName, current, 972 Carriers.OWNED_BY_DPC); 973 } finally { 974 // Delete test records. 975 int numRowsDeleted = mContentResolver.delete( 976 ContentUris.withAppendedId(URI_DPC, dpcRecordId1), null, null); 977 assertEquals(1, numRowsDeleted); 978 numRowsDeleted = mContentResolver.delete( 979 ContentUris.withAppendedId(URI_DPC, dpcRecordId2), null, null); 980 assertEquals(1, numRowsDeleted); 981 } 982 } 983 984 /** 985 * Verify that SecurityException is thrown if URL_DPC, URL_FILTERED and 986 * URL_ENFORCE_MANAGED is accessed from neither SYSTEM_UID nor PHONE_UID. 987 */ 988 @Test 989 @SmallTest testAccessUrlDpcThrowSecurityExceptionFromOtherUid()990 public void testAccessUrlDpcThrowSecurityExceptionFromOtherUid() { 991 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID + 123456); 992 993 // Test insert(). 994 ContentValues contentValuesDPC = new ContentValues(); 995 try { 996 mContentResolver.insert(URI_DPC, contentValuesDPC); 997 assertFalse("SecurityException should be thrown when URI_DPC is called from" 998 + " neither SYSTEM_UID nor PHONE_UID", true); 999 } catch (SecurityException e) { 1000 // Should catch SecurityException. 1001 } 1002 1003 // Test query(). 1004 try { 1005 mContentResolver.query(URI_DPC, 1006 new String[]{}, "", new String[]{}, null); 1007 assertFalse("SecurityException should be thrown when URI_DPC is called from" 1008 + " neither SYSTEM_UID nor PHONE_UID", true); 1009 } catch (SecurityException e) { 1010 // Should catch SecurityException. 1011 } 1012 try { 1013 mContentResolver.query(URI_ENFORCE_MANAGED, 1014 new String[]{}, "", new String[]{}, null); 1015 assertFalse("SecurityException should be thrown when URI_ENFORCE_MANAGED is " 1016 + "called from neither SYSTEM_UID nor PHONE_UID", true); 1017 } catch (SecurityException e) { 1018 // Should catch SecurityException. 1019 } 1020 1021 // Test update(). 1022 ContentValues contentValuesDPCUpdate = new ContentValues(); 1023 try { 1024 mContentResolver.update( 1025 Uri.parse(URI_DPC + "/1"), 1026 contentValuesDPCUpdate, "", new String[]{}); 1027 assertFalse("SecurityException should be thrown when URI_DPC is called" 1028 + " from neither SYSTEM_UID nor PHONE_UID", true); 1029 } catch (SecurityException e) { 1030 // Should catch SecurityException. 1031 } 1032 try { 1033 mContentResolver.update(URI_ENFORCE_MANAGED, contentValuesDPCUpdate, 1034 "", new String[]{}); 1035 assertFalse("SecurityException should be thrown when URI_DPC is called" 1036 + " from neither SYSTEM_UID nor PHONE_UID", true); 1037 } catch (SecurityException e) { 1038 // Should catch SecurityException. 1039 } 1040 1041 // Test delete(). 1042 try { 1043 mContentResolver.delete( 1044 Uri.parse(URI_DPC + "/0"), "", new String[]{}); 1045 assertFalse("SecurityException should be thrown when URI_DPC is called" 1046 + " from neither SYSTEM_UID nor PHONE_UID", true); 1047 } catch (SecurityException e) { 1048 // Should catch SecurityException. 1049 } 1050 } 1051 1052 /** 1053 * Verify that user/carrier edited/deleted APNs have priority in the EDITED field over 1054 * insertions which set EDITED=UNEDITED. In these cases instead of merging the APNs using the 1055 * new APN's value we keep the old value. 1056 */ 1057 @Test 1058 @SmallTest testPreserveEdited()1059 public void testPreserveEdited() { 1060 preserveEditedValueInMerge(Carriers.USER_EDITED); 1061 } 1062 1063 @Test 1064 @SmallTest testPreserveUserDeleted()1065 public void testPreserveUserDeleted() { 1066 preserveDeletedValueInMerge(Carriers.USER_DELETED); 1067 } 1068 1069 @Test 1070 @SmallTest testPreserveUserDeletedButPresentInXml()1071 public void testPreserveUserDeletedButPresentInXml() { 1072 preserveDeletedValueInMerge(Carriers.USER_DELETED_BUT_PRESENT_IN_XML); 1073 } 1074 1075 @Test 1076 @SmallTest testPreserveCarrierEdited()1077 public void testPreserveCarrierEdited() { 1078 preserveEditedValueInMerge(Carriers.CARRIER_EDITED); 1079 } 1080 1081 @Test 1082 @SmallTest testPreserveCarrierDeleted()1083 public void testPreserveCarrierDeleted() { 1084 preserveDeletedValueInMerge(Carriers.CARRIER_DELETED); 1085 } 1086 1087 @Test 1088 @SmallTest testPreserveCarrierDeletedButPresentInXml()1089 public void testPreserveCarrierDeletedButPresentInXml() { 1090 preserveDeletedValueInMerge(Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML); 1091 } 1092 preserveEditedValueInMerge(int value)1093 private void preserveEditedValueInMerge(int value) { 1094 // insert user deleted APN 1095 String carrierName1 = "carrier1"; 1096 String numeric1 = "123234"; 1097 String mcc1 = "123"; 1098 String mnc1 = "234"; 1099 ContentValues editedValue = new ContentValues(); 1100 editedValue.put(Carriers.NAME, carrierName1); 1101 editedValue.put(Carriers.NUMERIC, numeric1); 1102 editedValue.put(Carriers.MCC, mcc1); 1103 editedValue.put(Carriers.MNC, mnc1); 1104 editedValue.put(Carriers.EDITED_STATUS, value); 1105 assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue)); 1106 1107 Cursor cur = mContentResolver.query(URI_TELEPHONY, null, null, null, null); 1108 assertEquals(1, cur.getCount()); 1109 1110 // insert APN that conflicts with edited APN 1111 String carrierName2 = "carrier2"; 1112 ContentValues values = new ContentValues(); 1113 values.put(Carriers.NAME, carrierName2); 1114 values.put(Carriers.NUMERIC, numeric1); 1115 values.put(Carriers.MCC, mcc1); 1116 values.put(Carriers.MNC, mnc1); 1117 values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 1118 mContentResolver.insert(URI_TELEPHONY, values); 1119 1120 String[] testProjection = { 1121 Carriers.NAME, 1122 Carriers.APN, 1123 Carriers.EDITED_STATUS, 1124 Carriers.TYPE, 1125 Carriers.PROTOCOL, 1126 Carriers.BEARER_BITMASK, 1127 }; 1128 final int indexOfName = 0; 1129 final int indexOfEdited = 2; 1130 1131 // Assert that the conflicting APN is merged into the existing user-edited APN, so only 1 1132 // APN exists in the db 1133 cur = mContentResolver.query(URI_TELEPHONY, testProjection, null, null, null); 1134 assertEquals(1, cur.getCount()); 1135 cur.moveToFirst(); 1136 assertEquals(carrierName2, cur.getString(indexOfName)); 1137 assertEquals(value, cur.getInt(indexOfEdited)); 1138 } 1139 preserveDeletedValueInMerge(int value)1140 private void preserveDeletedValueInMerge(int value) { 1141 // insert user deleted APN 1142 String carrierName1 = "carrier1"; 1143 String numeric1 = "123234"; 1144 String mcc1 = "123"; 1145 String mnc1 = "234"; 1146 ContentValues editedValue = new ContentValues(); 1147 editedValue.put(Carriers.NAME, carrierName1); 1148 editedValue.put(Carriers.NUMERIC, numeric1); 1149 editedValue.put(Carriers.MCC, mcc1); 1150 editedValue.put(Carriers.MNC, mnc1); 1151 editedValue.put(Carriers.EDITED_STATUS, value); 1152 assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue)); 1153 1154 // insert APN that conflicts with edited APN 1155 String carrierName2 = "carrier2"; 1156 ContentValues values = new ContentValues(); 1157 values.put(Carriers.NAME, carrierName2); 1158 values.put(Carriers.NUMERIC, numeric1); 1159 values.put(Carriers.MCC, mcc1); 1160 values.put(Carriers.MNC, mnc1); 1161 values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 1162 mContentResolver.insert(URI_TELEPHONY, values); 1163 1164 String[] testProjection = { 1165 Carriers.NAME, 1166 Carriers.APN, 1167 Carriers.EDITED_STATUS, 1168 Carriers.TYPE, 1169 Carriers.PROTOCOL, 1170 Carriers.BEARER_BITMASK, 1171 }; 1172 final int indexOfEdited = 2; 1173 1174 // Assert that the conflicting APN is merged into the existing user-deleted APN. 1175 // Entries marked deleted will not show up in queries so we verify that no APNs can 1176 // be seen 1177 Cursor cur = mContentResolver.query(URI_TELEPHONY, testProjection, null, null, null); 1178 assertEquals(0, cur.getCount()); 1179 } 1180 1181 /** 1182 * Test URL_PREFERAPN_USING_SUBID works correctly. 1183 */ 1184 @Test 1185 @SmallTest testQueryPreferredApn()1186 public void testQueryPreferredApn() { 1187 // create APNs 1188 ContentValues preferredValues = new ContentValues(); 1189 final String preferredApn = "preferredApn"; 1190 final String preferredName = "preferredName"; 1191 preferredValues.put(Carriers.APN, preferredApn); 1192 preferredValues.put(Carriers.NAME, preferredName); 1193 preferredValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1194 ContentValues otherValues = new ContentValues(); 1195 final String otherApn = "otherApnName"; 1196 final String otherName = "otherName"; 1197 otherValues.put(Carriers.APN, otherApn); 1198 otherValues.put(Carriers.NAME, otherName); 1199 otherValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1200 1201 // insert APNs 1202 // TODO if using URL_TELEPHONY, SubscriptionManager.getDefaultSubscriptionId() returns -1 1203 Log.d(TAG, "testQueryPreferredApn: Bulk inserting contentValues=" + preferredValues + ", " 1204 + otherValues); 1205 Uri uri = mContentResolver.insert(CONTENT_URI_WITH_SUBID, preferredValues); 1206 mContentResolver.insert(CONTENT_URI_WITH_SUBID, otherValues); 1207 final String preferredApnIdString = uri.getLastPathSegment(); 1208 final long preferredApnId = Long.parseLong(preferredApnIdString); 1209 Log.d(TAG, "testQueryPreferredApn: preferredApnString=" + preferredApnIdString); 1210 1211 // set preferred apn 1212 preferredValues.put(COLUMN_APN_ID, preferredApnIdString); 1213 mContentResolver.insert(URL_PREFERAPN_USING_SUBID, preferredValues); 1214 1215 // query preferred APN 1216 final String[] testProjection = { Carriers.APN, Carriers.NAME }; 1217 Cursor cursor = mContentResolver.query( 1218 URL_PREFERAPN_USING_SUBID, testProjection, null, null, null); 1219 1220 // verify that preferred apn was set and retreived 1221 assertEquals(1, cursor.getCount()); 1222 cursor.moveToFirst(); 1223 assertEquals(preferredApn, cursor.getString(0)); 1224 assertEquals(preferredName, cursor.getString(1)); 1225 } 1226 1227 /** 1228 * Test that APN_SET_ID works correctly. 1229 */ 1230 @Test 1231 @SmallTest testApnSetId()1232 public void testApnSetId() { 1233 // create APNs 1234 ContentValues values1 = new ContentValues(); 1235 final String apn = "apnName"; 1236 final String apnName = "name"; 1237 values1.put(Carriers.APN, apn); 1238 values1.put(Carriers.NAME, apnName); 1239 values1.put(Carriers.NUMERIC, TEST_OPERATOR); 1240 1241 ContentValues values2 = new ContentValues(); 1242 final String otherApn = "otherApnName"; 1243 final String otherName = "otherName"; 1244 values2.put(Carriers.APN, otherApn); 1245 values2.put(Carriers.NAME, otherName); 1246 values2.put(Carriers.NUMERIC, TEST_OPERATOR); 1247 values2.put(Carriers.APN_SET_ID, 1); 1248 1249 // insert APNs 1250 // TODO if using URL_TELEPHONY, SubscriptionManager.getDefaultSubscriptionId() returns -1 1251 Log.d(TAG, "testApnSetId: inserting contentValues=" + values1 + ", " + values2); 1252 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values1); 1253 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values2); 1254 1255 // query APN with default APN_SET_ID 1256 final String[] testProjection = { Carriers.NAME }; 1257 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, 1258 Carriers.APN_SET_ID + "=?", new String[] { "0" }, null); 1259 assertEquals(1, cursor.getCount()); 1260 cursor.moveToFirst(); 1261 assertEquals(apnName, cursor.getString(0)); 1262 1263 // query APN with APN_SET_ID=1 1264 cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, 1265 Carriers.APN_SET_ID + "=?", new String[] { "1" }, null); 1266 assertEquals(1, cursor.getCount()); 1267 cursor.moveToFirst(); 1268 assertEquals(otherName, cursor.getString(0)); 1269 } 1270 1271 /** 1272 * Test that querying with the PREFERAPNSET url yields all APNs in the preferred set. 1273 */ 1274 @Test 1275 @SmallTest testPreferApnSetUrl()1276 public void testPreferApnSetUrl() { 1277 // create APNs 1278 ContentValues values1 = new ContentValues(); 1279 final String apn = "apnName"; 1280 final String apnName = "name"; 1281 values1.put(Carriers.APN, apn); 1282 values1.put(Carriers.NAME, apnName); 1283 values1.put(Carriers.NUMERIC, TEST_OPERATOR); 1284 1285 ContentValues values2 = new ContentValues(); 1286 final String apn2 = "otherApnName"; 1287 final String name2 = "name2"; 1288 values2.put(Carriers.APN, apn2); 1289 values2.put(Carriers.NAME, name2); 1290 values2.put(Carriers.NUMERIC, TEST_OPERATOR); 1291 values2.put(Carriers.APN_SET_ID, 1); 1292 1293 ContentValues values3 = new ContentValues(); 1294 final String apn3 = "thirdApnName"; 1295 final String name3 = "name3"; 1296 values3.put(Carriers.APN, apn3); 1297 values3.put(Carriers.NAME, name3); 1298 values3.put(Carriers.NUMERIC, TEST_OPERATOR); 1299 values3.put(Carriers.APN_SET_ID, 1); 1300 1301 // insert APNs 1302 // we explicitly include subid, as SubscriptionManager.getDefaultSubscriptionId() returns -1 1303 Log.d(TAG, "testPreferApnSetUrl: inserting contentValues=" + values1 + ", " + values2 1304 + ", " + values3); 1305 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values1); 1306 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values2); 1307 Uri uri = mContentResolver.insert(CONTENT_URI_WITH_SUBID, values3); 1308 1309 // before there's a preferred APN set, assert that all APNs are returned 1310 final String[] testProjection = { Carriers.NAME }; 1311 Cursor cursor = mContentResolver.query( 1312 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID), 1313 testProjection, null, null, null); 1314 assertEquals(3, cursor.getCount()); 1315 1316 // set the APN from values3 (apn_set_id = 1) to the preferred APN 1317 final String preferredApnIdString = uri.getLastPathSegment(); 1318 final long preferredApnId = Long.parseLong(preferredApnIdString); 1319 ContentValues prefer = new ContentValues(); 1320 prefer.put("apn_id", preferredApnId); 1321 int count = mContentResolver.update(URL_PREFERAPN_USING_SUBID, prefer, null, null); 1322 assertEquals(1, count); 1323 1324 // query APN with PREFERAPNSET url 1325 // explicitly include SUB_ID, as SubscriptionManager.getDefaultSubscriptionId() returns -1 1326 cursor = mContentResolver.query( 1327 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID), 1328 testProjection, null, null, null); 1329 assertEquals(2, cursor.getCount()); 1330 cursor.moveToFirst(); 1331 assertEquals(name2, cursor.getString(0)); 1332 cursor.moveToNext(); 1333 assertEquals(name3, cursor.getString(0)); 1334 } 1335 1336 /** 1337 * Test URL_RESTOREAPN_USING_SUBID works correctly. 1338 */ 1339 @Test 1340 @SmallTest testRestoreDefaultApn()1341 public void testRestoreDefaultApn() { 1342 // setup for multi-SIM 1343 TelephonyManager telephonyManager = 1344 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1345 doReturn(2).when(telephonyManager).getPhoneCount(); 1346 1347 // create APN to be deleted (including MVNO values) 1348 ContentValues targetValues = new ContentValues(); 1349 targetValues.put(Carriers.APN, "apnName"); 1350 targetValues.put(Carriers.NAME, "name"); 1351 targetValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1352 targetValues.put(Carriers.MVNO_TYPE, "spn"); 1353 targetValues.put(Carriers.MVNO_MATCH_DATA, TelephonyProviderTestable.TEST_SPN); 1354 // create other operator APN (sama MCCMNC) 1355 ContentValues otherValues = new ContentValues(); 1356 final String otherApn = "otherApnName"; 1357 final String otherName = "otherName"; 1358 final String otherMvnoTyp = "spn"; 1359 final String otherMvnoMatchData = "testOtherOperator"; 1360 otherValues.put(Carriers.APN, otherApn); 1361 otherValues.put(Carriers.NAME, otherName); 1362 otherValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1363 otherValues.put(Carriers.MVNO_TYPE, otherMvnoTyp); 1364 otherValues.put(Carriers.MVNO_MATCH_DATA, otherMvnoMatchData); 1365 1366 doReturn(true).when(telephonyManager).matchesCurrentSimOperator( 1367 anyString(), anyInt(), eq(TelephonyProviderTestable.TEST_SPN)); 1368 doReturn(false).when(telephonyManager).matchesCurrentSimOperator( 1369 anyString(), anyInt(), eq(otherMvnoMatchData)); 1370 1371 // insert APNs 1372 Log.d(TAG, "testRestoreDefaultApn: Bulk inserting contentValues=" + targetValues + ", " 1373 + otherValues); 1374 ContentValues[] values = new ContentValues[]{ targetValues, otherValues }; 1375 mContentResolver.bulkInsert(Carriers.CONTENT_URI, values); 1376 1377 // restore to default 1378 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1379 1380 // get values in table 1381 final String[] testProjection = 1382 { 1383 Carriers.APN, 1384 Carriers.NAME, 1385 Carriers.MVNO_TYPE, 1386 Carriers.MVNO_MATCH_DATA, 1387 }; 1388 // verify that deleted result match results of query 1389 Cursor cursor = mContentResolver.query( 1390 Carriers.CONTENT_URI, testProjection, null, null, null); 1391 assertEquals(1, cursor.getCount()); 1392 cursor.moveToFirst(); 1393 assertEquals(otherApn, cursor.getString(0)); 1394 assertEquals(otherName, cursor.getString(1)); 1395 assertEquals(otherMvnoTyp, cursor.getString(2)); 1396 assertEquals(otherMvnoMatchData, cursor.getString(3)); 1397 1398 // create APN to be deleted (not include MVNO values) 1399 ContentValues targetValues2 = new ContentValues(); 1400 targetValues2.put(Carriers.APN, "apnName"); 1401 targetValues2.put(Carriers.NAME, "name"); 1402 targetValues2.put(Carriers.NUMERIC, TEST_OPERATOR); 1403 1404 // insert APN 1405 mContentResolver.insert(Carriers.CONTENT_URI, targetValues2); 1406 1407 // restore to default 1408 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1409 1410 // verify that deleted result match results of query 1411 cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, null, null, null); 1412 assertEquals(1, cursor.getCount()); 1413 cursor.moveToFirst(); 1414 assertEquals(otherApn, cursor.getString(0)); 1415 assertEquals(otherName, cursor.getString(1)); 1416 assertEquals(otherMvnoTyp, cursor.getString(2)); 1417 assertEquals(otherMvnoMatchData, cursor.getString(3)); 1418 1419 // setup for single-SIM 1420 doReturn(1).when(telephonyManager).getPhoneCount(); 1421 1422 // restore to default 1423 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1424 1425 // verify that deleted values are gone 1426 cursor = mContentResolver.query( 1427 Carriers.CONTENT_URI, testProjection, null, null, null); 1428 assertEquals(0, cursor.getCount()); 1429 assertEquals(3, notifyChangeRestoreCount); 1430 } 1431 1432 /** 1433 * Test changes to siminfo/WFC_IMS_ENABLED and simInfo/ENHANCED_4G 1434 */ 1435 @Test 1436 @SmallTest testUpdateWfcEnabled()1437 public void testUpdateWfcEnabled() { 1438 // insert test contentValues 1439 ContentValues contentValues = new ContentValues(); 1440 final int insertSubId = 1; 1441 final String insertDisplayName = "exampleDisplayName"; 1442 final String insertCarrierName = "exampleCarrierName"; 1443 final String insertIccId = "exampleIccId"; 1444 final String insertCardId = "exampleCardId"; 1445 contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId); 1446 contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName); 1447 contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName); 1448 contentValues.put(SubscriptionManager.ICC_ID, insertIccId); 1449 contentValues.put(SubscriptionManager.CARD_ID, insertCardId); 1450 1451 Log.d(TAG, "testSimTable Inserting wfc contentValues: " + contentValues); 1452 mContentResolver.insert(SimInfo.CONTENT_URI, contentValues); 1453 assertEquals(0, notifyWfcCount); 1454 1455 // update wfc_enabled 1456 ContentValues values = new ContentValues(); 1457 values.put(Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, true); 1458 final String selection = SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?"; 1459 final String[] selectionArgs = { "" + insertSubId }; 1460 mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs); 1461 assertEquals(1, notifyWfcCount); 1462 assertEquals(0, notifyWfcCountWithTestSubId); 1463 1464 // update other fields 1465 values = new ContentValues(); 1466 values.put(SubscriptionManager.DISPLAY_NAME, "exampleDisplayNameNew"); 1467 mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs); 1468 // expect no change on wfc count 1469 assertEquals(1, notifyWfcCount); 1470 assertEquals(0, notifyWfcCountWithTestSubId); 1471 1472 // update WFC using subId 1473 values = new ContentValues(); 1474 values.put(Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, false); 1475 mContentResolver.update(SubscriptionManager.getUriForSubscriptionId(insertSubId), 1476 values, null, null); 1477 assertEquals(1, notifyWfcCount); 1478 assertEquals(0, notifyWfcCountWithTestSubId); 1479 } 1480 1481 @Test 1482 @SmallTest testSIMAPNLIST_MatchTheMVNOAPN()1483 public void testSIMAPNLIST_MatchTheMVNOAPN() { 1484 // Test on getSubscriptionMatchingAPNList() step 1 1485 final String apnName = "apnName"; 1486 final String carrierName = "name"; 1487 final String numeric = TEST_OPERATOR; 1488 final String mvnoType = "spn"; 1489 final String mvnoData = TEST_SPN; 1490 1491 // Insert the MVNO APN 1492 ContentValues contentValues = new ContentValues(); 1493 contentValues.put(Carriers.APN, apnName); 1494 contentValues.put(Carriers.NAME, carrierName); 1495 contentValues.put(Carriers.NUMERIC, numeric); 1496 contentValues.put(Carriers.MVNO_TYPE, mvnoType); 1497 contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData); 1498 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1499 1500 // Insert the MNO APN 1501 contentValues = new ContentValues(); 1502 contentValues.put(Carriers.APN, apnName); 1503 contentValues.put(Carriers.NAME, carrierName); 1504 contentValues.put(Carriers.NUMERIC, numeric); 1505 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1506 1507 TelephonyManager telephonyManager = 1508 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1509 doReturn(true).when(telephonyManager).matchesCurrentSimOperator( 1510 anyString(), anyInt(), eq(mvnoData)); 1511 doReturn(false).when(telephonyManager).matchesCurrentSimOperator( 1512 anyString(), anyInt(), eq("")); 1513 1514 // Query DB 1515 final String[] testProjection = 1516 { 1517 Carriers.APN, 1518 Carriers.NAME, 1519 Carriers.NUMERIC, 1520 Carriers.MVNO_MATCH_DATA 1521 }; 1522 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 1523 testProjection, null, null, null); 1524 1525 // When the DB has MVNO and MNO APN, the query based on SIM_APN_LIST will return MVNO APN 1526 cursor.moveToFirst(); 1527 assertEquals(cursor.getCount(), 1); 1528 assertEquals(apnName, cursor.getString(0)); 1529 assertEquals(carrierName, cursor.getString(1)); 1530 assertEquals(numeric, cursor.getString(2)); 1531 assertEquals(mvnoData, cursor.getString(3)); 1532 } 1533 1534 @Test 1535 @SmallTest testSIMAPNLIST_MatchTheMNOAPN()1536 public void testSIMAPNLIST_MatchTheMNOAPN() { 1537 // Test on getSubscriptionMatchingAPNList() step 2 1538 final String apnName = "apnName"; 1539 final String carrierName = "name"; 1540 final String numeric = TEST_OPERATOR; 1541 1542 // Insert the MNO APN 1543 ContentValues contentValues = new ContentValues(); 1544 contentValues.put(Carriers.APN, apnName); 1545 contentValues.put(Carriers.NAME, carrierName); 1546 contentValues.put(Carriers.NUMERIC, numeric); 1547 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1548 1549 // Query DB 1550 final String[] testProjection = 1551 { 1552 Carriers.APN, 1553 Carriers.NAME, 1554 Carriers.NUMERIC, 1555 }; 1556 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 1557 testProjection, null, null, null); 1558 1559 cursor.moveToFirst(); 1560 assertEquals(apnName, cursor.getString(0)); 1561 assertEquals(carrierName, cursor.getString(1)); 1562 assertEquals(numeric, cursor.getString(2)); 1563 } 1564 1565 @Test 1566 @SmallTest testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN()1567 public void testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN() { 1568 // Test on getSubscriptionMatchingAPNList() will return the {MCCMNC} 1569 final String apnName = "apnName"; 1570 final String carrierName = "name"; 1571 final int carrierId = TEST_CARRIERID; 1572 1573 // Add the APN that only have carrier id 1574 ContentValues contentValues = new ContentValues(); 1575 contentValues.put(Carriers.APN, apnName); 1576 contentValues.put(Carriers.NAME, carrierName); 1577 contentValues.put(Carriers.CARRIER_ID, carrierId); 1578 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1579 1580 // Add MNO APN that added by user 1581 contentValues = new ContentValues(); 1582 contentValues.put(Carriers.APN, apnName); 1583 contentValues.put(Carriers.NAME, carrierName); 1584 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1585 contentValues.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 1586 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1587 1588 // Query DB 1589 final String[] testProjection = 1590 { 1591 Carriers.APN, 1592 Carriers.NAME, 1593 Carriers.CARRIER_ID, 1594 }; 1595 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null); 1596 1597 // The query based on SIM_APN_LIST will return MNO APN and the APN that has carrier id 1598 assertEquals(cursor.getCount(), 2); 1599 } 1600 1601 @Test 1602 @SmallTest testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN()1603 public void testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN() { 1604 final String apnName = "apnName"; 1605 final String carrierName = "name"; 1606 final String mvnoType = "spn"; 1607 final String mvnoData = TEST_SPN; 1608 final int carrierId = TEST_CARRIERID; 1609 1610 // Add the APN that only have carrier id 1611 ContentValues contentValues = new ContentValues(); 1612 contentValues.put(Carriers.APN, apnName); 1613 contentValues.put(Carriers.NAME, carrierName); 1614 contentValues.put(Carriers.CARRIER_ID, carrierId); 1615 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1616 1617 // Add MVNO APN that added by user 1618 contentValues = new ContentValues(); 1619 contentValues.put(Carriers.APN, apnName); 1620 contentValues.put(Carriers.NAME, carrierName); 1621 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1622 contentValues.put(Carriers.MVNO_TYPE, mvnoType); 1623 contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData); 1624 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1625 1626 // Add MNO APN that added by user 1627 contentValues = new ContentValues(); 1628 contentValues.put(Carriers.APN, apnName); 1629 contentValues.put(Carriers.NAME, carrierName); 1630 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1631 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1632 1633 // Query DB 1634 final String[] testProjection = 1635 { 1636 Carriers.APN, 1637 Carriers.NAME, 1638 Carriers.CARRIER_ID, 1639 Carriers.MVNO_TYPE, 1640 }; 1641 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 1642 testProjection, null, null, null); 1643 1644 // The query based on SIM_APN_LIST will return MVNO APN and the APN that has carrier id 1645 assertEquals(cursor.getCount(), 2); 1646 while(cursor.moveToNext()) { 1647 assertTrue(!TextUtils.isEmpty(cursor.getString(2)) 1648 || !TextUtils.isEmpty(cursor.getString(3))); 1649 } 1650 } 1651 } 1652