Merge "Add summary and footer message for the ScreenResolutionFragment." into tm-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1d69657..fc2cb54 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5214,9 +5214,9 @@
     <!-- Title for accessibility shortcut preference for magnification. [CHAR LIMIT=60] -->
     <string name="accessibility_screen_magnification_shortcut_title">Magnification shortcut</string>
     <!-- Title for accessibility follow typing preference for magnification. [CHAR LIMIT=35] -->
-    <string name="accessibility_screen_magnification_follow_typing_title">Follow typing</string>
+    <string name="accessibility_screen_magnification_follow_typing_title">Magnify typing</string>
     <!-- Summary for accessibility follow typing preference for magnification. [CHAR LIMIT=none] -->
-    <string name="accessibility_screen_magnification_follow_typing_summary">Magnification area automatically follows the text as you type</string>
+    <string name="accessibility_screen_magnification_follow_typing_summary">Magnifier follows text as you type</string>
     <!-- Title for screen magnification footer. [CHAR LIMIT=60] -->
     <string name="accessibility_screen_magnification_about_title">About magnification</string>
     <!-- Screen magnification footer link content description [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/accessibility/TextReadingPreferenceFragmentForSetupWizard.java b/src/com/android/settings/accessibility/TextReadingPreferenceFragmentForSetupWizard.java
index c679330..0ff960f 100644
--- a/src/com/android/settings/accessibility/TextReadingPreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/accessibility/TextReadingPreferenceFragmentForSetupWizard.java
@@ -42,7 +42,7 @@
         final GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
         final String title = getContext().getString(
                 R.string.accessibility_text_reading_options_title);
-        final Drawable icon = getContext().getDrawable(R.drawable.ic_font_download);
+        final Drawable icon = getContext().getDrawable(R.drawable.ic_accessibility_visibility);
         icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.colorPrimary));
         AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(getContext(), layout, title,
                 /* description= */ null, icon);
diff --git a/src/com/android/settings/flashlight/FlashlightHandleActivity.java b/src/com/android/settings/flashlight/FlashlightHandleActivity.java
index 5894965..0847d49 100644
--- a/src/com/android/settings/flashlight/FlashlightHandleActivity.java
+++ b/src/com/android/settings/flashlight/FlashlightHandleActivity.java
@@ -21,12 +21,13 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.provider.Settings;
+import android.util.Log;
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.Indexable;
-import com.android.settingslib.search.SearchIndexableRaw;
 import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.SearchIndexableRaw;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -39,6 +40,9 @@
 
     public static final String EXTRA_FALLBACK_TO_HOMEPAGE = "fallback_to_homepage";
 
+    private static final String TAG = "FlashlightActivity";
+    private static final String DATA_KEY = "flashlight";
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -69,10 +73,20 @@
                     data.intentTargetPackage = context.getPackageName();
                     data.intentTargetClass = FlashlightHandleActivity.class.getName();
                     data.intentAction = Intent.ACTION_MAIN;
-                    data.key = "flashlight";
+                    data.key = DATA_KEY;
                     result.add(data);
 
                     return result;
                 }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    if (!FlashlightSlice.isFlashlightAvailable(context)) {
+                        Log.i(TAG, "Flashlight is unavailable");
+                        keys.add(DATA_KEY);
+                    }
+                    return keys;
+                }
             };
 }
diff --git a/src/com/android/settings/flashlight/FlashlightSlice.java b/src/com/android/settings/flashlight/FlashlightSlice.java
index eaf059a..5feaf4f 100644
--- a/src/com/android/settings/flashlight/FlashlightSlice.java
+++ b/src/com/android/settings/flashlight/FlashlightSlice.java
@@ -39,7 +39,6 @@
 import androidx.slice.builders.ListBuilder.RowBuilder;
 import androidx.slice.builders.SliceAction;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.slices.CustomSliceRegistry;
@@ -138,7 +137,6 @@
         return null;
     }
 
-    @VisibleForTesting
     static boolean isFlashlightAvailable(Context context) {
         int defaultAvailability = 0;
         try {
diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java
index d28d93a..c4f495c 100644
--- a/src/com/android/settings/network/UiccSlotUtil.java
+++ b/src/com/android/settings/network/UiccSlotUtil.java
@@ -25,6 +25,7 @@
 import android.telephony.UiccSlotMapping;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.utils.ThreadUtils;
 
 import com.google.common.collect.ImmutableList;
@@ -33,6 +34,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -126,7 +128,10 @@
 
         performSwitchToSlot(telMgr,
                 prepareUiccSlotMappings(uiccSlotMappings,
-                        inactiveRemovableSlot, /*removable sim's port Id*/ 0, removedSubInfo,
+                        /*slot is psim*/ true,
+                        inactiveRemovableSlot,
+                        /*removable sim's port Id*/ TelephonyManager.DEFAULT_PORT_INDEX,
+                        removedSubInfo,
                         telMgr.isMultiSimEnabled()),
                 context);
     }
@@ -159,7 +164,7 @@
         }
 
         performSwitchToSlot(telMgr,
-                prepareUiccSlotMappings(uiccSlotMappings,
+                prepareUiccSlotMappings(uiccSlotMappings, /*slot is not psim*/ false,
                         physicalSlotId, port, removedSubInfo, telMgr.isMultiSimEnabled()),
                 context);
     }
@@ -251,9 +256,27 @@
         return INVALID_PHYSICAL_SLOT_ID;
     }
 
-    private static Collection<UiccSlotMapping> prepareUiccSlotMappings(
-            Collection<UiccSlotMapping> uiccSlotMappings, int physicalSlotId, int port,
-            SubscriptionInfo removedSubInfo, boolean isMultiSimEnabled) {
+    // Device |                                        |Slot   |
+    // Working|                                        |Mapping|
+    // State  |Type                                    |Mode   |Friendly name
+    //--------------------------------------------------------------------------
+    // Single |SIM pSIM [RIL 0]                        |1      |pSIM active
+    // Single |SIM MEP Port #0 [RIL0]                  |2      |eSIM Port0 active
+    // Single |SIM MEP Port #1 [RIL0]                  |2.1    |eSIM Port1 active
+    // DSDS   |pSIM [RIL 0] + MEP Port #0 [RIL 1]      |3      |pSIM+Port0
+    // DSDS   |pSIM [RIL 0] + MEP Port #1 [RIL 1]      |3.1    |pSIM+Port1
+    // DSDS   |MEP Port #0 [RIL 0] + MEP Port #1 [RIL1]|3.2    |Dual-Ports-A
+    // DSDS   |MEP Port #1 [RIL 0] + MEP Port #0 [RIL1]|4      |Dual-Ports-B
+    //
+    // The rules are:
+    // 1. pSIM's logical slots always is [RIL 0].
+    // 2. assign the new active port to the same stack that will be de-activated
+    //    For example: mode#3->mode#4
+
+    @VisibleForTesting
+    static Collection<UiccSlotMapping> prepareUiccSlotMappings(
+            Collection<UiccSlotMapping> uiccSlotMappings, boolean isPsim, int physicalSlotId,
+            int port, SubscriptionInfo removedSubInfo, boolean isMultiSimEnabled) {
         Collection<UiccSlotMapping> newUiccSlotMappings = new ArrayList<>();
         if (!isMultiSimEnabled) {
             // In the 'SS mode', the port is 0.
@@ -268,25 +291,59 @@
                                     + "PhysicalSlotId%d-Port%d",
                             removedSubInfo.getSubscriptionId(), removedSubInfo.getSimSlotIndex(),
                             removedSubInfo.getPortIndex(), physicalSlotId, port));
+
+            int logicalSlotIndex = 0;
+            if (isPsim) {
+                // The target slot is psim
+                newUiccSlotMappings.add(
+                        new UiccSlotMapping(port, physicalSlotId, logicalSlotIndex++));
+            }
+            Collection<UiccSlotMapping> tempUiccSlotMappings =
+                    uiccSlotMappings.stream()
+                            .sorted(Comparator.comparingInt(UiccSlotMapping::getLogicalSlotIndex))
+                            .collect(Collectors.toList());
+            for (UiccSlotMapping uiccSlotMapping : tempUiccSlotMappings) {
+                if (isSubInfoMappingIntoUiccSlotMapping(uiccSlotMapping, removedSubInfo)) {
+                    if (!isPsim) {
+                        // Replace this uiccSlotMapping
+                        newUiccSlotMappings.add(new UiccSlotMapping(port, physicalSlotId,
+                                uiccSlotMapping.getLogicalSlotIndex()));
+                    }
+                    continue;
+                }
+
+                // If the psim is inserted, then change the
+                // logicalSlotIndex for another uiccSlotMappings.
+                newUiccSlotMappings.add(isPsim
+                        ? new UiccSlotMapping(
+                                uiccSlotMapping.getPortIndex(),
+                                uiccSlotMapping.getPhysicalSlotIndex(),
+                                logicalSlotIndex++
+                        ) : uiccSlotMapping);
+            }
+        } else {
+            // For no inserted psim case in DSDS+MEP, there is only one esim in device and
+            // then user inserts another esim in DSDS+MEP.
+            // If the target is esim, then replace the psim.
+            Log.i(TAG, "The removedSubInfo is null");
             newUiccSlotMappings =
                     uiccSlotMappings.stream().map(uiccSlotMapping -> {
-                        if (uiccSlotMapping.getLogicalSlotIndex()
-                                == removedSubInfo.getSimSlotIndex()
-                                && uiccSlotMapping.getPortIndex()
-                                == removedSubInfo.getPortIndex()) {
+                        if (!isPsim && uiccSlotMapping.getPhysicalSlotIndex() != physicalSlotId) {
                             return new UiccSlotMapping(port, physicalSlotId,
                                     uiccSlotMapping.getLogicalSlotIndex());
                         }
                         return uiccSlotMapping;
                     }).collect(Collectors.toList());
-        } else {
-            // DSDS+no MEP
-            // The removable slot should be in UiccSlotMapping.
-            newUiccSlotMappings = uiccSlotMappings;
-            Log.i(TAG, "The removedSubInfo is null");
         }
 
         Log.i(TAG, "The SimSlotMapping: " + newUiccSlotMappings);
         return newUiccSlotMappings;
     }
+
+    private static boolean isSubInfoMappingIntoUiccSlotMapping(UiccSlotMapping uiccSlotMapping,
+            SubscriptionInfo subscriptionInfo) {
+        return uiccSlotMapping != null
+                && uiccSlotMapping.getLogicalSlotIndex() == subscriptionInfo.getSimSlotIndex()
+                && uiccSlotMapping.getPortIndex() == subscriptionInfo.getPortIndex();
+    }
 }
diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
index 1a6879d..8a0a4b0 100644
--- a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
@@ -24,9 +24,11 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccPortInfo;
 import android.telephony.UiccSlotInfo;
+import android.telephony.UiccSlotMapping;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -39,8 +41,12 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
 public class UiccSlotUtilTest {
@@ -48,6 +54,9 @@
     @Mock
     private TelephonyManager mTelephonyManager;
 
+    private static final int ESIM_PHYSICAL_SLOT = 0;
+    private static final int PSIM_PHYSICAL_SLOT = 1;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -58,7 +67,7 @@
 
     @Test
     public void getSlotInfos_oneSimSlotDevice_returnTheCorrectSlotInfoList() {
-        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSimSlotDevice_ActivePsim());
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSimSlotDeviceActivePsim());
         ImmutableList<UiccSlotInfo> testUiccSlotInfos =
                 UiccSlotUtil.getSlotInfos(mTelephonyManager);
 
@@ -68,7 +77,7 @@
     @Test
     public void getSlotInfos_twoSimSlotsDevice_returnTheCorrectSlotInfoList() {
         when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
-                twoSimSlotsDevice_ActivePsimActiveEsim());
+                twoSimSlotsDeviceActivePsimActiveEsim());
         ImmutableList<UiccSlotInfo> testUiccSlotInfos =
                 UiccSlotUtil.getSlotInfos(mTelephonyManager);
 
@@ -78,7 +87,7 @@
     @Test
     public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot0_returnTheCorrectEsimSlot() {
         when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
-                twoSimSlotsDevice_ActiveEsimActivePsim());
+                twoSimSlotsDeviceActiveEsimActivePsim());
         int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
 
         assertThat(testSlot).isEqualTo(0);
@@ -87,7 +96,7 @@
     @Test
     public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() {
         when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
-                twoSimSlotsDevice_ActivePsimActiveEsim());
+                twoSimSlotsDeviceActivePsimActiveEsim());
         int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
 
         assertThat(testSlot).isEqualTo(1);
@@ -96,12 +105,253 @@
     @Test
     public void getEsimSlotId_noEimSlotDevice_returnTheCorrectEsimSlot() {
         when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
-                oneSimSlotDevice_ActivePsim());
+                oneSimSlotDeviceActivePsim());
         int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
 
         assertThat(testSlot).isEqualTo(-1);
     }
 
+    @Test
+    public void prepareUiccSlotMappings_fromPsimActiveToEsimPort0Active_esimPort0Active() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingSsModePsimActive();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingSsModeEsimPort0Active();
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, null, false);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromEsimPort0ActiveToPsimActive_psimActive() {
+        Collection<UiccSlotMapping> uiccSlotMappings =
+                createUiccSlotMappingSsModeEsimPort0Active();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingSsModePsimActive();
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, null, false);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort0ToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        SubscriptionInfo subInfo = createSubscriptionInfo(1, 0);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort1ToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(1, 1);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort0ToDualPortsB_dualPortsB() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsB();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(0, 0);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort1ToDualPortsA_dualPortsA() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsA();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(0, 0);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_noPsimAndFromPsimAndPort0ToDualPortsB_dualPortsB() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsB();
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, null, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_noPsimAndFromPsimAndPort1ToDualPortsA_dualPortsA() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsA();
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, null, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsAToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(0, 0);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsAToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(1, 1);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsBToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(1, 0);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsBToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+
+        SubscriptionInfo subInfo = createSubscriptionInfo(0, 1);
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, subInfo, true);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    private SubscriptionInfo createSubscriptionInfo(int logicalSlotIndex, int portIndex) {
+        return new SubscriptionInfo(
+                0, "", logicalSlotIndex, "", "", 0, 0, "", 0, null, "", "", "",
+                true /* isEmbedded */,
+                null, "", 25,
+                false, null, false, 0, 0, 0, null, null, true, portIndex);
+    }
+
+    private void compareTwoUiccSlotMappings(Collection<UiccSlotMapping> testUiccSlotMappings,
+            Collection<UiccSlotMapping> verifyUiccSlotMappings) {
+        assertThat(testUiccSlotMappings.size()).isEqualTo(verifyUiccSlotMappings.size());
+        Iterator<UiccSlotMapping> testIterator = testUiccSlotMappings.iterator();
+        Iterator<UiccSlotMapping> verifyIterator = verifyUiccSlotMappings.iterator();
+        while (testIterator.hasNext()) {
+            UiccSlotMapping testUiccSlotMapping = testIterator.next();
+            UiccSlotMapping verifyUiccSlotMapping = verifyIterator.next();
+            assertThat(testUiccSlotMapping.getLogicalSlotIndex()).isEqualTo(
+                    verifyUiccSlotMapping.getLogicalSlotIndex());
+            assertThat(testUiccSlotMapping.getPortIndex()).isEqualTo(
+                    verifyUiccSlotMapping.getPortIndex());
+            assertThat(testUiccSlotMapping.getPhysicalSlotIndex()).isEqualTo(
+                    verifyUiccSlotMapping.getPhysicalSlotIndex());
+        }
+    }
+
+    // Device |                                        |Slot   |
+    // Working|                                        |Mapping|
+    // State  |Type                                    |Mode   |Friendly name
+    //--------------------------------------------------------------------------
+    // Single |SIM pSIM [RIL 0]                        |1      |pSIM active
+    // Single |SIM MEP Port #0 [RIL0]                  |2      |eSIM Port0 active
+    // Single |SIM MEP Port #1 [RIL0]                  |2.1    |eSIM Port1 active
+    // DSDS   |pSIM [RIL 0] + MEP Port #0 [RIL 1]      |3      |pSIM+Port0
+    // DSDS   |pSIM [RIL 0] + MEP Port #1 [RIL 1]      |3.1    |pSIM+Port1
+    // DSDS   |MEP Port #0 [RIL 0] + MEP Port #1 [RIL1]|3.2    |Dual-Ports-A
+    // DSDS   |MEP Port #1 [RIL 0] + MEP Port #0 [RIL1]|4      |Dual-Ports-B
+    private List<UiccSlotMapping> createUiccSlotMappingSsModePsimActive() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, PSIM_PHYSICAL_SLOT, 0));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingSsModeEsimPort0Active() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, ESIM_PHYSICAL_SLOT, 0));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingSsModeEsimPort1Active() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(1, ESIM_PHYSICAL_SLOT, 0));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingPsimAndPort0() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, PSIM_PHYSICAL_SLOT, 0));
+        slotMap.add(new UiccSlotMapping(0, ESIM_PHYSICAL_SLOT, 1));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingPsimAndPort1() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, PSIM_PHYSICAL_SLOT, 0));
+        slotMap.add(new UiccSlotMapping(1, ESIM_PHYSICAL_SLOT, 1));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingDualPortsA() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, ESIM_PHYSICAL_SLOT, 0));
+        slotMap.add(new UiccSlotMapping(1, ESIM_PHYSICAL_SLOT, 1));
+
+        return slotMap;
+    }
+
+    private List<UiccSlotMapping> createUiccSlotMappingDualPortsB() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(1, ESIM_PHYSICAL_SLOT, 0));
+        slotMap.add(new UiccSlotMapping(0, ESIM_PHYSICAL_SLOT, 1));
+
+        return slotMap;
+    }
+
     /**
      * The "oneSimSlotDevice" has below cases
      * 1) The device is one psim slot and no esim slot
@@ -112,27 +362,27 @@
      * 2) The device is two psim slots
      */
 
-    private UiccSlotInfo[] oneSimSlotDevice_ActivePsim() {
+    private UiccSlotInfo[] oneSimSlotDeviceActivePsim() {
         return new UiccSlotInfo[]{createUiccSlotInfo(false, true, 0, true)};
     }
 
-    private UiccSlotInfo[] oneSimSlotDevice_ActiveEsim() {
+    private UiccSlotInfo[] oneSimSlotDeviceActiveEsim() {
         return new UiccSlotInfo[]{createUiccSlotInfo(true, false, 1, true)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_ActivePsimActiveEsim() {
+    private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveEsim() {
         return new UiccSlotInfo[]{
                 createUiccSlotInfo(false, true, 0, true),
                 createUiccSlotInfo(true, false, 1, true)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_ActiveEsimActivePsim() {
+    private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActivePsim() {
         return new UiccSlotInfo[]{
                 createUiccSlotInfo(true, false, 0, true),
                 createUiccSlotInfo(false, true, 1, true)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_twoActiveEsims() {
+    private UiccSlotInfo[] twoSimSlotsDeviceTwoActiveEsims() {
         // device supports MEP, so device can enable two esims.
         // If device has psim slot, the UiccSlotInfo of psim always be in UiccSlotInfo[].
         return new UiccSlotInfo[]{
@@ -140,19 +390,19 @@
                 createUiccSlotInfoForEsimMep(0, true, 1, true)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_ActivePsimInactiveEsim() {
+    private UiccSlotInfo[] twoSimSlotsDeviceActivePsimInactiveEsim() {
         return new UiccSlotInfo[]{
                 createUiccSlotInfo(false, true, 0, true),
                 createUiccSlotInfo(true, false, -1, false)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_InactivePsimActiveEsim() {
+    private UiccSlotInfo[] twoSimSlotsDeviceInactivePsimActiveEsim() {
         return new UiccSlotInfo[]{
                 createUiccSlotInfo(false, true, 0, false),
                 createUiccSlotInfo(true, false, 1, true)};
     }
 
-    private UiccSlotInfo[] twoSimSlotsDevice_NoInsertPsimActiveEsim() {
+    private UiccSlotInfo[] twoSimSlotsDeviceNoInsertPsimActiveEsim() {
         return new UiccSlotInfo[]{
                 createUiccSlotInfo(false, true, -1, false),
                 createUiccSlotInfo(true, false, 1, true)};