Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +15 −4 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.UiccProfile; import com.android.internal.telephony.uicc.UiccSlot; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -3417,10 +3418,20 @@ public class GsmCdmaPhone extends Phone { @Override public IccCard getIccCard() { // This used to always return a non-null object. But getUiccProfile() can return null. // For backward compatibility consideration, we return a dummy object instead of null. IccCard iccCard = getUiccProfile(); return (iccCard != null) ? iccCard : new IccCard(); // This function doesn't return null for backwards compatability purposes. // To differentiate between cases where SIM is absent vs. unknown we return a dummy // IccCard with the sim state set. 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() { Loading src/java/com/android/internal/telephony/IccCard.java +15 −1 Original line number Diff line number Diff line Loading @@ -39,11 +39,25 @@ import com.android.internal.telephony.uicc.IccRecords; * gets when it calls getIccCard is UiccProfile. */ 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 */ public State getState() { return State.UNKNOWN; return mIccCardState; } // todo: delete Loading src/java/com/android/internal/telephony/uicc/UiccSlot.java +16 −3 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public class UiccSlot extends Handler { private final Object mLock = new Object(); private boolean mActive; private boolean mStateIsUnknown = true; private CardState mCardState; private Context mContext; private CommandsInterface mCi; Loading Loading @@ -104,7 +105,7 @@ public class UiccSlot extends Handler { // no card present in the slot now; dispose card and make mUiccCard null if (mUiccCard != null) { mUiccCard.dispose(); mUiccCard = null; nullifyUiccCard(false /* sim state is not unknown */); } // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to // create a new UiccCard instance in two scenarios: Loading Loading @@ -151,7 +152,7 @@ public class UiccSlot extends Handler { mLastRadioState = RadioState.RADIO_UNAVAILABLE; mPhoneId = INVALID_PHONE_ID; if (mUiccCard != null) mUiccCard.dispose(); mUiccCard = null; nullifyUiccCard(true /* sim state is unknown */); } parseAtr(iss.atr); mCardState = iss.cardState; Loading @@ -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() { if (mAtr != null && mAtr.isEuiccSupported()) { mIsEuicc = true; Loading Loading @@ -333,7 +346,7 @@ public class UiccSlot extends Handler { if (mUiccCard != null) { mUiccCard.dispose(); } mUiccCard = null; nullifyUiccCard(true /* sim state is unknown */); if (mPhoneId != INVALID_PHONE_ID) { UiccController.updateInternalIccState( Loading tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading Loading @@ -61,6 +62,7 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccProfile; import com.android.internal.telephony.uicc.UiccSlot; import org.junit.After; import org.junit.Before; Loading Loading @@ -846,6 +848,26 @@ public class GsmCdmaPhoneTest extends TelephonyTest { 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 @SmallTest public void testGetEmptyIccCard() { Loading Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +15 −4 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ import com.android.internal.telephony.uicc.UiccCard; import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccController; import com.android.internal.telephony.uicc.UiccProfile; import com.android.internal.telephony.uicc.UiccSlot; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -3417,10 +3418,20 @@ public class GsmCdmaPhone extends Phone { @Override public IccCard getIccCard() { // This used to always return a non-null object. But getUiccProfile() can return null. // For backward compatibility consideration, we return a dummy object instead of null. IccCard iccCard = getUiccProfile(); return (iccCard != null) ? iccCard : new IccCard(); // This function doesn't return null for backwards compatability purposes. // To differentiate between cases where SIM is absent vs. unknown we return a dummy // IccCard with the sim state set. 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() { Loading
src/java/com/android/internal/telephony/IccCard.java +15 −1 Original line number Diff line number Diff line Loading @@ -39,11 +39,25 @@ import com.android.internal.telephony.uicc.IccRecords; * gets when it calls getIccCard is UiccProfile. */ 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 */ public State getState() { return State.UNKNOWN; return mIccCardState; } // todo: delete Loading
src/java/com/android/internal/telephony/uicc/UiccSlot.java +16 −3 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public class UiccSlot extends Handler { private final Object mLock = new Object(); private boolean mActive; private boolean mStateIsUnknown = true; private CardState mCardState; private Context mContext; private CommandsInterface mCi; Loading Loading @@ -104,7 +105,7 @@ public class UiccSlot extends Handler { // no card present in the slot now; dispose card and make mUiccCard null if (mUiccCard != null) { mUiccCard.dispose(); mUiccCard = null; nullifyUiccCard(false /* sim state is not unknown */); } // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to // create a new UiccCard instance in two scenarios: Loading Loading @@ -151,7 +152,7 @@ public class UiccSlot extends Handler { mLastRadioState = RadioState.RADIO_UNAVAILABLE; mPhoneId = INVALID_PHONE_ID; if (mUiccCard != null) mUiccCard.dispose(); mUiccCard = null; nullifyUiccCard(true /* sim state is unknown */); } parseAtr(iss.atr); mCardState = iss.cardState; Loading @@ -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() { if (mAtr != null && mAtr.isEuiccSupported()) { mIsEuicc = true; Loading Loading @@ -333,7 +346,7 @@ public class UiccSlot extends Handler { if (mUiccCard != null) { mUiccCard.dispose(); } mUiccCard = null; nullifyUiccCard(true /* sim state is unknown */); if (mPhoneId != INVALID_PHONE_ID) { UiccController.updateInternalIccState( Loading
tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading Loading @@ -61,6 +62,7 @@ import com.android.internal.telephony.uicc.IccCardApplicationStatus; import com.android.internal.telephony.uicc.IccException; import com.android.internal.telephony.uicc.IccRecords; import com.android.internal.telephony.uicc.UiccProfile; import com.android.internal.telephony.uicc.UiccSlot; import org.junit.After; import org.junit.Before; Loading Loading @@ -846,6 +848,26 @@ public class GsmCdmaPhoneTest extends TelephonyTest { 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 @SmallTest public void testGetEmptyIccCard() { Loading