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