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

Commit 64c811ab authored by Chen Xu's avatar Chen Xu Committed by android-build-merger
Browse files

Merge "refactor updateIccId for msim" am: 9d070f33

am: 9097ca5c

Change-Id: Id1e4fa8ed9f1f291507d289e99c00fc791dbbc8f
parents aa5d029f 9097ca5c
Loading
Loading
Loading
Loading
+29 −0
Original line number Original line Diff line number Diff line
@@ -1078,6 +1078,35 @@ public class SubscriptionController extends ISub.Stub {
        return 0;
        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.
     * Insert an empty SubInfo record into the database.
     *
     *
+53 −173
Original line number Original line 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 int EVENT_REFRESH_EMBEDDED_SUBSCRIPTIONS = 12;


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


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


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


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


        if (isAllIccIdQueryDone()) {
        updateSubscriptionInfoByIccId(slotId);
            updateSubscriptionInfoByIccId();
        List<SubscriptionInfo> subscriptionInfos = SubscriptionController.getInstance()
            int[] subIds = mSubscriptionManager.getActiveSubscriptionIdList();
                .getSubInfoUsingSlotIndexPrivileged(slotId, false);
            for (int subId : subIds) {
        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();
                TelephonyManager tm = TelephonyManager.getDefault();

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


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


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

                if (msisdn != null) {
                if (msisdn != null) {
                    SubscriptionController.getInstance().setDisplayNumber(msisdn, subId);
                    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.
                /* 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 =
                SharedPreferences sp =
                        PreferenceManager.getDefaultSharedPreferences(mContext);
                        PreferenceManager.getDefaultSharedPreferences(mContext);
                int storedSubId = sp.getInt(CURR_SUBID + slotId, -1);
                int storedSubId = sp.getInt(CURR_SUBID + slotId, -1);
@@ -530,9 +504,7 @@ public class SubscriptionInfoUpdater extends Handler {
            logd("SIM" + (slotId + 1) + " hot plug out");
            logd("SIM" + (slotId + 1) + " hot plug out");
        }
        }
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        if (isAllIccIdQueryDone()) {
        updateSubscriptionInfoByIccId(slotId);
            updateSubscriptionInfoByIccId();
        }
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_ABSENT);
        broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY);
        broadcastSimApplicationStateChanged(slotId, TelephonyManager.SIM_STATE_NOT_READY);
@@ -545,9 +517,7 @@ public class SubscriptionInfoUpdater extends Handler {
            logd("SIM" + (slotId + 1) + " Error ");
            logd("SIM" + (slotId + 1) + " Error ");
        }
        }
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        mIccId[slotId] = ICCID_STRING_FOR_NO_SIM;
        if (isAllIccIdQueryDone()) {
        updateSubscriptionInfoByIccId(slotId);
            updateSubscriptionInfoByIccId();
        }
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR,
        broadcastSimStateChanged(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR,
                IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
                IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR);
        broadcastSimCardStateChanged(slotId, TelephonyManager.SIM_STATE_CARD_IO_ERROR);
@@ -556,145 +526,51 @@ public class SubscriptionInfoUpdater extends Handler {
        updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
        updateCarrierServices(slotId, IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR);
    }
    }


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

        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
            loge("[updateSubscriptionInfoByIccId]- invalid slotIndex=" + slotIndex);
            mInsertSimState[i] = SIM_NOT_CHANGE;
            return;
        }

        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]);
        }
        }
        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
        // If SIM is not absent, insert new record or update existing record.
        for (int i = 0; i < PROJECT_SIM_NUM; i++) {
        if (!ICCID_STRING_FOR_NO_SIM.equals(mIccId[slotIndex])) {
            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)*/ {
           logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "
           logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "
                            + mIccId[i] + "slot: " + i);
                    + mIccId[slotIndex] + "slot: " + slotIndex);
                    mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i);
           mSubscriptionManager.addSubscriptionInfoRecord(mIccId[slotIndex], slotIndex);
                }
                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]);
        }
        }


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


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

                if (msisdn != null) {
                if (msisdn != null) {
                ContentValues value = new ContentValues(1);
                    value.put(SubscriptionManager.NUMBER, msisdn);
                    value.put(SubscriptionManager.NUMBER, msisdn);
                contentResolver.update(SubscriptionManager.getUriForSubscriptionId(
                    mContext.getContentResolver().update(SubscriptionManager.getUriForSubscriptionId(
                            temp.getSubscriptionId()), value, null, null);
                            temp.getSubscriptionId()), value, null, null);


                    // refresh Cached Active Subscription Info List
                    // refresh Cached Active Subscription Info List
                    SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
                    SubscriptionController.getInstance().refreshCachedActiveSubscriptionInfoList();
                }
                }
            }
            }
        }


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

        // No need to check return value here as we notify for the above changes anyway.
        if (subInfos != null) {
            UiccController uiccController = UiccController.getInstance();
            UiccController uiccController = UiccController.getInstance();
            UiccSlot[] uiccSlots = uiccController.getUiccSlots();
            UiccSlot[] uiccSlots = uiccController.getUiccSlots();
            if (uiccSlots != null) {
            if (uiccSlots != null) {
@@ -951,6 +827,10 @@ public class SubscriptionInfoUpdater extends Handler {
        Rlog.d(LOG_TAG, message);
        Rlog.d(LOG_TAG, message);
    }
    }


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

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


        replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null, new String[1]);
        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, "mContext", null, null);
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1);
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 1);
        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null, new int[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);
                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);


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


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


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


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


        waitForMs(100);
        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);
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
                eq("98106240020000000000"), eq(FAKE_SUB_ID_1));
                eq("98106240020000000000"), eq(FAKE_SUB_ID_1));
@@ -359,15 +353,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    @SmallTest
    @SmallTest
    public void testDualSimLoaded() throws Exception {
    public void testDualSimLoaded() throws Exception {
        // Mock there is two sim cards
        // Mock there is two sim cards

        replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null,
        replaceInstance(SubscriptionInfoUpdater.class, "mIccId", null,
                new String[]{null, null});
                new String[]{null, null});
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2);
        replaceInstance(SubscriptionInfoUpdater.class, "PROJECT_SIM_NUM", null, 2);
        replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null,
        replaceInstance(SubscriptionInfoUpdater.class, "mPhone", null,
                new Phone[]{mPhone, mPhone});
                new Phone[]{mPhone, mPhone});
        replaceInstance(SubscriptionInfoUpdater.class, "mInsertSimState", null,
                new int[]{SubscriptionInfoUpdater.SIM_NOT_CHANGE,
                        SubscriptionInfoUpdater.SIM_NOT_CHANGE});
        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null,
        replaceInstance(SubscriptionInfoUpdater.class, "sSimCardState", null,
                new int[]{0, 0});
                new int[]{0, 0});
        replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null,
        replaceInstance(SubscriptionInfoUpdater.class, "sSimApplicationState", null,
@@ -380,24 +370,29 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        doReturn(2).when(mTelephonyManager).getSimCount();
        doReturn(2).when(mTelephonyManager).getSimCount();
        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(eq(FAKE_SUB_ID_1));
        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));
        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();
        verify(mSubscriptionController, times(0)).clearSubInfo();
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        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
        // Mock sending a sim loaded for SIM 1
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1), anyBoolean());
        mUpdater.updateInternalIccState(
        mUpdater.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);
                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_1);


        waitForMs(100);
        waitForMs(100);


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


        // Mock sending a sim loaded for SIM 2
        // 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();
        doReturn("89012604200000000001").when(mIccRecord).getFullIccId();


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


    @Test
    @Test