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

Commit 96170b8a authored by Jordan Liu's avatar Jordan Liu
Browse files

Use a dummy IccCard to pass absent/unknown state

GsmCdmaPhone#getIccCard returns a dummy IccCard with the state set to
absent or unknown depending on UiccSlot#isStateUnknown.

Fixes: 78033484
Test: manual and new unit test testGetIccCardUnknownAndAbsent
Change-Id: I4a42ee6d4b6b14c0c02b7db709d2af6d6df90f26
parent 98b53968
Loading
Loading
Loading
Loading
+15 −4
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccCardApplication;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;


import java.io.FileDescriptor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.PrintWriter;
@@ -3417,10 +3418,20 @@ public class GsmCdmaPhone extends Phone {


    @Override
    @Override
    public IccCard getIccCard() {
    public IccCard getIccCard() {
        // This used to always return a non-null object. But getUiccProfile() can return null.
        // This function doesn't return null for backwards compatability purposes.
        // For backward compatibility consideration, we return a dummy object instead of null.
        // To differentiate between cases where SIM is absent vs. unknown we return a dummy
        IccCard iccCard = getUiccProfile();
        // IccCard with the sim state set.
        return (iccCard != null) ? iccCard : new IccCard();
        IccCard card = getUiccProfile();
        if (card != null) {
            return card;
        } else {
            UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId);
            if (slot == null || slot.isStateUnknown()) {
                return new IccCard(IccCardConstants.State.UNKNOWN);
            } else {
                return new IccCard(IccCardConstants.State.ABSENT);
            }
        }
    }
    }


    private UiccProfile getUiccProfile() {
    private UiccProfile getUiccProfile() {
+15 −1
Original line number Original line Diff line number Diff line
@@ -39,11 +39,25 @@ import com.android.internal.telephony.uicc.IccRecords;
 * gets when it calls getIccCard is UiccProfile.
 * gets when it calls getIccCard is UiccProfile.
 */
 */
public class IccCard {
public class IccCard {
    private State mIccCardState = State.UNKNOWN;

    /**
     * Empty constructor.
     */
    public IccCard() {}

    /**
     * Set the state of the IccCard to be returned in {@link getState}.
     */
    public IccCard(State state) {
        mIccCardState = state;
    }

    /**
    /**
     * @return combined Card and current App state
     * @return combined Card and current App state
     */
     */
    public State getState() {
    public State getState() {
        return State.UNKNOWN;
        return mIccCardState;
    }
    }


    // todo: delete
    // todo: delete
+16 −3
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ public class UiccSlot extends Handler {


    private final Object mLock = new Object();
    private final Object mLock = new Object();
    private boolean mActive;
    private boolean mActive;
    private boolean mStateIsUnknown = true;
    private CardState mCardState;
    private CardState mCardState;
    private Context mContext;
    private Context mContext;
    private CommandsInterface mCi;
    private CommandsInterface mCi;
@@ -104,7 +105,7 @@ public class UiccSlot extends Handler {
                // no card present in the slot now; dispose card and make mUiccCard null
                // no card present in the slot now; dispose card and make mUiccCard null
                if (mUiccCard != null) {
                if (mUiccCard != null) {
                    mUiccCard.dispose();
                    mUiccCard.dispose();
                    mUiccCard = null;
                    nullifyUiccCard(false /* sim state is not unknown */);
                }
                }
            // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to
            // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to
            // create a new UiccCard instance in two scenarios:
            // create a new UiccCard instance in two scenarios:
@@ -151,7 +152,7 @@ public class UiccSlot extends Handler {
                    mLastRadioState = RadioState.RADIO_UNAVAILABLE;
                    mLastRadioState = RadioState.RADIO_UNAVAILABLE;
                    mPhoneId = INVALID_PHONE_ID;
                    mPhoneId = INVALID_PHONE_ID;
                    if (mUiccCard != null) mUiccCard.dispose();
                    if (mUiccCard != null) mUiccCard.dispose();
                    mUiccCard = null;
                    nullifyUiccCard(true /* sim state is unknown */);
                }
                }
                parseAtr(iss.atr);
                parseAtr(iss.atr);
                mCardState = iss.cardState;
                mCardState = iss.cardState;
@@ -168,6 +169,18 @@ public class UiccSlot extends Handler {
        }
        }
    }
    }


    // whenever we set mUiccCard to null, we lose the ability to differentiate between absent and
    // unknown states. To mitigate this, we will us mStateIsUnknown to keep track. The sim is only
    // unknown if we haven't heard from the radio or if the radio has become unavailable.
    private void nullifyUiccCard(boolean stateUnknown) {
        mStateIsUnknown = stateUnknown;
        mUiccCard = null;
    }

    public boolean isStateUnknown() {
        return mStateIsUnknown;
    }

    private void checkIsEuiccSupported() {
    private void checkIsEuiccSupported() {
        if (mAtr != null && mAtr.isEuiccSupported()) {
        if (mAtr != null && mAtr.isEuiccSupported()) {
            mIsEuicc = true;
            mIsEuicc = true;
@@ -333,7 +346,7 @@ public class UiccSlot extends Handler {
        if (mUiccCard != null) {
        if (mUiccCard != null) {
            mUiccCard.dispose();
            mUiccCard.dispose();
        }
        }
        mUiccCard = null;
        nullifyUiccCard(true /* sim state is unknown */);


        if (mPhoneId != INVALID_PHONE_ID) {
        if (mPhoneId != INVALID_PHONE_ID) {
            UiccController.updateInternalIccState(
            UiccController.updateInternalIccState(
+22 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;


@@ -61,6 +62,7 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccException;
import com.android.internal.telephony.uicc.IccException;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.IccRecords;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.internal.telephony.uicc.UiccSlot;


import org.junit.After;
import org.junit.After;
import org.junit.Before;
import org.junit.Before;
@@ -846,6 +848,26 @@ public class GsmCdmaPhoneTest extends TelephonyTest {
        verify(mEriManager, times(1)).loadEriFile();
        verify(mEriManager, times(1)).loadEriFile();
    }
    }


    @Test
    @SmallTest
    public void testGetIccCardUnknownAndAbsent() {
        // If UiccSlot.isStateUnknown is true, we should return a dummy IccCard with the state
        // set to UNKNOWN
        doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
        UiccSlot mockSlot = mock(UiccSlot.class);
        doReturn(mockSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
        doReturn(true).when(mockSlot).isStateUnknown();

        IccCard iccCard = mPhoneUT.getIccCard();
        assertEquals(IccCardConstants.State.UNKNOWN, iccCard.getState());

        // if isStateUnknown is false, we should return a dummy IccCard with the state set to
        // ABSENT
        doReturn(false).when(mockSlot).isStateUnknown();
        iccCard = mPhoneUT.getIccCard();
        assertEquals(IccCardConstants.State.ABSENT, iccCard.getState());
    }

    @Test
    @Test
    @SmallTest
    @SmallTest
    public void testGetEmptyIccCard() {
    public void testGetEmptyIccCard() {