Loading src/com/android/settings/network/SubscriptionUtil.java +1 −1 Original line number Diff line number Diff line Loading @@ -479,7 +479,7 @@ public class SubscriptionUtil { .stream() .filter(subInfo -> subInfo.getSubscriptionId() == subId) .findFirst() .get(); .orElse(null); } /** Loading src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java +67 −18 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.app.PendingIntent; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.UiccCardInfo; import android.telephony.UiccPortInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; import android.telephony.euicc.EuiccManager; import android.util.Log; Loading @@ -28,6 +30,8 @@ import android.util.Log; import com.android.settings.SidecarFragment; import com.android.settings.network.telephony.EuiccOperationSidecar; import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.Comparator; import java.util.List; Loading @@ -44,6 +48,7 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { private int mPort; private SubscriptionInfo mRemovedSubInfo; private boolean mIsDuringSimSlotMapping; private List<SubscriptionInfo> mActiveSubInfos; /** Returns a SwitchToEuiccSubscriptionSidecar sidecar instance. */ public static SwitchToEuiccSubscriptionSidecar get(FragmentManager fm) { Loading Loading @@ -87,6 +92,10 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { setState(State.RUNNING, Substate.UNUSED); mCallbackIntent = createCallbackIntent(); mSubId = subscriptionId; SubscriptionManager subscriptionManager = getContext().getSystemService( SubscriptionManager.class); mActiveSubInfos = SubscriptionUtil.getActiveSubscriptions(subscriptionManager); int targetSlot = getTargetSlot(); if (targetSlot < 0) { Log.d(TAG, "There is no esim, the TargetSlot is " + targetSlot); Loading @@ -99,15 +108,29 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { mPort = (port < 0) ? getTargetPortId(targetSlot, removedSubInfo) : port; mRemovedSubInfo = removedSubInfo; Log.d(TAG, String.format("set esim into the SubId%d Slot%d:Port%d", String.format("set esim into the SubId%d Physical Slot%d:Port%d", mSubId, targetSlot, mPort)); if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null && removedSubInfo.isEmbedded()) { // In DSDS mode+MEP, if the replaced esim is active, then it should be disabled esim // profile before changing SimSlotMapping process. // Use INVALID_SUBSCRIPTION_ID to disable the esim profile. // The SimSlotMapping is ready, then to execute activate/inactivate esim. if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { // If the subId is INVALID_SUBSCRIPTION_ID, disable the esim (the default esim slot // which is selected by the framework). switchToSubscription(); } else if ((mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null && removedSubInfo.isEmbedded()) || isEsimEnabledAtTargetSlotPort(targetSlot, mPort)) { // Case1: In DSDS mode+MEP, if the replaced esim is active, then the replaced esim // should be disabled before changing SimSlotMapping process. // // Case2: If the user enables the esimA on the target slot:port and the target // slot:port is active and there is an active esimB on target slot:port, then the // settings disables the esimB before the settings enables the esimA on the // target slot:port. // // Step: // 1. disables the replaced esim. // 2. switches the SimSlotMapping if the target slot port is not active. // 3. enables the target esim. // Note: Use INVALID_SUBSCRIPTION_ID to disable the esim profile. Log.d(TAG, "disable the enabled esim before the settings enables the target esim"); mIsDuringSimSlotMapping = true; mEuiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mPort, mCallbackIntent); Loading @@ -117,8 +140,8 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } private int getTargetPortId(int physicalEsimSlotIndex, SubscriptionInfo removedSubInfo) { if (!isMultipleEnabledProfilesSupported()) { Log.d(TAG, "The device is no MEP, port is 0"); if (!isMultipleEnabledProfilesSupported(physicalEsimSlotIndex)) { Log.d(TAG, "The slotId" + physicalEsimSlotIndex + " is no MEP, port is 0"); return 0; } Loading Loading @@ -150,11 +173,12 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { // port is 0. int port = 0; SubscriptionManager subscriptionManager = getContext().getSystemService( SubscriptionManager.class); if(mActiveSubInfos == null){ Log.d(TAG, "mActiveSubInfos is null."); return port; } List<SubscriptionInfo> activeEsimSubInfos = SubscriptionUtil.getActiveSubscriptions(subscriptionManager) .stream() mActiveSubInfos.stream() .filter(i -> i.isEmbedded()) .sorted(Comparator.comparingInt(SubscriptionInfo::getPortIndex)) .collect(Collectors.toList()); Loading @@ -167,7 +191,31 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } private int getTargetSlot() { return UiccSlotUtil.getEsimSlotId(getContext()); return UiccSlotUtil.getEsimSlotId(getContext(), mSubId); } private boolean isEsimEnabledAtTargetSlotPort(int physicalSlotIndex, int portIndex) { int logicalSlotId = getLogicalSlotIndex(physicalSlotIndex, portIndex); if (logicalSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { return false; } return mActiveSubInfos != null && mActiveSubInfos.stream() .anyMatch(i -> i.isEmbedded() && i.getSimSlotIndex() == logicalSlotId); } private int getLogicalSlotIndex(int physicalSlotIndex, int portIndex) { ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(mTelephonyManager); if (slotInfos != null && physicalSlotIndex >= 0 && physicalSlotIndex < slotInfos.size() && slotInfos.get(physicalSlotIndex) != null) { for (UiccPortInfo portInfo : slotInfos.get(physicalSlotIndex).getPorts()) { if (portInfo.getPortIndex() == portIndex) { return portInfo.getLogicalSlotIndex(); } } } return SubscriptionManager.INVALID_SIM_SLOT_INDEX; } private void onSwitchSlotSidecarStateChange() { Loading @@ -185,14 +233,15 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } } private boolean isMultipleEnabledProfilesSupported() { private boolean isMultipleEnabledProfilesSupported(int physicalEsimSlotIndex) { List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo(); if (cardInfos == null) { Log.w(TAG, "UICC cards info list is empty."); return false; } return cardInfos.stream().anyMatch( cardInfo -> cardInfo.isMultipleEnabledProfilesSupported()); return cardInfos.stream() .anyMatch(cardInfo -> cardInfo.getPhysicalSlotIndex() == physicalEsimSlotIndex && cardInfo.isMultipleEnabledProfilesSupported()); } private void switchToSubscription() { Loading src/com/android/settings/network/UiccSlotUtil.java +22 −1 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.uicc.UiccController; import com.android.settingslib.utils.ThreadUtils; import com.google.common.collect.ImmutableList; Loading @@ -36,6 +38,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; Loading Loading @@ -183,9 +186,27 @@ public class UiccSlotUtil { * @param context the application context. * @return the esim slot. If the value is -1, there is not the esim. */ public static int getEsimSlotId(Context context) { public static int getEsimSlotId(Context context, int subId) { TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); List<UiccCardInfo> uiccCardInfos = telMgr.getUiccCardsInfo(); ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr); SubscriptionManager subscriptionManager = context.getSystemService( SubscriptionManager.class); SubscriptionInfo subInfo = SubscriptionUtil.getSubById(subscriptionManager, subId); // checking whether this is the removable esim. If it is, then return the removable slot id. if (subInfo != null && subInfo.isEmbedded()) { for (UiccCardInfo uiccCardInfo : uiccCardInfos) { if (uiccCardInfo.getCardId() == subInfo.getCardId() && uiccCardInfo.getCardId() > TelephonyManager.UNSUPPORTED_CARD_ID && uiccCardInfo.isEuicc() && uiccCardInfo.isRemovable()) { Log.d(TAG, "getEsimSlotId: This subInfo is removable esim."); return uiccCardInfo.getPhysicalSlotIndex(); } } } int firstEsimSlot = IntStream.range(0, slotInfos.size()) .filter( index -> { Loading tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java +69 −8 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; import android.telephony.UiccPortInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; Loading Loading @@ -53,16 +55,24 @@ public class UiccSlotUtilTest { private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private SubscriptionManager mSubscriptionManager; private static final int ESIM_PHYSICAL_SLOT = 0; private static final int PSIM_PHYSICAL_SLOT = 1; private List<SubscriptionInfo> mSubscriptionInfoList = new ArrayList<>(); private List<UiccCardInfo> mUiccCardInfo = new ArrayList<>(); @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mTelephonyManager.getUiccCardsInfo()).thenReturn(mUiccCardInfo); when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); when(mSubscriptionManager.getAllSubscriptionInfoList()).thenReturn(mSubscriptionInfoList); } @Test Loading @@ -88,15 +98,35 @@ public class UiccSlotUtilTest { public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot0_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActiveEsimActivePsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(0); } @Test public void getEsimSlotId_simIsRemovableEsimAndRemovableEsimIsSlot1_returnRemovableEsimSlot1() { int subId = 0; int cardId = 0; mSubscriptionInfoList.add(createSubscriptionInfo(subId,-1, -1, true, cardId)); mUiccCardInfo.add(createUiccCardInfo(true, 3, 0, false, -1, -1)); mUiccCardInfo.add(createUiccCardInfo(true, cardId, 1, true, -1, -1)); when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActiveEsimActiveRemovableEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext, subId); assertThat(testSlot).isEqualTo(1); } @Test public void getEsimSlotId_twoSimSlotsDeviceAndRemovableEsimIsSlot1_returnTheCorrectEsimSlot() { public void getEsimSlotId_simIsRemovableEsimAndTwoRemovableSlots_returnRemovableEsimSlot1() { int subId = 0; int cardId = 0; mSubscriptionInfoList.add(createSubscriptionInfo(subId,-1, -1, true, cardId)); mUiccCardInfo.add(createUiccCardInfo(false, 4, 0, true, -1, -1)); mUiccCardInfo.add(createUiccCardInfo(true, cardId, 1, true, -1, -1)); when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActivePsimActiveRemovableEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext, subId); assertThat(testSlot).isEqualTo(1); } Loading @@ -105,7 +135,7 @@ public class UiccSlotUtilTest { public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActivePsimActiveEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(1); } Loading @@ -114,7 +144,7 @@ public class UiccSlotUtilTest { public void getEsimSlotId_noEimSlotDevice_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( oneSimSlotDeviceActivePsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(-1); } Loading Loading @@ -620,13 +650,38 @@ public class UiccSlotUtilTest { } private SubscriptionInfo createSubscriptionInfo(int logicalSlotIndex, int portIndex) { return createSubscriptionInfo(0, logicalSlotIndex, portIndex, true, 25); } private SubscriptionInfo createSubscriptionInfo(int subId, int logicalSlotIndex, int portIndex, boolean isEmbedded, int cardId) { return new SubscriptionInfo( 0, "", logicalSlotIndex, "", "", 0, 0, "", 0, null, "", "", "", true /* isEmbedded */, null, "", 25, subId, "", logicalSlotIndex, "", "", 0, 0, "", 0, null, "", "", "", isEmbedded /* isEmbedded */, null, "", cardId, false, null, false, 0, 0, 0, null, null, true, portIndex); } private UiccCardInfo createUiccCardInfo(boolean isEuicc, int cardId, int physicalSlotIndex, boolean isRemovable, int logicalSlotIndex, int portIndex) { return new UiccCardInfo( isEuicc /* isEuicc */, cardId /* cardId */, null /* eid */, physicalSlotIndex /* physicalSlotIndex */, isRemovable /* isRemovable */, false /* isMultipleEnabledProfileSupported */, Collections.singletonList( new UiccPortInfo( "123451234567890" /* iccId */, portIndex /* portIdx */, logicalSlotIndex /* logicalSlotIdx */, true /* isActive */) )); } private List<SubscriptionInfo> createActiveSubscriptionInfoListOneSim(int logicalSlotIndex, int portIndex) { List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>(); Loading Loading @@ -737,6 +792,12 @@ public class UiccSlotUtilTest { createUiccSlotInfo(true, false, 1, true)}; } private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActiveRemovableEsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(true, false, 0, true), createUiccSlotInfo(true, true, 1, true)}; } private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveRemovableEsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(false, true, 0, true), Loading Loading
src/com/android/settings/network/SubscriptionUtil.java +1 −1 Original line number Diff line number Diff line Loading @@ -479,7 +479,7 @@ public class SubscriptionUtil { .stream() .filter(subInfo -> subInfo.getSubscriptionId() == subId) .findFirst() .get(); .orElse(null); } /** Loading
src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java +67 −18 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.app.PendingIntent; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.UiccCardInfo; import android.telephony.UiccPortInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; import android.telephony.euicc.EuiccManager; import android.util.Log; Loading @@ -28,6 +30,8 @@ import android.util.Log; import com.android.settings.SidecarFragment; import com.android.settings.network.telephony.EuiccOperationSidecar; import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.Comparator; import java.util.List; Loading @@ -44,6 +48,7 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { private int mPort; private SubscriptionInfo mRemovedSubInfo; private boolean mIsDuringSimSlotMapping; private List<SubscriptionInfo> mActiveSubInfos; /** Returns a SwitchToEuiccSubscriptionSidecar sidecar instance. */ public static SwitchToEuiccSubscriptionSidecar get(FragmentManager fm) { Loading Loading @@ -87,6 +92,10 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { setState(State.RUNNING, Substate.UNUSED); mCallbackIntent = createCallbackIntent(); mSubId = subscriptionId; SubscriptionManager subscriptionManager = getContext().getSystemService( SubscriptionManager.class); mActiveSubInfos = SubscriptionUtil.getActiveSubscriptions(subscriptionManager); int targetSlot = getTargetSlot(); if (targetSlot < 0) { Log.d(TAG, "There is no esim, the TargetSlot is " + targetSlot); Loading @@ -99,15 +108,29 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { mPort = (port < 0) ? getTargetPortId(targetSlot, removedSubInfo) : port; mRemovedSubInfo = removedSubInfo; Log.d(TAG, String.format("set esim into the SubId%d Slot%d:Port%d", String.format("set esim into the SubId%d Physical Slot%d:Port%d", mSubId, targetSlot, mPort)); if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null && removedSubInfo.isEmbedded()) { // In DSDS mode+MEP, if the replaced esim is active, then it should be disabled esim // profile before changing SimSlotMapping process. // Use INVALID_SUBSCRIPTION_ID to disable the esim profile. // The SimSlotMapping is ready, then to execute activate/inactivate esim. if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { // If the subId is INVALID_SUBSCRIPTION_ID, disable the esim (the default esim slot // which is selected by the framework). switchToSubscription(); } else if ((mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null && removedSubInfo.isEmbedded()) || isEsimEnabledAtTargetSlotPort(targetSlot, mPort)) { // Case1: In DSDS mode+MEP, if the replaced esim is active, then the replaced esim // should be disabled before changing SimSlotMapping process. // // Case2: If the user enables the esimA on the target slot:port and the target // slot:port is active and there is an active esimB on target slot:port, then the // settings disables the esimB before the settings enables the esimA on the // target slot:port. // // Step: // 1. disables the replaced esim. // 2. switches the SimSlotMapping if the target slot port is not active. // 3. enables the target esim. // Note: Use INVALID_SUBSCRIPTION_ID to disable the esim profile. Log.d(TAG, "disable the enabled esim before the settings enables the target esim"); mIsDuringSimSlotMapping = true; mEuiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mPort, mCallbackIntent); Loading @@ -117,8 +140,8 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } private int getTargetPortId(int physicalEsimSlotIndex, SubscriptionInfo removedSubInfo) { if (!isMultipleEnabledProfilesSupported()) { Log.d(TAG, "The device is no MEP, port is 0"); if (!isMultipleEnabledProfilesSupported(physicalEsimSlotIndex)) { Log.d(TAG, "The slotId" + physicalEsimSlotIndex + " is no MEP, port is 0"); return 0; } Loading Loading @@ -150,11 +173,12 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { // port is 0. int port = 0; SubscriptionManager subscriptionManager = getContext().getSystemService( SubscriptionManager.class); if(mActiveSubInfos == null){ Log.d(TAG, "mActiveSubInfos is null."); return port; } List<SubscriptionInfo> activeEsimSubInfos = SubscriptionUtil.getActiveSubscriptions(subscriptionManager) .stream() mActiveSubInfos.stream() .filter(i -> i.isEmbedded()) .sorted(Comparator.comparingInt(SubscriptionInfo::getPortIndex)) .collect(Collectors.toList()); Loading @@ -167,7 +191,31 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } private int getTargetSlot() { return UiccSlotUtil.getEsimSlotId(getContext()); return UiccSlotUtil.getEsimSlotId(getContext(), mSubId); } private boolean isEsimEnabledAtTargetSlotPort(int physicalSlotIndex, int portIndex) { int logicalSlotId = getLogicalSlotIndex(physicalSlotIndex, portIndex); if (logicalSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { return false; } return mActiveSubInfos != null && mActiveSubInfos.stream() .anyMatch(i -> i.isEmbedded() && i.getSimSlotIndex() == logicalSlotId); } private int getLogicalSlotIndex(int physicalSlotIndex, int portIndex) { ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(mTelephonyManager); if (slotInfos != null && physicalSlotIndex >= 0 && physicalSlotIndex < slotInfos.size() && slotInfos.get(physicalSlotIndex) != null) { for (UiccPortInfo portInfo : slotInfos.get(physicalSlotIndex).getPorts()) { if (portInfo.getPortIndex() == portIndex) { return portInfo.getLogicalSlotIndex(); } } } return SubscriptionManager.INVALID_SIM_SLOT_INDEX; } private void onSwitchSlotSidecarStateChange() { Loading @@ -185,14 +233,15 @@ public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar { } } private boolean isMultipleEnabledProfilesSupported() { private boolean isMultipleEnabledProfilesSupported(int physicalEsimSlotIndex) { List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo(); if (cardInfos == null) { Log.w(TAG, "UICC cards info list is empty."); return false; } return cardInfos.stream().anyMatch( cardInfo -> cardInfo.isMultipleEnabledProfilesSupported()); return cardInfos.stream() .anyMatch(cardInfo -> cardInfo.getPhysicalSlotIndex() == physicalEsimSlotIndex && cardInfo.isMultipleEnabledProfilesSupported()); } private void switchToSubscription() { Loading
src/com/android/settings/network/UiccSlotUtil.java +22 −1 Original line number Diff line number Diff line Loading @@ -22,11 +22,13 @@ import android.provider.Settings; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.uicc.UiccController; import com.android.settingslib.utils.ThreadUtils; import com.google.common.collect.ImmutableList; Loading @@ -36,6 +38,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; Loading Loading @@ -183,9 +186,27 @@ public class UiccSlotUtil { * @param context the application context. * @return the esim slot. If the value is -1, there is not the esim. */ public static int getEsimSlotId(Context context) { public static int getEsimSlotId(Context context, int subId) { TelephonyManager telMgr = context.getSystemService(TelephonyManager.class); List<UiccCardInfo> uiccCardInfos = telMgr.getUiccCardsInfo(); ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr); SubscriptionManager subscriptionManager = context.getSystemService( SubscriptionManager.class); SubscriptionInfo subInfo = SubscriptionUtil.getSubById(subscriptionManager, subId); // checking whether this is the removable esim. If it is, then return the removable slot id. if (subInfo != null && subInfo.isEmbedded()) { for (UiccCardInfo uiccCardInfo : uiccCardInfos) { if (uiccCardInfo.getCardId() == subInfo.getCardId() && uiccCardInfo.getCardId() > TelephonyManager.UNSUPPORTED_CARD_ID && uiccCardInfo.isEuicc() && uiccCardInfo.isRemovable()) { Log.d(TAG, "getEsimSlotId: This subInfo is removable esim."); return uiccCardInfo.getPhysicalSlotIndex(); } } } int firstEsimSlot = IntStream.range(0, slotInfos.size()) .filter( index -> { Loading
tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java +69 −8 Original line number Diff line number Diff line Loading @@ -25,7 +25,9 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; import android.telephony.UiccPortInfo; import android.telephony.UiccSlotInfo; import android.telephony.UiccSlotMapping; Loading Loading @@ -53,16 +55,24 @@ public class UiccSlotUtilTest { private Context mContext; @Mock private TelephonyManager mTelephonyManager; @Mock private SubscriptionManager mSubscriptionManager; private static final int ESIM_PHYSICAL_SLOT = 0; private static final int PSIM_PHYSICAL_SLOT = 1; private List<SubscriptionInfo> mSubscriptionInfoList = new ArrayList<>(); private List<UiccCardInfo> mUiccCardInfo = new ArrayList<>(); @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(ApplicationProvider.getApplicationContext()); when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mTelephonyManager.getUiccCardsInfo()).thenReturn(mUiccCardInfo); when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); when(mSubscriptionManager.getAllSubscriptionInfoList()).thenReturn(mSubscriptionInfoList); } @Test Loading @@ -88,15 +98,35 @@ public class UiccSlotUtilTest { public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot0_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActiveEsimActivePsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(0); } @Test public void getEsimSlotId_simIsRemovableEsimAndRemovableEsimIsSlot1_returnRemovableEsimSlot1() { int subId = 0; int cardId = 0; mSubscriptionInfoList.add(createSubscriptionInfo(subId,-1, -1, true, cardId)); mUiccCardInfo.add(createUiccCardInfo(true, 3, 0, false, -1, -1)); mUiccCardInfo.add(createUiccCardInfo(true, cardId, 1, true, -1, -1)); when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActiveEsimActiveRemovableEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext, subId); assertThat(testSlot).isEqualTo(1); } @Test public void getEsimSlotId_twoSimSlotsDeviceAndRemovableEsimIsSlot1_returnTheCorrectEsimSlot() { public void getEsimSlotId_simIsRemovableEsimAndTwoRemovableSlots_returnRemovableEsimSlot1() { int subId = 0; int cardId = 0; mSubscriptionInfoList.add(createSubscriptionInfo(subId,-1, -1, true, cardId)); mUiccCardInfo.add(createUiccCardInfo(false, 4, 0, true, -1, -1)); mUiccCardInfo.add(createUiccCardInfo(true, cardId, 1, true, -1, -1)); when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActivePsimActiveRemovableEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext, subId); assertThat(testSlot).isEqualTo(1); } Loading @@ -105,7 +135,7 @@ public class UiccSlotUtilTest { public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( twoSimSlotsDeviceActivePsimActiveEsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(1); } Loading @@ -114,7 +144,7 @@ public class UiccSlotUtilTest { public void getEsimSlotId_noEimSlotDevice_returnTheCorrectEsimSlot() { when(mTelephonyManager.getUiccSlotsInfo()).thenReturn( oneSimSlotDeviceActivePsim()); int testSlot = UiccSlotUtil.getEsimSlotId(mContext); int testSlot = UiccSlotUtil.getEsimSlotId(mContext,0); assertThat(testSlot).isEqualTo(-1); } Loading Loading @@ -620,13 +650,38 @@ public class UiccSlotUtilTest { } private SubscriptionInfo createSubscriptionInfo(int logicalSlotIndex, int portIndex) { return createSubscriptionInfo(0, logicalSlotIndex, portIndex, true, 25); } private SubscriptionInfo createSubscriptionInfo(int subId, int logicalSlotIndex, int portIndex, boolean isEmbedded, int cardId) { return new SubscriptionInfo( 0, "", logicalSlotIndex, "", "", 0, 0, "", 0, null, "", "", "", true /* isEmbedded */, null, "", 25, subId, "", logicalSlotIndex, "", "", 0, 0, "", 0, null, "", "", "", isEmbedded /* isEmbedded */, null, "", cardId, false, null, false, 0, 0, 0, null, null, true, portIndex); } private UiccCardInfo createUiccCardInfo(boolean isEuicc, int cardId, int physicalSlotIndex, boolean isRemovable, int logicalSlotIndex, int portIndex) { return new UiccCardInfo( isEuicc /* isEuicc */, cardId /* cardId */, null /* eid */, physicalSlotIndex /* physicalSlotIndex */, isRemovable /* isRemovable */, false /* isMultipleEnabledProfileSupported */, Collections.singletonList( new UiccPortInfo( "123451234567890" /* iccId */, portIndex /* portIdx */, logicalSlotIndex /* logicalSlotIdx */, true /* isActive */) )); } private List<SubscriptionInfo> createActiveSubscriptionInfoListOneSim(int logicalSlotIndex, int portIndex) { List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>(); Loading Loading @@ -737,6 +792,12 @@ public class UiccSlotUtilTest { createUiccSlotInfo(true, false, 1, true)}; } private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActiveRemovableEsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(true, false, 0, true), createUiccSlotInfo(true, true, 1, true)}; } private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveRemovableEsim() { return new UiccSlotInfo[]{ createUiccSlotInfo(false, true, 0, true), Loading