aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/internal/telephony/uicc
diff options
context:
space:
mode:
authorMuralidhar Reddy <muralidharm@google.com>2023-01-05 16:37:49 +0000
committerMuralidhar Reddy <muralidharm@google.com>2023-01-19 04:05:12 +0000
commit80b86e12c3a0efbd206d5af1ef40febdae908f5f (patch)
treea1077413831275d355189a7824ed4401082613f3 /src/java/com/android/internal/telephony/uicc
parent13fabc3153a95d0aa6f66bca2f4e5fa682b4fc35 (diff)
downloadtelephony-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.java8
-rw-r--r--src/java/com/android/internal/telephony/uicc/UiccSlot.java76
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) {