diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ba74aa8d74f..94b8e129151 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -39,6 +39,7 @@ + diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java index 0751141ce45..b1f089aad61 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java @@ -35,12 +35,14 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; +import android.telephony.UiccCardInfo; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.android.internal.telephony.PhoneConstants; import com.android.settings.R; import com.android.settingslib.DeviceInfoUtils; import com.android.settingslib.Utils; @@ -50,6 +52,7 @@ import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; import java.util.List; +import java.util.Map; public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause { @@ -82,6 +85,8 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O @VisibleForTesting final static int ICCID_INFO_VALUE_ID = R.id.icc_id_value; @VisibleForTesting + final static int EID_INFO_LABEL_ID = R.id.esim_id_label; + @VisibleForTesting final static int EID_INFO_VALUE_ID = R.id.esim_id_value; @VisibleForTesting final static int IMS_REGISTRATION_STATE_LABEL_ID = R.id.ims_reg_state_label; @@ -105,7 +110,7 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O }; private SubscriptionInfo mSubscriptionInfo; - private int mSlotIndex; + private final int mSlotIndex; private final SimStatusDialogFragment mDialog; private final TelephonyManager mTelephonyManager; @@ -398,10 +403,43 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O } private void updateEid() { - if (mEuiccManager.isEnabled()) { - mDialog.setText(EID_INFO_VALUE_ID, mEuiccManager.getEid()); - } else { + boolean shouldHaveEid = false; + String eid = null; + + if (mTelephonyManager.getPhoneCount() > PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM) { + // Get EID per-SIM in multi-SIM mode + Map mapping = mTelephonyManager.getLogicalToPhysicalSlotMapping(); + int pSlotId = mapping.getOrDefault(mSlotIndex, + SubscriptionManager.INVALID_SIM_SLOT_INDEX); + + if (pSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + List infos = mTelephonyManager.getUiccCardsInfo(); + + for (UiccCardInfo info : infos) { + if (info.getSlotIndex() == pSlotId) { + if (info.isEuicc()) { + shouldHaveEid = true; + eid = info.getEid(); + + if (TextUtils.isEmpty(eid)) { + eid = mEuiccManager.createForCardId(info.getCardId()).getEid(); + } + } + break; + } + } + } + } else if (mEuiccManager.isEnabled()) { + // Get EID of default eSIM in single-SIM mode + shouldHaveEid = true; + eid = mEuiccManager.getEid(); + } + + if (!shouldHaveEid) { + mDialog.removeSettingFromScreen(EID_INFO_LABEL_ID); mDialog.removeSettingFromScreen(EID_INFO_VALUE_ID); + } else if (!TextUtils.isEmpty(eid)) { + mDialog.setText(EID_INFO_VALUE_ID, eid); } } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java index 2c0b4fce44e..41ae49cc156 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.deviceinfo.simstatus; import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_DATA_NETWORK_TYPE_VALUE_ID; import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.CELL_VOICE_NETWORK_TYPE_VALUE_ID; +import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_LABEL_ID; import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.EID_INFO_VALUE_ID; import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_LABEL_ID; import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController.ICCID_INFO_VALUE_ID; @@ -55,10 +56,12 @@ import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.telephony.UiccCardInfo; import android.telephony.euicc.EuiccManager; import androidx.lifecycle.LifecycleOwner; +import com.android.internal.telephony.PhoneConstants; import com.android.settings.R; import com.android.settings.testutils.shadow.ShadowDeviceInfoUtils; import com.android.settingslib.DeviceInfoUtils; @@ -79,7 +82,9 @@ import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowDeviceInfoUtils.class}) @@ -117,6 +122,9 @@ public class SimStatusDialogControllerTest { private LifecycleOwner mLifecycleOwner; private Lifecycle mLifecycle; + private static final String TEST_EID_FROM_CARD = "11111111111111111111111111111111"; + private static final String TEST_EID_FROM_MANAGER = "22222222222222222222222222222222"; + @Before public void setup() { MockitoAnnotations.initMocks(this); @@ -140,13 +148,22 @@ public class SimStatusDialogControllerTest { doReturn(mSignalStrength).when(mController).getSignalStrength(); doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt()); - when(mEuiccManager.isEnabled()).thenReturn(true); - when(mEuiccManager.getEid()).thenReturn(""); ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager); ReflectionHelpers.setField(mController, "mCarrierConfigManager", mCarrierConfigManager); ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo); ReflectionHelpers.setField(mController, "mEuiccManager", mEuiccManager); ReflectionHelpers.setField(mController, "mSubscriptionManager", mSubscriptionManager); + + when(mTelephonyManager.getPhoneCount()).thenReturn( + PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(new ArrayList()); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn( + new HashMap()); + + when(mEuiccManager.isEnabled()).thenReturn(false); + when(mEuiccManager.getEid()).thenReturn(""); + when(mEuiccManager.createForCardId(anyInt())).thenReturn(mEuiccManager); + when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mPersistableBundle); when(mPersistableBundle.getBoolean( CarrierConfigManager.KEY_SHOW_SIGNAL_STRENGTH_IN_SIM_STATUS_BOOL)) @@ -408,25 +425,283 @@ public class SimStatusDialogControllerTest { } @Test - @Ignore - public void initialize_showEid_shouldSetEidToSetting() { - final String eid = "12351351231241"; - when(mEuiccManager.getEid()).thenReturn(eid); + public void initialize_updateEid_shouldNotSetEid() { + when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo1 = new UiccCardInfo( + false, // isEuicc + 0, // cardId + null, // eid + "123451234567890", // iccid + 0, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo1); + UiccCardInfo uiccCardInfo2 = new UiccCardInfo( + true, // isEuicc + 1, // cardId + null, // eid (unavailable) + null, // iccid + 1, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo2); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 1); + slotMapping.put(1, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(null); mController.initialize(); - verify(mDialog).setText(EID_INFO_VALUE_ID, eid); + // Keep 'Not available' if neither the card nor the associated manager can provide EID. + verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any()); verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); } @Test - @Ignore - public void initialize_showEid_euiccManagerIsNotEnabled() { - when(mEuiccManager.isEnabled()).thenReturn(false); + public void initialize_updateEid_shouldSetEidFromCard() { + when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo1 = new UiccCardInfo( + true, // isEuicc + 0, // cardId + TEST_EID_FROM_CARD, // eid + null, // iccid + 0, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo1); + UiccCardInfo uiccCardInfo2 = new UiccCardInfo( + false, // isEuicc + 1, // cardId + null, // eid + "123451234567890", // iccid + 1, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo2); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + slotMapping.put(1, 1); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); mController.initialize(); + // Set EID retrieved from the card. + verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_CARD); + verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldSetEidFromManager() { + when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo1 = new UiccCardInfo( + false, // isEuicc + 0, // cardId + null, // eid + "123451234567890", // iccid + 0, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo1); + UiccCardInfo uiccCardInfo2 = new UiccCardInfo( + true, // isEuicc + 1, // cardId + null, // eid (unavailable) + null, // iccid + 1, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo2); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 1); + slotMapping.put(1, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + when(mEuiccManager.createForCardId(0)).thenThrow( + new RuntimeException("Unexpected card ID was specified")); + when(mEuiccManager.createForCardId(1)).thenReturn(mEuiccManager); + + mController.initialize(); + + // Set EID retrieved from the manager associated with the card which cannot provide EID. + verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER); + verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldRemoveEid() { + when(mTelephonyManager.getPhoneCount()).thenReturn(PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo1 = new UiccCardInfo( + false, // isEuicc + 0, // cardId + null, // eid + "123451234567890", // iccid + 0, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo1); + UiccCardInfo uiccCardInfo2 = new UiccCardInfo( + true, // isEuicc + 1, // cardId + TEST_EID_FROM_CARD, // eid + null, // iccid + 1, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo2); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + slotMapping.put(1, 1); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + + mController.initialize(); + + // Remove EID if the card is not eUICC. verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any()); + verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID)); + verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldNotSetEidInSingleSimMode() { + when(mTelephonyManager.getPhoneCount()).thenReturn( + PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo = new UiccCardInfo( + true, // isEuicc + 0, // cardId + TEST_EID_FROM_CARD, // eid (not used) + null, // iccid + 0, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(null); + + mController.initialize(); + + // Keep 'Not available' if the default eUICC manager cannot provide EID in Single SIM mode. + verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any()); + verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldSetEidInSingleSimModeWithEnabledEuicc() { + when(mTelephonyManager.getPhoneCount()).thenReturn( + PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo = new UiccCardInfo( + true, // isEuicc (eUICC slot is selected) + 0, // cardId + TEST_EID_FROM_CARD, // eid (not used) + null, // iccid + 0, // slotIndex + false); // isRemovable + uiccCardInfos.add(uiccCardInfo); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + when(mEuiccManager.createForCardId(anyInt())).thenThrow( + new RuntimeException("EID shall be retrieved from the default eUICC manager")); + + mController.initialize(); + + // Set EID retrieved from the default eUICC manager in Single SIM mode. + verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER); + verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldSetEidInSingleSimModeWithDisabledEuicc() { + when(mTelephonyManager.getPhoneCount()).thenReturn( + PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo = new UiccCardInfo( + false, // isEuicc (eUICC slot is not selected) + 0, // cardId + null, // eid + "123451234567890", // iccid + 0, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(true); + when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + when(mEuiccManager.createForCardId(anyInt())).thenThrow( + new RuntimeException("EID shall be retrieved from the default eUICC manager")); + + mController.initialize(); + + // Set EID retrieved from the default eUICC manager in Single SIM mode. + verify(mDialog).setText(EID_INFO_VALUE_ID, TEST_EID_FROM_MANAGER); + verify(mDialog, never()).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); + } + + @Test + public void initialize_updateEid_shouldRemoveEidInSingleSimMode() { + when(mTelephonyManager.getPhoneCount()).thenReturn( + PhoneConstants.MAX_PHONE_COUNT_SINGLE_SIM); + + ArrayList uiccCardInfos = new ArrayList<>(); + UiccCardInfo uiccCardInfo = new UiccCardInfo( + false, // isEuicc + 0, // cardId + null, // eid + "123451234567890", // iccid + 0, // slotIndex + true); // isRemovable + uiccCardInfos.add(uiccCardInfo); + when(mTelephonyManager.getUiccCardsInfo()).thenReturn(uiccCardInfos); + + Map slotMapping = new HashMap<>(); + slotMapping.put(0, 0); + when(mTelephonyManager.getLogicalToPhysicalSlotMapping()).thenReturn(slotMapping); + + when(mEuiccManager.isEnabled()).thenReturn(false); + when(mEuiccManager.getEid()).thenReturn(null); + + mController.initialize(); + + // Remove EID if the default eUICC manager indicates that eSIM is not enabled. + verify(mDialog, never()).setText(eq(EID_INFO_VALUE_ID), any()); + verify(mDialog).removeSettingFromScreen(eq(EID_INFO_LABEL_ID)); verify(mDialog).removeSettingFromScreen(eq(EID_INFO_VALUE_ID)); }