Merge changes I6871db6c,Ia261e3b4,I1588bd4a,I1b81faf0,I9a596440, ...

* changes:
  [MEP] sort the simSlotMapping by logcal slot id
  In E+E, the user can't enable the PSIM
  [MEP] psim's logical slot index is 0
  [MEP] The condition of "null point check" is wrong
  Fix the settings crash when SimDialogActivity is null
  [MEP] The subscriptionInfo's getSimSlotIndex is logical slotId
  [MEP] the port id is wrong
  [MEP] Inserting a pSIM while user has 2 esims, showing the MEP dialog
  [MEP] Refactor SlotSidecar API for all of sim page.
  [MEP]The Esim's PhysicalSlotIndex is wrong
  Lost code for setting the list as visible
  The list does not follow the UX dialog design doc in alert dialog.
  The carrier name is wrong in the dialog
  Refine the mobile data selection UI
diff --git a/res/layout/select_account_list_item.xml b/res/layout/select_account_list_item.xml
index 716adff..dbc31be 100644
--- a/res/layout/select_account_list_item.xml
+++ b/res/layout/select_account_list_item.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:minHeight="?attr/listPreferredItemHeightSmall"
-    android:background="@drawable/sim_confirm_dialog_rounded_bg"
     android:gravity="center">
     <TextView android:id="@+id/title"
         android:textAppearance="@style/TextAppearance.SimConfirmDialogList"
@@ -36,6 +35,5 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@id/title"
-        android:textColor="?android:attr/textColorSecondary"
         android:layout_alignStart="@id/title" />
 </LinearLayout>
diff --git a/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml b/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
index 003cdbf..700fab3 100644
--- a/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
+++ b/res/layout/sim_confirm_dialog_item_multiple_enabled_profiles_supported.xml
@@ -25,6 +25,5 @@
     android:paddingBottom="?attr/listPreferredItemPaddingEnd"
     android:paddingLeft="?attr/listPreferredItemPaddingLeft"
     android:paddingRight="?attr/listPreferredItemPaddingRight"
-    android:background="@drawable/sim_confirm_dialog_rounded_bg"
     android:textAppearance="@style/TextAppearance.SimConfirmDialogList"
     />
diff --git a/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml b/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml
index 610bf3d..081efb3 100644
--- a/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml
+++ b/res/layout/sim_confirm_dialog_multiple_enabled_profiles_supported.xml
@@ -26,15 +26,19 @@
             android:paddingEnd="24dp"
             android:paddingTop="16dp"
             android:paddingStart="24dp"
+            android:paddingBottom="32dp"
             android:gravity="center"
-            android:textAppearance="@style/TextAppearance.DialogMessage"/>
+            android:textAppearance="@style/TextAppearance.DialogMessage"
+            android:visibility="gone"/>
         <ListView
             android:id="@+id/carrier_list"
             android:layout_gravity="center"
-            android:paddingTop="16dp"
-            android:dividerHeight="1dp"
+            android:divider="?android:attr/colorBackgroundFloating"
+            android:dividerHeight="4dp"
+            android:background="@drawable/sim_confirm_dialog_rounded_bg"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content"
+            android:visibility="gone"/>
 
         <LinearLayout
             android:id="@+id/info_outline_layout"
@@ -46,7 +50,8 @@
             android:paddingTop="16dp"
             android:paddingStart="24dp"
             android:layout_marginBottom="16dp"
-            android:baselineAligned="true">
+            android:baselineAligned="true"
+            android:visibility="gone">
                 <ImageView
                     android:src="@drawable/ic_info_outline_24dp"
                     android:layout_width="wrap_content"
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
index a388855..f69c952 100644
--- a/res/values-night/styles.xml
+++ b/res/values-night/styles.xml
@@ -28,6 +28,6 @@
     <style name="TextAppearance.SimConfirmDialogList.Summary">
         <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml
index 4564827..946cd91 100644
--- a/res/values-night/themes.xml
+++ b/res/values-night/themes.xml
@@ -34,12 +34,6 @@
         <item name="android:colorBackground">@*android:color/surface_dark</item>
     </style>
 
-    <style name="Theme.AlertDialog.Base.Material3" parent="Theme.MaterialComponents.DayNight.Dialog.Alert">
-        <item name="colorPrimary">@*android:color/primary_device_default_settings</item>
-        <item name="colorAccent">@*android:color/accent_device_default_dark</item>
-        <item name="android:colorBackground">@*android:color/surface_dark</item>
-    </style>
-
     <!-- Material theme for the pages containing TabLayout and ViewPager -->
     <style name="Theme.TabTheme" parent="@style/Theme.MaterialComponents.DayNight">
         <item name="colorPrimary">@*android:color/edge_effect_device_default_dark</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f225150..8b73585 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -440,4 +440,8 @@
     <dimen name="chartview_trapezoid_radius">5dp</dimen>
     <dimen name="chartview_trapezoid_margin_start">1dp</dimen>
     <dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
+
+    <!-- Sims/Data mobile/Calls/SMS select dialog-->
+    <dimen name="sims_select_margin_bottom">24dp</dimen>
+    <dimen name="sims_select_margin_top">8dp</dimen>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index afa13a1..838d63b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -919,6 +919,7 @@
 
     <style name="TextAppearance.SimConfirmDialogList.Summary">
         <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="SimConfirmDialog.OutlineButton" parent="@android:style/Widget.Material.Button">
diff --git a/src/com/android/settings/network/SwitchSlotSidecar.java b/src/com/android/settings/network/SwitchSlotSidecar.java
index abf8842..7005452 100644
--- a/src/com/android/settings/network/SwitchSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchSlotSidecar.java
@@ -78,11 +78,19 @@
         super.run(param);
     }
 
-    /** Starts switching to the removable slot. */
-    public void runSwitchToEuiccSlot(int id, int port, SubscriptionInfo removedSubInfo) {
+    /**
+     * Start the SimSlotMapping process if the euicc slot is not in SimSlotMapping list.
+     * @param physicalSlotId The physical slot id.
+     * @param port The port id.
+     * @param removedSubInfo The subscriptionInfo which is selected by the user to disable when all
+     *                      of sim slots are full in the device. If all of slots are not full in
+     *                       the device, then this is null.
+     */
+    public void runSwitchToEuiccSlot(int physicalSlotId, int port,
+            SubscriptionInfo removedSubInfo) {
         Param param = new Param();
         param.command = Command.SWITCH_TO_EUICC_SIM;
-        param.slotId = id;
+        param.slotId = physicalSlotId;
         param.removedSubInfo = removedSubInfo;
         param.port = port;
         super.run(param);
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index 888e5b2..0b39d6a 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -21,14 +21,13 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccSlotMapping;
 import android.telephony.euicc.EuiccManager;
 import android.util.Log;
 
 import com.android.settings.SidecarFragment;
 import com.android.settings.network.telephony.EuiccOperationSidecar;
 
-import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -37,7 +36,6 @@
     private static final String TAG = "SwitchToEuiccSidecar";
     private static final String ACTION_SWITCH_TO_SUBSCRIPTION =
             "com.android.settings.network.SWITCH_TO_SUBSCRIPTION";
-    private static final int ESIM_SLOT_ID = 1;
 
     private PendingIntent mCallbackIntent;
     private int mSubId;
@@ -70,20 +68,15 @@
         }
     }
 
-    /** Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile. */
-    // ToDo: delete this api and refactor the related code.
-    public void run(int subscriptionId) {
-        setState(State.RUNNING, Substate.UNUSED);
-        mCallbackIntent = createCallbackIntent();
-        mEuiccManager.switchToSubscription(subscriptionId, mCallbackIntent);
-    }
-
     /**
      * Starts calling EuiccManager#switchToSubscription to enable/disable the eSIM profile.
      *
      * @param subscriptionId the esim's subscriptionId.
-     * @param port the esim's portId. If user wants to inactivate esim, then user must to assign the
-     *             the port. If user wants to activate esim, then the port can be -1.
+     * @param port the esim's portId. If user wants to inactivate esim, then user must to assign
+     *             the corresponding port. If user wants to activate esim, then the port can be
+     *             {@link UiccSlotUtil#INVALID_PORT_ID}. When it is
+     *             {@link UiccSlotUtil#INVALID_PORT_ID}, the system will reassign a corresponding
+     *             port id.
      * @param removedSubInfo if the all of slots have sims, it should remove the one of active sim.
      *                       If the removedSubInfo is null, then use the default value.
      *                       The default value is the esim slot and portId 0.
@@ -92,11 +85,20 @@
         setState(State.RUNNING, Substate.UNUSED);
         mCallbackIntent = createCallbackIntent();
         mSubId = subscriptionId;
+        int targetSlot = getTargetSlot();
+        if (targetSlot < 0) {
+            Log.d(TAG, "There is no esim, the TargetSlot is " + targetSlot);
+            setState(State.ERROR, Substate.UNUSED);
+            return;
+        }
+
         // To check whether the esim slot's port is active. If yes, skip setSlotMapping. If no,
         // set this slot+port into setSimSlotMapping.
         mPort = (port < 0) ? getTargetPortId(removedSubInfo) : port;
         mRemovedSubInfo = removedSubInfo;
-        Log.i(TAG, "The SubId is " + mSubId + ". The port is " + mPort);
+        Log.d(TAG,
+                String.format("set esim into the SubId%d Slot%d:Port%d",
+                        mSubId, targetSlot, mPort));
 
         if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null
                 && removedSubInfo.isEmbedded()) {
@@ -108,7 +110,7 @@
             mEuiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mPort,
                     mCallbackIntent);
         } else {
-            mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, removedSubInfo);
+            mSwitchSlotSidecar.runSwitchToEuiccSlot(targetSlot, mPort, removedSubInfo);
         }
     }
 
@@ -124,18 +126,26 @@
             return removedSubInfo.getPortIndex();
         }
 
-        // In DSDS+MEP mode, the removedSubInfo is psim or is null, it means the this esim need
-        // another port in the esim slot.
-        // To find another esim's port and value is from 0;
+        // In DSDS+MEP mode, the removedSubInfo is psim or is null, it means this esim needs
+        // a new corresponding port in the esim slot.
+        // For example:
+        // 1) If there is no enabled esim and the user add new esim. This new esim's port is 0.
+        // 2) If there is one enabled esim in port0 and the user add new esim. This new esim's
+        // port is 1.
+        // 3) If there is one enabled esim in port1 and the user add new esim. This new esim's
+        // port is 0.
+
         int port = 0;
-        Collection<UiccSlotMapping> uiccSlotMappings = mTelephonyManager.getSimSlotMapping();
-        for (UiccSlotMapping uiccSlotMapping :
-                uiccSlotMappings.stream()
-                        .filter(
-                                uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex()
-                                        == getTargetSlot())
-                        .collect(Collectors.toList())) {
-            if (uiccSlotMapping.getPortIndex() == port) {
+        SubscriptionManager subscriptionManager = getContext().getSystemService(
+                SubscriptionManager.class);
+        List<SubscriptionInfo> activeEsimSubInfos =
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager)
+                        .stream()
+                        .filter(i -> i.isEmbedded())
+                        .sorted(Comparator.comparingInt(SubscriptionInfo::getPortIndex))
+                        .collect(Collectors.toList());
+        for (SubscriptionInfo subscriptionInfo : activeEsimSubInfos) {
+            if (subscriptionInfo.getPortIndex() == port) {
                 port++;
             }
         }
@@ -143,7 +153,7 @@
     }
 
     private int getTargetSlot() {
-        return ESIM_SLOT_ID;
+        return UiccSlotUtil.getEsimSlotId(getContext());
     }
 
     private void onSwitchSlotSidecarStateChange() {
diff --git a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
index 9b9c0dd..a870f3b 100644
--- a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
@@ -81,29 +81,6 @@
     }
 
     /**
-     * Starts switching to the removable slot. It disables the active eSIM profile before switching
-     * if there is one.
-     *
-     * @param physicalSlotId removable physical SIM slot ID.
-     */
-    // ToDo: delete this api and refactor the related code.
-    public void run(int physicalSlotId) {
-        mPhysicalSlotId = physicalSlotId;
-        SubscriptionManager subscriptionManager =
-                getContext().getSystemService(SubscriptionManager.class);
-        if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).stream()
-                .anyMatch(SubscriptionInfo::isEmbedded)) {
-            // In SS mode, the esim is active, then inactivate the esim.
-            Log.i(TAG, "There is an active eSIM profile. Disable the profile first.");
-            // Use INVALID_SUBSCRIPTION_ID to disable the only active profile.
-            mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 0, null);
-        } else {
-            Log.i(TAG, "There is no active eSIM profiles. Start to switch to removable slot.");
-            mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, null);
-        }
-    }
-
-    /**
      * Starts switching to the removable slot.
      *
      * @param physicalSlotId removable physical SIM slot ID.
@@ -124,7 +101,7 @@
             // Use INVALID_SUBSCRIPTION_ID to disable the only active profile.
             mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID, 0, null);
         } else if (mTelephonyManager.isMultiSimEnabled() && mRemovedSubInfo != null) {
-            // In DSDS mode+MEP, if the replaced esim is active, then it should be disabled esim
+            // In DSDS mode+MEP, if the replaced esim is active, then it should disable that esim
             // profile before changing SimSlotMapping process.
             // Use INVALID_SUBSCRIPTION_ID to disable the esim profile.
             mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java
index 8938cdb..8fdc370 100644
--- a/src/com/android/settings/network/UiccSlotUtil.java
+++ b/src/com/android/settings/network/UiccSlotUtil.java
@@ -20,11 +20,13 @@
 import android.content.Context;
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccSlotInfo;
 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,9 +35,11 @@
 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;
+import java.util.stream.IntStream;
 
 // ToDo: to do the refactor for renaming
 public class UiccSlotUtil {
@@ -44,6 +48,7 @@
 
     private static final long DEFAULT_WAIT_AFTER_SWITCH_TIMEOUT_MILLIS = 25 * 1000L;
 
+    public static final int INVALID_LOGICAL_SLOT_ID = -1;
     public static final int INVALID_PHYSICAL_SLOT_ID = -1;
     public static final int INVALID_PORT_ID = -1;
 
@@ -112,9 +117,27 @@
         }
         TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
         int inactiveRemovableSlot = getInactiveRemovableSlot(telMgr.getUiccSlotsInfo(), slotId);
+        Log.d(TAG, "The InactiveRemovableSlot: " + inactiveRemovableSlot);
+        if (inactiveRemovableSlot == INVALID_PHYSICAL_SLOT_ID) {
+            // The slot is invalid slot id, then to skip this.
+            // The slot is active, then the sim can enable directly.
+            return;
+        }
+
+        Collection<UiccSlotMapping> uiccSlotMappings = telMgr.getSimSlotMapping();
+        Log.d(TAG, "The SimSlotMapping: " + uiccSlotMappings);
+
+        SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        int excludedLogicalSlotIndex = getExcludedLogicalSlotIndex(uiccSlotMappings,
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager), removedSubInfo,
+                telMgr.isMultiSimEnabled());
         performSwitchToSlot(telMgr,
-                prepareUiccSlotMappingsForRemovableSlot(telMgr.getSimSlotMapping(),
-                        inactiveRemovableSlot, removedSubInfo, telMgr.isMultiSimEnabled()),
+                prepareUiccSlotMappings(uiccSlotMappings,
+                        /*slot is psim*/ true,
+                        inactiveRemovableSlot,
+                        /*removable sim's port Id*/ TelephonyManager.DEFAULT_PORT_INDEX,
+                        excludedLogicalSlotIndex),
                 context);
     }
 
@@ -122,7 +145,7 @@
      * Switches to the Euicc slot. It waits for SIM_STATE_LOADED after switch.
      *
      * @param context the application context.
-     * @param slotId the Euicc slot id.
+     * @param physicalSlotId the Euicc slot id.
      * @param port the Euicc slot port id.
      * @param removedSubInfo In the DSDS+MEP mode, if the all of slots have sims, it should
      *                       remove the one of active sim.
@@ -130,7 +153,7 @@
      *                       The default value is the esim slot and portId 0.
      * @throws UiccSlotsException if there is an error.
      */
-    public static synchronized void switchToEuiccSlot(Context context, int slotId, int port,
+    public static synchronized void switchToEuiccSlot(Context context, int physicalSlotId, int port,
             SubscriptionInfo removedSubInfo) throws UiccSlotsException {
         if (ThreadUtils.isMainThread()) {
             throw new IllegalThreadStateException(
@@ -138,47 +161,51 @@
         }
         TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
         Collection<UiccSlotMapping> uiccSlotMappings = telMgr.getSimSlotMapping();
-        Log.i(TAG, "The SimSlotMapping: " + uiccSlotMappings);
+        Log.d(TAG, "The SimSlotMapping: " + uiccSlotMappings);
 
-        if (isTargetSlotActive(uiccSlotMappings, slotId, port)) {
-            Log.i(TAG, "The slot is active, then the sim can enable directly.");
+        if (isTargetSlotActive(uiccSlotMappings, physicalSlotId, port)) {
+            Log.d(TAG, "The slot is active, then the sim can enable directly.");
             return;
         }
 
-        Collection<UiccSlotMapping> newUiccSlotMappings = new ArrayList<>();
-        if (!telMgr.isMultiSimEnabled()) {
-            // In the 'SS mode', the port is 0.
-            newUiccSlotMappings.add(new UiccSlotMapping(port, slotId, 0));
-        } else {
-            // DSDS+MEP
-            // The target slot+port is not active, but the all of logical slots are full. It
-            // needs to replace one of logical slots.
-            int removedSlot =
-                    (removedSubInfo != null) ? removedSubInfo.getSimSlotIndex() : slotId;
-            int removedPort = (removedSubInfo != null) ? removedSubInfo.getPortIndex() : 0;
-            Log.i(TAG,
-                    String.format("Start to set SimSlotMapping from slot%d-port%d to slot%d-port%d",
-                            slotId, port, removedSlot, removedPort));
-            newUiccSlotMappings =
-                    uiccSlotMappings.stream().map(uiccSlotMapping -> {
-                        if (uiccSlotMapping.getPhysicalSlotIndex() == removedSlot
-                                && uiccSlotMapping.getPortIndex() == removedPort) {
-                            return new UiccSlotMapping(port, slotId,
-                                    uiccSlotMapping.getLogicalSlotIndex());
-                        }
-                        return uiccSlotMapping;
-                    }).collect(Collectors.toList());
-        }
+        SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        int excludedLogicalSlotIndex = getExcludedLogicalSlotIndex(uiccSlotMappings,
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager), removedSubInfo,
+                telMgr.isMultiSimEnabled());
+        performSwitchToSlot(telMgr,
+                prepareUiccSlotMappings(uiccSlotMappings, /*slot is not psim*/ false,
+                        physicalSlotId, port, excludedLogicalSlotIndex),
+                context);
+    }
 
-        Log.i(TAG, "The SimSlotMapping: " + newUiccSlotMappings);
-        performSwitchToSlot(telMgr, newUiccSlotMappings, context);
+    /**
+     * @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) {
+        TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
+        ImmutableList<UiccSlotInfo> slotInfos = UiccSlotUtil.getSlotInfos(telMgr);
+        int firstEsimSlot = IntStream.range(0, slotInfos.size())
+                .filter(
+                        index -> {
+                            UiccSlotInfo slotInfo = slotInfos.get(index);
+                            if (slotInfo == null) {
+                                return false;
+                            }
+                            return !slotInfo.isRemovable();
+                        })
+                .findFirst().orElse(-1);
+
+        Log.i(TAG, "firstEsimSlot: " + firstEsimSlot);
+        return firstEsimSlot;
     }
 
     private static boolean isTargetSlotActive(Collection<UiccSlotMapping> uiccSlotMappings,
-            int slotId, int port) {
+            int physicalSlotId, int port) {
         return uiccSlotMappings.stream()
                 .anyMatch(
-                        uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex() == slotId
+                        uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex() == physicalSlotId
                                 && uiccSlotMapping.getPortIndex() == port);
     }
 
@@ -239,49 +266,112 @@
         return INVALID_PHYSICAL_SLOT_ID;
     }
 
-    private static Collection<UiccSlotMapping> prepareUiccSlotMappingsForRemovableSlot(
-            Collection<UiccSlotMapping> uiccSlotMappings, int slotId,
-            SubscriptionInfo removedSubInfo, boolean isMultiSimEnabled) {
-        if (slotId == INVALID_PHYSICAL_SLOT_ID
-                || uiccSlotMappings.stream().anyMatch(uiccSlotMapping ->
-                        uiccSlotMapping.getPhysicalSlotIndex() == slotId
-                                && uiccSlotMapping.getPortIndex() == 0)) {
-            // The slot is invalid slot id, then to skip this.
-            // The slot is active, then the sim can enable directly.
+    // 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, int removedLogicalSlotId) {
+        if (removedLogicalSlotId == INVALID_LOGICAL_SLOT_ID) {
+            Log.d(TAG, "There is no removedLogicalSlotId. Do nothing.");
             return uiccSlotMappings;
         }
-
+        Log.d(TAG,
+                String.format(
+                        "Create new SimSlotMapping. Remove the UiccSlotMapping of logicalSlot%d"
+                                + ", and insert PhysicalSlotId%d-Port%d",
+                        removedLogicalSlotId, physicalSlotId, port));
         Collection<UiccSlotMapping> newUiccSlotMappings = new ArrayList<>();
-        if (!isMultiSimEnabled) {
-            // In the 'SS mode', the port is 0.
-            newUiccSlotMappings.add(new UiccSlotMapping(0, slotId, 0));
-        } else if (removedSubInfo != null) {
-            // DSDS+MEP
-            // The target slot+port is not active, but the all of logical slots are full. It
-            // needs to replace one of logical slots.
-            Log.i(TAG,
-                    String.format("Start to set SimSlotMapping from slot%d-port%d to slot%d-port%d",
-                            slotId, 0, removedSubInfo.getSimSlotIndex(),
-                            removedSubInfo.getPortIndex()));
-            newUiccSlotMappings =
-                    uiccSlotMappings.stream().map(uiccSlotMapping -> {
-                        if (uiccSlotMapping.getPhysicalSlotIndex()
-                                == removedSubInfo.getSimSlotIndex()
-                                && uiccSlotMapping.getPortIndex()
-                                == removedSubInfo.getPortIndex()) {
-                            return new UiccSlotMapping(0, slotId,
-                                    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");
+        int logicalSlotIndex = 0;
+        if (isPsim) {
+            // The target slot is psim. The psim is always the first index at LogicalSlot.
+            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 (uiccSlotMapping.getLogicalSlotIndex() == removedLogicalSlotId) {
+                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);
         }
 
-        Log.i(TAG, "The SimSlotMapping: " + newUiccSlotMappings);
+        Log.d(TAG, "The new SimSlotMapping: " + newUiccSlotMappings);
         return newUiccSlotMappings;
     }
+
+    /**
+     * To get the excluded logical slot index from uiccSlotMapping list. If the sim which is
+     * enabled by user does not have the corresponding slot, then it needs to do the
+     * SimSlotMapping changed. This method can find the logical slot index of the corresponding slot
+     * before the Frameworks do the SimSlotMapping changed.
+     *
+     * @param uiccSlotMappings The uiccSlotMapping list from the Telephony Frameworks.
+     * @param activeSubInfos The active subscriptionInfo list.
+     * @param removedSubInfo The removed sim card which is selected by the user. If the user
+     *                       don't select removed sim , then the value is null.
+     * @param isMultiSimEnabled whether the device is in the DSDS mode or not.
+     * @return The logical slot index of removed slot. If it can't find the removed slot, it
+     * returns {@link #INVALID_LOGICAL_SLOT_ID}.
+     */
+    @VisibleForTesting
+    static int getExcludedLogicalSlotIndex(Collection<UiccSlotMapping> uiccSlotMappings,
+            Collection<SubscriptionInfo> activeSubInfos, SubscriptionInfo removedSubInfo,
+            boolean isMultiSimEnabled) {
+        if (!isMultiSimEnabled) {
+            Log.i(TAG, "In the ss mode.");
+            return 0;
+        }
+        if (removedSubInfo != null) {
+            // Use removedSubInfo's logicalSlotIndex
+            Log.i(TAG, "The removedSubInfo is not null");
+            return removedSubInfo.getSimSlotIndex();
+        }
+        // If it needs to do simSlotMapping when user enables sim and there is an empty slot which
+        // there is no enabled sim in this slot, then the empty slot can be removed.
+        Log.i(TAG, "The removedSubInfo is null");
+        return uiccSlotMappings.stream()
+                .filter(uiccSlotMapping -> {
+                    // find the empty slots.
+                    for (SubscriptionInfo subInfo : activeSubInfos) {
+                        if (subInfo.getSimSlotIndex() == uiccSlotMapping.getLogicalSlotIndex()) {
+                            return false;
+                        }
+                    }
+                    return true;
+                })
+                .sorted(Comparator.comparingInt(UiccSlotMapping::getLogicalSlotIndex))
+                .mapToInt(uiccSlotMapping -> uiccSlotMapping.getLogicalSlotIndex())
+                .findFirst()
+                .orElse(INVALID_LOGICAL_SLOT_ID);
+    }
 }
diff --git a/src/com/android/settings/network/telephony/ConfirmDialogFragment.java b/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
index 6352180..dceaf1c 100644
--- a/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
+++ b/src/com/android/settings/network/telephony/ConfirmDialogFragment.java
@@ -25,6 +25,7 @@
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.TextView;
 
@@ -115,13 +116,12 @@
         AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
                 .setPositiveButton(posBtnString, this)
                 .setNegativeButton(negBtnString, this);
+        View content = LayoutInflater.from(getContext()).inflate(
+                R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
 
-        if (list != null && !list.isEmpty()) {
+        if (list != null && !list.isEmpty() && content != null) {
             Log.i(TAG, "list =" + list.toString());
 
-            View content = LayoutInflater.from(getContext()).inflate(
-                    R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
-
             if (!TextUtils.isEmpty(title)) {
                 View titleView = LayoutInflater.from(getContext()).inflate(
                         R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported,
@@ -133,6 +133,7 @@
             TextView dialogMessage = content.findViewById(R.id.msg);
             if (!TextUtils.isEmpty(message) && dialogMessage != null) {
                 dialogMessage.setText(message);
+                dialogMessage.setVisibility(View.VISIBLE);
             }
 
             final ArrayAdapter<String> arrayAdapterItems = new ArrayAdapter<String>(
@@ -140,8 +141,8 @@
                     R.layout.sim_confirm_dialog_item_multiple_enabled_profiles_supported, list);
             final ListView lvItems = content.findViewById(R.id.carrier_list);
             if (lvItems != null) {
+                lvItems.setVisibility(View.VISIBLE);
                 lvItems.setAdapter(arrayAdapterItems);
-                lvItems.setChoiceMode(ListView.CHOICE_MODE_NONE);
                 lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                     @Override
                     public void onItemClick(AdapterView<?> parent, View view, int position,
@@ -158,6 +159,10 @@
                     }
                 });
             }
+            final LinearLayout infoOutline = content.findViewById(R.id.info_outline_layout);
+            if (infoOutline != null) {
+                infoOutline.setVisibility(View.VISIBLE);
+            }
             builder.setView(content);
         } else {
             if (!TextUtils.isEmpty(title)) {
diff --git a/src/com/android/settings/sim/ChooseSimActivity.java b/src/com/android/settings/sim/ChooseSimActivity.java
index d0ccc4c..cebc1ba 100644
--- a/src/com/android/settings/sim/ChooseSimActivity.java
+++ b/src/com/android/settings/sim/ChooseSimActivity.java
@@ -159,11 +159,12 @@
         mSelectedItemIndex = subItem.getId();
         if (mSelectedItemIndex == INDEX_PSIM) {
             Log.i(TAG, "Ready to switch to pSIM slot.");
-            mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID);
+            mSwitchToRemovableSlotSidecar.run(UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, null);
         } else {
             Log.i(TAG, "Ready to switch to eSIM subscription with index: " + mSelectedItemIndex);
             mSwitchToEuiccSubscriptionSidecar.run(
-                    mEmbeddedSubscriptions.get(mSelectedItemIndex).getSubscriptionId());
+                    mEmbeddedSubscriptions.get(mSelectedItemIndex).getSubscriptionId(),
+                    UiccSlotUtil.INVALID_PORT_ID, null);
         }
     }
 
diff --git a/src/com/android/settings/sim/PreferredSimDialogFragment.java b/src/com/android/settings/sim/PreferredSimDialogFragment.java
index 7786dd1..6b5e2b5 100644
--- a/src/com/android/settings/sim/PreferredSimDialogFragment.java
+++ b/src/com/android/settings/sim/PreferredSimDialogFragment.java
@@ -84,10 +84,11 @@
     private void updateDialog(AlertDialog dialog) {
         Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed);
 
-        final SubscriptionInfo info = getPreferredSubscription();
         if (mWasDismissed) {
             return;
         }
+
+        final SubscriptionInfo info = getPreferredSubscription();
         if (info == null) {
             dismiss();
             return;
diff --git a/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java b/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java
index f5c2406..1f84177 100644
--- a/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java
+++ b/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java
@@ -26,8 +26,6 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.ListView;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
@@ -88,10 +86,11 @@
         if (subInfos == null || dds == null) {
             return null;
         }
-        return subInfos.stream().filter(subinfo -> subinfo != dds).findFirst().orElse(null);
+        return subInfos.stream().filter(subinfo -> subinfo.getSubscriptionId()
+                != dds.getSubscriptionId()).findFirst().orElse(null);
     }
 
-    private SubscriptionInfo getDefaultDataSubId() {
+    private SubscriptionInfo getDefaultDataSubInfo() {
         return getSubscriptionManager().getDefaultDataSubscriptionInfo();
     }
 
@@ -101,20 +100,22 @@
             return;
         }
 
-        SubscriptionInfo activeSubInfo = getDefaultDataSubId();
-        SubscriptionInfo newSubInfo = getNonDefaultDataSubscriptionInfo(activeSubInfo);
+        SubscriptionInfo currentDataSubInfo = getDefaultDataSubInfo();
+        SubscriptionInfo newSubInfo = getNonDefaultDataSubscriptionInfo(currentDataSubInfo);
 
-        if (newSubInfo == null || activeSubInfo == null) {
+        if (newSubInfo == null || currentDataSubInfo == null) {
+            Log.d(TAG, "one of target SubscriptionInfos is null");
             dismiss();
             return;
         }
-
+        Log.d(TAG, "newSubId: " + newSubInfo.getSubscriptionId()
+                + "currentDataSubID: " + currentDataSubInfo.getSubscriptionId());
         setTargetSubscriptionInfo(newSubInfo);
 
         CharSequence newDataCarrierName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
                 newSubInfo, getContext());
         CharSequence currentDataCarrierName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
-                activeSubInfo, getContext());
+                currentDataSubInfo, getContext());
 
         String positive = getContext().getString(
                 R.string.select_specific_sim_for_data_button, newDataCarrierName);
@@ -123,18 +124,10 @@
 
         View content = LayoutInflater.from(getContext()).inflate(
                 R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
-        TextView dialogMessage = content.findViewById(R.id.msg);
+        TextView dialogMessage = content != null ? content.findViewById(R.id.msg) : null;
         if (!TextUtils.isEmpty(message) && dialogMessage != null) {
             dialogMessage.setText(message);
-        }
-
-        final ListView lvItems = content.findViewById(R.id.carrier_list);
-        if (lvItems != null) {
-            lvItems.setVisibility(View.GONE);
-        }
-        final LinearLayout infoOutline = content.findViewById(R.id.info_outline_layout);
-        if (infoOutline != null) {
-            infoOutline.setVisibility(View.GONE);
+            dialogMessage.setVisibility(View.VISIBLE);
         }
         dialog.setView(content);
 
diff --git a/src/com/android/settings/sim/SimDialogFragment.java b/src/com/android/settings/sim/SimDialogFragment.java
index 889f062..2e4fa49 100644
--- a/src/com/android/settings/sim/SimDialogFragment.java
+++ b/src/com/android/settings/sim/SimDialogFragment.java
@@ -83,6 +83,12 @@
         }
     }
 
+    @Override
+    public void dismiss() {
+        mChangeListener.stop();
+        super.dismiss();
+    }
+
     public abstract void updateDialog();
 
     @Override
diff --git a/src/com/android/settings/sim/SimListDialogFragment.java b/src/com/android/settings/sim/SimListDialogFragment.java
index 629a087..166d00a 100644
--- a/src/com/android/settings/sim/SimListDialogFragment.java
+++ b/src/com/android/settings/sim/SimListDialogFragment.java
@@ -19,7 +19,6 @@
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.os.Bundle;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -28,6 +27,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
@@ -47,12 +47,10 @@
  * Shows a dialog consisting of a list of SIMs (aka subscriptions), possibly including an additional
  * entry indicating "ask me every time".
  */
-public class SimListDialogFragment extends SimDialogFragment implements
-        DialogInterface.OnClickListener {
+public class SimListDialogFragment extends SimDialogFragment {
     private static final String TAG = "SimListDialogFragment";
     protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time";
     protected static final String KEY_SHOW_CANCEL_ITEM = "show_cancel_item";
-    private static final int LIST_VIEW_DIVIDER_LINE_WEIGHT = 2;
 
     protected SelectSubscriptionAdapter mAdapter;
     @VisibleForTesting
@@ -79,21 +77,36 @@
         TextView titleTextView = titleView.findViewById(R.id.title);
         titleTextView.setText(getContext().getString(getTitleResId()));
         builder.setCustomTitle(titleTextView);
-
         mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions);
-        setAdapter(builder);
 
         final AlertDialog dialog = builder.create();
-        ListView listView = dialog.getListView();
-        if (listView != null) {
-            listView.setDividerHeight(LIST_VIEW_DIVIDER_LINE_WEIGHT);
+
+        View content = LayoutInflater.from(getContext()).inflate(
+                R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
+
+        final ListView lvItems = content != null ? content.findViewById(R.id.carrier_list) : null;
+        if (lvItems != null) {
+            setAdapter(lvItems);
+            lvItems.setVisibility(View.VISIBLE);
+            lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                @Override
+                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                    onClick(position);
+                }
+            });
         }
+
+        dialog.setView(content);
         updateDialog();
+
         return dialog;
     }
 
-    @Override
-    public void onClick(DialogInterface dialog, int selectionIndex) {
+    /**
+     * If the user click the item at the list, then it sends the callback.
+     * @param selectionIndex the index of item in the list.
+     */
+    public void onClick(int selectionIndex) {
         if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
             int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
             final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
@@ -103,6 +116,7 @@
             final SimDialogActivity activity = (SimDialogActivity) getActivity();
             activity.onSubscriptionSelected(getDialogType(), subId);
         }
+        dismiss();
     }
 
     protected List<SubscriptionInfo> getCurrentSubscriptions() {
@@ -114,12 +128,13 @@
     @Override
     public void updateDialog() {
         Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed);
+        if (mWasDismissed) {
+            return;
+        }
 
         List<SubscriptionInfo> currentSubscriptions = getCurrentSubscriptions();
         if (currentSubscriptions == null) {
-            if (!mWasDismissed) {
-                dismiss();
-            }
+            dismiss();
             return;
         }
         boolean includeAskEveryTime = getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME);
@@ -143,14 +158,15 @@
         if (currentSubscriptions.equals(mSubscriptions)) {
             return;
         }
+
         mSubscriptions.clear();
         mSubscriptions.addAll(currentSubscriptions);
         mAdapter.notifyDataSetChanged();
     }
 
     @VisibleForTesting
-    void setAdapter(AlertDialog.Builder builder) {
-        builder.setAdapter(mAdapter, this);
+    void setAdapter(ListView lvItems) {
+        lvItems.setAdapter(mAdapter);
     }
 
     @Override
@@ -200,6 +216,16 @@
             final TextView title = convertView.findViewById(R.id.title);
             final TextView summary = convertView.findViewById(R.id.summary);
 
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) parent.getLayoutParams();
+            if (lp != null) {
+                lp.setMargins(0, mContext.getResources().getDimensionPixelSize(
+                        R.dimen.sims_select_margin_top), 0,
+                        mContext.getResources().getDimensionPixelSize(
+                                R.dimen.sims_select_margin_bottom));
+                convertView.setLayoutParams(lp);
+            }
+
             if (sub == null) {
                 if (position == 0) {
                     title.setText(R.string.sim_calls_ask_first_prefs_title);
diff --git a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
index be2fa2d..db6e1b4 100644
--- a/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
+++ b/src/com/android/settings/sim/SwitchToEsimConfirmDialogActivity.java
@@ -23,6 +23,7 @@
 import com.android.settings.R;
 import com.android.settings.SidecarFragment;
 import com.android.settings.network.SwitchToEuiccSubscriptionSidecar;
+import com.android.settings.network.UiccSlotUtil;
 import com.android.settings.network.telephony.AlertDialogFragment;
 import com.android.settings.network.telephony.ConfirmDialogFragment;
 import com.android.settings.network.telephony.SubscriptionActionDialogActivity;
@@ -110,7 +111,8 @@
             return;
         }
         Log.i(TAG, "User confirmed to switch to embedded slot.");
-        mSwitchToEuiccSubscriptionSidecar.run(mSubToEnabled.getSubscriptionId());
+        mSwitchToEuiccSubscriptionSidecar.run(mSubToEnabled.getSubscriptionId(),
+                UiccSlotUtil.INVALID_PORT_ID, null);
         showProgressDialog(
                 getString(
                         R.string.sim_action_switch_sub_dialog_progress,
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
index e0bc9cd..4a6b96c 100644
--- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
+++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
@@ -26,12 +26,14 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
 import android.util.Log;
 
 import com.android.settings.network.SubscriptionUtil;
 import com.android.settings.network.UiccSlotUtil;
 import com.android.settings.network.UiccSlotsException;
+import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity;
 import com.android.settings.sim.ChooseSimActivity;
 import com.android.settings.sim.DsdsDialogActivity;
 import com.android.settings.sim.SimActivationNotifier;
@@ -40,6 +42,7 @@
 
 import com.google.common.collect.ImmutableList;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -83,8 +86,8 @@
             throw new IllegalStateException("Cannot be called from main thread.");
         }
 
-        if (mTelMgr.getActiveModemCount() > 1) {
-            Log.i(TAG, "The device is already in DSDS mode. Do nothing.");
+        if (mTelMgr.getActiveModemCount() > 1 && !isMultipleEnabledProfilesSupported()) {
+            Log.i(TAG, "The device is already in DSDS mode and no MEP. Do nothing.");
             return;
         }
 
@@ -96,17 +99,30 @@
 
         int lastRemovableSlotState = getLastRemovableSimSlotState(mContext);
         int currentRemovableSlotState = removableSlotInfo.getCardStateInfo();
+        boolean isRemovableSimInserted =
+                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+        boolean isRemovableSimRemoved =
+                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT;
 
         // Sets the current removable slot state.
         setRemovableSimSlotState(mContext, currentRemovableSlotState);
 
-        if (lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
-                && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT) {
+        if (mTelMgr.getActiveModemCount() > 1 && isMultipleEnabledProfilesSupported()) {
+            if(!isRemovableSimInserted) {
+                Log.i(TAG, "Removable Sim is not inserted in DSDS mode and MEP. Do nothing.");
+                return;
+            }
+            handleRemovableSimInsertUnderDsdsMep(removableSlotInfo);
+            return;
+        }
+
+        if (isRemovableSimInserted) {
             handleSimInsert(removableSlotInfo);
             return;
         }
-        if (lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
-                && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT) {
+        if (isRemovableSimRemoved) {
             handleSimRemove(removableSlotInfo);
             return;
         }
@@ -210,10 +226,11 @@
         }
 
         List<SubscriptionInfo> groupedEmbeddedSubscriptions = getGroupedEmbeddedSubscriptions();
-
         if (groupedEmbeddedSubscriptions.size() == 0 || !removableSlotInfo.getPorts().stream()
                 .findFirst().get().isActive()) {
-            Log.i(TAG, "eSIM slot is active or no subscriptions exist. Do nothing.");
+            Log.i(TAG, "eSIM slot is active or no subscriptions exist. Do nothing."
+                            + " The removableSlotInfo: " + removableSlotInfo
+                            + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions);
             return;
         }
 
@@ -231,6 +248,24 @@
         startChooseSimActivity(false);
     }
 
+    private void handleRemovableSimInsertUnderDsdsMep(UiccSlotInfo removableSlotInfo) {
+        Log.i(TAG, "Handle Removable SIM inserted under DSDS+Mep.");
+
+        if (removableSlotInfo.getPorts().stream().findFirst().get().isActive()) {
+            Log.i(TAG, "The removable slot is already active. Do nothing. removableSlotInfo: "
+                    + removableSlotInfo);
+            return;
+        }
+
+        List<SubscriptionInfo> subscriptionInfos = getAvailableRemovableSubscription();
+        if (subscriptionInfos == null || subscriptionInfos.get(0) == null) {
+            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.");
+            return;
+        }
+        Log.d(TAG, "getAvailableRemovableSubscription:" + subscriptionInfos);
+        startSimConfirmDialogActivity(subscriptionInfos.get(0).getSubscriptionId());
+    }
+
     private int getLastRemovableSimSlotState(Context context) {
         final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
         return prefs.getInt(KEY_REMOVABLE_SLOT_STATE, UiccSlotInfo.CARD_STATE_INFO_ABSENT);
@@ -260,7 +295,6 @@
         }
         for (UiccSlotInfo slotInfo : slotInfos) {
             if (slotInfo != null && slotInfo.isRemovable()) {
-
                 return slotInfo;
             }
         }
@@ -296,6 +330,16 @@
                         .collect(Collectors.toList()));
     }
 
+    protected List<SubscriptionInfo> getAvailableRemovableSubscription() {
+        List<SubscriptionInfo> subList = new ArrayList<>();
+        for (SubscriptionInfo info : SubscriptionUtil.getAvailableSubscriptions(mContext)) {
+            if (!info.isEmbedded()) {
+                subList.add(info);
+            }
+        }
+        return subList;
+    }
+
     private void startChooseSimActivity(boolean psimInserted) {
         Intent intent = ChooseSimActivity.getIntent(mContext);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -316,5 +360,26 @@
         mContext.startActivity(intent);
     }
 
+    private void startSimConfirmDialogActivity(int subId) {
+        if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
+            Log.i(TAG, "Unable to enable subscription due to invalid subscription ID.");
+            return;
+        }
+        Log.d(TAG, "Start ToggleSubscriptionDialogActivity with " + subId + " under DSDS+Mep.");
+        Intent intent = ToggleSubscriptionDialogActivity.getIntent(mContext, subId, true);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private boolean isMultipleEnabledProfilesSupported() {
+        List<UiccCardInfo> cardInfos = mTelMgr.getUiccCardsInfo();
+        if (cardInfos == null) {
+            Log.d(TAG, "UICC cards info list is empty.");
+            return false;
+        }
+        return cardInfos.stream().anyMatch(
+                cardInfo -> cardInfo.isMultipleEnabledProfilesSupported());
+    }
+
     private SimSlotChangeHandler() {}
 }
diff --git a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
index 070bcb1..7b17b74 100644
--- a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
@@ -77,7 +77,7 @@
         doReturn(activity).when(mFragment).getActivity();
         doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
 
-        mFragment.onClick(alertDialog, 1);
+        mFragment.onClick(1);
         verify(activity).onSubscriptionSelected(dialogType, SIM2_ID);
     }
 
@@ -117,7 +117,7 @@
         doReturn(activity).when(mFragment).getActivity();
         doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
 
-        mFragment.onClick(alertDialog, 0);
+        mFragment.onClick(0);
         verify(activity).onSubscriptionSelected(dialogType,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
new file mode 100644
index 0000000..2cf9845
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network;
+
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+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;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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 {
+    private Context mContext;
+    @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);
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+    }
+
+    @Test
+    public void getSlotInfos_oneSimSlotDevice_returnTheCorrectSlotInfoList() {
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(oneSimSlotDeviceActivePsim());
+        ImmutableList<UiccSlotInfo> testUiccSlotInfos =
+                UiccSlotUtil.getSlotInfos(mTelephonyManager);
+
+        assertThat(testUiccSlotInfos.size()).isEqualTo(1);
+    }
+
+    @Test
+    public void getSlotInfos_twoSimSlotsDevice_returnTheCorrectSlotInfoList() {
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
+                twoSimSlotsDeviceActivePsimActiveEsim());
+        ImmutableList<UiccSlotInfo> testUiccSlotInfos =
+                UiccSlotUtil.getSlotInfos(mTelephonyManager);
+
+        assertThat(testUiccSlotInfos.size()).isEqualTo(2);
+    }
+
+    @Test
+    public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot0_returnTheCorrectEsimSlot() {
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
+                twoSimSlotsDeviceActiveEsimActivePsim());
+        int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
+
+        assertThat(testSlot).isEqualTo(0);
+    }
+
+    @Test
+    public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() {
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
+                twoSimSlotsDeviceActivePsimActiveEsim());
+        int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
+
+        assertThat(testSlot).isEqualTo(1);
+    }
+
+    @Test
+    public void getEsimSlotId_noEimSlotDevice_returnTheCorrectEsimSlot() {
+        when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
+                oneSimSlotDeviceActivePsim());
+        int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
+
+        assertThat(testSlot).isEqualTo(-1);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimActiveToEsimPort0Active_esimPort0Active() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingSsModePsimActive();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingSsModeEsimPort0Active();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromEsimPort0ActiveToPsimActive_psimActive() {
+        Collection<UiccSlotMapping> uiccSlotMappings =
+                createUiccSlotMappingSsModeEsimPort0Active();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingSsModePsimActive();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort0ToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort1ToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort0ToDualPortsB_dualPortsB() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsB();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromPsimAndPort1ToDualPortsA_dualPortsA() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsA();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_noPsimAndFromPsimAndPort0ToDualPortsB_dualPortsB() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsB();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 1, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_noPsimAndFromPsimAndPort1ToDualPortsA_dualPortsA() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingDualPortsA();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, false, ESIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_oneEsimAndFromDualPortsAToPsimAndPort1_psimAndPort1() {
+        // There is only one enabled esimPort1 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_oneEsimAndFromDualPortsAToPsimAndPort0_psimAndPort0() {
+        // There is only one enabled esimPort0 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_oneEsimAndFromDualPortsBToPsimAndPort1_psimAndPort1() {
+        // There is only one enabled esimPort1 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_oneEsimAndFromDualPortsBToPsimAndPort0_psimAndPort0() {
+        // There is only one enabled esimPort0 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsAToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsAToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsBToPsimAndPort1_psimAndPort1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort1();
+        int removedLogicalSlotIndex = 1;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void prepareUiccSlotMappings_fromDualPortsBToPsimAndPort0_psimAndPort0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<UiccSlotMapping> verifyUiccSlotMappings =
+                createUiccSlotMappingPsimAndPort0();
+        int removedLogicalSlotIndex = 0;
+
+        Collection<UiccSlotMapping> testUiccSlotMappings = UiccSlotUtil.prepareUiccSlotMappings(
+                uiccSlotMappings, true, PSIM_PHYSICAL_SLOT, 0, removedLogicalSlotIndex);
+
+        compareTwoUiccSlotMappings(testUiccSlotMappings, verifyUiccSlotMappings);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromPsimActiveToEsimPort0Active_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingSsModePsimActive();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(0, 0);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, false);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromEsimPort0ActiveToPsimActive_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingSsModeEsimPort0Active();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(0, 0);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, false);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromPsimAndPort0ToPsimAndPort1_logicalSlot1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 0);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(1, 0);
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromPsimAndPort1ToPsimAndPort0_logicalSlot1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 1);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(1, 1);
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromPsimAndPort0ToDualPortsB_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 0);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(0, 0);
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromPsimAndPort1ToDualPortsA_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 1);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(0, 0);
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_noPsimAndFromPsimAndPort0ToDualPortsB_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort0();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(1, 0);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_noPsimAndFromPsimAndPort1ToDualPortsA_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingPsimAndPort1();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(1, 1);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_oneEsimAndFromDualPortsAToPsimAndPort1_logicalSlot0() {
+        // There is only one enabled esimPort1 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(1, 1);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_oneEsimAndFromDualPortsAToPsimAndPort0_logicalSlot1() {
+        // There is only one enabled esimPort0 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(0, 0);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_oneEsimAndFromDualPortsBToPsimAndPort1_logicalSlot1() {
+        // There is only one enabled esimPort1 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(0, 1);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_oneEsimAndFromDualPortsBToPsimAndPort0_logicalSlot0() {
+        // There is only one enabled esimPort0 before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListOneSim(1, 0);
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromDualPortsAToPsimAndPort1_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 1);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(0, 0);
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromDualPortsAToPsimAndPort0_logicalSlot1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 0, 1, 1);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(1, 1);
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromDualPortsBToPsimAndPort1_logicalSlot1() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 1, 1, 0);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(1, 0);
+        int verifyExcludedLogicalSlotIndex = 1;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_fromDualPortsBToPsimAndPort0_logicalSlot0() {
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList =
+                createActiveSubscriptionInfoListTwoSims(0, 1, 1, 0);
+        SubscriptionInfo removedSubInfo = createSubscriptionInfo(0, 1);
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_noEsimAndFromDualPortsAToPsimAndPort1_logicalSlot0() {
+        // There is no profiles enabled on either esim port before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsA();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList = new ArrayList<>();
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_noEsimAndFromDualPortsBToPsimAndPort0_logicalSlot0() {
+        // There is no profiles enabled on either esim port before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsB();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList = new ArrayList<>();
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    @Test
+    public void getExcludedLogicalSlotIndex_noEsimNoOrdingFromDualPortsBToPsimAndPort1_logical0() {
+        // There is no profiles enabled on either esim port before user enables the psim.
+        Collection<UiccSlotMapping> uiccSlotMappings = createUiccSlotMappingDualPortsBNoOrding();
+        Collection<SubscriptionInfo> activeSubscriptionInfoList = new ArrayList<>();
+        SubscriptionInfo removedSubInfo = null;
+        int verifyExcludedLogicalSlotIndex = 0;
+
+        int testExcludedLogicalSlotIndex = UiccSlotUtil.getExcludedLogicalSlotIndex(
+                uiccSlotMappings, activeSubscriptionInfoList, removedSubInfo, true);
+
+        assertThat(testExcludedLogicalSlotIndex).isEqualTo(verifyExcludedLogicalSlotIndex);
+    }
+
+    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());
+        }
+    }
+
+    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 List<SubscriptionInfo> createActiveSubscriptionInfoListOneSim(int logicalSlotIndex,
+            int portIndex) {
+        List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>();
+        subscriptionInfoList.add(createSubscriptionInfo(logicalSlotIndex, portIndex));
+
+        return subscriptionInfoList;
+    }
+
+    private List<SubscriptionInfo> createActiveSubscriptionInfoListTwoSims(int logicalSlotIndex1,
+            int portIndex1, int logicalSlotIndex2, int portIndex2) {
+        List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>();
+        subscriptionInfoList.add(createSubscriptionInfo(logicalSlotIndex1, portIndex1));
+        subscriptionInfoList.add(createSubscriptionInfo(logicalSlotIndex2, portIndex2));
+        return subscriptionInfoList;
+    }
+
+    // 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;
+    }
+    private List<UiccSlotMapping> createUiccSlotMappingDualPortsBNoOrding() {
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
+        slotMap.add(new UiccSlotMapping(0, ESIM_PHYSICAL_SLOT, 1));
+        slotMap.add(new UiccSlotMapping(1, ESIM_PHYSICAL_SLOT, 0));
+
+        return slotMap;
+    }
+    /**
+     * The "oneSimSlotDevice" has below cases
+     * 1) The device is one psim slot and no esim slot
+     * 2) The device is no psim slot and one esim slot. like the watch.
+     *
+     * The "twoSimsSlotDevice" has below cases
+     * 1) The device is one psim slot and one esim slot
+     * 2) The device is two psim slots
+     */
+
+    private UiccSlotInfo[] oneSimSlotDeviceActivePsim() {
+        return new UiccSlotInfo[]{createUiccSlotInfo(false, true, 0, true)};
+    }
+
+    private UiccSlotInfo[] oneSimSlotDeviceActiveEsim() {
+        return new UiccSlotInfo[]{createUiccSlotInfo(true, false, 1, true)};
+    }
+
+    private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveEsim() {
+        return new UiccSlotInfo[]{
+                createUiccSlotInfo(false, true, 0, true),
+                createUiccSlotInfo(true, false, 1, true)};
+    }
+
+    private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActivePsim() {
+        return new UiccSlotInfo[]{
+                createUiccSlotInfo(true, false, 0, true),
+                createUiccSlotInfo(false, true, 1, true)};
+    }
+
+    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[]{
+                createUiccSlotInfo(false, true, -1, true),
+                createUiccSlotInfoForEsimMep(0, true, 1, true)};
+    }
+
+    private UiccSlotInfo[] twoSimSlotsDeviceActivePsimInactiveEsim() {
+        return new UiccSlotInfo[]{
+                createUiccSlotInfo(false, true, 0, true),
+                createUiccSlotInfo(true, false, -1, false)};
+    }
+
+    private UiccSlotInfo[] twoSimSlotsDeviceInactivePsimActiveEsim() {
+        return new UiccSlotInfo[]{
+                createUiccSlotInfo(false, true, 0, false),
+                createUiccSlotInfo(true, false, 1, true)};
+    }
+
+    private UiccSlotInfo[] twoSimSlotsDeviceNoInsertPsimActiveEsim() {
+        return new UiccSlotInfo[]{
+                createUiccSlotInfo(false, true, -1, false),
+                createUiccSlotInfo(true, false, 1, true)};
+    }
+    //ToDo: add more cases.
+
+    private UiccSlotInfo createUiccSlotInfo(boolean isEuicc, boolean isRemovable,
+            int logicalSlotIdx, boolean isActive) {
+        return new UiccSlotInfo(
+                isEuicc, /* isEuicc */
+                "123", /* cardId */
+                CARD_STATE_INFO_PRESENT, /* cardStateInfo */
+                true, /* isExtendApduSupported */
+                isRemovable, /* isRemovable */
+                Collections.singletonList(
+                        new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
+                                logicalSlotIdx /* logicalSlotIdx */, isActive /* isActive */))
+        );
+    }
+
+    private UiccSlotInfo createUiccSlotInfoForEsimMep(int logicalSlotIdx1, boolean isActiveEsim1,
+            int logicalSlotIdx2, boolean isActiveEsim2) {
+        return new UiccSlotInfo(
+                true, /* isEuicc */
+                "123", /* cardId */
+                CARD_STATE_INFO_PRESENT, /* cardStateInfo */
+                true, /* isExtendApduSupported */
+                false, /* isRemovable */
+                Arrays.asList(
+                        new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
+                                logicalSlotIdx1 /* logicalSlotIdx */, isActiveEsim1 /* isActive */),
+                        new UiccPortInfo("" /* iccId */, 1 /* portIdx */,
+                                logicalSlotIdx2 /* logicalSlotIdx */,
+                                isActiveEsim2 /* isActive */)));
+    }
+}