Loading src/java/com/android/internal/telephony/uicc/UiccController.java +8 −0 Original line number Diff line number Diff line Loading @@ -1091,6 +1091,14 @@ public class UiccController extends Handler { return; } UiccPort port = card.getUiccPort(status.mSlotPortMapping.mPortIndex); if (port == null) { if (DBG) log("mUiccSlots[" + slotId + "] has no UiccPort with index[" + status.mSlotPortMapping.mPortIndex + "]. Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); return; } String cardString = null; boolean isEuicc = mUiccSlots[slotId].isEuicc(); if (isEuicc) { Loading src/java/com/android/internal/telephony/uicc/UiccSlot.java +49 −27 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode; import com.android.internal.telephony.uicc.euicc.EuiccCard; import com.android.internal.telephony.util.ArrayUtils; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; Loading Loading @@ -80,7 +81,6 @@ 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 UiccCard mUiccCard; private boolean mIsEuicc; Loading @@ -96,6 +96,9 @@ public class UiccSlot extends Handler { private HashMap<Integer, Integer> mLastRadioState = new HashMap<>(); // Store iccId of each port. private HashMap<Integer, String> mIccIds = new HashMap<>(); // IccCardStatus and IccSlotStatus events order is not guaranteed. Inorder to handle MEP mode, // map each available portIdx with CardState for card state checking private HashMap<Integer, CardState> mCardState = new HashMap<>(); private static final int EVENT_CARD_REMOVED = 13; private static final int EVENT_CARD_ADDED = 14; Loading @@ -104,7 +107,6 @@ public class UiccSlot extends Handler { if (DBG) log("Creating"); mContext = c; mActive = isActive; mCardState = null; mSupportedMepMode = MultipleEnabledProfilesMode.NONE; } Loading @@ -114,8 +116,8 @@ public class UiccSlot extends Handler { public void update(CommandsInterface ci, IccCardStatus ics, int phoneId, int slotIndex) { synchronized (mLock) { mPortIdxToPhoneId.put(ics.mSlotPortMapping.mPortIndex, phoneId); CardState oldState = mCardState; mCardState = ics.mCardState; CardState oldState = mCardState.get(ics.mSlotPortMapping.mPortIndex); mCardState.put(ics.mSlotPortMapping.mPortIndex, ics.mCardState); mIccIds.put(ics.mSlotPortMapping.mPortIndex, ics.iccid); parseAtr(ics.atr); mIsRemovable = isSlotRemovable(slotIndex); Loading @@ -129,7 +131,7 @@ public class UiccSlot extends Handler { log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState); } if (absentStateUpdateNeeded(oldState)) { if (absentStateUpdateNeeded(oldState, ics.mSlotPortMapping.mPortIndex)) { updateCardStateAbsent(ci.getRadioState(), phoneId, ics.mSlotPortMapping.mPortIndex); // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to Loading @@ -137,7 +139,8 @@ public class UiccSlot extends Handler { // 1. mCardState is changing from ABSENT to non ABSENT. // 2. The latest mCardState is not ABSENT, but there is no UiccCard instance. } else if ((oldState == null || oldState == CardState.CARDSTATE_ABSENT || mUiccCard == null) && mCardState != CardState.CARDSTATE_ABSENT) { || mUiccCard == null) && mCardState.get(ics.mSlotPortMapping.mPortIndex) != CardState.CARDSTATE_ABSENT) { // No notification while we are just powering up if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE && mLastRadioState.getOrDefault(ics.mSlotPortMapping.mPortIndex, Loading @@ -148,9 +151,11 @@ public class UiccSlot extends Handler { } // card is present in the slot now; create new mUiccCard if (mUiccCard != null) { if (mUiccCard != null && (!mIsEuicc || ArrayUtils.isEmpty(mUiccCard.getUiccPortList()))) { loge("update: mUiccCard != null when card was present; disposing it now"); mUiccCard.dispose(); mUiccCard = null; } if (!mIsEuicc) { Loading @@ -164,8 +169,14 @@ public class UiccSlot extends Handler { loge("update: eid is missing. ics.eid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, ics.eid)); } if (mUiccCard == null) { mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock, isMultipleEnabledProfileSupported(), getSupportedMepMode()); } else { // In MEP case, UiccCard instance is already created, just call update API. // UiccPort initialization is handled inside UiccCard. mUiccCard.update(mContext, ci, ics, phoneId); } } } else { if (mUiccCard != null) { Loading @@ -182,15 +193,15 @@ public class UiccSlot extends Handler { public void update(CommandsInterface[] ci, IccSlotStatus iss, int slotIndex) { synchronized (mLock) { IccSimPortInfo[] simPortInfos = iss.mSimPortInfos; CardState oldState = mCardState; parseAtr(iss.atr); mCardState = iss.cardState; mEid = iss.eid; mIsRemovable = isSlotRemovable(slotIndex); mSupportedMepMode = iss.mSupportedMepMode; for (int i = 0; i < simPortInfos.length; i++) { int phoneId = iss.mSimPortInfos[i].mLogicalSlotIndex; CardState oldState = mCardState.get(i); mCardState.put(i, iss.cardState); mIccIds.put(i, simPortInfos[i].mIccId); if (!iss.mSimPortInfos[i].mPortActive) { // TODO: (b/79432584) evaluate whether should broadcast card state change Loading @@ -210,7 +221,7 @@ public class UiccSlot extends Handler { mUiccCard.disposePort(i); } } else { if (absentStateUpdateNeeded(oldState)) { if (absentStateUpdateNeeded(oldState, i)) { int radioState = SubscriptionManager.isValidPhoneId(phoneId) ? ci[phoneId].getRadioState() : TelephonyManager.RADIO_POWER_UNAVAILABLE; Loading Loading @@ -322,9 +333,9 @@ public class UiccSlot extends Handler { mAtr.isMultipleEnabledProfilesSupported(); } private boolean absentStateUpdateNeeded(CardState oldState) { private boolean absentStateUpdateNeeded(CardState oldState, int portIndex) { return (oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null) && mCardState == CardState.CARDSTATE_ABSENT; && mCardState.get(portIndex) == CardState.CARDSTATE_ABSENT; } private void updateCardStateAbsent(int radioState, int phoneId, int portIndex) { Loading @@ -344,8 +355,8 @@ public class UiccSlot extends Handler { UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT, null, phoneId); } // no card present in the slot now; dispose card and make mUiccCard null nullifyUiccCard(false /* sim state is not unknown */); // no card present in the slot now; dispose port and then card if needed. disposeUiccCardIfNeeded(false /* sim state is not unknown */, portIndex); mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE); } Loading @@ -360,8 +371,21 @@ public class UiccSlot extends Handler { mUiccCard = null; } private void disposeUiccCardIfNeeded(boolean isStateUnknown, int portIndex) { // First dispose UiccPort corresponding to the portIndex if (mUiccCard != null) { mUiccCard.disposePort(portIndex); if (ArrayUtils.isEmpty(mUiccCard.getUiccPortList())) { // No UiccPort objects are found, safe to dispose the card nullifyUiccCard(isStateUnknown); } } } public boolean isStateUnknown() { if (mCardState == null || mCardState == CardState.CARDSTATE_ABSENT) { // CardState is not specific to any port index, use default port. CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX); if (cardState == null || cardState == CardState.CARDSTATE_ABSENT) { // mStateIsUnknown is valid only in this scenario. return mStateIsUnknown; } Loading Loading @@ -572,11 +596,9 @@ public class UiccSlot extends Handler { */ public CardState getCardState() { synchronized (mLock) { if (mCardState == null) { return CardState.CARDSTATE_ABSENT; } else { return mCardState; } // CardState is not specific to any port index, use default port. CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX); return cardState == null ? CardState.CARDSTATE_ABSENT : cardState; } } Loading @@ -601,7 +623,8 @@ public class UiccSlot extends Handler { * Processes radio state unavailable event */ public void onRadioStateUnavailable(int phoneId) { nullifyUiccCard(true /* sim state is unknown */); int portIndex = getPortIndexFromPhoneId(phoneId); disposeUiccCardIfNeeded(true /* sim state is unknown */, portIndex); if (phoneId != INVALID_PHONE_ID) { if (PhoneFactory.isSubscriptionManagerServiceEnabled()) { Loading @@ -611,11 +634,10 @@ public class UiccSlot extends Handler { UiccController.updateInternalIccState( mContext, IccCardConstants.State.UNKNOWN, null, phoneId); } mLastRadioState.put(getPortIndexFromPhoneId(phoneId), TelephonyManager.RADIO_POWER_UNAVAILABLE); } mCardState = null; mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE); // Reset CardState mCardState.put(portIndex, null); } private void log(String msg) { Loading Loading
src/java/com/android/internal/telephony/uicc/UiccController.java +8 −0 Original line number Diff line number Diff line Loading @@ -1091,6 +1091,14 @@ public class UiccController extends Handler { return; } UiccPort port = card.getUiccPort(status.mSlotPortMapping.mPortIndex); if (port == null) { if (DBG) log("mUiccSlots[" + slotId + "] has no UiccPort with index[" + status.mSlotPortMapping.mPortIndex + "]. Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); return; } String cardString = null; boolean isEuicc = mUiccSlots[slotId].isEuicc(); if (isEuicc) { Loading
src/java/com/android/internal/telephony/uicc/UiccSlot.java +49 −27 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.uicc.IccCardStatus.CardState; import com.android.internal.telephony.uicc.IccSlotStatus.MultipleEnabledProfilesMode; import com.android.internal.telephony.uicc.euicc.EuiccCard; import com.android.internal.telephony.util.ArrayUtils; import com.android.internal.telephony.util.TelephonyUtils; import com.android.telephony.Rlog; Loading Loading @@ -80,7 +81,6 @@ 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 UiccCard mUiccCard; private boolean mIsEuicc; Loading @@ -96,6 +96,9 @@ public class UiccSlot extends Handler { private HashMap<Integer, Integer> mLastRadioState = new HashMap<>(); // Store iccId of each port. private HashMap<Integer, String> mIccIds = new HashMap<>(); // IccCardStatus and IccSlotStatus events order is not guaranteed. Inorder to handle MEP mode, // map each available portIdx with CardState for card state checking private HashMap<Integer, CardState> mCardState = new HashMap<>(); private static final int EVENT_CARD_REMOVED = 13; private static final int EVENT_CARD_ADDED = 14; Loading @@ -104,7 +107,6 @@ public class UiccSlot extends Handler { if (DBG) log("Creating"); mContext = c; mActive = isActive; mCardState = null; mSupportedMepMode = MultipleEnabledProfilesMode.NONE; } Loading @@ -114,8 +116,8 @@ public class UiccSlot extends Handler { public void update(CommandsInterface ci, IccCardStatus ics, int phoneId, int slotIndex) { synchronized (mLock) { mPortIdxToPhoneId.put(ics.mSlotPortMapping.mPortIndex, phoneId); CardState oldState = mCardState; mCardState = ics.mCardState; CardState oldState = mCardState.get(ics.mSlotPortMapping.mPortIndex); mCardState.put(ics.mSlotPortMapping.mPortIndex, ics.mCardState); mIccIds.put(ics.mSlotPortMapping.mPortIndex, ics.iccid); parseAtr(ics.atr); mIsRemovable = isSlotRemovable(slotIndex); Loading @@ -129,7 +131,7 @@ public class UiccSlot extends Handler { log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState); } if (absentStateUpdateNeeded(oldState)) { if (absentStateUpdateNeeded(oldState, ics.mSlotPortMapping.mPortIndex)) { updateCardStateAbsent(ci.getRadioState(), phoneId, ics.mSlotPortMapping.mPortIndex); // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to Loading @@ -137,7 +139,8 @@ public class UiccSlot extends Handler { // 1. mCardState is changing from ABSENT to non ABSENT. // 2. The latest mCardState is not ABSENT, but there is no UiccCard instance. } else if ((oldState == null || oldState == CardState.CARDSTATE_ABSENT || mUiccCard == null) && mCardState != CardState.CARDSTATE_ABSENT) { || mUiccCard == null) && mCardState.get(ics.mSlotPortMapping.mPortIndex) != CardState.CARDSTATE_ABSENT) { // No notification while we are just powering up if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE && mLastRadioState.getOrDefault(ics.mSlotPortMapping.mPortIndex, Loading @@ -148,9 +151,11 @@ public class UiccSlot extends Handler { } // card is present in the slot now; create new mUiccCard if (mUiccCard != null) { if (mUiccCard != null && (!mIsEuicc || ArrayUtils.isEmpty(mUiccCard.getUiccPortList()))) { loge("update: mUiccCard != null when card was present; disposing it now"); mUiccCard.dispose(); mUiccCard = null; } if (!mIsEuicc) { Loading @@ -164,8 +169,14 @@ public class UiccSlot extends Handler { loge("update: eid is missing. ics.eid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, ics.eid)); } if (mUiccCard == null) { mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock, isMultipleEnabledProfileSupported(), getSupportedMepMode()); } else { // In MEP case, UiccCard instance is already created, just call update API. // UiccPort initialization is handled inside UiccCard. mUiccCard.update(mContext, ci, ics, phoneId); } } } else { if (mUiccCard != null) { Loading @@ -182,15 +193,15 @@ public class UiccSlot extends Handler { public void update(CommandsInterface[] ci, IccSlotStatus iss, int slotIndex) { synchronized (mLock) { IccSimPortInfo[] simPortInfos = iss.mSimPortInfos; CardState oldState = mCardState; parseAtr(iss.atr); mCardState = iss.cardState; mEid = iss.eid; mIsRemovable = isSlotRemovable(slotIndex); mSupportedMepMode = iss.mSupportedMepMode; for (int i = 0; i < simPortInfos.length; i++) { int phoneId = iss.mSimPortInfos[i].mLogicalSlotIndex; CardState oldState = mCardState.get(i); mCardState.put(i, iss.cardState); mIccIds.put(i, simPortInfos[i].mIccId); if (!iss.mSimPortInfos[i].mPortActive) { // TODO: (b/79432584) evaluate whether should broadcast card state change Loading @@ -210,7 +221,7 @@ public class UiccSlot extends Handler { mUiccCard.disposePort(i); } } else { if (absentStateUpdateNeeded(oldState)) { if (absentStateUpdateNeeded(oldState, i)) { int radioState = SubscriptionManager.isValidPhoneId(phoneId) ? ci[phoneId].getRadioState() : TelephonyManager.RADIO_POWER_UNAVAILABLE; Loading Loading @@ -322,9 +333,9 @@ public class UiccSlot extends Handler { mAtr.isMultipleEnabledProfilesSupported(); } private boolean absentStateUpdateNeeded(CardState oldState) { private boolean absentStateUpdateNeeded(CardState oldState, int portIndex) { return (oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null) && mCardState == CardState.CARDSTATE_ABSENT; && mCardState.get(portIndex) == CardState.CARDSTATE_ABSENT; } private void updateCardStateAbsent(int radioState, int phoneId, int portIndex) { Loading @@ -344,8 +355,8 @@ public class UiccSlot extends Handler { UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT, null, phoneId); } // no card present in the slot now; dispose card and make mUiccCard null nullifyUiccCard(false /* sim state is not unknown */); // no card present in the slot now; dispose port and then card if needed. disposeUiccCardIfNeeded(false /* sim state is not unknown */, portIndex); mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE); } Loading @@ -360,8 +371,21 @@ public class UiccSlot extends Handler { mUiccCard = null; } private void disposeUiccCardIfNeeded(boolean isStateUnknown, int portIndex) { // First dispose UiccPort corresponding to the portIndex if (mUiccCard != null) { mUiccCard.disposePort(portIndex); if (ArrayUtils.isEmpty(mUiccCard.getUiccPortList())) { // No UiccPort objects are found, safe to dispose the card nullifyUiccCard(isStateUnknown); } } } public boolean isStateUnknown() { if (mCardState == null || mCardState == CardState.CARDSTATE_ABSENT) { // CardState is not specific to any port index, use default port. CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX); if (cardState == null || cardState == CardState.CARDSTATE_ABSENT) { // mStateIsUnknown is valid only in this scenario. return mStateIsUnknown; } Loading Loading @@ -572,11 +596,9 @@ public class UiccSlot extends Handler { */ public CardState getCardState() { synchronized (mLock) { if (mCardState == null) { return CardState.CARDSTATE_ABSENT; } else { return mCardState; } // CardState is not specific to any port index, use default port. CardState cardState = mCardState.get(TelephonyManager.DEFAULT_PORT_INDEX); return cardState == null ? CardState.CARDSTATE_ABSENT : cardState; } } Loading @@ -601,7 +623,8 @@ public class UiccSlot extends Handler { * Processes radio state unavailable event */ public void onRadioStateUnavailable(int phoneId) { nullifyUiccCard(true /* sim state is unknown */); int portIndex = getPortIndexFromPhoneId(phoneId); disposeUiccCardIfNeeded(true /* sim state is unknown */, portIndex); if (phoneId != INVALID_PHONE_ID) { if (PhoneFactory.isSubscriptionManagerServiceEnabled()) { Loading @@ -611,11 +634,10 @@ public class UiccSlot extends Handler { UiccController.updateInternalIccState( mContext, IccCardConstants.State.UNKNOWN, null, phoneId); } mLastRadioState.put(getPortIndexFromPhoneId(phoneId), TelephonyManager.RADIO_POWER_UNAVAILABLE); } mCardState = null; mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE); // Reset CardState mCardState.put(portIndex, null); } private void log(String msg) { Loading