diff options
author | Muralidhar Reddy <muralidharm@google.com> | 2023-01-05 16:37:49 +0000 |
---|---|---|
committer | Muralidhar Reddy <muralidharm@google.com> | 2023-01-19 04:05:12 +0000 |
commit | 80b86e12c3a0efbd206d5af1ef40febdae908f5f (patch) | |
tree | a1077413831275d355189a7824ed4401082613f3 /src/java/com/android/internal/telephony/uicc | |
parent | 13fabc3153a95d0aa6f66bca2f4e5fa682b4fc35 (diff) | |
download | telephony-80b86e12c3a0efbd206d5af1ef40febdae908f5f.tar.gz |
[MEP] Handle UiccCard and UiccPort disposal when more than one port is supported.
Whenever platform receives the CARDSTATE_ABSENT for any one of the UiccPort, complete UiccCard is disposed. Modified the logic to improve the behavior of Port and Card disposal.
Test: Manual test on Pixel 7 and Pixel 6, atest FrameworksTelephonyTests
Bug: 237562186
Change-Id: I78e231043135516c9b5f9777add52367bf16d93f
Diffstat (limited to 'src/java/com/android/internal/telephony/uicc')
-rw-r--r-- | src/java/com/android/internal/telephony/uicc/UiccController.java | 8 | ||||
-rw-r--r-- | src/java/com/android/internal/telephony/uicc/UiccSlot.java | 76 |
2 files changed, 57 insertions, 27 deletions
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java index 48524ff46b..4d87a3f18c 100644 --- a/src/java/com/android/internal/telephony/uicc/UiccController.java +++ b/src/java/com/android/internal/telephony/uicc/UiccController.java @@ -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) { diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java index a395b2f7d8..a49a7d3c24 100644 --- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java +++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java @@ -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; @@ -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; @@ -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; @@ -104,7 +107,6 @@ public class UiccSlot extends Handler { if (DBG) log("Creating"); mContext = c; mActive = isActive; - mCardState = null; mSupportedMepMode = MultipleEnabledProfilesMode.NONE; } @@ -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); @@ -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 @@ -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, @@ -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) { @@ -164,8 +169,14 @@ public class UiccSlot extends Handler { loge("update: eid is missing. ics.eid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, ics.eid)); } - mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock, - isMultipleEnabledProfileSupported(), getSupportedMepMode()); + 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) { @@ -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 @@ -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; @@ -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) { @@ -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); } @@ -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; } @@ -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; } } @@ -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()) { @@ -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) { |