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

Commit 61263a70 authored by Amit Mahajan's avatar Amit Mahajan Committed by Automerger Merge Worker
Browse files

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

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1359764

Change-Id: I899706a160f7e6bed6b3876485bb5fc70942c45c
parents e1821cd1 f18b8abc
Loading
Loading
Loading
Loading
+27 −7
Original line number Original line 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)) {
            if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
                logd("Slot of SIM" + (phoneId + 1) + " becomes inactive");
                logd("Slot of SIM" + (phoneId + 1) + " becomes inactive");
            }
            }
            cleanSubscriptionInPhone(phoneId);
            cleanSubscriptionInPhone(phoneId, false);
        }
        }
        if (!TextUtils.isEmpty(iccId)) {
        if (!TextUtils.isEmpty(iccId)) {
            // If iccId is new, add a subscription record in the db.
            // 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;
     * Clean subscription info when sim state becomes ABSENT. There are 2 scenarios for this:
        if (sInactiveIccIds[phoneId] != null) {
     * 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
            // 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.
            // 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]);
                    + 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);
            ContentValues value = new ContentValues(1);
            value.put(SubscriptionManager.UICC_APPLICATIONS_ENABLED, true);
            value.put(SubscriptionManager.UICC_APPLICATIONS_ENABLED, true);
            sContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
            sContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                    SubscriptionManager.ICC_ID + "=\'" + sInactiveIccIds[phoneId] + "\'", null);
                    SubscriptionManager.ICC_ID + "=\'" + iccId + "\'", null);
            sInactiveIccIds[phoneId] = null;
            sInactiveIccIds[phoneId] = null;
        }
        }
        sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
        updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
        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)) {
        if (sIccId[phoneId] != null && !sIccId[phoneId].equals(ICCID_STRING_FOR_NO_SIM)) {
            logd("SIM" + (phoneId + 1) + " hot plug out");
            logd("SIM" + (phoneId + 1) + " hot plug out");
        }
        }
        cleanSubscriptionInPhone(phoneId);
        cleanSubscriptionInPhone(phoneId, true);


        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_ABSENT, null);
        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_ABSENT);
        broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_ABSENT);
+38 −10
Original line number Original line 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_SUB_ID_2 = 1;
    private static final int FAKE_CARD_ID = 0;
    private static final int FAKE_CARD_ID = 0;
    private static final String FAKE_EID = "89049032000001000000031328322874";
    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_1 = "123456";
    private static final String FAKE_MCC_MNC_2 = "456789";
    private static final String FAKE_MCC_MNC_2 = "456789";


@@ -309,6 +310,24 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                UICC_APPLICATIONS_ENABLED));
                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
    @Test
    @SmallTest
    @SmallTest
    public void testSimError() throws Exception {
    public void testSimError() throws Exception {
@@ -343,13 +362,11 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
        verify(mSubscriptionController, times(0)).notifySubscriptionInfoChanged();
    }
    }


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


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


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


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