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.Environment; 38 import android.os.Bundle; 39 import android.os.PersistableBundle; 40 import android.os.Process; 41 import android.provider.Telephony; 42 import android.provider.Telephony.Carriers; 43 import android.provider.Telephony.SimInfo; 44 import android.telephony.SubscriptionManager; 45 import android.telephony.TelephonyManager; 46 import android.test.mock.MockContentResolver; 47 import android.test.mock.MockContext; 48 import android.test.suitebuilder.annotation.SmallTest; 49 import android.text.TextUtils; 50 import android.util.Log; 51 52 import androidx.test.InstrumentationRegistry; 53 54 import junit.framework.TestCase; 55 56 import org.junit.Ignore; 57 import org.junit.Test; 58 import org.mockito.MockitoAnnotations; 59 import org.mockito.Mock; 60 import static org.mockito.Mockito.when; 61 62 import com.android.internal.telephony.PhoneFactory; 63 64 import java.io.File; 65 import java.io.FileInputStream; 66 import java.io.IOException; 67 import java.util.Arrays; 68 import java.util.List; 69 import java.util.stream.IntStream; 70 71 /** 72 * Tests for testing CRUD operations of TelephonyProvider. 73 * Uses a MockContentResolver to get permission WRITE_APN_SETTINGS in order to test insert/delete 74 * Uses TelephonyProviderTestable to set up in-memory database 75 * 76 * Build, install and run the tests by running the commands below: 77 * runtest --path <dir or file> 78 * runtest --path <dir or file> --test-method <testMethodName> 79 * e.g.) 80 * runtest --path tests/src/com/android/providers/telephony/TelephonyProviderTest.java \ 81 * --test-method testInsertCarriers 82 */ 83 public class TelephonyProviderTest extends TestCase { 84 private static final String TAG = "TelephonyProviderTest"; 85 86 private MockContextWithProvider mContext; 87 private MockContentResolver mContentResolver; 88 private TelephonyProviderTestable mTelephonyProviderTestable; 89 @Mock 90 private Resources mockContextResources; 91 92 private int notifyChangeCount; 93 private int notifyChangeRestoreCount; 94 private int notifyWfcCount; 95 private int notifyWfcCountWithTestSubId; 96 97 private static final String TEST_SUBID = "1"; 98 private static final String TEST_OPERATOR = "123456"; 99 private static final String TEST_MCC = "123"; 100 private static final String TEST_MNC = "456"; 101 private static final String TEST_SPN = TelephonyProviderTestable.TEST_SPN; 102 private static final int TEST_CARRIERID = 1; 103 104 // Used to test the path for URL_TELEPHONY_USING_SUBID with subid 1 105 private static final Uri CONTENT_URI_WITH_SUBID = Uri.parse( 106 "content://telephony/carriers/subId/" + TEST_SUBID); 107 108 // Used to test the "restore to default" 109 private static final Uri URL_RESTOREAPN_USING_SUBID = Uri.parse( 110 "content://telephony/carriers/restore/subId/" + TEST_SUBID); 111 // Used to test the preferred apn 112 private static final Uri URL_PREFERAPN_USING_SUBID = Uri.parse( 113 "content://telephony/carriers/preferapn/subId/" + TEST_SUBID); 114 private static final Uri URL_WFC_ENABLED_USING_SUBID = Uri.parse( 115 "content://telephony/siminfo/" + TEST_SUBID); 116 private static final Uri URL_SIM_APN_LIST = Uri.parse( 117 "content://telephony/carriers/sim_apn_list"); 118 119 private static final String COLUMN_APN_ID = "apn_id"; 120 121 // Constants for DPC related tests. 122 private static final Uri URI_DPC = Uri.parse("content://telephony/carriers/dpc"); 123 private static final Uri URI_TELEPHONY = Carriers.CONTENT_URI; 124 private static final Uri URI_FILTERED = Uri.parse("content://telephony/carriers/filtered"); 125 private static final Uri URI_ENFORCE_MANAGED= Uri.parse("content://telephony/carriers/enforce_managed"); 126 private static final String ENFORCED_KEY = "enforced"; 127 128 129 private static final String MATCHING_ICCID = "MATCHING_ICCID"; 130 private static final String MATCHING_PHONE_NUMBER = "MATCHING_PHONE_NUMBER"; 131 private static final int MATCHING_CARRIER_ID = 123456789; 132 133 // Represents an entry in the SimInfoDb 134 private static final ContentValues TEST_SIM_INFO_VALUES_US; 135 private static final ContentValues TEST_SIM_INFO_VALUES_FR; 136 private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE = 999999; 137 private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE 138 = "ARBITRARY_TEST_STRING_VALUE"; 139 140 private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID; 141 private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1 = 111111; 142 private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1 143 = "ARBITRARY_TEST_STRING_VALUE_1"; 144 145 private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID; 146 private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2 = 222222; 147 private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2 148 = "ARBITRARY_TEST_STRING_VALUE_2"; 149 150 private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID; 151 private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3 = 333333; 152 private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3 153 = "ARBITRARY_TEST_STRING_VALUE_3"; 154 155 static { 156 TEST_SIM_INFO_VALUES_US = populateContentValues( 157 MATCHING_ICCID, 158 MATCHING_PHONE_NUMBER, 159 MATCHING_CARRIER_ID, 160 "us", 161 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 162 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE); 163 164 TEST_SIM_INFO_VALUES_FR = populateContentValues( 165 MATCHING_ICCID, 166 MATCHING_PHONE_NUMBER, 167 MATCHING_CARRIER_ID, 168 "fr", 169 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 170 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE); 171 172 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID = populateContentValues( 173 MATCHING_ICCID, 174 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1, 175 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 176 null, 177 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 178 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1); 179 180 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID = populateContentValues( 181 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2, 182 MATCHING_PHONE_NUMBER, 183 MATCHING_CARRIER_ID, 184 null, 185 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 186 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2); 187 188 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID = populateContentValues( 189 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3, 190 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3, 191 MATCHING_CARRIER_ID, 192 null, 193 ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3, 194 ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3); 195 } 196 populateContentValues( String iccId, String phoneNumber, int carrierId, String isoCountryCode, int arbitraryIntVal, String arbitraryStringVal)197 private static ContentValues populateContentValues( 198 String iccId, String phoneNumber, int carrierId, String isoCountryCode, 199 int arbitraryIntVal, String arbitraryStringVal) { 200 ContentValues contentValues = new ContentValues(); 201 202 contentValues.put(Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID, arbitraryIntVal); 203 contentValues.put(Telephony.SimInfo.COLUMN_ICC_ID, iccId); 204 contentValues.put(Telephony.SimInfo.COLUMN_NUMBER, phoneNumber); 205 contentValues.put(Telephony.SimInfo.COLUMN_CARD_ID, arbitraryStringVal); 206 contentValues.put(Telephony.SimInfo.COLUMN_CARRIER_ID, carrierId); 207 contentValues.put(Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED, arbitraryIntVal); 208 contentValues.put(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED, arbitraryIntVal); 209 contentValues.put(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED, arbitraryIntVal); 210 contentValues.put(Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, arbitraryIntVal); 211 contentValues.put(Telephony.SimInfo.COLUMN_WFC_IMS_MODE, arbitraryIntVal); 212 contentValues.put(Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE, arbitraryIntVal); 213 contentValues.put(Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING, arbitraryIntVal); 214 contentValues.put(Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS, 215 arbitraryStringVal); 216 if (isoCountryCode != null) { 217 contentValues.put(Telephony.SimInfo.COLUMN_ISO_COUNTRY_CODE, isoCountryCode); 218 } 219 220 return contentValues; 221 } 222 223 /** 224 * This is used to give the TelephonyProviderTest a mocked context which takes a 225 * TelephonyProvider and attaches it to the ContentResolver with telephony authority. 226 * The mocked context also gives WRITE_APN_SETTINGS permissions 227 */ 228 private class MockContextWithProvider extends MockContext { 229 private final MockContentResolver mResolver; 230 private TelephonyManager mTelephonyManager = mock(TelephonyManager.class); 231 private SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class); 232 233 private final List<String> GRANTED_PERMISSIONS = Arrays.asList( 234 Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.WRITE_APN_SETTINGS, 235 Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 236 MockContextWithProvider(TelephonyProvider telephonyProvider, Boolean isActiveSubscription)237 public MockContextWithProvider(TelephonyProvider telephonyProvider, 238 Boolean isActiveSubscription) { 239 mResolver = new MockContentResolver() { 240 @Override 241 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 242 int userHandle) { 243 notifyChangeCount++; 244 if (URL_RESTOREAPN_USING_SUBID.equals(uri)) { 245 notifyChangeRestoreCount++; 246 } else if (SubscriptionManager.WFC_ENABLED_CONTENT_URI.equals(uri)) { 247 notifyWfcCount++; 248 } else if (URL_WFC_ENABLED_USING_SUBID.equals(uri)) { 249 notifyWfcCountWithTestSubId++; 250 } 251 } 252 }; 253 254 // return test subId 0 for all operators 255 doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(anyInt()); 256 doReturn(isActiveSubscription).when(mSubscriptionManager) 257 .isActiveSubscriptionId(anyInt()); 258 doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); 259 doReturn(TEST_OPERATOR).when(mTelephonyManager).getSimOperator(); 260 doReturn(TEST_CARRIERID).when(mTelephonyManager).getSimCarrierId(); 261 262 // Add authority="telephony" to given telephonyProvider 263 ProviderInfo providerInfo = new ProviderInfo(); 264 providerInfo.authority = "telephony"; 265 266 // Add context to given telephonyProvider 267 telephonyProvider.attachInfoForTesting(this, providerInfo); 268 Log.d(TAG, "MockContextWithProvider: telephonyProvider.getContext(): " 269 + telephonyProvider.getContext()); 270 271 // Add given telephonyProvider to mResolver with authority="telephony" so that 272 // mResolver can send queries to mTelephonyProvider 273 mResolver.addProvider("telephony", telephonyProvider); 274 Log.d(TAG, "MockContextWithProvider: Add telephonyProvider to mResolver"); 275 } 276 277 @Override getSystemService(String name)278 public Object getSystemService(String name) { 279 if (name.equals(Context.TELEPHONY_SERVICE)) { 280 Log.d(TAG, "getSystemService: returning mock TM"); 281 return mTelephonyManager; 282 } else if (name.equals(Context.TELEPHONY_SUBSCRIPTION_SERVICE)){ 283 Log.d(TAG, "getSystemService: returning mock SubscriptionManager"); 284 return mSubscriptionManager; 285 } else { 286 Log.d(TAG, "getSystemService: returning null"); 287 return null; 288 } 289 } 290 291 @Override getSystemServiceName(Class<?> serviceClass)292 public String getSystemServiceName(Class<?> serviceClass) { 293 if (serviceClass.equals(TelephonyManager.class)) { 294 return Context.TELEPHONY_SERVICE; 295 } else if (serviceClass.equals(SubscriptionManager.class)) { 296 return Context.TELEPHONY_SUBSCRIPTION_SERVICE; 297 } else { 298 Log.d(TAG, "getSystemServiceName: returning null"); 299 return null; 300 } 301 } 302 303 @Override getResources()304 public Resources getResources() { 305 return mockContextResources; 306 } 307 308 @Override getContentResolver()309 public MockContentResolver getContentResolver() { 310 return mResolver; 311 } 312 313 @Override getSharedPreferences(String name, int mode)314 public SharedPreferences getSharedPreferences(String name, int mode) { 315 return InstrumentationRegistry.getContext().getSharedPreferences(name, mode); 316 } 317 318 // Gives permission to write to the APN table within the MockContext 319 @Override checkCallingOrSelfPermission(String permission)320 public int checkCallingOrSelfPermission(String permission) { 321 if (GRANTED_PERMISSIONS.contains(permission)) { 322 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 323 + ", returning PackageManager.PERMISSION_GRANTED"); 324 return PackageManager.PERMISSION_GRANTED; 325 } else { 326 Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission 327 + ", returning PackageManager.PERMISSION_DENIED"); 328 return PackageManager.PERMISSION_DENIED; 329 } 330 } 331 332 @Override enforceCallingOrSelfPermission(String permission, String message)333 public void enforceCallingOrSelfPermission(String permission, String message) { 334 if (permission == android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE 335 || permission == android.Manifest.permission.MODIFY_PHONE_STATE) { 336 return; 337 } 338 throw new SecurityException("Unavailable permission requested"); 339 } 340 341 @Override getFilesDir()342 public File getFilesDir() { 343 return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); 344 } 345 } 346 347 @Override setUp()348 protected void setUp() throws Exception { 349 super.setUp(); 350 MockitoAnnotations.initMocks(this); 351 mTelephonyProviderTestable = new TelephonyProviderTestable(); 352 when(mockContextResources.getStringArray(anyInt())).thenReturn(new String[]{"ca", "us"}); 353 notifyChangeCount = 0; 354 notifyChangeRestoreCount = 0; 355 } 356 setUpMockContext(boolean isActiveSubId)357 private void setUpMockContext(boolean isActiveSubId) { 358 mContext = new MockContextWithProvider(mTelephonyProviderTestable, isActiveSubId); 359 mContentResolver = mContext.getContentResolver(); 360 } 361 362 @Override tearDown()363 protected void tearDown() throws Exception { 364 super.tearDown(); 365 mTelephonyProviderTestable.closeDatabase(); 366 367 // Remove the internal file created by SIM-specific settings restore 368 File file = new File(mContext.getFilesDir(), 369 mTelephonyProviderTestable.BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE); 370 if (file.exists()) { 371 file.delete(); 372 } 373 } 374 375 /** 376 * Test bulk inserting, querying; 377 * Verify that the inserted values match the result of the query. 378 */ 379 @Test 380 @SmallTest testBulkInsertCarriers()381 public void testBulkInsertCarriers() { 382 setUpMockContext(true); 383 384 // insert 2 test contentValues 385 ContentValues contentValues = new ContentValues(); 386 final String insertApn = "exampleApnName"; 387 final String insertName = "exampleName"; 388 final Integer insertCurrent = 1; 389 final String insertNumeric = TEST_OPERATOR; 390 contentValues.put(Carriers.APN, insertApn); 391 contentValues.put(Carriers.NAME, insertName); 392 contentValues.put(Carriers.CURRENT, insertCurrent); 393 contentValues.put(Carriers.NUMERIC, insertNumeric); 394 395 ContentValues contentValues2 = new ContentValues(); 396 final String insertApn2 = "exampleApnName2"; 397 final String insertName2 = "exampleName2"; 398 final Integer insertCurrent2 = 1; 399 final String insertNumeric2 = "789123"; 400 contentValues2.put(Carriers.APN, insertApn2); 401 contentValues2.put(Carriers.NAME, insertName2); 402 contentValues2.put(Carriers.CURRENT, insertCurrent2); 403 contentValues2.put(Carriers.NUMERIC, insertNumeric2); 404 405 Log.d(TAG, "testInsertCarriers: Bulk inserting contentValues=" + contentValues 406 + ", " + contentValues2); 407 ContentValues[] values = new ContentValues[]{ contentValues, contentValues2 }; 408 int rows = mContentResolver.bulkInsert(Carriers.CONTENT_URI, values); 409 assertEquals(2, rows); 410 assertEquals(1, notifyChangeCount); 411 412 // get values in table 413 final String[] testProjection = 414 { 415 Carriers.APN, 416 Carriers.NAME, 417 Carriers.CURRENT, 418 }; 419 final String selection = Carriers.NUMERIC + "=?"; 420 String[] selectionArgs = { insertNumeric }; 421 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 422 + "\ntestInsertCarriers selection: " + selection 423 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 424 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, 425 testProjection, selection, selectionArgs, null); 426 427 // verify that inserted values match results of query 428 assertNotNull(cursor); 429 assertEquals(1, cursor.getCount()); 430 cursor.moveToFirst(); 431 final String resultApn = cursor.getString(0); 432 final String resultName = cursor.getString(1); 433 final Integer resultCurrent = cursor.getInt(2); 434 assertEquals(insertApn, resultApn); 435 assertEquals(insertName, resultName); 436 assertEquals(insertCurrent, resultCurrent); 437 } 438 439 /** 440 * Test inserting, querying, and deleting values in carriers table. 441 * Verify that the inserted values match the result of the query and are deleted. 442 */ 443 @Test 444 @SmallTest testInsertCarriers()445 public void testInsertCarriers() { 446 doSimpleTestForUri(Carriers.CONTENT_URI); 447 } 448 449 /** 450 * Test migrating int-based MCC/MNCs over to Strings in the sim info table 451 */ 452 @Test 453 @SmallTest testMccMncMigration()454 public void testMccMncMigration() { 455 setUpMockContext(true); 456 457 CarrierIdProviderTestable carrierIdProvider = new CarrierIdProviderTestable(); 458 carrierIdProvider.initializeForTesting(mContext); 459 mContentResolver.addProvider(Telephony.CarrierId.All.CONTENT_URI.getAuthority(), 460 carrierIdProvider); 461 // Insert a few values into the carrier ID db 462 List<String> mccMncs = Arrays.asList("99910", "999110", "999060", "99905"); 463 ContentValues[] carrierIdMccMncs = mccMncs.stream() 464 .map((mccMnc) -> { 465 ContentValues cv = new ContentValues(1); 466 cv.put(Telephony.CarrierId.All.MCCMNC, mccMnc); 467 return cv; 468 }).toArray(ContentValues[]::new); 469 mContentResolver.bulkInsert(Telephony.CarrierId.All.CONTENT_URI, carrierIdMccMncs); 470 471 // Populate the sim info db with int-format entries 472 ContentValues[] existingSimInfoEntries = IntStream.range(0, mccMncs.size()) 473 .mapToObj((idx) -> { 474 int mcc = Integer.valueOf(mccMncs.get(idx).substring(0, 3)); 475 int mnc = Integer.valueOf(mccMncs.get(idx).substring(3)); 476 ContentValues cv = new ContentValues(4); 477 cv.put(SubscriptionManager.MCC, mcc); 478 cv.put(SubscriptionManager.MNC, mnc); 479 cv.put(SubscriptionManager.ICC_ID, String.valueOf(idx)); 480 cv.put(SubscriptionManager.CARD_ID, String.valueOf(idx)); 481 return cv; 482 }).toArray(ContentValues[]::new); 483 484 mContentResolver.bulkInsert(SimInfo.CONTENT_URI, existingSimInfoEntries); 485 486 // Run the upgrade helper on all the sim info entries. 487 String[] proj = {SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, 488 SubscriptionManager.MCC, SubscriptionManager.MNC, 489 SubscriptionManager.MCC_STRING, SubscriptionManager.MNC_STRING}; 490 try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj, 491 null, null, null)) { 492 while (c.moveToNext()) { 493 TelephonyProvider.fillInMccMncStringAtCursor(mContext, 494 mTelephonyProviderTestable.getWritableDatabase(), c); 495 } 496 } 497 498 // Loop through and make sure that everything got filled in correctly. 499 try (Cursor c = mContentResolver.query(SimInfo.CONTENT_URI, proj, 500 null, null, null)) { 501 while (c.moveToNext()) { 502 String mcc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MCC_STRING)); 503 String mnc = c.getString(c.getColumnIndexOrThrow(SubscriptionManager.MNC_STRING)); 504 assertTrue(mccMncs.contains(mcc + mnc)); 505 } 506 } 507 } 508 509 /** 510 * Test updating values in carriers table. Verify that when update hits a conflict using URL_ID 511 * we merge the rows. 512 */ 513 @Test 514 @SmallTest testUpdateConflictingCarriers()515 public void testUpdateConflictingCarriers() { 516 setUpMockContext(true); 517 518 // insert 2 test contentValues 519 ContentValues contentValues = new ContentValues(); 520 final String insertApn = "exampleApnName"; 521 final String insertName = "exampleName"; 522 final String insertNumeric = TEST_OPERATOR; 523 final String insertMcc = TEST_MCC; 524 final String insertMnc = TEST_MNC; 525 contentValues.put(Carriers.APN, insertApn); 526 contentValues.put(Carriers.NAME, insertName); 527 contentValues.put(Carriers.NUMERIC, insertNumeric); 528 contentValues.put(Carriers.MCC, insertMcc); 529 contentValues.put(Carriers.MNC, insertMnc); 530 531 ContentValues contentValues2 = new ContentValues(); 532 final String insertName2 = "exampleName2"; 533 contentValues2.put(Carriers.NAME, insertName2); 534 535 Uri row1 = mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 536 Uri row2 = mContentResolver.insert(Carriers.CONTENT_URI, contentValues2); 537 538 // use URL_ID to update row2 apn so it conflicts with row1 539 Log.d(TAG, "testUpdateConflictingCarriers: update row2=" + row2); 540 contentValues.put(Carriers.NAME, insertName2); 541 mContentResolver.update(row2, contentValues, null, null); 542 543 // verify that only 1 APN now exists and it has the fields from row1 and row2 544 final String[] testProjection = 545 { 546 Carriers.APN, 547 Carriers.NAME, 548 Carriers.NUMERIC, 549 Carriers.MCC, 550 Carriers.MNC 551 }; 552 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, null, null, 553 null); 554 assertNotNull(cursor); 555 assertEquals(1, cursor.getCount()); 556 cursor.moveToFirst(); 557 assertEquals(insertApn, cursor.getString(0 /* APN */)); 558 assertEquals(insertName2, cursor.getString(1 /* NAME */)); 559 assertEquals(insertNumeric, cursor.getString(2 /* NUMERIC */)); 560 assertEquals(insertMcc, cursor.getString(3 /* MCC */)); 561 assertEquals(insertMnc, cursor.getString(4 /* MNC */)); 562 } 563 564 /** 565 * Test inserting, querying, and deleting values in carriers table. 566 * Verify that the inserted values match the result of the query and are deleted. 567 */ 568 @Test 569 @SmallTest testInsertCarriersWithSubId()570 public void testInsertCarriersWithSubId() { 571 doSimpleTestForUri(CONTENT_URI_WITH_SUBID); 572 } 573 doSimpleTestForUri(Uri uri)574 private void doSimpleTestForUri(Uri uri) { 575 setUpMockContext(true); 576 577 // insert test contentValues 578 ContentValues contentValues = new ContentValues(); 579 final String insertApn = "exampleApnName"; 580 final String insertName = "exampleName"; 581 final String insertNumeric = TEST_OPERATOR; 582 contentValues.put(Carriers.APN, insertApn); 583 contentValues.put(Carriers.NAME, insertName); 584 contentValues.put(Carriers.NUMERIC, insertNumeric); 585 586 Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues); 587 mContentResolver.insert(uri, contentValues); 588 589 // get values in table 590 final String[] testProjection = 591 { 592 Carriers.APN, 593 Carriers.NAME, 594 }; 595 final String selection = Carriers.NUMERIC + "=?"; 596 String[] selectionArgs = { insertNumeric }; 597 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 598 + "\ntestInsertCarriers selection: " + selection 599 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 600 Cursor cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 601 602 // verify that inserted values match results of query 603 assertNotNull(cursor); 604 assertEquals(1, cursor.getCount()); 605 cursor.moveToFirst(); 606 final String resultApn = cursor.getString(0); 607 final String resultName = cursor.getString(1); 608 assertEquals(insertApn, resultApn); 609 assertEquals(insertName, resultName); 610 611 // delete test content 612 final String selectionToDelete = Carriers.NUMERIC + "=?"; 613 String[] selectionArgsToDelete = { insertNumeric }; 614 Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete 615 + "testInsertCarriers selectionArgs: " + selectionArgs); 616 int numRowsDeleted = mContentResolver.delete(uri, selectionToDelete, selectionArgsToDelete); 617 assertEquals(1, numRowsDeleted); 618 619 // verify that deleted values are gone 620 cursor = mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 621 assertEquals(0, cursor.getCount()); 622 } 623 624 @Test 625 @SmallTest testOwnedBy()626 public void testOwnedBy() { 627 setUpMockContext(true); 628 629 // insert test contentValues 630 ContentValues contentValues = new ContentValues(); 631 final String insertApn = "exampleApnName"; 632 final String insertName = "exampleName"; 633 final String insertNumeric = TEST_OPERATOR; 634 final Integer insertOwnedBy = Carriers.OWNED_BY_OTHERS; 635 contentValues.put(Carriers.APN, insertApn); 636 contentValues.put(Carriers.NAME, insertName); 637 contentValues.put(Carriers.NUMERIC, insertNumeric); 638 contentValues.put(Carriers.OWNED_BY, insertOwnedBy); 639 640 Log.d(TAG, "testInsertCarriers Inserting contentValues: " + contentValues); 641 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 642 643 // get values in table 644 final String[] testProjection = 645 { 646 Carriers.APN, 647 Carriers.NAME, 648 Carriers.OWNED_BY, 649 }; 650 final String selection = Carriers.NUMERIC + "=?"; 651 String[] selectionArgs = { insertNumeric }; 652 Log.d(TAG, "testInsertCarriers query projection: " + testProjection 653 + "\ntestInsertCarriers selection: " + selection 654 + "\ntestInsertCarriers selectionArgs: " + selectionArgs); 655 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, 656 testProjection, selection, selectionArgs, null); 657 658 // verify that inserted values match results of query 659 assertNotNull(cursor); 660 assertEquals(1, cursor.getCount()); 661 cursor.moveToFirst(); 662 final String resultApn = cursor.getString(0); 663 final String resultName = cursor.getString(1); 664 final Integer resultOwnedBy = cursor.getInt(2); 665 assertEquals(insertApn, resultApn); 666 assertEquals(insertName, resultName); 667 // Verify that OWNED_BY is force set to OWNED_BY_OTHERS when inserted with general uri 668 assertEquals(insertOwnedBy, resultOwnedBy); 669 670 // delete test content 671 final String selectionToDelete = Carriers.NUMERIC + "=?"; 672 String[] selectionArgsToDelete = { insertNumeric }; 673 Log.d(TAG, "testInsertCarriers deleting selection: " + selectionToDelete 674 + "testInsertCarriers selectionArgs: " + selectionArgs); 675 int numRowsDeleted = mContentResolver.delete(Carriers.CONTENT_URI, 676 selectionToDelete, selectionArgsToDelete); 677 assertEquals(1, numRowsDeleted); 678 679 // verify that deleted values are gone 680 cursor = mContentResolver.query(Carriers.CONTENT_URI, 681 testProjection, selection, selectionArgs, null); 682 assertEquals(0, cursor.getCount()); 683 } 684 685 /** 686 * Test inserting, querying, and deleting values in carriers table. 687 * Verify that the inserted values match the result of the query and are deleted. 688 */ 689 @Test 690 @SmallTest testSimTable()691 public void testSimTable() { 692 setUpMockContext(true); 693 694 // insert test contentValues 695 ContentValues contentValues = new ContentValues(); 696 final int insertSubId = 11; 697 final String insertDisplayName = "exampleDisplayName"; 698 final String insertCarrierName = "exampleCarrierName"; 699 final String insertIccId = "exampleIccId"; 700 final String insertCardId = "exampleCardId"; 701 final int insertProfileClass = SubscriptionManager.PROFILE_CLASS_DEFAULT; 702 contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId); 703 contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName); 704 contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName); 705 contentValues.put(SubscriptionManager.ICC_ID, insertIccId); 706 contentValues.put(SubscriptionManager.CARD_ID, insertCardId); 707 contentValues.put(SubscriptionManager.PROFILE_CLASS, insertProfileClass); 708 709 Log.d(TAG, "testSimTable Inserting contentValues: " + contentValues); 710 mContentResolver.insert(SimInfo.CONTENT_URI, contentValues); 711 712 // get values in table 713 final String[] testProjection = 714 { 715 SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, 716 SubscriptionManager.CARRIER_NAME, 717 SubscriptionManager.CARD_ID, 718 SubscriptionManager.PROFILE_CLASS, 719 }; 720 final String selection = SubscriptionManager.DISPLAY_NAME + "=?"; 721 String[] selectionArgs = { insertDisplayName }; 722 Log.d(TAG,"\ntestSimTable selection: " + selection 723 + "\ntestSimTable selectionArgs: " + selectionArgs.toString()); 724 Cursor cursor = mContentResolver.query(SimInfo.CONTENT_URI, 725 testProjection, selection, selectionArgs, null); 726 727 // verify that inserted values match results of query 728 assertNotNull(cursor); 729 assertEquals(1, cursor.getCount()); 730 cursor.moveToFirst(); 731 final int resultSubId = cursor.getInt(0); 732 final String resultCarrierName = cursor.getString(1); 733 final String resultCardId = cursor.getString(2); 734 final int resultProfileClass = cursor.getInt(3); 735 assertEquals(insertSubId, resultSubId); 736 assertEquals(insertCarrierName, resultCarrierName); 737 assertEquals(insertCardId, resultCardId); 738 assertEquals(insertProfileClass, resultProfileClass); 739 740 // delete test content 741 final String selectionToDelete = SubscriptionManager.DISPLAY_NAME + "=?"; 742 String[] selectionArgsToDelete = { insertDisplayName }; 743 Log.d(TAG, "testSimTable deleting selection: " + selectionToDelete 744 + "testSimTable selectionArgs: " + selectionArgs); 745 int numRowsDeleted = mContentResolver.delete(SimInfo.CONTENT_URI, 746 selectionToDelete, selectionArgsToDelete); 747 assertEquals(1, numRowsDeleted); 748 749 // verify that deleted values are gone 750 cursor = mContentResolver.query(SimInfo.CONTENT_URI, 751 testProjection, selection, selectionArgs, null); 752 assertEquals(0, cursor.getCount()); 753 } 754 755 @Test testFullRestoreOnMatchingIccId()756 public void testFullRestoreOnMatchingIccId() { 757 byte[] simSpecificSettingsData = getBackupData( 758 new ContentValues[]{ 759 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID, 760 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID, 761 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID}); 762 createInternalBackupFile(simSpecificSettingsData); 763 mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES_US); 764 765 mContext.getContentResolver().call( 766 SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 767 SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME, 768 MATCHING_ICCID, null); 769 770 Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI, 771 null, null, null, null); 772 assertEquals(1, cursor.getCount()); 773 cursor.moveToFirst(); 774 775 // Make sure SubId didn't get overridden. 776 assertEquals( 777 (int)TEST_SIM_INFO_VALUES_US.getAsInteger( 778 Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID), 779 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID)); 780 // Ensure all other values got updated. 781 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 782 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED)); 783 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 784 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED)); 785 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 786 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED)); 787 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 788 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED)); 789 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 790 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_MODE)); 791 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 792 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE)); 793 794 assertRestoredSubIdIsRemembered(); 795 } 796 797 @Test testFullRestoreOnMatchingNumberAndCid()798 public void testFullRestoreOnMatchingNumberAndCid() { 799 byte[] simSpecificSettingsData = getBackupData( 800 new ContentValues[]{ 801 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID, 802 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID}); 803 createInternalBackupFile(simSpecificSettingsData); 804 mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES_US); 805 806 mContext.getContentResolver().call( 807 SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 808 SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME, 809 MATCHING_ICCID, null); 810 811 Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI, 812 null, null, null, null); 813 assertEquals(1, cursor.getCount()); 814 cursor.moveToFirst(); 815 816 // Make sure SubId didn't get overridden. 817 assertEquals( 818 (int) TEST_SIM_INFO_VALUES_US.getAsInteger( 819 Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID), 820 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID)); 821 // Ensure all other values got updated. 822 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 823 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED)); 824 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 825 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED)); 826 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 827 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED)); 828 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 829 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED)); 830 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 831 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_MODE)); 832 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2, 833 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE)); 834 835 assertRestoredSubIdIsRemembered(); 836 } 837 838 @Test testFullRestoreOnMatchingCidOnly()839 public void testFullRestoreOnMatchingCidOnly() { 840 byte[] simSpecificSettingsData = getBackupData( 841 new ContentValues[]{ 842 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID}); 843 createInternalBackupFile(simSpecificSettingsData); 844 mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES_US); 845 846 mContext.getContentResolver().call( 847 SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 848 SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME, 849 MATCHING_ICCID, null); 850 851 Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI, 852 null, null, null, null); 853 assertEquals(1, cursor.getCount()); 854 cursor.moveToFirst(); 855 856 // Make sure SubId didn't get overridden. 857 assertEquals( 858 (int) TEST_SIM_INFO_VALUES_US.getAsInteger( 859 Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID), 860 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID)); 861 // Ensure sensitive settings did not get updated. 862 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 863 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED)); 864 // Ensure all other values got updated. 865 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3, 866 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED)); 867 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3, 868 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED)); 869 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, 870 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED)); 871 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3, 872 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_MODE)); 873 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3, 874 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE)); 875 876 assertRestoredSubIdIsRemembered(); 877 } 878 879 @Test testFullRestoreOnMatchingIccIdWithFranceISO()880 public void testFullRestoreOnMatchingIccIdWithFranceISO() { 881 byte[] simSpecificSettingsData = getBackupData( 882 new ContentValues[]{ 883 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID, 884 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID, 885 BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID}); 886 createInternalBackupFile(simSpecificSettingsData); 887 mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES_FR); 888 889 mContext.getContentResolver().call( 890 SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 891 SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME, 892 MATCHING_ICCID, null); 893 894 Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI, 895 null, null, null, null); 896 assertEquals(1, cursor.getCount()); 897 cursor.moveToFirst(); 898 899 // Make sure SubId didn't get overridden. 900 assertEquals( 901 (int) TEST_SIM_INFO_VALUES_FR.getAsInteger( 902 Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID), 903 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID)); 904 // Ensure all other values got updated. 905 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 906 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED)); 907 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 908 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED)); 909 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 910 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED)); 911 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 912 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED)); 913 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 914 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_MODE)); 915 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1, 916 getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE)); 917 918 assertRestoredSubIdIsRemembered(); 919 } 920 assertRestoredSubIdIsRemembered()921 private void assertRestoredSubIdIsRemembered() { 922 PersistableBundle bundle = getPersistableBundleFromInternalStorageFile(); 923 int[] previouslyRestoredSubIds = 924 bundle.getIntArray(TelephonyProvider.KEY_PREVIOUSLY_RESTORED_SUB_IDS); 925 assertNotNull(previouslyRestoredSubIds); 926 assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE, previouslyRestoredSubIds[0]); 927 } 928 getPersistableBundleFromInternalStorageFile()929 private PersistableBundle getPersistableBundleFromInternalStorageFile() { 930 File file = new File(Environment.getExternalStoragePublicDirectory( 931 Environment.DIRECTORY_DOWNLOADS), 932 TelephonyProvider.BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE); 933 try (FileInputStream fis = new FileInputStream(file)) { 934 return PersistableBundle.readFromStream(fis); 935 } catch (IOException e) { 936 } 937 938 return null; 939 } 940 getBackupData(ContentValues[] contentValues)941 private byte[] getBackupData(ContentValues[] contentValues) { 942 setUpMockContext(true); 943 944 int rowsAdded = mContentResolver.bulkInsert(SubscriptionManager.CONTENT_URI, contentValues); 945 assertEquals(rowsAdded, contentValues.length); 946 947 Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI, 948 null, null, null, null); 949 assertEquals(cursor.getCount(), contentValues.length); 950 951 Bundle bundle = mContext.getContentResolver().call( 952 SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI, 953 SubscriptionManager.GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null); 954 byte[] data = bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA); 955 956 int rowsDeleted = mContentResolver.delete(SubscriptionManager.CONTENT_URI, null, null); 957 assertEquals(rowsDeleted, contentValues.length); 958 959 return data; 960 } 961 createInternalBackupFile(byte[] data)962 private void createInternalBackupFile(byte[] data) { 963 mTelephonyProviderTestable.writeSimSettingsToInternalStorage(data); 964 } 965 getIntValueFromCursor(Cursor cursor, String columnName)966 private int getIntValueFromCursor(Cursor cursor, String columnName) { 967 int columnIndex = cursor.getColumnIndex(columnName); 968 return cursor.getInt(columnIndex); 969 } 970 parseIdFromInsertedUri(Uri uri)971 private int parseIdFromInsertedUri(Uri uri) throws NumberFormatException { 972 return (uri != null) ? Integer.parseInt(uri.getLastPathSegment()) : -1; 973 } 974 insertApnRecord(Uri uri, String apn, String name, int current, String numeric)975 private int insertApnRecord(Uri uri, String apn, String name, int current, String numeric) { 976 ContentValues contentValues = new ContentValues(); 977 contentValues.put(Carriers.APN, apn); 978 contentValues.put(Carriers.NAME, name); 979 contentValues.put(Carriers.CURRENT, current); 980 contentValues.put(Carriers.NUMERIC, numeric); 981 Uri resultUri = mContentResolver.insert(uri, contentValues); 982 return parseIdFromInsertedUri(resultUri); 983 } 984 985 /** 986 * Test URL_ENFORCE_MANAGED and URL_FILTERED works correctly. 987 * Verify that when enforce is set true via URL_ENFORCE_MANAGED, only DPC records are returned 988 * for URL_FILTERED and URL_FILTERED_ID. 989 * Verify that when enforce is set false via URL_ENFORCE_MANAGED, only non-DPC records 990 * are returned for URL_FILTERED and URL_FILTERED_ID. 991 */ 992 @Test 993 @SmallTest testEnforceManagedUri()994 public void testEnforceManagedUri() { 995 setUpMockContext(true); 996 997 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 998 999 final int current = 1; 1000 final String numeric = TEST_OPERATOR; 1001 1002 // Insert DPC record. 1003 final String dpcRecordApn = "exampleApnNameDPC"; 1004 final String dpcRecordName = "exampleNameDPC"; 1005 final int dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 1006 current, numeric); 1007 1008 // Insert non-DPC record. 1009 final String othersRecordApn = "exampleApnNameOTHERS"; 1010 final String othersRecordName = "exampleNameDPOTHERS"; 1011 final int othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 1012 current, numeric); 1013 1014 // Set enforced = false. 1015 ContentValues enforceManagedValue = new ContentValues(); 1016 enforceManagedValue.put(ENFORCED_KEY, false); 1017 Log.d(TAG, "testEnforceManagedUri Updating enforced = false: " 1018 + enforceManagedValue); 1019 mContentResolver.update(URI_ENFORCE_MANAGED, enforceManagedValue, "", new String[]{}); 1020 1021 // Verify that enforced is set to false in TelephonyProvider. 1022 Cursor enforceCursor = mContentResolver.query(URI_ENFORCE_MANAGED, 1023 null, null, null, null); 1024 assertNotNull(enforceCursor); 1025 assertEquals(1, enforceCursor.getCount()); 1026 enforceCursor.moveToFirst(); 1027 assertEquals(0, enforceCursor.getInt(0)); 1028 1029 // Verify URL_FILTERED query only returns non-DPC record. 1030 final String[] testProjection = 1031 { 1032 Carriers._ID, 1033 Carriers.OWNED_BY 1034 }; 1035 final String selection = Carriers.NUMERIC + "=?"; 1036 final String[] selectionArgs = { numeric }; 1037 final Cursor cursorNotEnforced = mContentResolver.query(URI_FILTERED, 1038 testProjection, selection, selectionArgs, null); 1039 assertNotNull(cursorNotEnforced); 1040 assertEquals(1, cursorNotEnforced.getCount()); 1041 cursorNotEnforced.moveToFirst(); 1042 assertEquals(othersRecordId, cursorNotEnforced.getInt(0)); 1043 assertEquals(Carriers.OWNED_BY_OTHERS, cursorNotEnforced.getInt(1)); 1044 1045 // Verify that URL_FILTERED_ID cannot get DPC record. 1046 Cursor cursorNotEnforcedDpc = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 1047 Integer.toString(dpcRecordId)), null, null, null, null); 1048 assertNotNull(cursorNotEnforcedDpc); 1049 assertTrue(cursorNotEnforcedDpc.getCount() == 0); 1050 // Verify that URL_FILTERED_ID can get non-DPC record. 1051 Cursor cursorNotEnforcedOthers = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 1052 Integer.toString(othersRecordId)), null, null, null, null); 1053 assertNotNull(cursorNotEnforcedOthers); 1054 assertTrue(cursorNotEnforcedOthers.getCount() == 1); 1055 1056 // Set enforced = true. 1057 enforceManagedValue.put(ENFORCED_KEY, true); 1058 Log.d(TAG, "testEnforceManagedUri Updating enforced = true: " 1059 + enforceManagedValue); 1060 mContentResolver.update(URI_ENFORCE_MANAGED, enforceManagedValue, "", new String[]{}); 1061 1062 // Verify that enforced is set to true in TelephonyProvider. 1063 enforceCursor = mContentResolver.query(URI_ENFORCE_MANAGED, 1064 null, null, null, null); 1065 assertNotNull(enforceCursor); 1066 assertEquals(1, enforceCursor.getCount()); 1067 enforceCursor.moveToFirst(); 1068 assertEquals(1, enforceCursor.getInt(0)); 1069 1070 // Verify URL_FILTERED query only returns DPC record. 1071 final Cursor cursorEnforced = mContentResolver.query(URI_FILTERED, 1072 testProjection, selection, selectionArgs, null); 1073 assertNotNull(cursorEnforced); 1074 assertEquals(1, cursorEnforced.getCount()); 1075 cursorEnforced.moveToFirst(); 1076 assertEquals(dpcRecordId, cursorEnforced.getInt(0)); 1077 assertEquals(Carriers.OWNED_BY_DPC, cursorEnforced.getInt(1)); 1078 1079 // Verify that URL_FILTERED_ID can get DPC record. 1080 cursorNotEnforcedDpc = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 1081 Integer.toString(dpcRecordId)), null, null, null, null); 1082 assertNotNull(cursorNotEnforcedDpc); 1083 assertTrue(cursorNotEnforcedDpc.getCount() == 1); 1084 // Verify that URL_FILTERED_ID cannot get non-DPC record. 1085 cursorNotEnforcedOthers = mContentResolver.query(Uri.withAppendedPath(URI_FILTERED, 1086 Integer.toString(othersRecordId)), null, null, null, null); 1087 assertNotNull(cursorNotEnforcedOthers); 1088 assertTrue(cursorNotEnforcedOthers.getCount() == 0); 1089 1090 // Delete testing records. 1091 int numRowsDeleted = mContentResolver.delete(URI_TELEPHONY, selection, selectionArgs); 1092 assertEquals(1, numRowsDeleted); 1093 1094 numRowsDeleted = mContentResolver.delete( 1095 ContentUris.withAppendedId(URI_DPC, dpcRecordId), "", null); 1096 assertEquals(1, numRowsDeleted); 1097 } 1098 queryFullTestApnRecord(Uri uri, String numeric)1099 private Cursor queryFullTestApnRecord(Uri uri, String numeric) { 1100 final String selection = Carriers.NUMERIC + "=?"; 1101 String[] selectionArgs = { numeric }; 1102 final String[] testProjection = 1103 { 1104 Carriers._ID, 1105 Carriers.APN, 1106 Carriers.NAME, 1107 Carriers.CURRENT, 1108 Carriers.OWNED_BY, 1109 }; 1110 return mContentResolver.query(uri, testProjection, selection, selectionArgs, null); 1111 } 1112 1113 @Test 1114 @SmallTest 1115 /** 1116 * Test URL_TELEPHONY cannot insert, query, update or delete DPC records. 1117 */ testTelephonyUriDpcRecordAccessControl()1118 public void testTelephonyUriDpcRecordAccessControl() { 1119 setUpMockContext(true); 1120 1121 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 1122 1123 final int current = 1; 1124 final String numeric = TEST_OPERATOR; 1125 final String selection = Carriers.NUMERIC + "=?"; 1126 final String[] selectionArgs = { numeric }; 1127 1128 // Insert DPC record. 1129 final String dpcRecordApn = "exampleApnNameDPC"; 1130 final String dpcRecordName = "exampleNameDPC"; 1131 final int dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 1132 current, numeric); 1133 1134 // Insert non-DPC record. 1135 final String othersRecordApn = "exampleApnNameOTHERS"; 1136 final String othersRecordName = "exampleNameDPOTHERS"; 1137 final int othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 1138 current, numeric); 1139 1140 // Verify URL_TELEPHONY query only returns non-DPC record. 1141 final Cursor cursorTelephony = queryFullTestApnRecord(URI_TELEPHONY, numeric); 1142 assertNotNull(cursorTelephony); 1143 assertEquals(1, cursorTelephony.getCount()); 1144 cursorTelephony.moveToFirst(); 1145 assertApnEquals(cursorTelephony, othersRecordId, othersRecordApn, othersRecordName, 1146 current, Carriers.OWNED_BY_OTHERS); 1147 1148 // Verify URI_TELEPHONY updates only non-DPC records. 1149 ContentValues contentValuesOthersUpdate = new ContentValues(); 1150 final String othersRecordUpdatedApn = "exampleApnNameOTHERSUpdated"; 1151 final String othersRecordUpdatedName = "exampleNameOTHERSpdated"; 1152 contentValuesOthersUpdate.put(Carriers.APN, othersRecordUpdatedApn); 1153 contentValuesOthersUpdate.put(Carriers.NAME, othersRecordUpdatedName); 1154 1155 final int updateCount = mContentResolver.update(URI_TELEPHONY, contentValuesOthersUpdate, 1156 selection, selectionArgs); 1157 assertEquals(1, updateCount); 1158 final Cursor cursorNonDPCUpdate = queryFullTestApnRecord(URI_TELEPHONY, numeric); 1159 final Cursor cursorDPCUpdate = queryFullTestApnRecord(URI_DPC, numeric); 1160 1161 // Verify that non-DPC records are updated. 1162 assertNotNull(cursorNonDPCUpdate); 1163 assertEquals(1, cursorNonDPCUpdate.getCount()); 1164 cursorNonDPCUpdate.moveToFirst(); 1165 assertApnEquals(cursorNonDPCUpdate, othersRecordId, othersRecordUpdatedApn, 1166 othersRecordUpdatedName); 1167 1168 // Verify that DPC records are not updated. 1169 assertNotNull(cursorDPCUpdate); 1170 assertEquals(1, cursorDPCUpdate.getCount()); 1171 cursorDPCUpdate.moveToFirst(); 1172 assertApnEquals(cursorDPCUpdate, dpcRecordId, dpcRecordApn, dpcRecordName); 1173 1174 // Verify URI_TELEPHONY deletes only non-DPC records. 1175 int numRowsDeleted = mContentResolver.delete(URI_TELEPHONY, selection, selectionArgs); 1176 assertEquals(1, numRowsDeleted); 1177 final Cursor cursorTelephonyRemaining = queryFullTestApnRecord(URI_TELEPHONY, numeric); 1178 assertNotNull(cursorTelephonyRemaining); 1179 assertEquals(0, cursorTelephonyRemaining.getCount()); 1180 final Cursor cursorDPCDeleted = queryFullTestApnRecord(URI_DPC, numeric); 1181 assertNotNull(cursorDPCDeleted); 1182 assertEquals(1, cursorDPCDeleted.getCount()); 1183 1184 // Delete remaining test records. 1185 numRowsDeleted = mContentResolver.delete( 1186 ContentUris.withAppendedId(URI_DPC, dpcRecordId), "", null); 1187 assertEquals(1, numRowsDeleted); 1188 } 1189 1190 /** 1191 * Test URL_DPC cannot insert or query non-DPC records. 1192 * Test URL_DPC_ID cannot update or delete non-DPC records. 1193 */ 1194 @Test 1195 @SmallTest testDpcUri()1196 public void testDpcUri() { 1197 setUpMockContext(true); 1198 1199 int dpcRecordId = 0, othersRecordId = 0; 1200 try { 1201 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 1202 1203 final int current = 1; 1204 final String numeric = TEST_OPERATOR; 1205 1206 // Insert DPC record. 1207 final String dpcRecordApn = "exampleApnNameDPC"; 1208 final String dpcRecordName = "exampleNameDPC"; 1209 dpcRecordId = insertApnRecord(URI_DPC, dpcRecordApn, dpcRecordName, 1210 current, numeric); 1211 1212 // Insert non-DPC record. 1213 final String othersRecordApn = "exampleApnNameOTHERS"; 1214 final String othersRecordName = "exampleNameDPOTHERS"; 1215 othersRecordId = insertApnRecord(URI_TELEPHONY, othersRecordApn, othersRecordName, 1216 current, numeric); 1217 1218 Log.d(TAG, "testDPCIdUri Id for inserted DPC record: " + dpcRecordId); 1219 Log.d(TAG, "testDPCIdUri Id for inserted non-DPC record: " + othersRecordId); 1220 1221 // Verify that URI_DPC query only returns DPC records. 1222 final Cursor cursorDPC = queryFullTestApnRecord(URI_DPC, numeric); 1223 assertNotNull(cursorDPC); 1224 assertEquals(1, cursorDPC.getCount()); 1225 cursorDPC.moveToFirst(); 1226 assertApnEquals(cursorDPC, dpcRecordId, dpcRecordApn, dpcRecordName, current, 1227 Carriers.OWNED_BY_DPC); 1228 1229 // Verify that URI_DPC_ID updates only DPC records. 1230 ContentValues contentValuesDpcUpdate = new ContentValues(); 1231 final String dpcRecordUpdatedApn = "exampleApnNameDPCUpdated"; 1232 final String dpcRecordUpdatedName = "exampleNameDPCUpdated"; 1233 contentValuesDpcUpdate.put(Carriers.APN, dpcRecordUpdatedApn); 1234 contentValuesDpcUpdate.put(Carriers.NAME, dpcRecordUpdatedName); 1235 final int updateCount = mContentResolver.update( 1236 ContentUris.withAppendedId(URI_DPC, dpcRecordId), 1237 contentValuesDpcUpdate, null, null); 1238 assertEquals(1, updateCount); 1239 final Cursor cursorNonDPCUpdate = queryFullTestApnRecord(URI_TELEPHONY, numeric); 1240 final Cursor cursorDPCUpdate = queryFullTestApnRecord(URI_DPC, numeric); 1241 1242 // Verify that non-DPC records are not updated. 1243 assertNotNull(cursorNonDPCUpdate); 1244 assertEquals(1, cursorNonDPCUpdate.getCount()); 1245 cursorNonDPCUpdate.moveToFirst(); 1246 assertApnEquals(cursorNonDPCUpdate, othersRecordId, othersRecordApn, othersRecordName); 1247 1248 // Verify that DPC records are updated. 1249 assertNotNull(cursorDPCUpdate); 1250 assertEquals(1, cursorDPCUpdate.getCount()); 1251 cursorDPCUpdate.moveToFirst(); 1252 assertApnEquals(cursorDPCUpdate, dpcRecordId, dpcRecordUpdatedApn, 1253 dpcRecordUpdatedName); 1254 1255 // Test URI_DPC_ID deletes only DPC records. 1256 int numRowsDeleted = mContentResolver.delete( 1257 ContentUris.withAppendedId(URI_DPC, dpcRecordId), null, null); 1258 assertEquals(1, numRowsDeleted); 1259 numRowsDeleted = mContentResolver.delete( 1260 ContentUris.withAppendedId(URI_DPC, dpcRecordId), null, null); 1261 assertEquals(0, numRowsDeleted); 1262 1263 } finally { 1264 // Delete remaining test records. 1265 int numRowsDeleted = mContentResolver.delete( 1266 ContentUris.withAppendedId(URI_TELEPHONY, othersRecordId), null, null); 1267 assertEquals(1, numRowsDeleted); 1268 } 1269 } 1270 assertApnEquals(Cursor cursor, Object... values)1271 private void assertApnEquals(Cursor cursor, Object... values) { 1272 assertTrue(values.length <= cursor.getColumnCount()); 1273 for (int i = 0; i < values.length; i ++) { 1274 if (values[i] instanceof Integer) { 1275 assertEquals(values[i], cursor.getInt(i)); 1276 } else if (values[i] instanceof String) { 1277 assertEquals(values[i], cursor.getString(i)); 1278 } else { 1279 fail("values input type not correct"); 1280 } 1281 } 1282 } 1283 1284 /** 1285 * Test URL_DPC does not change database on conflict for insert and update. 1286 */ 1287 @Test 1288 @SmallTest testDpcUriOnConflict()1289 public void testDpcUriOnConflict() { 1290 setUpMockContext(true); 1291 1292 int dpcRecordId1 = 0, dpcRecordId2 = 0; 1293 try { 1294 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID); 1295 1296 final int current = 1; 1297 final String numeric = TEST_OPERATOR; 1298 1299 // Insert DPC record 1. 1300 final String dpcRecordApn1 = "exampleApnNameDPC"; 1301 final String dpcRecordName = "exampleNameDPC"; 1302 dpcRecordId1 = insertApnRecord(URI_DPC, dpcRecordApn1, dpcRecordName, 1303 current, numeric); 1304 Log.d(TAG, "testDpcUriOnConflict Id for DPC record 1: " + dpcRecordId1); 1305 1306 // Insert conflicting DPC record. 1307 final String dpcRecordNameConflict = "exampleNameDPCConflict"; 1308 final int dpcRecordIdConflict = insertApnRecord(URI_DPC, dpcRecordApn1, 1309 dpcRecordNameConflict, current, numeric); 1310 1311 // Verity that conflicting DPC record is not inserted. 1312 assertEquals(-1, dpcRecordIdConflict); 1313 // Verify that APN 1 is not replaced or updated. 1314 Cursor cursorDPC1 = queryFullTestApnRecord(URI_DPC, numeric); 1315 assertNotNull(cursorDPC1); 1316 assertEquals(1, cursorDPC1.getCount()); 1317 cursorDPC1.moveToFirst(); 1318 assertApnEquals(cursorDPC1, dpcRecordId1, dpcRecordApn1, dpcRecordName, current, 1319 Carriers.OWNED_BY_DPC); 1320 1321 // Insert DPC record 2. 1322 final String dpcRecordApn2 = "exampleApnNameDPC2"; 1323 dpcRecordId2 = insertApnRecord(URI_DPC, dpcRecordApn2, dpcRecordName, 1324 current, numeric); 1325 Log.d(TAG, "testDpcUriOnConflict Id for DPC record 2: " + dpcRecordId2); 1326 1327 // Update DPC record 2 to the values of DPC record 1. 1328 ContentValues contentValuesDpcUpdate = new ContentValues(); 1329 contentValuesDpcUpdate.put(Carriers.APN, dpcRecordApn1); 1330 contentValuesDpcUpdate.put(Carriers.NAME, dpcRecordNameConflict); 1331 final int updateCount = mContentResolver.update( 1332 ContentUris.withAppendedId(URI_DPC, dpcRecordId2), 1333 contentValuesDpcUpdate, null, null); 1334 1335 // Verify that database is not updated. 1336 assertEquals(0, updateCount); 1337 Cursor cursorDPC2 = queryFullTestApnRecord(URI_DPC, numeric); 1338 assertNotNull(cursorDPC2); 1339 assertEquals(2, cursorDPC2.getCount()); 1340 cursorDPC2.moveToFirst(); 1341 assertApnEquals(cursorDPC2, dpcRecordId1, dpcRecordApn1, dpcRecordName, current, 1342 Carriers.OWNED_BY_DPC); 1343 cursorDPC2.moveToNext(); 1344 assertApnEquals(cursorDPC2, dpcRecordId2, dpcRecordApn2, dpcRecordName, current, 1345 Carriers.OWNED_BY_DPC); 1346 } finally { 1347 // Delete test records. 1348 int numRowsDeleted = mContentResolver.delete( 1349 ContentUris.withAppendedId(URI_DPC, dpcRecordId1), null, null); 1350 assertEquals(1, numRowsDeleted); 1351 numRowsDeleted = mContentResolver.delete( 1352 ContentUris.withAppendedId(URI_DPC, dpcRecordId2), null, null); 1353 assertEquals(1, numRowsDeleted); 1354 } 1355 } 1356 1357 /** 1358 * Verify that SecurityException is thrown if URL_DPC, URL_FILTERED and 1359 * URL_ENFORCE_MANAGED is accessed from neither SYSTEM_UID nor PHONE_UID. 1360 */ 1361 @Test 1362 @SmallTest testAccessUrlDpcThrowSecurityExceptionFromOtherUid()1363 public void testAccessUrlDpcThrowSecurityExceptionFromOtherUid() { 1364 setUpMockContext(true); 1365 1366 mTelephonyProviderTestable.fakeCallingUid(Process.SYSTEM_UID + 123456); 1367 1368 // Test insert(). 1369 ContentValues contentValuesDPC = new ContentValues(); 1370 try { 1371 mContentResolver.insert(URI_DPC, contentValuesDPC); 1372 assertFalse("SecurityException should be thrown when URI_DPC is called from" 1373 + " neither SYSTEM_UID nor PHONE_UID", true); 1374 } catch (SecurityException e) { 1375 // Should catch SecurityException. 1376 } 1377 1378 // Test query(). 1379 try { 1380 mContentResolver.query(URI_DPC, 1381 new String[]{}, "", new String[]{}, null); 1382 assertFalse("SecurityException should be thrown when URI_DPC is called from" 1383 + " neither SYSTEM_UID nor PHONE_UID", true); 1384 } catch (SecurityException e) { 1385 // Should catch SecurityException. 1386 } 1387 try { 1388 mContentResolver.query(URI_ENFORCE_MANAGED, 1389 new String[]{}, "", new String[]{}, null); 1390 assertFalse("SecurityException should be thrown when URI_ENFORCE_MANAGED is " 1391 + "called from neither SYSTEM_UID nor PHONE_UID", true); 1392 } catch (SecurityException e) { 1393 // Should catch SecurityException. 1394 } 1395 1396 // Test update(). 1397 ContentValues contentValuesDPCUpdate = new ContentValues(); 1398 try { 1399 mContentResolver.update( 1400 Uri.parse(URI_DPC + "/1"), 1401 contentValuesDPCUpdate, "", new String[]{}); 1402 assertFalse("SecurityException should be thrown when URI_DPC is called" 1403 + " from neither SYSTEM_UID nor PHONE_UID", true); 1404 } catch (SecurityException e) { 1405 // Should catch SecurityException. 1406 } 1407 try { 1408 mContentResolver.update(URI_ENFORCE_MANAGED, contentValuesDPCUpdate, 1409 "", new String[]{}); 1410 assertFalse("SecurityException should be thrown when URI_DPC is called" 1411 + " from neither SYSTEM_UID nor PHONE_UID", true); 1412 } catch (SecurityException e) { 1413 // Should catch SecurityException. 1414 } 1415 1416 // Test delete(). 1417 try { 1418 mContentResolver.delete( 1419 Uri.parse(URI_DPC + "/0"), "", new String[]{}); 1420 assertFalse("SecurityException should be thrown when URI_DPC is called" 1421 + " from neither SYSTEM_UID nor PHONE_UID", true); 1422 } catch (SecurityException e) { 1423 // Should catch SecurityException. 1424 } 1425 } 1426 1427 /** 1428 * Verify that user/carrier edited/deleted APNs have priority in the EDITED field over 1429 * insertions which set EDITED=UNEDITED. In these cases instead of merging the APNs using the 1430 * new APN's value we keep the old value. 1431 */ 1432 @Test 1433 @SmallTest testPreserveEdited()1434 public void testPreserveEdited() { 1435 preserveEditedValueInMerge(Carriers.USER_EDITED); 1436 } 1437 1438 @Test 1439 @SmallTest testPreserveUserDeleted()1440 public void testPreserveUserDeleted() { 1441 preserveDeletedValueInMerge(Carriers.USER_DELETED); 1442 } 1443 1444 @Test 1445 @SmallTest testPreserveUserDeletedButPresentInXml()1446 public void testPreserveUserDeletedButPresentInXml() { 1447 preserveDeletedValueInMerge(Carriers.USER_DELETED_BUT_PRESENT_IN_XML); 1448 } 1449 1450 @Test 1451 @SmallTest testPreserveCarrierEdited()1452 public void testPreserveCarrierEdited() { 1453 preserveEditedValueInMerge(Carriers.CARRIER_EDITED); 1454 } 1455 1456 @Test 1457 @SmallTest testPreserveCarrierDeleted()1458 public void testPreserveCarrierDeleted() { 1459 preserveDeletedValueInMerge(Carriers.CARRIER_DELETED); 1460 } 1461 1462 @Test 1463 @SmallTest testPreserveCarrierDeletedButPresentInXml()1464 public void testPreserveCarrierDeletedButPresentInXml() { 1465 preserveDeletedValueInMerge(Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML); 1466 } 1467 preserveEditedValueInMerge(int value)1468 private void preserveEditedValueInMerge(int value) { 1469 setUpMockContext(true); 1470 1471 // insert user deleted APN 1472 String carrierName1 = "carrier1"; 1473 String numeric1 = "123234"; 1474 String mcc1 = "123"; 1475 String mnc1 = "234"; 1476 ContentValues editedValue = new ContentValues(); 1477 editedValue.put(Carriers.NAME, carrierName1); 1478 editedValue.put(Carriers.NUMERIC, numeric1); 1479 editedValue.put(Carriers.MCC, mcc1); 1480 editedValue.put(Carriers.MNC, mnc1); 1481 editedValue.put(Carriers.EDITED_STATUS, value); 1482 assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue)); 1483 1484 Cursor cur = mContentResolver.query(URI_TELEPHONY, null, null, null, null); 1485 assertEquals(1, cur.getCount()); 1486 1487 // insert APN that conflicts with edited APN 1488 String carrierName2 = "carrier2"; 1489 ContentValues values = new ContentValues(); 1490 values.put(Carriers.NAME, carrierName2); 1491 values.put(Carriers.NUMERIC, numeric1); 1492 values.put(Carriers.MCC, mcc1); 1493 values.put(Carriers.MNC, mnc1); 1494 values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 1495 mContentResolver.insert(URI_TELEPHONY, values); 1496 1497 String[] testProjection = { 1498 Carriers.NAME, 1499 Carriers.APN, 1500 Carriers.EDITED_STATUS, 1501 Carriers.TYPE, 1502 Carriers.PROTOCOL, 1503 Carriers.BEARER_BITMASK, 1504 }; 1505 final int indexOfName = 0; 1506 final int indexOfEdited = 2; 1507 1508 // Assert that the conflicting APN is merged into the existing user-edited APN, so only 1 1509 // APN exists in the db 1510 cur = mContentResolver.query(URI_TELEPHONY, testProjection, null, null, null); 1511 assertEquals(1, cur.getCount()); 1512 cur.moveToFirst(); 1513 assertEquals(carrierName2, cur.getString(indexOfName)); 1514 assertEquals(value, cur.getInt(indexOfEdited)); 1515 } 1516 preserveDeletedValueInMerge(int value)1517 private void preserveDeletedValueInMerge(int value) { 1518 setUpMockContext(true); 1519 1520 // insert user deleted APN 1521 String carrierName1 = "carrier1"; 1522 String numeric1 = "123234"; 1523 String mcc1 = "123"; 1524 String mnc1 = "234"; 1525 ContentValues editedValue = new ContentValues(); 1526 editedValue.put(Carriers.NAME, carrierName1); 1527 editedValue.put(Carriers.NUMERIC, numeric1); 1528 editedValue.put(Carriers.MCC, mcc1); 1529 editedValue.put(Carriers.MNC, mnc1); 1530 editedValue.put(Carriers.EDITED_STATUS, value); 1531 assertNotNull(mContentResolver.insert(URI_TELEPHONY, editedValue)); 1532 1533 // insert APN that conflicts with edited APN 1534 String carrierName2 = "carrier2"; 1535 ContentValues values = new ContentValues(); 1536 values.put(Carriers.NAME, carrierName2); 1537 values.put(Carriers.NUMERIC, numeric1); 1538 values.put(Carriers.MCC, mcc1); 1539 values.put(Carriers.MNC, mnc1); 1540 values.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 1541 mContentResolver.insert(URI_TELEPHONY, values); 1542 1543 String[] testProjection = { 1544 Carriers.NAME, 1545 Carriers.APN, 1546 Carriers.EDITED_STATUS, 1547 Carriers.TYPE, 1548 Carriers.PROTOCOL, 1549 Carriers.BEARER_BITMASK, 1550 }; 1551 final int indexOfEdited = 2; 1552 1553 // Assert that the conflicting APN is merged into the existing user-deleted APN. 1554 // Entries marked deleted will not show up in queries so we verify that no APNs can 1555 // be seen 1556 Cursor cur = mContentResolver.query(URI_TELEPHONY, testProjection, null, null, null); 1557 assertEquals(0, cur.getCount()); 1558 } 1559 1560 /** 1561 * Test URL_PREFERAPN_USING_SUBID works correctly. 1562 */ 1563 @Test 1564 @SmallTest testQueryPreferredApn()1565 public void testQueryPreferredApn() { 1566 setUpMockContext(true); 1567 1568 // create APNs 1569 ContentValues preferredValues = new ContentValues(); 1570 final String preferredApn = "preferredApn"; 1571 final String preferredName = "preferredName"; 1572 preferredValues.put(Carriers.APN, preferredApn); 1573 preferredValues.put(Carriers.NAME, preferredName); 1574 preferredValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1575 ContentValues otherValues = new ContentValues(); 1576 final String otherApn = "otherApnName"; 1577 final String otherName = "otherName"; 1578 otherValues.put(Carriers.APN, otherApn); 1579 otherValues.put(Carriers.NAME, otherName); 1580 otherValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1581 1582 // insert APNs 1583 // TODO if using URL_TELEPHONY, SubscriptionManager.getDefaultSubscriptionId() returns -1 1584 Log.d(TAG, "testQueryPreferredApn: Bulk inserting contentValues=" + preferredValues + ", " 1585 + otherValues); 1586 Uri uri = mContentResolver.insert(CONTENT_URI_WITH_SUBID, preferredValues); 1587 mContentResolver.insert(CONTENT_URI_WITH_SUBID, otherValues); 1588 final String preferredApnIdString = uri.getLastPathSegment(); 1589 final long preferredApnId = Long.parseLong(preferredApnIdString); 1590 Log.d(TAG, "testQueryPreferredApn: preferredApnString=" + preferredApnIdString); 1591 1592 // set preferred apn 1593 preferredValues.put(COLUMN_APN_ID, preferredApnIdString); 1594 mContentResolver.insert(URL_PREFERAPN_USING_SUBID, preferredValues); 1595 1596 // query preferred APN 1597 final String[] testProjection = { Carriers.APN, Carriers.NAME }; 1598 Cursor cursor = mContentResolver.query( 1599 URL_PREFERAPN_USING_SUBID, testProjection, null, null, null); 1600 1601 // verify that preferred apn was set and retreived 1602 assertEquals(1, cursor.getCount()); 1603 cursor.moveToFirst(); 1604 assertEquals(preferredApn, cursor.getString(0)); 1605 assertEquals(preferredName, cursor.getString(1)); 1606 } 1607 1608 /** 1609 * Test that APN_SET_ID works correctly. 1610 */ 1611 @Test 1612 @SmallTest testApnSetId()1613 public void testApnSetId() { 1614 setUpMockContext(true); 1615 1616 // create APNs 1617 ContentValues values1 = new ContentValues(); 1618 final String apn = "apnName"; 1619 final String apnName = "name"; 1620 values1.put(Carriers.APN, apn); 1621 values1.put(Carriers.NAME, apnName); 1622 values1.put(Carriers.NUMERIC, TEST_OPERATOR); 1623 1624 ContentValues values2 = new ContentValues(); 1625 final String otherApn = "otherApnName"; 1626 final String otherName = "otherName"; 1627 values2.put(Carriers.APN, otherApn); 1628 values2.put(Carriers.NAME, otherName); 1629 values2.put(Carriers.NUMERIC, TEST_OPERATOR); 1630 values2.put(Carriers.APN_SET_ID, 1); 1631 1632 // insert APNs 1633 // TODO if using URL_TELEPHONY, SubscriptionManager.getDefaultSubscriptionId() returns -1 1634 Log.d(TAG, "testApnSetId: inserting contentValues=" + values1 + ", " + values2); 1635 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values1); 1636 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values2); 1637 1638 // query APN with default APN_SET_ID 1639 final String[] testProjection = { Carriers.NAME }; 1640 Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, 1641 Carriers.APN_SET_ID + "=?", new String[] { "0" }, null); 1642 assertEquals(1, cursor.getCount()); 1643 cursor.moveToFirst(); 1644 assertEquals(apnName, cursor.getString(0)); 1645 1646 // query APN with APN_SET_ID=1 1647 cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, 1648 Carriers.APN_SET_ID + "=?", new String[] { "1" }, null); 1649 assertEquals(1, cursor.getCount()); 1650 cursor.moveToFirst(); 1651 assertEquals(otherName, cursor.getString(0)); 1652 PhoneFactory.addLocalLog("TelephonyProvider", 1); 1653 } 1654 1655 /** 1656 * Test that querying with the PREFERAPNSET url yields all APNs in the preferred set. 1657 */ 1658 @Test 1659 @SmallTest testPreferApnSetUrl()1660 public void testPreferApnSetUrl() { 1661 setUpMockContext(true); 1662 1663 // create APNs 1664 ContentValues values1 = new ContentValues(); 1665 final String apn = "apnName"; 1666 final String apnName = "name"; 1667 values1.put(Carriers.APN, apn); 1668 values1.put(Carriers.NAME, apnName); 1669 values1.put(Carriers.NUMERIC, TEST_OPERATOR); 1670 1671 ContentValues values2 = new ContentValues(); 1672 final String apn2 = "otherApnName"; 1673 final String name2 = "name2"; 1674 values2.put(Carriers.APN, apn2); 1675 values2.put(Carriers.NAME, name2); 1676 values2.put(Carriers.NUMERIC, TEST_OPERATOR); 1677 values2.put(Carriers.APN_SET_ID, 1); 1678 1679 ContentValues values3 = new ContentValues(); 1680 final String apn3 = "thirdApnName"; 1681 final String name3 = "name3"; 1682 values3.put(Carriers.APN, apn3); 1683 values3.put(Carriers.NAME, name3); 1684 values3.put(Carriers.NUMERIC, TEST_OPERATOR); 1685 values3.put(Carriers.APN_SET_ID, 1); 1686 1687 // values4 has a matching setId but it belongs to a different carrier 1688 ContentValues values4 = new ContentValues(); 1689 final String apn4 = "fourthApnName"; 1690 final String name4 = "name4"; 1691 values4.put(Carriers.APN, apn4); 1692 values4.put(Carriers.NAME, name4); 1693 values4.put(Carriers.NUMERIC, "999888"); 1694 values4.put(Carriers.APN_SET_ID, 1); 1695 1696 // insert APNs 1697 // we explicitly include subid, as SubscriptionManager.getDefaultSubscriptionId() returns -1 1698 Log.d(TAG, "testPreferApnSetUrl: inserting contentValues=" + values1 + ", " + values2 1699 + ", " + values3 + ", " + values4); 1700 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values1); 1701 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values2); 1702 mContentResolver.insert(CONTENT_URI_WITH_SUBID, values4); 1703 Uri uri = mContentResolver.insert(CONTENT_URI_WITH_SUBID, values3); 1704 1705 // verify all APNs were correctly inserted 1706 final String[] testProjection = { Carriers.NAME }; 1707 Cursor cursor = mContentResolver.query( 1708 Carriers.CONTENT_URI, testProjection, null, null, null); 1709 assertEquals(4, cursor.getCount()); 1710 1711 // preferapnset/subId returns null when there is no preferred APN 1712 cursor = mContentResolver.query( 1713 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID), 1714 testProjection, null, null, null); 1715 assertNull(cursor); 1716 1717 // set the APN from values3 (apn_set_id = 1) to the preferred APN 1718 final String preferredApnIdString = uri.getLastPathSegment(); 1719 final long preferredApnId = Long.parseLong(preferredApnIdString); 1720 ContentValues prefer = new ContentValues(); 1721 prefer.put("apn_id", preferredApnId); 1722 int count = mContentResolver.update(URL_PREFERAPN_USING_SUBID, prefer, null, null); 1723 assertEquals(1, count); 1724 1725 // query APN with PREFERAPNSET url 1726 // explicitly include SUB_ID, as SubscriptionManager.getDefaultSubscriptionId() returns -1 1727 cursor = mContentResolver.query( 1728 Uri.withAppendedPath(Carriers.CONTENT_URI, "preferapnset/subId/" + TEST_SUBID), 1729 testProjection, null, null, null); 1730 // values4 which was inserted with a different carrier is not included in the results 1731 assertEquals(2, cursor.getCount()); 1732 cursor.moveToFirst(); 1733 assertEquals(name2, cursor.getString(0)); 1734 cursor.moveToNext(); 1735 assertEquals(name3, cursor.getString(0)); 1736 } 1737 1738 /** 1739 * Test URL_RESTOREAPN_USING_SUBID works correctly. 1740 */ 1741 @Test 1742 @SmallTest testRestoreDefaultApn()1743 public void testRestoreDefaultApn() { 1744 setUpMockContext(true); 1745 1746 // setup for multi-SIM 1747 TelephonyManager telephonyManager = 1748 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1749 doReturn(2).when(telephonyManager).getPhoneCount(); 1750 1751 // create APN to be deleted (including MVNO values) 1752 ContentValues targetValues = new ContentValues(); 1753 targetValues.put(Carriers.APN, "apnName"); 1754 targetValues.put(Carriers.NAME, "name"); 1755 targetValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1756 targetValues.put(Carriers.MVNO_TYPE, "spn"); 1757 targetValues.put(Carriers.MVNO_MATCH_DATA, TelephonyProviderTestable.TEST_SPN); 1758 // create other operator APN (sama MCCMNC) 1759 ContentValues otherValues = new ContentValues(); 1760 final String otherApn = "otherApnName"; 1761 final String otherName = "otherName"; 1762 final String otherMvnoTyp = "spn"; 1763 final String otherMvnoMatchData = "testOtherOperator"; 1764 otherValues.put(Carriers.APN, otherApn); 1765 otherValues.put(Carriers.NAME, otherName); 1766 otherValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1767 otherValues.put(Carriers.MVNO_TYPE, otherMvnoTyp); 1768 otherValues.put(Carriers.MVNO_MATCH_DATA, otherMvnoMatchData); 1769 1770 doReturn(true).when(telephonyManager).matchesCurrentSimOperator( 1771 anyString(), anyInt(), eq(TelephonyProviderTestable.TEST_SPN)); 1772 doReturn(false).when(telephonyManager).matchesCurrentSimOperator( 1773 anyString(), anyInt(), eq(otherMvnoMatchData)); 1774 1775 // insert APNs 1776 Log.d(TAG, "testRestoreDefaultApn: Bulk inserting contentValues=" + targetValues + ", " 1777 + otherValues); 1778 ContentValues[] values = new ContentValues[]{ targetValues, otherValues }; 1779 mContentResolver.bulkInsert(Carriers.CONTENT_URI, values); 1780 1781 // restore to default 1782 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1783 1784 // get values in table 1785 final String[] testProjection = 1786 { 1787 Carriers.APN, 1788 Carriers.NAME, 1789 Carriers.MVNO_TYPE, 1790 Carriers.MVNO_MATCH_DATA, 1791 }; 1792 // verify that deleted result match results of query 1793 Cursor cursor = mContentResolver.query( 1794 Carriers.CONTENT_URI, testProjection, null, null, null); 1795 assertEquals(1, cursor.getCount()); 1796 cursor.moveToFirst(); 1797 assertEquals(otherApn, cursor.getString(0)); 1798 assertEquals(otherName, cursor.getString(1)); 1799 assertEquals(otherMvnoTyp, cursor.getString(2)); 1800 assertEquals(otherMvnoMatchData, cursor.getString(3)); 1801 1802 // create APN to be deleted (not include MVNO values) 1803 ContentValues targetValues2 = new ContentValues(); 1804 targetValues2.put(Carriers.APN, "apnName"); 1805 targetValues2.put(Carriers.NAME, "name"); 1806 targetValues2.put(Carriers.NUMERIC, TEST_OPERATOR); 1807 1808 // insert APN 1809 mContentResolver.insert(Carriers.CONTENT_URI, targetValues2); 1810 1811 // restore to default 1812 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1813 1814 // verify that deleted result match results of query 1815 cursor = mContentResolver.query(Carriers.CONTENT_URI, testProjection, null, null, null); 1816 assertEquals(1, cursor.getCount()); 1817 cursor.moveToFirst(); 1818 assertEquals(otherApn, cursor.getString(0)); 1819 assertEquals(otherName, cursor.getString(1)); 1820 assertEquals(otherMvnoTyp, cursor.getString(2)); 1821 assertEquals(otherMvnoMatchData, cursor.getString(3)); 1822 1823 // setup for single-SIM 1824 doReturn(1).when(telephonyManager).getPhoneCount(); 1825 1826 // restore to default 1827 mContentResolver.delete(URL_RESTOREAPN_USING_SUBID, null, null); 1828 1829 // verify that deleted values are gone 1830 cursor = mContentResolver.query( 1831 Carriers.CONTENT_URI, testProjection, null, null, null); 1832 assertEquals(0, cursor.getCount()); 1833 assertEquals(3, notifyChangeRestoreCount); 1834 } 1835 1836 /** 1837 * Test changes to siminfo/WFC_IMS_ENABLED and simInfo/ENHANCED_4G 1838 */ 1839 @Test 1840 @SmallTest testUpdateWfcEnabled()1841 public void testUpdateWfcEnabled() { 1842 setUpMockContext(true); 1843 1844 // insert test contentValues 1845 ContentValues contentValues = new ContentValues(); 1846 final int insertSubId = 1; 1847 final String insertDisplayName = "exampleDisplayName"; 1848 final String insertCarrierName = "exampleCarrierName"; 1849 final String insertIccId = "exampleIccId"; 1850 final String insertCardId = "exampleCardId"; 1851 contentValues.put(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID, insertSubId); 1852 contentValues.put(SubscriptionManager.DISPLAY_NAME, insertDisplayName); 1853 contentValues.put(SubscriptionManager.CARRIER_NAME, insertCarrierName); 1854 contentValues.put(SubscriptionManager.ICC_ID, insertIccId); 1855 contentValues.put(SubscriptionManager.CARD_ID, insertCardId); 1856 1857 Log.d(TAG, "testSimTable Inserting wfc contentValues: " + contentValues); 1858 mContentResolver.insert(SimInfo.CONTENT_URI, contentValues); 1859 assertEquals(0, notifyWfcCount); 1860 1861 // update wfc_enabled 1862 ContentValues values = new ContentValues(); 1863 values.put(Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, true); 1864 final String selection = SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=?"; 1865 final String[] selectionArgs = { "" + insertSubId }; 1866 mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs); 1867 assertEquals(1, notifyWfcCount); 1868 assertEquals(0, notifyWfcCountWithTestSubId); 1869 1870 // update other fields 1871 values = new ContentValues(); 1872 values.put(SubscriptionManager.DISPLAY_NAME, "exampleDisplayNameNew"); 1873 mContentResolver.update(SimInfo.CONTENT_URI, values, selection, selectionArgs); 1874 // expect no change on wfc count 1875 assertEquals(1, notifyWfcCount); 1876 assertEquals(0, notifyWfcCountWithTestSubId); 1877 1878 // update WFC using subId 1879 values = new ContentValues(); 1880 values.put(Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED, false); 1881 mContentResolver.update(SubscriptionManager.getUriForSubscriptionId(insertSubId), 1882 values, null, null); 1883 assertEquals(1, notifyWfcCount); 1884 assertEquals(0, notifyWfcCountWithTestSubId); 1885 } 1886 1887 @Test 1888 @SmallTest testSIMAPNLIST_MatchTheMVNOAPN()1889 public void testSIMAPNLIST_MatchTheMVNOAPN() { 1890 setUpMockContext(true); 1891 1892 // Test on getSubscriptionMatchingAPNList() step 1 1893 final String apnName = "apnName"; 1894 final String carrierName = "name"; 1895 final String numeric = TEST_OPERATOR; 1896 final String mvnoType = "spn"; 1897 final String mvnoData = TEST_SPN; 1898 1899 // Insert the MVNO APN 1900 ContentValues contentValues = new ContentValues(); 1901 contentValues.put(Carriers.APN, apnName); 1902 contentValues.put(Carriers.NAME, carrierName); 1903 contentValues.put(Carriers.NUMERIC, numeric); 1904 contentValues.put(Carriers.MVNO_TYPE, mvnoType); 1905 contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData); 1906 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1907 1908 // Insert the MNO APN 1909 contentValues = new ContentValues(); 1910 contentValues.put(Carriers.APN, apnName); 1911 contentValues.put(Carriers.NAME, carrierName); 1912 contentValues.put(Carriers.NUMERIC, numeric); 1913 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1914 1915 TelephonyManager telephonyManager = 1916 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1917 doReturn(true).when(telephonyManager).matchesCurrentSimOperator( 1918 anyString(), anyInt(), eq(mvnoData)); 1919 doReturn(false).when(telephonyManager).matchesCurrentSimOperator( 1920 anyString(), anyInt(), eq("")); 1921 1922 // Query DB 1923 final String[] testProjection = 1924 { 1925 Carriers.APN, 1926 Carriers.NAME, 1927 Carriers.NUMERIC, 1928 Carriers.MVNO_MATCH_DATA 1929 }; 1930 1931 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 1932 testProjection, null, null, null); 1933 1934 // When the DB has MVNO and MNO APN, the query based on SIM_APN_LIST will return MVNO APN 1935 cursor.moveToFirst(); 1936 assertEquals(cursor.getCount(), 1); 1937 assertEquals(apnName, cursor.getString(0)); 1938 assertEquals(carrierName, cursor.getString(1)); 1939 assertEquals(numeric, cursor.getString(2)); 1940 assertEquals(mvnoData, cursor.getString(3)); 1941 } 1942 1943 @Test 1944 @SmallTest testSIMAPNLIST_MatchTheMNOAPN()1945 public void testSIMAPNLIST_MatchTheMNOAPN() { 1946 setUpMockContext(true); 1947 1948 // Test on getSubscriptionMatchingAPNList() step 2 1949 final String apnName = "apnName"; 1950 final String carrierName = "name"; 1951 final String numeric = TEST_OPERATOR; 1952 1953 // Insert the MNO APN 1954 ContentValues contentValues = new ContentValues(); 1955 contentValues.put(Carriers.APN, apnName); 1956 contentValues.put(Carriers.NAME, carrierName); 1957 contentValues.put(Carriers.NUMERIC, numeric); 1958 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1959 1960 // Query DB 1961 final String[] testProjection = 1962 { 1963 Carriers.APN, 1964 Carriers.NAME, 1965 Carriers.NUMERIC, 1966 }; 1967 1968 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 1969 testProjection, null, null, null); 1970 1971 cursor.moveToFirst(); 1972 assertEquals(apnName, cursor.getString(0)); 1973 assertEquals(carrierName, cursor.getString(1)); 1974 assertEquals(numeric, cursor.getString(2)); 1975 } 1976 1977 @Test 1978 @SmallTest testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN()1979 public void testSIMAPNLIST_MatchTheCarrierIDANDMNOAPN() { 1980 setUpMockContext(true); 1981 1982 // Test on getSubscriptionMatchingAPNList() will return the {MCCMNC} 1983 final String apnName = "apnName"; 1984 final String carrierName = "name"; 1985 final int carrierId = TEST_CARRIERID; 1986 1987 // Add the APN that only have carrier id 1988 ContentValues contentValues = new ContentValues(); 1989 contentValues.put(Carriers.APN, apnName); 1990 contentValues.put(Carriers.NAME, carrierName); 1991 contentValues.put(Carriers.CARRIER_ID, carrierId); 1992 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 1993 1994 // Add MNO APN that added by user 1995 contentValues = new ContentValues(); 1996 contentValues.put(Carriers.APN, apnName); 1997 contentValues.put(Carriers.NAME, carrierName); 1998 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 1999 contentValues.put(Carriers.EDITED_STATUS, Carriers.UNEDITED); 2000 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 2001 2002 // Query DB 2003 final String[] testProjection = 2004 { 2005 Carriers.APN, 2006 Carriers.NAME, 2007 Carriers.CARRIER_ID, 2008 }; 2009 2010 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, testProjection, null, null, null); 2011 2012 // The query based on SIM_APN_LIST will return MNO APN and the APN that has carrier id 2013 assertEquals(cursor.getCount(), 2); 2014 } 2015 2016 @Test 2017 @SmallTest testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN()2018 public void testSIMAPNLIST_MatchTheCarrierAPNAndMVNOAPN() { 2019 setUpMockContext(true); 2020 2021 final String apnName = "apnName"; 2022 final String carrierName = "name"; 2023 final String mvnoType = "spn"; 2024 final String mvnoData = TEST_SPN; 2025 final int carrierId = TEST_CARRIERID; 2026 2027 // Add the APN that only have carrier id 2028 ContentValues contentValues = new ContentValues(); 2029 contentValues.put(Carriers.APN, apnName); 2030 contentValues.put(Carriers.NAME, carrierName); 2031 contentValues.put(Carriers.CARRIER_ID, carrierId); 2032 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 2033 2034 // Add MVNO APN that added by user 2035 contentValues = new ContentValues(); 2036 contentValues.put(Carriers.APN, apnName); 2037 contentValues.put(Carriers.NAME, carrierName); 2038 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 2039 contentValues.put(Carriers.MVNO_TYPE, mvnoType); 2040 contentValues.put(Carriers.MVNO_MATCH_DATA, mvnoData); 2041 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 2042 2043 // Add MNO APN that added by user 2044 contentValues = new ContentValues(); 2045 contentValues.put(Carriers.APN, apnName); 2046 contentValues.put(Carriers.NAME, carrierName); 2047 contentValues.put(Carriers.NUMERIC, TEST_OPERATOR); 2048 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 2049 2050 // Query DB 2051 final String[] testProjection = 2052 { 2053 Carriers.APN, 2054 Carriers.NAME, 2055 Carriers.CARRIER_ID, 2056 Carriers.MVNO_TYPE, 2057 }; 2058 2059 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 2060 testProjection, null, null, null); 2061 2062 // The query based on SIM_APN_LIST will return MVNO APN and the APN that has carrier id 2063 assertEquals(cursor.getCount(), 2); 2064 while(cursor.moveToNext()) { 2065 assertTrue(!TextUtils.isEmpty(cursor.getString(2)) 2066 || !TextUtils.isEmpty(cursor.getString(3))); 2067 } 2068 } 2069 2070 @Test 2071 @SmallTest testSIMAPNLIST_isNotActiveSubscription()2072 public void testSIMAPNLIST_isNotActiveSubscription() { 2073 setUpMockContext(false); 2074 2075 // Test on getSubscriptionMatchingAPNList() step 2 2076 final String apnName = "apnName"; 2077 final String carrierName = "name"; 2078 final String numeric = TEST_OPERATOR; 2079 2080 // Insert the MNO APN 2081 ContentValues contentValues = new ContentValues(); 2082 contentValues.put(Carriers.APN, apnName); 2083 contentValues.put(Carriers.NAME, carrierName); 2084 contentValues.put(Carriers.NUMERIC, numeric); 2085 mContentResolver.insert(Carriers.CONTENT_URI, contentValues); 2086 2087 // Query DB 2088 final String[] testProjection = 2089 { 2090 Carriers.APN, 2091 Carriers.NAME, 2092 Carriers.NUMERIC, 2093 }; 2094 Cursor cursor = mContentResolver.query(URL_SIM_APN_LIST, 2095 testProjection, null, null, null); 2096 2097 assertNull(cursor); 2098 } 2099 } 2100