Loading src/java/com/android/internal/telephony/uicc/UiccController.java +41 −19 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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(); } Loading Loading @@ -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); Loading Loading @@ -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)) { Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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); Loading tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java +22 −10 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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() { Loading @@ -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); Loading @@ -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()); } } Loading
src/java/com/android/internal/telephony/uicc/UiccController.java +41 −19 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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(); } Loading Loading @@ -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); Loading Loading @@ -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)) { Loading @@ -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); Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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); Loading
tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java +22 −10 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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() { Loading @@ -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); Loading @@ -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()); } }