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