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