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

Commit 47606f56 authored by Jordan Liu's avatar Jordan Liu
Browse files

Fix logic for removable eUICCs being default

Currently the logic for whether to let a removable eUICC be the
default checks that there is no built-in eUICC. This leads to issues
when there is a built-in eUICC but it's inactive. In that case we
should still set the removable eUICC to the default, so this CL updates
the logic to check if there is a built-in *active* eUICC.

Bug: 141026212
Test: manually verified that a removable eUICC was selected as default
on Sargo with built-in eSIM inactive, also atest UiccControllerTest
Change-Id: I6e6a97af53303eca1a34ff3efd708ea02f0ff5d3
Merged-In: I6e6a97af53303eca1a34ff3efd708ea02f0ff5d3
parent ca77bef0
Loading
Loading
Loading
Loading
+41 −19
Original line number Diff line number Diff line
@@ -159,6 +159,12 @@ public class UiccController extends Handler {
    // Whether the device has an eUICC built in.
    private boolean mHasBuiltInEuicc = false;

    // Whether the device has a currently active built in eUICC
    private boolean mHasActiveBuiltInEuicc = false;

    // The physical slots which correspond to built-in eUICCs
    private final int[] mEuiccSlots;

    // SharedPreferences key for saving the default euicc card ID
    private static final String DEFAULT_CARD = "default_card";

@@ -236,6 +242,8 @@ public class UiccController extends Handler {
        mCardStrings = loadCardStrings();
        mDefaultEuiccCardId = UNINITIALIZED_CARD_ID;

        mEuiccSlots = mContext.getResources()
                .getIntArray(com.android.internal.R.array.non_removable_euicc_slots);
        mHasBuiltInEuicc = hasBuiltInEuicc();
    }

@@ -821,6 +829,7 @@ public class UiccController extends Handler {
        int numActiveSlots = 0;
        boolean isDefaultEuiccCardIdSet = false;
        boolean anyEuiccIsActive = false;
        mHasActiveBuiltInEuicc = false;
        for (int i = 0; i < status.size(); i++) {
            IccSlotStatus iss = status.get(i);
            boolean isActive = (iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_ACTIVE);
@@ -854,6 +863,10 @@ public class UiccController extends Handler {
            if (mUiccSlots[i].isEuicc()) {
                if (isActive) {
                    anyEuiccIsActive = true;

                    if (isBuiltInEuiccSlot(i)) {
                        mHasActiveBuiltInEuicc = true;
                    }
                }
                String eid = iss.eid;
                if (TextUtils.isEmpty(eid)) {
@@ -876,23 +889,17 @@ public class UiccController extends Handler {
            }
        }

        if (mHasBuiltInEuicc && !anyEuiccIsActive && !isDefaultEuiccCardIdSet) {
            log("onGetSlotStatusDone: setting TEMPORARILY_UNSUPPORTED_CARD_ID");
            isDefaultEuiccCardIdSet = true;
            mDefaultEuiccCardId = TEMPORARILY_UNSUPPORTED_CARD_ID;
        }

        if (!mHasBuiltInEuicc && !isDefaultEuiccCardIdSet) {
            // if there are no built-in eUICCs, then consider setting a removable eUICC to the
            // default.
        if (!mHasActiveBuiltInEuicc && !isDefaultEuiccCardIdSet) {
            // if there are no active built-in eUICCs, then consider setting a removable eUICC to
            // the default.
            // Note that on HAL<1.2, it's possible that a built-in eUICC exists, but does not
            // correspond to any slot in mUiccSlots. This logic is still safe in that case because
            // SlotStatus is only for HAL >= 1.2
            for (int i = 0; i < status.size(); i++) {
                if (mUiccSlots[i].isEuicc()) {
                    isDefaultEuiccCardIdSet = true;
                    String eid = status.get(i).eid;
                    if (!TextUtils.isEmpty(eid)) {
                        isDefaultEuiccCardIdSet = true;
                        mDefaultEuiccCardId = convertToPublicCardId(eid);
                        log("Using eid=" + eid + " from removable eUICC in slot="
                                + i + " to set mDefaultEuiccCardId=" + mDefaultEuiccCardId);
@@ -902,8 +909,16 @@ public class UiccController extends Handler {
            }
        }

        if (mHasBuiltInEuicc && !anyEuiccIsActive && !isDefaultEuiccCardIdSet) {
            log("onGetSlotStatusDone: setting TEMPORARILY_UNSUPPORTED_CARD_ID");
            isDefaultEuiccCardIdSet = true;
            mDefaultEuiccCardId = TEMPORARILY_UNSUPPORTED_CARD_ID;
        }


        if (!isDefaultEuiccCardIdSet) {
            // no eUICCs at all
            // no known eUICCs at all (it's possible that an eUICC is inserted and we just don't
            // know it's EID)
            mDefaultEuiccCardId = UNINITIALIZED_CARD_ID;
        }

@@ -1043,8 +1058,9 @@ public class UiccController extends Handler {
                        + " mDefaultEuiccCardId=" + mDefaultEuiccCardId;
                sLocalLog.log(logStr);
                log(logStr);
            } else if (!mHasBuiltInEuicc) {
                // we only set a removable eUICC to the default if there are no non-removable eUICCs
            } else if (!mHasActiveBuiltInEuicc) {
                // we only set a removable eUICC to the default if there are no active non-removable
                // eUICCs
                mDefaultEuiccCardId = convertToPublicCardId(eid);
                String logStr = "onEidReady: eid=" + eid + " from removable eUICC in slot="
                        + slotId + " mDefaultEuiccCardId=" + mDefaultEuiccCardId;
@@ -1057,15 +1073,20 @@ public class UiccController extends Handler {

    // Return true if the device has at least one built in eUICC based on the resource overlay
    private boolean hasBuiltInEuicc() {
        int[] euiccSlots = mContext.getResources()
                .getIntArray(com.android.internal.R.array.non_removable_euicc_slots);
        if (euiccSlots == null || euiccSlots.length == 0) {
            log("hasBuiltInEuicc: non_removable_euicc_slots resource is empty; returning false.");
        return mEuiccSlots != null &&  mEuiccSlots.length > 0;
    }

    private boolean isBuiltInEuiccSlot(int slotIndex) {
        if (!mHasBuiltInEuicc) {
            return false;
        }
        log("hasBuiltInEuicc: non_removable_euicc_slots resource not empty, returning true");
        for (int slot : mEuiccSlots) {
            if (slot == slotIndex) {
                return true;
            }
        }
        return false;
    }

    /**
     * static method to return whether CDMA is supported on the device
@@ -1109,6 +1130,7 @@ public class UiccController extends Handler {
        pw.flush();
        pw.println(" mIsCdmaSupported=" + isCdmaSupported(mContext));
        pw.println(" mHasBuiltInEuicc=" + mHasBuiltInEuicc);
        pw.println(" mHasActiveBuiltInEuicc=" + mHasActiveBuiltInEuicc);
        pw.println(" mUiccSlots: size=" + mUiccSlots.length);
        pw.println(" mCardStrings=" + mCardStrings);
        pw.println(" mDefaultEuiccCardId=" + mDefaultEuiccCardId);
+22 −10
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ public class UiccControllerTest extends TelephonyTest {
    private static final int ICC_CHANGED_EVENT = 0;
    private static final int EVENT_GET_ICC_STATUS_DONE = 3;
    private static final int EVENT_GET_SLOT_STATUS_DONE = 4;
    private static final int EVENT_EID_READY = 9;
    @Mock
    private Handler mMockedHandler;
    @Mock
@@ -556,10 +557,10 @@ public class UiccControllerTest extends TelephonyTest {
    }

    /**
     * The default eUICC should not be the removable slot if there is a built-in eUICC, even if that
     * The default eUICC should not be the removable slot if there is a built-in eUICC, unless that
     * eUICC is inactive.
     * When there is a built-in eUICC which is inactive, we set the mDefaultEuiccCardId to
     * TEMPORARILY_UNSUPPORTED_CARD_ID.
     * the removable eUICC.
     */
    @Test
    public void testDefaultEuiccIsNotRemovable_EuiccIsInactive() {
@@ -577,16 +578,16 @@ public class UiccControllerTest extends TelephonyTest {
        doReturn(true).when(mMockSlot).isEuicc();
        doReturn(false).when(mMockSlot).isRemovable();
        mUiccControllerUT.mUiccSlots[1] = mMockRemovableEuiccSlot;
        doReturn(true).when(mMockSlot).isEuicc();
        doReturn(true).when(mMockSlot).isRemovable();
        doReturn(true).when(mMockRemovableEuiccSlot).isEuicc();
        doReturn(true).when(mMockRemovableEuiccSlot).isRemovable();

        // simulate slot status loaded so that the UiccController sets the card ID
        // simulate slot status loaded with no EID provided (like HAL < 1.4)
        IccSlotStatus iss1 = new IccSlotStatus();
        iss1.setSlotState(0 /* active */);
        iss1.eid = "AB123456";
        iss1.setSlotState(0 /* inactive */);
        iss1.eid = "";
        IccSlotStatus iss2 = new IccSlotStatus();
        iss2.setSlotState(1 /* active */);
        iss2.eid = "ZYW13094";
        iss2.eid = "";
        ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
        status.add(iss1);
        status.add(iss2);
@@ -594,8 +595,19 @@ public class UiccControllerTest extends TelephonyTest {
        Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_SLOT_STATUS_DONE, ar);
        mUiccControllerUT.handleMessage(msg);

        // assert that the default eUICC cardId is TEMPORARILY_UNSUPPORTED_CARD_ID
        assertEquals(TelephonyManager.UNSUPPORTED_CARD_ID,
        // slot status update will not set the default euicc because all EIDs are ""
        assertEquals(TelephonyManager.UNINITIALIZED_CARD_ID,
                mUiccControllerUT.getCardIdForDefaultEuicc());

        // when EID is loaded for slot 1, then the default euicc should be set
        ar = new AsyncResult(1 /* slot */, null, null);
        msg = Message.obtain(mUiccControllerUT, EVENT_EID_READY, ar);
        doReturn(mMockEuiccCard).when(mMockRemovableEuiccSlot).getUiccCard();
        String eidForRemovableEuicc = "ASLDKFJLKSJDF";
        doReturn(eidForRemovableEuicc).when(mMockEuiccCard).getEid();
        mUiccControllerUT.handleMessage(msg);

        assertEquals(mUiccControllerUT.convertToPublicCardId(eidForRemovableEuicc),
                mUiccControllerUT.getCardIdForDefaultEuicc());
    }
}