Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc5ebc6f authored by Chen Xu's avatar Chen Xu Committed by Android (Google) Code Review
Browse files

Merge "refactor updateIccId for msim"

parents 6dc4a897 37f0cc88
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -1073,6 +1073,35 @@ public class SubscriptionController extends ISub.Stub {
        return 0;
    }

    /**
     * Clear an subscriptionInfo to subinfo database if needed by updating slot index to invalid.
     * @param slotIndex the slot which the SIM is removed
     */
    public void clearSubInfoRecord(int slotIndex) {
        if (DBG) logdl("[clearSubInfoRecord]+ iccId:" + " slotIndex:" + slotIndex);

        // update simInfo db with invalid slot index
        List<SubscriptionInfo> oldSubInfo = getSubInfoUsingSlotIndexPrivileged(slotIndex,
                false);
        ContentResolver resolver = mContext.getContentResolver();
        ContentValues value = new ContentValues(1);
        value.put(SubscriptionManager.SIM_SLOT_INDEX,
                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
        if (oldSubInfo != null) {
            for (int i = 0; i < oldSubInfo.size(); i++) {
                resolver.update(SubscriptionManager.getUriForSubscriptionId(
                        oldSubInfo.get(i).getSubscriptionId()), value, null, null);
            }
        }
        // Refresh the Cache of Active Subscription Info List
        refreshCachedActiveSubscriptionInfoList();

        sSlotIndexToSubId.remove(slotIndex);

        // update default subId
        clearDefaultsForInactiveSubIds();
    }

    /**
     * Insert an empty SubInfo record into the database.
     *
+71 −190
Original line number Diff line number Diff line
@@ -85,28 +85,6 @@ public class SubscriptionInfoUpdater extends Handler {
    private static final int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12;

    private static final String ICCID_STRING_FOR_NO_SIM = "";
    /**
     *  int[] sInsertSimState maintains all slots' SIM inserted status currently,
     *  it may contain 4 kinds of values:
     *    SIM_NOT_INSERT : no SIM inserted in slot i now
     *    SIM_CHANGED    : a valid SIM insert in slot i and is different SIM from last time
     *                     it will later become SIM_NEW or SIM_REPOSITION during update procedure
     *    SIM_NOT_CHANGE : a valid SIM insert in slot i and is the same SIM as last time
     *    SIM_NEW        : a valid SIM insert in slot i and is a new SIM
     *    SIM_REPOSITION : a valid SIM insert in slot i and is inserted in different slot last time
     *    positive integer #: index to distinguish SIM cards with the same IccId
     */
    public static final int SIM_NOT_CHANGE = 0;
    public static final int SIM_CHANGED    = -1;
    public static final int SIM_NEW        = -2;
    public static final int SIM_REPOSITION = -3;
    public static final int SIM_NOT_INSERT = -99;

    public static final int STATUS_NO_SIM_INSERTED = 0x00;
    public static final int STATUS_SIM1_INSERTED = 0x01;
    public static final int STATUS_SIM2_INSERTED = 0x02;
    public static final int STATUS_SIM3_INSERTED = 0x04;
    public static final int STATUS_SIM4_INSERTED = 0x08;

    // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED.
    public static final String CURR_SUBID = "curr_subid";
@@ -114,7 +92,6 @@ public class SubscriptionInfoUpdater extends Handler {
    private static Phone[] mPhone;
    private static Context mContext = null;
    private static String mIccId[] = new String[PROJECT_SIM_NUM];
    private static int[] mInsertSimState = new int[PROJECT_SIM_NUM];
    private static int[] sSimCardState = new int[PROJECT_SIM_NUM];
    private static int[] sSimApplicationState = new int[PROJECT_SIM_NUM];
    private SubscriptionManager mSubscriptionManager = null;
@@ -330,9 +307,7 @@ public class SubscriptionInfoUpdater extends Handler {
            logd("NOT Querying IccId its already set sIccid[" + slotId + "]=" + iccId);
        }

        if (isAllIccIdQueryDone()) {
            updateSubscriptionInfoByIccId();
        }
        updateSubscriptionInfoByIccId(slotId);

        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_LOCKED, reason);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_PRESENT);
@@ -366,9 +341,7 @@ public class SubscriptionInfoUpdater extends Handler {
            // phase, the subscription list is accessible. Treating NOT_READY
            // as equivalent to ABSENT, once the rest of the system can handle it.
            mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
            if (isAllIccIdQueryDone()) {
                updateSubscriptionInfoByIccId();
            }
            updateSubscriptionInfoByIccId(slotId);
        }

        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY,
@@ -400,14 +373,16 @@ public class SubscriptionInfoUpdater extends Handler {
        }
        mIccId[slotId] = IccUtils.stripTrailingFs(records.getFullIccId());

        if (isAllIccIdQueryDone()) {
            updateSubscriptionInfoByIccId();
            int[] subIds = mSubscriptionManager.getActiveSubscriptionIdList();
            for (int subId : subIds) {
        updateSubscriptionInfoByIccId(slotId);
        List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance()
                .getSubInfoUsingSlotIndexPrivileged(slotId, false);
        if (subscriptionInfos == null || subscriptionInfos.isEmpty()) {
            loge("empty subinfo for slotId: " + slotId + "could not update ContentResolver");
        } else {
            for (SubscriptionInfo sub : subscriptionInfos) {
                int subId = sub.getSubscriptionId();
                TelephonyManager tm = TelephonyManager.getDefault();

                String operator = tm.getSimOperatorNumeric(subId);
                slotId = SubscriptionController.getInstance().getPhoneId(subId);

                if (!TextUtils.isEmpty(operator)) {
                    if (subId == SubscriptionController.getInstance().getDefaultSubId()) {
@@ -427,8 +402,6 @@ public class SubscriptionInfoUpdater extends Handler {
                }

                String msisdn = tm.getLine1Number(subId);
                ContentResolver contentResolver = mContext.getContentResolver();

                if (msisdn != null) {
                    SubscriptionController.getInstance().setDisplayNumber(msisdn, subId);
                }
@@ -449,7 +422,8 @@ public class SubscriptionInfoUpdater extends Handler {
                }

                /* Update preferred network type and network selection mode on SIM change.
                 * Storing last subId in SharedPreference for now to detect SIM change. */
                 * Storing last subId in SharedPreference for now to detect SIM change.
                 */
                SharedPreferences sp =
                        PreferenceManager.getDefaultSharedPreferences(mContext);
                int storedSubId = sp.getInt(CURR_SUBID + slotId, -1);
@@ -530,9 +504,7 @@ public class SubscriptionInfoUpdater extends Handler {
            logd("SIM" + (slotId + 1) + " hot plug out");
        }
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        if (isAllIccIdQueryDone()) {
            updateSubscriptionInfoByIccId();
        }
        updateSubscriptionInfoByIccId(slotId);
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT);
        broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY);
@@ -545,9 +517,7 @@ public class SubscriptionInfoUpdater extends Handler {
            logd("SIM" + (slotId + 1) + " Error ");
        }
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        if (isAllIccIdQueryDone()) {
            updateSubscriptionInfoByIccId();
        }
        updateSubscriptionInfoByIccId(slotId);
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR,
                IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR);
@@ -556,138 +526,43 @@ public class SubscriptionInfoUpdater extends Handler {
        updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
    }

    /**
     * TODO: Simplify more, as no one is interested in what happened
     * only what the current list contains.
     */
    synchronized private void updateSubscriptionInfoByIccId() {
    synchronized private void updateSubscriptionInfoByIccId(int slotIndex) {
        logd("updateSubscriptionInfoByIccId:+ Start");

        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            mInsertSimState[i] = SIM_NOT_CHANGE;
        }

        int insertedSimCount = PROJECT_SIM_NUM;
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (ICCID_STRING_FOR_NO_SIM.equals(mIccId[i])) {
                insertedSimCount--;
                mInsertSimState[i] = SIM_NOT_INSERT;
            }
        }
        logd("insertedSimCount = " + insertedSimCount);

        // We only clear the slot-to-sub map when one/some SIM was removed. Note this is a
        // workaround for some race conditions that the empty map was accessed while we are
        // rebuilding the map.
        if (SubscriptionController.getInstance().getActiveSubIdList().length > insertedSimCount) {
            SubscriptionController.getInstance().clearSubInfo();
        }

        int index = 0;
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mInsertSimState[i] == SIM_NOT_INSERT) {
                continue;
            }
            index = 2;
            for (int j = i + 1; j < PROJECT_SIM_NUM; j++) {
                if (mInsertSimState[j] == SIM_NOT_CHANGE && mIccId[i].equals(mIccId[j])) {
                    mInsertSimState[i] = 1;
                    mInsertSimState[j] = index;
                    index++;
                }
            }
        }

        ContentResolver contentResolver = mContext.getContentResolver();
        String[] oldIccId = new String[PROJECT_SIM_NUM];
        String[] decIccId = new String[PROJECT_SIM_NUM];
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            oldIccId[i] = null;
            List<SubscriptionInfo> oldSubInfo = SubscriptionController.getInstance()
                    .getSubInfoUsingSlotIndexPrivileged(i, false);
            decIccId[i] = IccUtils.getDecimalSubstring(mIccId[i]);
            if (oldSubInfo != null && oldSubInfo.size() > 0) {
                oldIccId[i] = oldSubInfo.get(0).getIccId();
                logd("updateSubscriptionInfoByIccId: oldSubId = "
                        + oldSubInfo.get(0).getSubscriptionId());
                if (mInsertSimState[i] == SIM_NOT_CHANGE && !(mIccId[i].equals(oldIccId[i])
                            || (decIccId[i] != null && decIccId[i].equals(oldIccId[i])))) {
                    mInsertSimState[i] = SIM_CHANGED;
                }
                if (mInsertSimState[i] != SIM_NOT_CHANGE) {
                    ContentValues value = new ContentValues(1);
                    value.put(SubscriptionManager.SIM_SLOT_INDEX,
                            SubscriptionManager.INVALID_SIM_SLOT_INDEX);
                    contentResolver.update(SubscriptionManager.getUriForSubscriptionId(
                            oldSubInfo.get(0).getSubscriptionId()), value, null, null);

                    // refresh Cached Active Subscription Info List
                    SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
                }
            } else {
                if (mInsertSimState[i] == SIM_NOT_CHANGE) {
                    // no SIM inserted last time, but there is one SIM inserted now
                    mInsertSimState[i] = SIM_CHANGED;
                }
                oldIccId[i] = ICCID_STRING_FOR_NO_SIM;
                logd("updateSubscriptionInfoByIccId: No SIM in slot " + i + " last time");
            }
        }

        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            logd("updateSubscriptionInfoByIccId: oldIccId[" + i + "] = " + oldIccId[i] +
                    ", sIccId[" + i + "] = " + mIccId[i]);
        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
            loge("[updateSubscriptionInfoByIccId]- invalid slotIndex=" + slotIndex);
            return;
        }
        logd("updateSubscriptionInfoByIccId: removing subscription info record: slotIndex "
                + slotIndex);
        // Clear slotIndex only when sim absent is not enough. It's possible to switch SIM profile
        // within the same slot. Need to clear the slot index of the previous sub. Thus always clear
        // for the changing slot first.
        SubscriptionController.getInstance().clearSubInfoRecord(slotIndex);

        //check if the inserted SIM is new SIM
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mInsertSimState[i] == SIM_NOT_INSERT) {
                logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time");
            } else {
                if (mInsertSimState[i] > 0) {
                    //some special SIMs may have the same IccIds, add suffix to distinguish them
                    //FIXME: addSubInfoRecord can return an error.
                    mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i]
                            + Integer.toString(mInsertSimState[i]), i);
                    logd("SUB" + (i + 1) + " has invalid IccId");
                } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ {
        // If SIM is not absent, insert new record or update existing record.
        if (!ICCID_STRING_FOR_NO_SIM.equals(mIccId[slotIndex])) {
           logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "
                            + mIccId[i] + "slot: " + i);
                    mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i);
                }
                if (isNewSim(mIccId[i], decIccId[i], oldIccId)) {
                    mInsertSimState[i] = SIM_NEW;
                }
            }
        }

        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            if (mInsertSimState[i] == SIM_CHANGED) {
                mInsertSimState[i] = SIM_REPOSITION;
            }
            logd("updateSubscriptionInfoByIccId: sInsertSimState[" + i + "] = "
                    + mInsertSimState[i]);
                    + mIccId[slotIndex] + "slot: " + slotIndex);
           mSubscriptionManager.addSubscriptionInfoRecord(mIccId[slotIndex], slotIndex);
        }

        List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
        int nSubCount = (subInfos == null) ? 0 : subInfos.size();
        logd("updateSubscriptionInfoByIccId: nSubCount = " + nSubCount);
        List<SubscriptionInfo> subInfos = SubscriptionController.getInstance()
                .getSubInfoUsingSlotIndexPrivileged(slotIndex, false);
        if (subInfos != null) {
            boolean changed = false;
        for (int i=0; i < nSubCount; i++) {
            for (int i = 0; i < subInfos.size(); i++) {
                SubscriptionInfo temp = subInfos.get(i);
                ContentValues value = new ContentValues(1);

                String msisdn = TelephonyManager.getDefault().getLine1Number(
                        temp.getSubscriptionId());

            UiccSlot uiccSlot = UiccController.getInstance()
                    .getUiccSlotForPhone(temp.getSimSlotIndex());
                UiccSlot uiccSlot = UiccController.getInstance().getUiccSlotForPhone(slotIndex);
                boolean isEuicc = (uiccSlot != null && uiccSlot.isEuicc());

                if (isEuicc != temp.isEmbedded() || !TextUtils.equals(msisdn, temp.getNumber())) {
                    value.put(SubscriptionManager.IS_EMBEDDED, isEuicc);
                    value.put(SubscriptionManager.NUMBER, msisdn);
                contentResolver.update(SubscriptionManager.getUriForSubscriptionId(
                    mContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId(
                            temp.getSubscriptionId()), value, null, null);
                    changed = true;
                }
@@ -696,12 +571,13 @@ public class SubscriptionInfoUpdater extends Handler {
                // refresh Cached Active Subscription Info List
                SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
            }
        }

        // TODO investigate if we can update for each slot separately.
        if (isAllIccIdQueryDone()) {
            // Ensure the modems are mapped correctly
            mSubscriptionManager.setDefaultDataSubId(
                    mSubscriptionManager.getDefaultDataSubscriptionId());

        // No need to check return value here as we notify for the above changes anyway.
            UiccController uiccController = UiccController.getInstance();
            UiccSlot[] uiccSlots = uiccController.getUiccSlots();
            if (uiccSlots != null) {
@@ -711,6 +587,7 @@ public class SubscriptionInfoUpdater extends Handler {
                                uiccSlot.getUiccCard().getCardId()))
                        .forEach(cardId -> updateEmbeddedSubscriptions(cardId));
            }
        }

        SubscriptionController.getInstance().notifySubscriptionInfoChanged();
        logd("updateSubscriptionInfoByIccId:- SubscriptionInfo update complete");
@@ -962,6 +839,10 @@ public class SubscriptionInfoUpdater extends Handler {
        Rlog.d(LOG_TAG, message);
    }

    private void loge(String message) {
        Rlog.e(LOG_TAG, message);
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("SubscriptionInfoUpdater:");
        mCarrierServiceBindHelper.dump(fd, pw, args);
+19 −25
Original line number Diff line number Diff line
@@ -122,7 +122,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        super.setUp(this.getClass().getSimpleName());

        replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]);
        replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null, new int[1]);
        replaceInstance(SubscriptionInfoUpdater.class, "mContext", null, null);
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1);
        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[1]);
@@ -176,14 +175,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);

        waitForMs(100);
        verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX),
                eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX));
        verify(mSubscriptionController, times(1)).clearSubInfoRecord(eq(FAKE_SUB_ID_1));

        CarrierConfigManager mConfigManager = (CarrierConfigManager)
                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
                eq(IccCardConstants.INTENT_VALUE_ICC_ABSENT));
        verify(mSubscriptionController, times(1)).clearSubInfo();
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
    }

@@ -238,8 +235,8 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testSimLoaded() throws Exception {
        /* mock new sim got loaded and there is no sim loaded before */
        doReturn(null).when(mSubscriptionController)
        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
@@ -303,12 +300,12 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testSimLoadedEmptyOperatorNumeric() throws Exception {
        /* mock new sim got loaded and there is no sim loaded before */
        doReturn(null).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        // operator numeric is empty
        doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
        mUpdater.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);

@@ -340,9 +337,6 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {

        waitForMs(100);

        /* old IccId != new queried IccId */
        verify(mSubscriptionContent).put(eq(SubscriptionManager.SIM_SLOT_INDEX),
                eq(SubscriptionManager.INVALID_SIM_SLOT_INDEX));
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
                eq("98106240020000000000"), eq(FAKE_SUB_ID_1));
@@ -359,15 +353,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    @SmallTest
    public void testDualSimLoaded() throws Exception {
        // Mock there is two sim cards

        replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null,
                new String[]{null, null});
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2);
        replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null,
                new Phone[]{mPhone, mPhone});
        replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null,
                new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE,
                        SubscriptionInfoUpdater.SIM_NOT_CHANGE});
        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null,
                new int[]{0, 0});
        replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null,
@@ -380,24 +370,29 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        doReturn(2).when(mTelephonyManager).getSimCount();
        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1));
        doReturn(FAKE_MCC_MNC_2).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_2));
        // Mock there is no sim inserted before
        doReturn(null).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(anyInt(), anyBoolean());
        verify(mSubscriptionController, times(0)).clearSubInfo();
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt());
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());

        // Mock sending a sim loaded for SIM 1
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
        mUpdater.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);

        waitForMs(100);

        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt());
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(anyString(), anyInt());
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(1)).setMccMnc(anyString(), anyInt());

        // Mock sending a sim loaded for SIM 2
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_2), anyBoolean());
        doReturn(FAKE_SUB_ID_2).when(mSubInfo).getSubscriptionId();
        doReturn("89012604200000000001").when(mIccRecord).getFullIccId();

        mUpdater.updateInternalIccState(
@@ -411,8 +406,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                eq(FAKE_SUB_ID_2));
        verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_1), eq(FAKE_SUB_ID_1));
        verify(mSubscriptionController, times(1)).setMccMnc(eq(FAKE_MCC_MNC_2), eq(FAKE_SUB_ID_2));
        verify(mSubscriptionController, times(0)).clearSubInfo();
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(2)).notifySubscriptionInfoChanged();
    }

    @Test