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 package com.android.internal.telephony; 17 18 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertTrue; 23 import static org.mockito.ArgumentMatchers.isNull; 24 import static org.mockito.Mockito.any; 25 import static org.mockito.Mockito.anyBoolean; 26 import static org.mockito.Mockito.anyInt; 27 import static org.mockito.Mockito.anyString; 28 import static org.mockito.Mockito.doReturn; 29 import static org.mockito.Mockito.eq; 30 import static org.mockito.Mockito.never; 31 import static org.mockito.Mockito.times; 32 import static org.mockito.Mockito.verify; 33 import static org.mockito.Mockito.when; 34 35 import android.content.ContentProvider; 36 import android.content.ContentValues; 37 import android.content.Context; 38 import android.content.Intent; 39 import android.content.pm.UserInfo; 40 import android.net.Uri; 41 import android.os.HandlerThread; 42 import android.service.euicc.EuiccProfileInfo; 43 import android.service.euicc.EuiccService; 44 import android.service.euicc.GetEuiccProfileInfoListResult; 45 import android.telephony.CarrierConfigManager; 46 import android.telephony.SubscriptionInfo; 47 import android.telephony.SubscriptionManager; 48 import android.test.mock.MockContentProvider; 49 import android.test.mock.MockContentResolver; 50 import android.test.suitebuilder.annotation.SmallTest; 51 52 import com.android.internal.telephony.euicc.EuiccController; 53 import com.android.internal.telephony.uicc.IccFileHandler; 54 import com.android.internal.telephony.uicc.IccRecords; 55 56 import org.junit.After; 57 import org.junit.Before; 58 import org.junit.Test; 59 import org.mockito.ArgumentCaptor; 60 import org.mockito.Mock; 61 import org.mockito.invocation.InvocationOnMock; 62 import org.mockito.stubbing.Answer; 63 64 import java.util.ArrayList; 65 import java.util.Arrays; 66 import java.util.HashMap; 67 import java.util.List; 68 69 public class SubscriptionInfoUpdaterTest extends TelephonyTest { 70 71 private static final int FAKE_SUB_ID_1 = 0; 72 private static final int FAKE_SUB_ID_2 = 1; 73 private static final String FAKE_MCC_MNC_1 = "123456"; 74 private static final String FAKE_MCC_MNC_2 = "456789"; 75 76 private SubscriptionInfoUpdaterHandlerThread mSubscriptionInfoUpdaterHandlerThread; 77 private SubscriptionInfoUpdater mUpdater; 78 private IccRecords mIccRecord; 79 @Mock 80 private UserInfo mUserInfo; 81 @Mock 82 private SubscriptionInfo mSubInfo; 83 @Mock 84 private ContentProvider mContentProvider; 85 @Mock 86 private HashMap<String, Object> mSubscriptionContent; 87 @Mock 88 private IccFileHandler mIccFileHandler; 89 @Mock 90 private EuiccController mEuiccController; 91 @Mock 92 private IntentBroadcaster mIntentBroadcaster; 93 94 /*Custom ContentProvider */ 95 private class FakeSubscriptionContentProvider extends MockContentProvider { 96 @Override 97 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 98 return mContentProvider.update(uri, values, selection, selectionArgs); 99 } 100 } 101 102 private class SubscriptionInfoUpdaterHandlerThread extends HandlerThread { 103 104 private SubscriptionInfoUpdaterHandlerThread(String name) { 105 super(name); 106 } 107 108 @Override 109 public void onLooperPrepared() { 110 mUpdater = new SubscriptionInfoUpdater(getLooper(), mContext, new Phone[]{mPhone}, 111 new CommandsInterface[]{mSimulatedCommands}); 112 setReady(true); 113 } 114 } 115 116 @Before 117 public void setUp() throws Exception { 118 super.setUp(this.getClass().getSimpleName()); 119 120 replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]); 121 replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[1]); 122 replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null); 123 replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1); 124 replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]); 125 replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, new int[1]); 126 127 replaceInstance(EuiccController.class, "sInstance", null, mEuiccController); 128 replaceInstance(IntentBroadcaster.class, "sIntentBroadcaster", null, mIntentBroadcaster); 129 130 doReturn(1).when(mTelephonyManager).getSimCount(); 131 doReturn(1).when(mTelephonyManager).getPhoneCount(); 132 133 when(mContentProvider.update(any(), any(), any(), isNull())).thenAnswer( 134 new Answer<Integer>() { 135 @Override 136 public Integer answer(InvocationOnMock invocation) throws Throwable { 137 ContentValues values = invocation.getArgument(1); 138 for (String key : values.keySet()) { 139 mSubscriptionContent.put(key, values.get(key)); 140 } 141 return 1; 142 } 143 }); 144 145 doReturn(mUserInfo).when(mIActivityManager).getCurrentUser(); 146 doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getSubId(0); 147 doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionManager).getActiveSubscriptionIdList(); 148 ((MockContentResolver) mContext.getContentResolver()).addProvider( 149 SubscriptionManager.CONTENT_URI.getAuthority(), 150 new FakeSubscriptionContentProvider()); 151 doReturn(new int[]{}).when(mSubscriptionController).getActiveSubIdList(); 152 mIccRecord = mUiccProfile.getIccRecords(); 153 154 mSubscriptionInfoUpdaterHandlerThread = new SubscriptionInfoUpdaterHandlerThread(TAG); 155 mSubscriptionInfoUpdaterHandlerThread.start(); 156 waitUntilReady(); 157 } 158 159 @After 160 public void tearDown() throws Exception { 161 mSubscriptionInfoUpdaterHandlerThread.quit(); 162 super.tearDown(); 163 } 164 165 @Test 166 @SmallTest 167 public void testSimAbsent() throws Exception { 168 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) 169 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); 170 doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController).getActiveSubIdList(); 171 mUpdater.updateInternalIccState( 172 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1); 173 174 waitForMs(100); 175 verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), 176 eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); 177 178 CarrierConfigManager mConfigManager = (CarrierConfigManager) 179 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 180 verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 181 eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT)); 182 verify(mSubscriptionController, times(1)).clearSubInfo(); 183 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 184 } 185 186 @Test 187 @SmallTest 188 public void testSimUnknown() throws Exception { 189 mUpdater.updateInternalIccState( 190 IccCardConstants.INTENT_VALUE_ICC_UNKNOWN, null, FAKE_SUB_ID_1); 191 192 waitForMs(100); 193 verify(mSubscriptionContent, times(0)).put(anyString(), any()); 194 CarrierConfigManager mConfigManager = (CarrierConfigManager) 195 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 196 verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 197 eq(IccCardConstants.INTENT_VALUE_ICC_UNKNOWN)); 198 verify(mSubscriptionController, times(0)).clearSubInfo(); 199 verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); 200 } 201 202 @Test 203 @SmallTest 204 public void testSimError() throws Exception { 205 mUpdater.updateInternalIccState( 206 IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR, null, FAKE_SUB_ID_1); 207 208 waitForMs(100); 209 verify(mSubscriptionContent, times(0)).put(anyString(), any()); 210 CarrierConfigManager mConfigManager = (CarrierConfigManager) 211 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 212 verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 213 eq(IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR)); 214 verify(mSubscriptionController, times(0)).clearSubInfo(); 215 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 216 } 217 218 @Test 219 @SmallTest 220 public void testWrongSimState() throws Exception { 221 mUpdater.updateInternalIccState( 222 IccCardConstants.INTENT_VALUE_ICC_IMSI, null, 2); 223 224 waitForMs(100); 225 verify(mSubscriptionContent, times(0)).put(anyString(), any()); 226 CarrierConfigManager mConfigManager = (CarrierConfigManager) 227 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 228 verify(mConfigManager, times(0)).updateConfigForPhoneId(eq(2), 229 eq(IccCardConstants.INTENT_VALUE_ICC_IMSI)); 230 verify(mSubscriptionController, times(0)).clearSubInfo(); 231 verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); 232 } 233 234 @Test 235 @SmallTest 236 public void testSimLoaded() throws Exception { 237 /* mock new sim got loaded and there is no sim loaded before */ 238 doReturn(null).when(mSubscriptionController) 239 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); 240 doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); 241 doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); 242 243 mUpdater.updateInternalIccState( 244 IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); 245 246 waitForMs(100); 247 248 // verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for 249 // READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE 250 /* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent() 251 * uncomment code below when that is fixed 252 */ 253 /* ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); 254 ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class); 255 verify(mContext, times(2)).sendBroadcast(intentArgumentCaptor.capture(), 256 stringArgumentCaptor.capture()); 257 assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED, 258 intentArgumentCaptor.getAllValues().get(0).getAction()); 259 assertEquals(Manifest.permission.READ_PHONE_STATE, 260 stringArgumentCaptor.getAllValues().get(0)); 261 assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED, 262 intentArgumentCaptor.getAllValues().get(1).getAction()); 263 assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 264 stringArgumentCaptor.getAllValues().get(1)); */ 265 266 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 267 verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); 268 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( 269 eq("89012604200000000000"), eq(FAKE_SUB_ID_1)); 270 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 271 verify(mSubscriptionController, times(1)).setMccMnc(FAKE_MCC_MNC_1, FAKE_SUB_ID_1); 272 verify(mSubscriptionController, times(0)).clearSubInfo(); 273 CarrierConfigManager mConfigManager = (CarrierConfigManager) 274 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 275 verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 276 eq(IccCardConstants.INTENT_VALUE_ICC_LOADED)); 277 278 // ACTION_USER_UNLOCKED should trigger another SIM_STATE_CHANGED 279 Intent intentSimStateChanged = new Intent(Intent.ACTION_USER_UNLOCKED); 280 mContext.sendBroadcast(intentSimStateChanged); 281 waitForMs(100); 282 283 // verify SIM_STATE_CHANGED broadcast 284 /* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent() 285 * uncomment code below when that is fixed 286 */ 287 /* verify(mContext, times(4)).sendBroadcast(intentArgumentCaptor.capture(), 288 stringArgumentCaptor.capture()); 289 assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED, 290 intentArgumentCaptor.getAllValues().get(2).getAction()); 291 assertEquals(Manifest.permission.READ_PHONE_STATE, 292 stringArgumentCaptor.getAllValues().get(2)); 293 assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED, 294 intentArgumentCaptor.getAllValues().get(3).getAction()); 295 assertEquals(Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 296 stringArgumentCaptor.getAllValues().get(3)); */ 297 } 298 299 @Test 300 @SmallTest 301 public void testSimLoadedEmptyOperatorNumeric() throws Exception { 302 /* mock new sim got loaded and there is no sim loaded before */ 303 doReturn(null).when(mSubscriptionController) 304 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); 305 doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); 306 // operator numeric is empty 307 doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); 308 mUpdater.updateInternalIccState( 309 IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); 310 311 waitForMs(100); 312 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 313 verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1); 314 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( 315 eq("89012604200000000000"), eq(FAKE_SUB_ID_1)); 316 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 317 verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); 318 verify(mSubscriptionController, times(0)).clearSubInfo(); 319 CarrierConfigManager mConfigManager = (CarrierConfigManager) 320 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 321 verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 322 eq(IccCardConstants.INTENT_VALUE_ICC_LOADED)); 323 } 324 325 @Test 326 @SmallTest 327 public void testSimLockedWithOutIccId() throws Exception { 328 /* mock no IccId Info present and try to query IccId 329 after IccId query, update subscriptionDB */ 330 doReturn("98106240020000000000").when(mIccRecord).getFullIccId(); 331 332 doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController) 333 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean()); 334 mUpdater.updateInternalIccState( 335 IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1); 336 337 waitForMs(100); 338 339 /* old IccId != new queried IccId */ 340 verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX), 341 eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX)); 342 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 343 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( 344 eq("98106240020000000000"), eq(FAKE_SUB_ID_1)); 345 346 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 347 verify(mSubscriptionController, times(0)).clearSubInfo(); 348 CarrierConfigManager mConfigManager = (CarrierConfigManager) 349 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 350 verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 351 eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED)); 352 } 353 354 @Test 355 @SmallTest 356 public void testDualSimLoaded() throws Exception { 357 // Mock there is two sim cards 358 359 replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, 360 new String[]{null, null}); 361 replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2); 362 replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null, 363 new Phone[]{mPhone, mPhone}); 364 replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, 365 new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE, 366 SubscriptionInfoUpdater.SIM_NOT_CHANGE}); 367 replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, 368 new int[]{0, 0}); 369 replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null, 370 new int[]{0, 0}); 371 372 doReturn(new int[]{FAKE_SUB_ID_1, FAKE_SUB_ID_2}).when(mSubscriptionManager) 373 .getActiveSubscriptionIdList(); 374 doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_1)); 375 doReturn(FAKE_SUB_ID_2).when(mSubscriptionController).getPhoneId(eq(FAKE_SUB_ID_2)); 376 doReturn(2).when(mTelephonyManager).getSimCount(); 377 doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1)); 378 doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2)); 379 // Mock there is no sim inserted before 380 doReturn(null).when(mSubscriptionController) 381 .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); 382 verify(mSubscriptionController, times(0)).clearSubInfo(); 383 doReturn("89012604200000000000").when(mIccRecord).getFullIccId(); 384 385 // Mock sending a sim loaded for SIM 1 386 mUpdater.updateInternalIccState( 387 IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1); 388 389 waitForMs(100); 390 391 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 392 verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt()); 393 verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged(); 394 verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt()); 395 396 // Mock sending a sim loaded for SIM 2 397 doReturn("89012604200000000001").when(mIccRecord).getFullIccId(); 398 399 mUpdater.updateInternalIccState( 400 IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2); 401 402 waitForMs(100); 403 404 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000000"), 405 eq(FAKE_SUB_ID_1)); 406 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000001"), 407 eq(FAKE_SUB_ID_2)); 408 verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1)); 409 verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2)); 410 verify(mSubscriptionController, times(0)).clearSubInfo(); 411 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 412 } 413 414 @Test 415 @SmallTest 416 public void testSimLockWithIccId() throws Exception { 417 /* no need for IccId query */ 418 419 replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, 420 new String[]{"89012604200000000000"}); 421 422 mUpdater.updateInternalIccState( 423 IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1); 424 425 waitForMs(100); 426 427 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 428 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord( 429 anyString(), eq(FAKE_SUB_ID_1)); 430 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 431 verify(mSubscriptionController, times(0)).clearSubInfo(); 432 CarrierConfigManager mConfigManager = (CarrierConfigManager) 433 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 434 /* broadcast is done */ 435 verify(mConfigManager, times(1)).updateConfigForPhoneId(eq(FAKE_SUB_ID_1), 436 eq(IccCardConstants.INTENT_VALUE_ICC_LOCKED)); 437 } 438 439 @Test 440 @SmallTest 441 public void testUpdateEmbeddedSubscriptions_listSuccess() throws Exception { 442 when(mEuiccManager.isEnabled()).thenReturn(true); 443 444 EuiccProfileInfo[] euiccProfiles = new EuiccProfileInfo[] { 445 new EuiccProfileInfo("1", null /* accessRules */, null /* nickname */), 446 new EuiccProfileInfo("3", null /* accessRules */, null /* nickname */), 447 }; 448 when(mEuiccController.blockingGetEuiccProfileInfoList()).thenReturn( 449 new GetEuiccProfileInfoListResult( 450 EuiccService.RESULT_OK, euiccProfiles, false /* removable */)); 451 452 List<SubscriptionInfo> subInfoList = new ArrayList<>(); 453 // 1: not embedded, but has matching iccid with an embedded subscription. 454 subInfoList.add(new SubscriptionInfo( 455 0, "1", 0, "", "", 0, 0, "", 0, null, 0, 0, "", false /* isEmbedded */, 456 null /* accessRules */)); 457 // 2: embedded but no longer present. 458 subInfoList.add(new SubscriptionInfo( 459 0, "2", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, 460 null /* accessRules */)); 461 462 when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate( 463 new String[] { "1", "3"}, false /* removable */)).thenReturn(subInfoList); 464 465 assertTrue(mUpdater.updateEmbeddedSubscriptions()); 466 467 // 3 is new and so a new entry should have been created. 468 verify(mSubscriptionController).insertEmptySubInfoRecord( 469 "3", SubscriptionManager.SIM_NOT_INSERTED); 470 // 1 already existed, so no new entries should be created for it. 471 verify(mSubscriptionController, times(0)).clearSubInfo(); 472 verify(mSubscriptionController, never()).insertEmptySubInfoRecord(eq("1"), anyInt()); 473 474 // Info for 1 and 3 should be updated as active embedded subscriptions. 475 ArgumentCaptor<ContentValues> iccid1Values = ArgumentCaptor.forClass(ContentValues.class); 476 verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid1Values.capture(), 477 eq(SubscriptionManager.ICC_ID + "=\"1\""), isNull()); 478 assertEquals(1, 479 iccid1Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue()); 480 ArgumentCaptor<ContentValues> iccid3Values = ArgumentCaptor.forClass(ContentValues.class); 481 verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid3Values.capture(), 482 eq(SubscriptionManager.ICC_ID + "=\"3\""), isNull()); 483 assertEquals(1, 484 iccid3Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue()); 485 486 // 2 should have been removed since it was returned from the cache but was not present 487 // in the list provided by the LPA. 488 ArgumentCaptor<ContentValues> iccid2Values = ArgumentCaptor.forClass(ContentValues.class); 489 verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid2Values.capture(), 490 eq(SubscriptionManager.ICC_ID + " IN (\"2\")"), isNull()); 491 assertEquals(0, 492 iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue()); 493 } 494 495 @Test 496 @SmallTest 497 public void testUpdateEmbeddedSubscriptions_listFailure() throws Exception { 498 when(mEuiccManager.isEnabled()).thenReturn(true); 499 when(mEuiccController.blockingGetEuiccProfileInfoList()) 500 .thenReturn(new GetEuiccProfileInfoListResult( 501 42, null /* subscriptions */, false /* removable */)); 502 503 List<SubscriptionInfo> subInfoList = new ArrayList<>(); 504 // 1: not embedded, but has matching iccid with an embedded subscription. 505 subInfoList.add(new SubscriptionInfo( 506 0, "1", 0, "", "", 0, 0, "", 0, null, 0, 0, "", false /* isEmbedded */, 507 null /* accessRules */)); 508 // 2: embedded. 509 subInfoList.add(new SubscriptionInfo( 510 0, "2", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */, 511 null /* accessRules */)); 512 513 when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate( 514 new String[0], false /* removable */)).thenReturn(subInfoList); 515 516 assertTrue(mUpdater.updateEmbeddedSubscriptions()); 517 518 // No new entries should be created. 519 verify(mSubscriptionController, times(0)).clearSubInfo(); 520 verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt()); 521 522 // 1 should not have been touched. 523 verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(), 524 eq(SubscriptionManager.ICC_ID + "=\"1\""), isNull()); 525 verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(), 526 eq(SubscriptionManager.ICC_ID + "IN (\"1\")"), isNull()); 527 528 // 2 should have been removed since it was returned from the cache but the LPA had an 529 // error when listing. 530 ArgumentCaptor<ContentValues> iccid2Values = ArgumentCaptor.forClass(ContentValues.class); 531 verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid2Values.capture(), 532 eq(SubscriptionManager.ICC_ID + " IN (\"2\")"), isNull()); 533 assertEquals(0, 534 iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue()); 535 } 536 537 @Test 538 @SmallTest 539 public void testUpdateEmbeddedSubscriptions_emptyToEmpty() throws Exception { 540 when(mEuiccManager.isEnabled()).thenReturn(true); 541 when(mEuiccController.blockingGetEuiccProfileInfoList()) 542 .thenReturn(new GetEuiccProfileInfoListResult( 543 42, null /* subscriptions */, true /* removable */)); 544 545 List<SubscriptionInfo> subInfoList = new ArrayList<>(); 546 // 1: not embedded. 547 subInfoList.add(new SubscriptionInfo( 548 0, "1", 0, "", "", 0, 0, "", 0, null, 0, 0, "", false /* isEmbedded */, 549 null /* accessRules */)); 550 551 when(mSubscriptionController.getSubscriptionInfoListForEmbeddedSubscriptionUpdate( 552 new String[0], false /* removable */)).thenReturn(subInfoList); 553 554 assertFalse(mUpdater.updateEmbeddedSubscriptions()); 555 556 // No new entries should be created. 557 verify(mSubscriptionController, never()).insertEmptySubInfoRecord(anyString(), anyInt()); 558 559 // No existing entries should have been updated. 560 verify(mContentProvider, never()).update(eq(SubscriptionManager.CONTENT_URI), any(), 561 any(), isNull()); 562 } 563 564 @Test 565 @SmallTest 566 public void testHexIccIdSuffix() throws Exception { 567 doReturn(null).when(mSubscriptionController) 568 .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean()); 569 verify(mSubscriptionController, times(0)).clearSubInfo(); 570 doReturn("890126042000000000Ff").when(mIccRecord).getFullIccId(); 571 572 // Mock sending a sim loaded for SIM 1 573 mUpdater.updateInternalIccState( 574 IccCardConstants.INTENT_VALUE_ICC_LOADED, "TESTING", FAKE_SUB_ID_1); 575 576 waitForMs(100); 577 578 SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext); 579 verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged(); 580 verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("890126042000000000"), 581 eq(FAKE_SUB_ID_1)); 582 verify(mSubscriptionController, times(0)).clearSubInfo(); 583 } 584 } 585