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

Commit f18b8abc authored by Amit Mahajan's avatar Amit Mahajan Committed by Gerrit Code Review
Browse files

Merge "Handle race condition between SIM app deactivation and SIM removal."

parents daee86e9 e7cca9c4
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -641,7 +641,7 @@ public class SubscriptionInfoUpdater extends Handler {
            if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
                logd("Slot of SIM" + (phoneId + 1) + " becomes inactive");
            }
            cleanSubscriptionInPhone(phoneId);
            cleanSubscriptionInPhone(phoneId, false);
        }
        if (!TextUtils.isEmpty(iccId)) {
            // If iccId is new, add a subscription record in the db.
@@ -654,19 +654,39 @@ public class SubscriptionInfoUpdater extends Handler {
        }
    }

    private void cleanSubscriptionInPhone(int phoneId) {
        sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
        if (sInactiveIccIds[phoneId] != null) {
    /**
     * Clean subscription info when sim state becomes ABSENT. There are 2 scenarios for this:
     * 1. SIM is actually removed
     * 2. Slot becomes inactive, which results in SIM being treated as ABSENT, but SIM may not
     * have been removed.
     * @param phoneId phoneId for which the cleanup needs to be done
     * @param isSimAbsent boolean to indicate if the SIM is actually ABSENT (case 1 above)
     */
    private void cleanSubscriptionInPhone(int phoneId, boolean isSimAbsent) {
        if (sInactiveIccIds[phoneId] != null || (isSimAbsent && sIccId[phoneId] != null
                && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM))) {
            // When a SIM is unplugged, mark uicc applications enabled. This is to make sure when
            // user unplugs and re-inserts the SIM card, we re-enable it.
            logd("cleanSubscriptionInPhone " + phoneId + " inactive iccid "
            // In certain cases this can happen before sInactiveIccIds is updated, which is why we
            // check for sIccId as well (in case of isSimAbsent). The scenario is: after SIM
            // deactivate request is sent to RIL, SIM is removed before SIM state is updated to
            // NOT_READY. We do not need to check if this exact scenario is hit, because marking
            // uicc applications enabled when SIM is removed should be okay to do regardless.
            logd("cleanSubscriptionInPhone: " + phoneId + ", inactive iccid "
                    + sInactiveIccIds[phoneId]);
            if (sInactiveIccIds[phoneId] == null) {
                logd("cleanSubscriptionInPhone: " + phoneId + ", isSimAbsent=" + isSimAbsent
                        + ", iccid=" + sIccId[phoneId]);
            }
            String iccId = sInactiveIccIds[phoneId] != null
                    ? sInactiveIccIds[phoneId] : sIccId[phoneId];
            ContentValues value = new ContentValues(1);
            value.put(SubscriptionManager.UICC_APPLICATIONS_ENABLED, true);
            sContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                    SubscriptionManager.ICC_ID + "=\'" + sInactiveIccIds[phoneId] + "\'", null);
                    SubscriptionManager.ICC_ID + "=\'" + iccId + "\'", null);
            sInactiveIccIds[phoneId] = null;
        }
        sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
        updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
    }

@@ -678,7 +698,7 @@ public class SubscriptionInfoUpdater extends Handler {
        if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
            logd("SIM" + (phoneId + 1) + " hot plug out");
        }
        cleanSubscriptionInPhone(phoneId);
        cleanSubscriptionInPhone(phoneId, true);

        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_ABSENT);
+38 −10
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    private static final int FAKE_SUB_ID_2 = 1;
    private static final int FAKE_CARD_ID = 0;
    private static final String FAKE_EID = "89049032000001000000031328322874";
    private static final String FAKE_ICCID_1 = "89012604200000000000";
    private static final String FAKE_MCC_MNC_1 = "123456";
    private static final String FAKE_MCC_MNC_2 = "456789";

@@ -309,6 +310,24 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                UICC_APPLICATIONS_ENABLED));
    }

    @Test
    @SmallTest
    public void testSimRemovedWhileDisablingUiccApps() throws Exception {
        loadSim();

        mUpdater.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
        processAllMessages();

        // UICC_APPLICATIONS_ENABLED should be reset to true.
        ArgumentCaptor<ContentValues> valueCapture = ArgumentCaptor.forClass(ContentValues.class);
        verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), valueCapture.capture(),
                eq(SubscriptionManager.ICC_ID + "=\'" + FAKE_ICCID_1 + "\'"), eq(null));
        ContentValues contentValues = valueCapture.getValue();
        assertTrue(contentValues != null && contentValues.getAsBoolean(
                UICC_APPLICATIONS_ENABLED));
    }

    @Test
    @SmallTest
    public void testSimError() throws Exception {
@@ -343,13 +362,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
    }

    @Test
    @SmallTest
    public void testSimLoaded() throws Exception {
    private void loadSim() {
        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
        doReturn(Arrays.asList(mSubInfo)).when(mSubscriptionController)
                .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
        doReturn(FAKE_MCC_MNC_1).when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
        when(mActivityManager.updateMccMncConfiguration(anyString(), anyString())).thenReturn(
                true);
@@ -360,6 +377,17 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        processAllMessages();
        assertTrue(mUpdater.isSubInfoInitialized());

        CarrierConfigManager mConfigManager = (CarrierConfigManager)
                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
                eq(IccCardConstants.INTENT_VALUE_ICC_LOADED));
    }

    @Test
    @SmallTest
    public void testSimLoaded() throws Exception {
        loadSim();

        // verify SIM_STATE_CHANGED broadcast. It should be broadcast twice, once for
        // READ_PHONE_STATE and once for READ_PRIVILEGED_PHONE_STATE
        /* todo: cannot verify as intent is sent using ActivityManagerNative.broadcastStickyIntent()
@@ -381,7 +409,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
                eq("89012604200000000000"), eq(FAKE_SUB_ID_1));
                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(1)).setMccMnc(FAKE_MCC_MNC_1, FAKE_SUB_ID_1);
        verify(mSubscriptionController, times(0)).clearSubInfo();
@@ -414,7 +442,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
    @Test
    @SmallTest
    public void testSimLoadedEmptyOperatorNumeric() throws Exception {
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
        // operator numeric is empty
        doReturn("").when(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
        doReturn(FAKE_SUB_ID_1).when(mSubInfo).getSubscriptionId();
@@ -428,7 +456,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mTelephonyManager).getSimOperatorNumeric(FAKE_SUB_ID_1);
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(
                eq("89012604200000000000"), eq(FAKE_SUB_ID_1));
                eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(0)).setMccMnc(anyString(), anyInt());
        verify(mSubscriptionController, times(0)).clearSubInfo();
@@ -488,7 +516,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        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));
        verify(mSubscriptionController, times(0)).clearSubInfo();
        doReturn("89012604200000000000").when(mIccRecord).getFullIccId();
        doReturn(FAKE_ICCID_1).when(mIccRecord).getFullIccId();
        SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
        verify(mSubscriptionManager, times(0)).addSubscriptionInfoRecord(anyString(), anyInt());
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
@@ -516,7 +544,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                IccCardConstants.INTENT_VALUE_ICC_LOADED, null, FAKE_SUB_ID_2);

        processAllMessages();
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000000"),
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq(FAKE_ICCID_1),
                eq(FAKE_SUB_ID_1));
        verify(mSubscriptionManager, times(1)).addSubscriptionInfoRecord(eq("89012604200000000001"),
                eq(FAKE_SUB_ID_2));
@@ -533,7 +561,7 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        doReturn("98106240020000000000").when(mIccRecord).getFullIccId();

        replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,
                new String[]{"89012604200000000000"});
                new String[]{FAKE_ICCID_1});

        mUpdater.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_LOCKED, "TESTING", FAKE_SUB_ID_1);