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

Commit 8bedc899 authored by Muralidhar Reddy Mule's avatar Muralidhar Reddy Mule Committed by Android (Google) Code Review
Browse files

Merge "[MEP] Handle UiccCard and UiccPort disposal when more than one port is supported."

parents c8951481 80b86e12
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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) {
+49 −27
Original line number Diff line number Diff line
@@ -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));
                    }
                    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) {