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