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

Commit 5bc37428 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."...

Merge "Handle race condition between SIM app deactivation and SIM removal." am: f18b8abc am: 61263a70 am: 5a697706

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

Change-Id: Ib99e3a65583887a133a3186cdef8d379bb19e310
parents 9409627c 5a697706
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -619,7 +619,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.
@@ -632,19 +632,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 */);
    }

@@ -656,7 +676,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
@@ -85,6 +85,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";

@@ -312,6 +313,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 {
@@ -346,13 +365,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);
@@ -363,6 +380,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()
@@ -384,7 +412,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();
@@ -417,7 +445,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();
@@ -431,7 +459,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();
@@ -491,7 +519,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();
@@ -519,7 +547,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));
@@ -536,7 +564,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);