Home | History | Annotate | Download | only in telephony
      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