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

Commit f0866cbb authored by Malcolm Chen's avatar Malcolm Chen
Browse files

Broadcast state change if cardState becomes ABSENT in SlotStatus update.

CardState may be updated in SlotStatus changed. When that happens, we
need to check if we need to broadcast ABSENT state update, just like we
do when uicc card status is changed.

Bug: 79190707
Test: unittest
Change-Id: I029090b82984088f6a486be91935949ab9f24184
Merged-In: I029090b82984088f6a486be91935949ab9f24184
parent f77ee05f
Loading
Loading
Loading
Loading
+38 −17
Original line number Diff line number Diff line
@@ -91,22 +91,8 @@ public class UiccSlot extends Handler {
                log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState);
            }

            if ((oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null)
                    && mCardState == CardState.CARDSTATE_ABSENT) {
                // No notifications while radio is off or we just powering up
                if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) {
                    if (DBG) log("update: notify card removed");
                    sendMessage(obtainMessage(EVENT_CARD_REMOVED, null));
                }

                UiccController.updateInternalIccState(
                        IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, mPhoneId);

                // no card present in the slot now; dispose card and make mUiccCard null
                if (mUiccCard != null) {
                    mUiccCard.dispose();
                    nullifyUiccCard(false /* sim state is not unknown */);
                }
            if (absentStateUpdateNeeded(oldState)) {
                updateCardStateAbsent();
            // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to
            // create a new UiccCard instance in two scenarios:
            //   1. mCardState is changing from ABSENT to non ABSENT.
@@ -145,11 +131,14 @@ public class UiccSlot extends Handler {
    public void update(CommandsInterface ci, IccSlotStatus iss) {
        if (DBG) log("slotStatus update: " + iss.toString());
        synchronized (mLock) {
            CardState oldState = mCardState;
            mCi = ci;
            parseAtr(iss.atr);
            mCardState = iss.cardState;
            mIccId = iss.iccid;
            if (iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_INACTIVE) {
                // TODO: (b/79432584) evaluate whether should broadcast card state change
                // even if it's inactive.
                if (mActive) {
                    mActive = false;
                    mLastRadioState = RadioState.RADIO_UNAVAILABLE;
@@ -157,10 +146,42 @@ public class UiccSlot extends Handler {
                    if (mUiccCard != null) mUiccCard.dispose();
                    nullifyUiccCard(true /* sim state is unknown */);
                }
            } else if (!mActive && iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_ACTIVE) {
            } else {
                mActive = true;
                mPhoneId = iss.logicalSlotIndex;
                if (absentStateUpdateNeeded(oldState)) {
                    updateCardStateAbsent();
                }
                // TODO: (b/79432584) Create UiccCard or EuiccCard object here.
                // Right now It's OK not creating it because Card status update will do it.
                // But we should really make them symmetric.
            }
        }
    }

    private boolean absentStateUpdateNeeded(CardState oldState) {
        return (oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null)
                && mCardState == CardState.CARDSTATE_ABSENT;
    }

    private void updateCardStateAbsent() {
        RadioState radioState =
                (mCi == null) ? RadioState.RADIO_UNAVAILABLE : mCi.getRadioState();
        // No notifications while radio is off or we just powering up
        if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) {
            if (DBG) log("update: notify card removed");
            sendMessage(obtainMessage(EVENT_CARD_REMOVED, null));
        }

        UiccController.updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, mPhoneId);

        // no card present in the slot now; dispose card and make mUiccCard null
        if (mUiccCard != null) {
            mUiccCard.dispose();
            nullifyUiccCard(false /* sim state is not unknown */);
        }
        mLastRadioState = radioState;
    }

    // whenever we set mUiccCard to null, we lose the ability to differentiate between absent and
+31 −1
Original line number Diff line number Diff line
@@ -102,8 +102,9 @@ public class UiccSlotTest extends TelephonyTest {

    @Test
    @SmallTest
    public void testUpdateSlotStatus() {
    public void testUpdateInactiveSlotStatus() {
        IccSlotStatus iss = new IccSlotStatus();
        iss.logicalSlotIndex = 0;
        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.iccid = "fake-iccid";
@@ -122,8 +123,35 @@ public class UiccSlotTest extends TelephonyTest {
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
        assertEquals(iss.iccid, mUiccSlot.getIccId());
    }

    @Test
    @SmallTest
    public void testUpdateActiveSlotStatus() {
        // initial state
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
        assertNull(mUiccSlot.getIccId());

        mSimulatedCommands.setRadioPower(true, null);
        int phoneId = 0;
        IccSlotStatus iss = new IccSlotStatus();
        iss.logicalSlotIndex = phoneId;
        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
        iss.cardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
        iss.iccid = "fake-iccid";

        // update slot to inactive
        mUiccSlot.update(mSimulatedCommands, iss);

        // assert on updated values
        assertTrue(mUiccSlot.isActive());
        assertNull(mUiccSlot.getUiccCard());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
        assertEquals(iss.iccid, mUiccSlot.getIccId());
        verify(mSubInfoRecordUpdater).updateInternalIccState(
                IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);

        // update slot to active
        mUiccSlot.update(mSimulatedCommands, iss);
@@ -136,6 +164,7 @@ public class UiccSlotTest extends TelephonyTest {
    @SmallTest
    public void testUpdateSlotStatusEuiccIsSupported() {
        IccSlotStatus iss = new IccSlotStatus();
        iss.logicalSlotIndex = 0;
        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.iccid = "fake-iccid";
@@ -170,6 +199,7 @@ public class UiccSlotTest extends TelephonyTest {
    @SmallTest
    public void testUpdateSlotStatusEuiccIsNotSupported() {
        IccSlotStatus iss = new IccSlotStatus();
        iss.logicalSlotIndex = 0;
        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        iss.iccid = "fake-iccid";