From 81dbc00b6e50cf8dc3a10b82eb98568c5123065d Mon Sep 17 00:00:00 2001 From: Yoshiaki Naka Date: Fri, 13 Sep 2019 21:41:01 +0900 Subject: [PATCH] Retrieve EID from each card Each eUICC has its own EID. The same EID retrieved from the default eUICC shall not be displayed for all the SIM status dialogs when the device supports multiple UICCs. Bug: 141256483 Test: Manual and SimStatusDialogControllerTest Change-Id: I367ae3a5f97ff92e03312bed6fe37727ae3798ab --- AndroidManifest.xml | 1 + .../simstatus/SimStatusDialogController.java | 46 ++- .../SimStatusDialogControllerTest.java | 295 +++++++++++++++++- 3 files changed, 328 insertions(+), 14 deletions(-) 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)); }