diff --git a/src/com/android/settings/network/telephony/SubscriptionRepository.kt b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
index 43bba07..33c1e655 100644
--- a/src/com/android/settings/network/telephony/SubscriptionRepository.kt
+++ b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
@@ -40,6 +40,7 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.shareIn
+import java.util.stream.Collectors
 
 private const val TAG = "SubscriptionRepository"
 
@@ -154,6 +155,18 @@
             .conflate()
             .flowOn(Dispatchers.Default)
 
+    fun removableSubscriptionInfoListFlow(): Flow<List<SubscriptionInfo>> {
+        return subscriptionsChangedFlow()
+            .map {
+                subscriptionManager.availableSubscriptionInfoList?.stream()
+                    ?.filter { sub: SubscriptionInfo -> !sub.isEmbedded }
+                    ?.collect(Collectors.toList()) ?: emptyList()
+            }
+            .conflate()
+            .onEach { Log.d(TAG, "getRemovableSubscriptionVisibleFlow: $it") }
+            .flowOn(Dispatchers.Default)
+    }
+
     @OptIn(ExperimentalCoroutinesApi::class)
     fun phoneNumberFlow(subId: Int): Flow<String?> =
         activeSubscriptionInfoFlow(subId).flatMapLatest { subInfo ->
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
deleted file mode 100644
index f808924..0000000
--- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2020 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.sim.receivers;
-
-import static android.content.Context.MODE_PRIVATE;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
-import android.telephony.UiccSlotInfo;
-import android.util.Log;
-
-import com.android.settings.flags.Flags;
-import com.android.settings.network.SubscriptionUtil;
-import com.android.settings.network.UiccSlotUtil;
-import com.android.settings.network.UiccSlotsException;
-import com.android.settings.sim.ChooseSimActivity;
-import com.android.settings.sim.DsdsDialogActivity;
-import com.android.settings.sim.SimActivationNotifier;
-import com.android.settings.sim.SimNotificationService;
-import com.android.settings.sim.SwitchToEsimConfirmDialogActivity;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nullable;
-
-/** Perform actions after a slot change event is triggered. */
-public class SimSlotChangeHandler {
-    private static final String TAG = "SimSlotChangeHandler";
-
-    private static final String EUICC_PREFS = "euicc_prefs";
-    // Shared preference keys
-    private static final String KEY_REMOVABLE_SLOT_STATE = "removable_slot_state";
-    private static final String KEY_SUW_PSIM_ACTION = "suw_psim_action";
-    // User's last removable SIM insertion / removal action during SUW.
-    private static final int LAST_USER_ACTION_IN_SUW_NONE = 0;
-    private static final int LAST_USER_ACTION_IN_SUW_INSERT = 1;
-    private static final int LAST_USER_ACTION_IN_SUW_REMOVE = 2;
-
-    private static volatile SimSlotChangeHandler sSlotChangeHandler;
-
-    /** Returns a SIM slot change handler singleton. */
-    public static SimSlotChangeHandler get() {
-        if (sSlotChangeHandler == null) {
-            synchronized (SimSlotChangeHandler.class) {
-                if (sSlotChangeHandler == null) {
-                    sSlotChangeHandler = new SimSlotChangeHandler();
-                }
-            }
-        }
-        return sSlotChangeHandler;
-    }
-
-    private SubscriptionManager mSubMgr;
-    private TelephonyManager mTelMgr;
-    private Context mContext;
-
-    void onSlotsStatusChange(Context context) {
-        init(context);
-
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new IllegalStateException("Cannot be called from main thread.");
-        }
-
-        UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo();
-        if (removableSlotInfo == null) {
-            Log.e(TAG, "Unable to find the removable slot. Do nothing.");
-            return;
-        }
-        Log.i(TAG, "The removableSlotInfo: " + removableSlotInfo);
-        int lastRemovableSlotState = getLastRemovableSimSlotState(mContext);
-        int currentRemovableSlotState = removableSlotInfo.getCardStateInfo();
-        Log.d(TAG,
-                "lastRemovableSlotState: " + lastRemovableSlotState + ",currentRemovableSlotState: "
-                        + currentRemovableSlotState);
-        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 (mTelMgr.getActiveModemCount() > 1) {
-            if (!isRemovableSimInserted) {
-                Log.d(TAG, "Removable Sim is not inserted in DSDS mode. Do nothing.");
-                return;
-            }
-
-            if (Flags.isDualSimOnboardingEnabled()) {
-                // ForNewUi, when the user inserts the psim, showing the sim onboarding for the user
-                // to setup the sim switching or the default data subscription in DSDS.
-                // Will show dialog for below case.
-                // 1. the psim slot is not active.
-                // 2. there are one or more active sim.
-                handleRemovableSimInsertWhenDsds(removableSlotInfo);
-                return;
-            } else if (!isMultipleEnabledProfilesSupported()) {
-                Log.d(TAG, "The device is already in DSDS mode and no MEP. Do nothing.");
-                return;
-            } else if (isMultipleEnabledProfilesSupported()) {
-                handleRemovableSimInsertUnderDsdsMep(removableSlotInfo);
-                return;
-            }
-        }
-
-        if (isRemovableSimInserted) {
-            handleSimInsert(removableSlotInfo);
-            return;
-        }
-        if (isRemovableSimRemoved) {
-            handleSimRemove(removableSlotInfo);
-            return;
-        }
-        Log.i(TAG, "Do nothing on slot status changes.");
-    }
-
-    void onSuwFinish(Context context) {
-        init(context);
-
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            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.");
-            return;
-        }
-
-        UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo();
-        if (removableSlotInfo == null) {
-            Log.e(TAG, "Unable to find the removable slot. Do nothing.");
-            return;
-        }
-
-        boolean embeddedSimExist = getGroupedEmbeddedSubscriptions().size() != 0;
-        int removableSlotAction = getSuwRemovableSlotAction(mContext);
-        setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_NONE);
-
-        if (embeddedSimExist
-                && removableSlotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_PRESENT) {
-            if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
-                Log.i(TAG, "DSDS condition satisfied. Show notification.");
-                SimNotificationService.scheduleSimNotification(
-                        mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS);
-            } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) {
-                Log.i(
-                        TAG,
-                        "Both removable SIM and eSIM are present. DSDS condition doesn't"
-                                + " satisfied. User inserted pSIM during SUW. Show choose SIM"
-                                + " screen.");
-                startChooseSimActivity(true);
-            }
-        } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) {
-            handleSimRemove(removableSlotInfo);
-        }
-    }
-
-    private void init(Context context) {
-        mSubMgr =
-                (SubscriptionManager)
-                        context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        mTelMgr = context.getSystemService(TelephonyManager.class);
-        mContext = context;
-    }
-
-    private void handleSimInsert(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "Handle SIM inserted.");
-        if (!isSuwFinished(mContext)) {
-            Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished");
-            setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_INSERT);
-            return;
-        }
-        if (removableSlotInfo.getPorts().stream().findFirst().get().isActive()) {
-            Log.i(TAG, "The removable slot is already active. Do nothing.");
-            return;
-        }
-
-        if (hasActiveEsimSubscription()) {
-            if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
-                Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.");
-                if (Flags.isDualSimOnboardingEnabled()) {
-                    // enable dsds by sim onboarding flow
-                    handleRemovableSimInsertWhenDsds(removableSlotInfo);
-                } else {
-                    startDsdsDialogActivity();
-                }
-            } else {
-                Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.");
-                startChooseSimActivity(true);
-            }
-            return;
-        }
-
-        Log.i(
-                TAG,
-                "No enabled eSIM profile. Ready to switch to removable slot and show"
-                        + " notification.");
-        try {
-            UiccSlotUtil.switchToRemovableSlot(
-                    UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, mContext.getApplicationContext());
-        } catch (UiccSlotsException e) {
-            Log.e(TAG, "Failed to switch to removable slot.");
-            return;
-        }
-        SimNotificationService.scheduleSimNotification(
-                mContext, SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT);
-    }
-
-    private void handleSimRemove(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "Handle SIM removed.");
-
-        if (!isSuwFinished(mContext)) {
-            Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished");
-            setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_REMOVE);
-            return;
-        }
-
-        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."
-                    + " The removableSlotInfo: " + removableSlotInfo
-                    + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions);
-            return;
-        }
-
-        // If there is only 1 eSIM profile exists, we ask the user if they want to switch to that
-        // profile.
-        if (groupedEmbeddedSubscriptions.size() == 1) {
-            Log.i(TAG, "Only 1 eSIM profile found. Ask user's consent to switch.");
-            startSwitchSlotConfirmDialogActivity(groupedEmbeddedSubscriptions.get(0));
-            return;
-        }
-
-        // If there are more than 1 eSIM profiles installed, we show a screen to let users to choose
-        // the number they want to use.
-        Log.i(TAG, "Multiple eSIM profiles found. Ask user which subscription to use.");
-        startChooseSimActivity(false);
-    }
-
-    private boolean hasOtherActiveSubInfo(int psimSubId) {
-        List<SubscriptionInfo> activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
-        return activeSubs.stream()
-                .anyMatch(subscriptionInfo -> subscriptionInfo.getSubscriptionId() != psimSubId);
-    }
-
-    private boolean hasAnyPortActiveInSlot(UiccSlotInfo removableSlotInfo) {
-        return removableSlotInfo.getPorts().stream().anyMatch(UiccPortInfo::isActive);
-    }
-
-    private void handleRemovableSimInsertWhenDsds(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "ForNewUi: Handle Removable SIM inserted");
-        List<SubscriptionInfo> subscriptionInfos = getAvailableRemovableSubscription();
-        if (subscriptionInfos.isEmpty()) {
-            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.");
-            return;
-        }
-        Log.d(TAG, "getAvailableRemovableSubscription:" + subscriptionInfos);
-        int psimSubId = subscriptionInfos.get(0).getSubscriptionId();
-        if (!hasAnyPortActiveInSlot(removableSlotInfo) || hasOtherActiveSubInfo(psimSubId)) {
-            Log.d(TAG, "ForNewUi Start Setup flow");
-            startSimConfirmDialogActivity(psimSubId);
-        }
-    }
-
-    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.isEmpty()) {
-            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);
-    }
-
-    private void setRemovableSimSlotState(Context context, int state) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply();
-        Log.d(TAG, "setRemovableSimSlotState: " + state);
-    }
-
-    private int getSuwRemovableSlotAction(Context context) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE);
-    }
-
-    private void setSuwRemovableSlotAction(Context context, int action) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply();
-    }
-
-    @Nullable
-    private UiccSlotInfo getRemovableUiccSlotInfo() {
-        UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo();
-        if (slotInfos == null) {
-            Log.e(TAG, "slotInfos is null. Unable to get slot infos.");
-            return null;
-        }
-        for (UiccSlotInfo slotInfo : slotInfos) {
-            if (slotInfo != null && slotInfo.isRemovable()) {
-                return slotInfo;
-            }
-        }
-        return null;
-    }
-
-    private static boolean isSuwFinished(Context context) {
-        try {
-            // DEVICE_PROVISIONED is 0 if still in setup wizard. 1 if setup completed.
-            return Settings.Global.getInt(
-                    context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED)
-                    == 1;
-        } catch (Settings.SettingNotFoundException e) {
-            Log.e(TAG, "Cannot get DEVICE_PROVISIONED from the device.", e);
-            return false;
-        }
-    }
-
-    private boolean hasActiveEsimSubscription() {
-        List<SubscriptionInfo> activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
-        return activeSubs.stream().anyMatch(SubscriptionInfo::isEmbedded);
-    }
-
-    private List<SubscriptionInfo> getGroupedEmbeddedSubscriptions() {
-        List<SubscriptionInfo> groupedSubscriptions =
-                SubscriptionUtil.getSelectableSubscriptionInfoList(mContext);
-        if (groupedSubscriptions == null) {
-            return ImmutableList.of();
-        }
-        return ImmutableList.copyOf(
-                groupedSubscriptions.stream()
-                        .filter(sub -> sub.isEmbedded())
-                        .collect(Collectors.toList()));
-    }
-
-    protected List<SubscriptionInfo> getAvailableRemovableSubscription() {
-        List<SubscriptionInfo> removableSubscriptions =
-                SubscriptionUtil.getAvailableSubscriptions(mContext);
-        return ImmutableList.copyOf(
-                removableSubscriptions.stream()
-                        // ToDo: This condition is for psim only. If device supports removable
-                        //  esim, it needs an new condition.
-                        .filter(sub -> !sub.isEmbedded())
-                        .collect(Collectors.toList()));
-    }
-
-    private void startChooseSimActivity(boolean psimInserted) {
-        Intent intent = ChooseSimActivity.getIntent(mContext);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startSwitchSlotConfirmDialogActivity(SubscriptionInfo subscriptionInfo) {
-        Intent intent = new Intent(mContext, SwitchToEsimConfirmDialogActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startDsdsDialogActivity() {
-        Intent intent = new Intent(mContext, DsdsDialogActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startSimConfirmDialogActivity(int subId) {
-        if (!isSuwFinished(mContext)) {
-            Log.d(TAG, "Still in SUW. Do nothing");
-            return;
-        }
-        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.");
-        SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId, true, true);
-    }
-
-    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/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt
new file mode 100644
index 0000000..940184a
--- /dev/null
+++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2020 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.sim.receivers
+
+import android.content.Context
+import android.content.Intent
+import android.os.Looper
+import android.os.UserHandle
+import android.provider.Settings
+import android.provider.Settings.SettingNotFoundException
+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.flags.Flags
+import com.android.settings.network.SubscriptionUtil
+import com.android.settings.network.UiccSlotUtil
+import com.android.settings.network.UiccSlotsException
+import com.android.settings.network.telephony.SubscriptionRepository
+import com.android.settings.sim.ChooseSimActivity
+import com.android.settings.sim.DsdsDialogActivity
+import com.android.settings.sim.SimActivationNotifier
+import com.android.settings.sim.SimNotificationService
+import com.android.settings.sim.SwitchToEsimConfirmDialogActivity
+import com.google.common.collect.ImmutableList
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.coroutines.withTimeoutOrNull
+import java.util.stream.Collectors
+import kotlin.concurrent.Volatile
+
+/** Perform actions after a slot change event is triggered.  */
+class SimSlotChangeHandler private constructor() {
+    private var mSubMgr: SubscriptionManager? = null
+    private var mTelMgr: TelephonyManager? = null
+    private var mContext: Context? = null
+
+    fun onSlotsStatusChange(context: Context) {
+        init(context)
+
+        check(Looper.myLooper() != Looper.getMainLooper()) { "Cannot be called from main thread." }
+
+        val removableSlotInfo = removableUiccSlotInfo
+        if (removableSlotInfo == null) {
+            Log.e(TAG, "Unable to find the removable slot. Do nothing.")
+            return
+        }
+        Log.i(
+            TAG,
+            "The removableSlotInfo: $removableSlotInfo"
+        )
+        val lastRemovableSlotState = getLastRemovableSimSlotState(mContext!!)
+        val currentRemovableSlotState = removableSlotInfo.cardStateInfo
+        Log.d(
+            TAG,
+            ("lastRemovableSlotState: " + lastRemovableSlotState + ",currentRemovableSlotState: "
+                    + currentRemovableSlotState)
+        )
+        val isRemovableSimInserted =
+            lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+                    && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+        val isRemovableSimRemoved =
+            lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+                    && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+
+        // Sets the current removable slot state.
+        setRemovableSimSlotState(mContext!!, currentRemovableSlotState)
+
+        if (mTelMgr!!.activeModemCount > 1) {
+            if (!isRemovableSimInserted) {
+                Log.d(TAG, "Removable Sim is not inserted in DSDS mode. Do nothing.")
+                return
+            }
+
+            if (Flags.isDualSimOnboardingEnabled()) {
+                // ForNewUi, when the user inserts the psim, showing the sim onboarding for the user
+                // to setup the sim switching or the default data subscription in DSDS.
+                // Will show dialog for below case.
+                // 1. the psim slot is not active.
+                // 2. there are one or more active sim.
+                handleRemovableSimInsertWhenDsds(removableSlotInfo)
+                return
+            } else if (!isMultipleEnabledProfilesSupported) {
+                Log.d(TAG, "The device is already in DSDS mode and no MEP. Do nothing.")
+                return
+            } else if (isMultipleEnabledProfilesSupported) {
+                handleRemovableSimInsertUnderDsdsMep(removableSlotInfo)
+                return
+            }
+        }
+
+        if (isRemovableSimInserted) {
+            handleSimInsert(removableSlotInfo)
+            return
+        }
+        if (isRemovableSimRemoved) {
+            handleSimRemove(removableSlotInfo)
+            return
+        }
+        Log.i(TAG, "Do nothing on slot status changes.")
+    }
+
+    fun onSuwFinish(context: Context) {
+        init(context)
+
+        check(Looper.myLooper() != Looper.getMainLooper()) { "Cannot be called from main thread." }
+
+        if (mTelMgr!!.activeModemCount > 1) {
+            Log.i(TAG, "The device is already in DSDS mode. Do nothing.")
+            return
+        }
+
+        val removableSlotInfo = removableUiccSlotInfo
+        if (removableSlotInfo == null) {
+            Log.e(TAG, "Unable to find the removable slot. Do nothing.")
+            return
+        }
+
+        val embeddedSimExist = groupedEmbeddedSubscriptions.size != 0
+        val removableSlotAction = getSuwRemovableSlotAction(mContext!!)
+        setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_NONE)
+
+        if (embeddedSimExist
+            && removableSlotInfo.cardStateInfo == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+        ) {
+            if (mTelMgr!!.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
+                Log.i(TAG, "DSDS condition satisfied. Show notification.")
+                SimNotificationService.scheduleSimNotification(
+                    mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS
+                )
+            } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) {
+                Log.i(
+                    TAG,
+                    ("Both removable SIM and eSIM are present. DSDS condition doesn't"
+                            + " satisfied. User inserted pSIM during SUW. Show choose SIM"
+                            + " screen.")
+                )
+                startChooseSimActivity(true)
+            }
+        } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) {
+            handleSimRemove(removableSlotInfo)
+        }
+    }
+
+    private fun init(context: Context) {
+        mSubMgr =
+            context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
+        mTelMgr = context.getSystemService(TelephonyManager::class.java)
+        mContext = context
+    }
+
+    private fun handleSimInsert(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle SIM inserted.")
+        if (!isSuwFinished(mContext!!)) {
+            Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished")
+            setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_INSERT)
+            return
+        }
+        if (removableSlotInfo.ports.stream().findFirst().get().isActive) {
+            Log.i(TAG, "The removable slot is already active. Do nothing.")
+            return
+        }
+
+        if (hasActiveEsimSubscription()) {
+            if (mTelMgr!!.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
+                Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.")
+                if (Flags.isDualSimOnboardingEnabled()) {
+                    // enable dsds by sim onboarding flow
+                    handleRemovableSimInsertWhenDsds(removableSlotInfo)
+                } else {
+                    startDsdsDialogActivity()
+                }
+            } else {
+                Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.")
+                startChooseSimActivity(true)
+            }
+            return
+        }
+
+        Log.i(
+            TAG,
+            "No enabled eSIM profile. Ready to switch to removable slot and show"
+                    + " notification."
+        )
+        try {
+            UiccSlotUtil.switchToRemovableSlot(
+                UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, mContext!!.applicationContext
+            )
+        } catch (e: UiccSlotsException) {
+            Log.e(TAG, "Failed to switch to removable slot.")
+            return
+        }
+        SimNotificationService.scheduleSimNotification(
+            mContext, SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT
+        )
+    }
+
+    private fun handleSimRemove(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle SIM removed.")
+
+        if (!isSuwFinished(mContext!!)) {
+            Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished")
+            setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_REMOVE)
+            return
+        }
+
+        val groupedEmbeddedSubscriptions =
+            groupedEmbeddedSubscriptions
+        if (groupedEmbeddedSubscriptions.isEmpty() || !removableSlotInfo.ports.stream()
+                .findFirst().get().isActive
+        ) {
+            Log.i(
+                TAG, ("eSIM slot is active or no subscriptions exist. Do nothing."
+                        + " The removableSlotInfo: " + removableSlotInfo
+                        + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions)
+            )
+            return
+        }
+
+        // If there is only 1 eSIM profile exists, we ask the user if they want to switch to that
+        // profile.
+        if (groupedEmbeddedSubscriptions.size == 1) {
+            Log.i(TAG, "Only 1 eSIM profile found. Ask user's consent to switch.")
+            startSwitchSlotConfirmDialogActivity(groupedEmbeddedSubscriptions[0])
+            return
+        }
+
+        // If there are more than 1 eSIM profiles installed, we show a screen to let users to choose
+        // the number they want to use.
+        Log.i(TAG, "Multiple eSIM profiles found. Ask user which subscription to use.")
+        startChooseSimActivity(false)
+    }
+
+    private fun hasOtherActiveSubInfo(psimSubId: Int): Boolean {
+        val activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr)
+        return activeSubs.stream()
+            .anyMatch { subscriptionInfo -> subscriptionInfo.subscriptionId != psimSubId }
+    }
+
+    private fun hasAnyPortActiveInSlot(removableSlotInfo: UiccSlotInfo): Boolean {
+        return removableSlotInfo.ports.stream().anyMatch { slot -> slot.isActive }
+    }
+
+    private fun handleRemovableSimInsertWhenDsds(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "ForNewUi: Handle Removable SIM inserted")
+        CoroutineScope(Dispatchers.Default + SupervisorJob()).launch {
+            withContext(Dispatchers.Default) {
+                val subscriptionInfos =
+                    withTimeoutOrNull(DEFAULT_WAIT_AFTER_SIM_INSERTED_TIMEOUT_MILLIS) {
+                        SubscriptionRepository(mContext!!)
+                            .removableSubscriptionInfoListFlow()
+                            .firstOrNull { it.isNotEmpty() }
+                    }
+
+                if (subscriptionInfos.isNullOrEmpty()) {
+                    Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.")
+                    return@withContext
+                }
+                Log.d(
+                    TAG,
+                    "getAvailableRemovableSubscription:$subscriptionInfos"
+                )
+                val psimSubId = subscriptionInfos[0].subscriptionId
+                if (!hasAnyPortActiveInSlot(removableSlotInfo)
+                        || hasOtherActiveSubInfo(psimSubId)) {
+                    Log.d(TAG, "ForNewUi Start Setup flow")
+                    startSimConfirmDialogActivity(psimSubId)
+                }
+            }
+        }
+    }
+
+    private fun handleRemovableSimInsertUnderDsdsMep(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle Removable SIM inserted under DSDS+Mep.")
+
+        if (removableSlotInfo.ports.stream().findFirst().get().isActive) {
+            Log.i(
+                TAG, "The removable slot is already active. Do nothing. removableSlotInfo: "
+                        + removableSlotInfo
+            )
+            return
+        }
+
+        val subscriptionInfos =
+            availableRemovableSubscription
+        if (subscriptionInfos.isEmpty()) {
+            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.")
+            return
+        }
+        Log.d(
+            TAG,
+            "getAvailableRemovableSubscription:$subscriptionInfos"
+        )
+        startSimConfirmDialogActivity(subscriptionInfos[0].subscriptionId)
+    }
+
+    private fun getLastRemovableSimSlotState(context: Context): Int {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        return prefs.getInt(KEY_REMOVABLE_SLOT_STATE, UiccSlotInfo.CARD_STATE_INFO_ABSENT)
+    }
+
+    private fun setRemovableSimSlotState(context: Context, state: Int) {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply()
+        Log.d(TAG, "setRemovableSimSlotState: $state")
+    }
+
+    private fun getSuwRemovableSlotAction(context: Context): Int {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE)
+    }
+
+    private fun setSuwRemovableSlotAction(context: Context, action: Int) {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply()
+    }
+
+    private val removableUiccSlotInfo: UiccSlotInfo?
+        get() {
+            val slotInfos = mTelMgr!!.uiccSlotsInfo
+            if (slotInfos == null) {
+                Log.e(
+                    TAG,
+                    "slotInfos is null. Unable to get slot infos."
+                )
+                return null
+            }
+            for (slotInfo in slotInfos) {
+                if (slotInfo != null && slotInfo.isRemovable) {
+                    return slotInfo
+                }
+            }
+            return null
+        }
+
+    private fun hasActiveEsimSubscription(): Boolean {
+        val activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr)
+        return activeSubs.stream().anyMatch { subscriptionInfo -> subscriptionInfo.isEmbedded }
+    }
+
+    private val groupedEmbeddedSubscriptions: List<SubscriptionInfo>
+        get() {
+            val groupedSubscriptions =
+                SubscriptionUtil.getSelectableSubscriptionInfoList(mContext)
+                    ?: return ImmutableList.of()
+            return ImmutableList.copyOf(
+                groupedSubscriptions.stream()
+                    .filter { sub: SubscriptionInfo -> sub.isEmbedded }
+                    .collect(Collectors.toList()))
+        }
+
+    protected val availableRemovableSubscription: List<SubscriptionInfo>
+        get() {
+            val removableSubscriptions =
+                SubscriptionUtil.getAvailableSubscriptions(mContext)
+            return ImmutableList.copyOf(
+                removableSubscriptions.stream()
+                    // ToDo: This condition is for psim only. If device supports removable
+                    //  esim, it needs an new condition.
+                    .filter { sub: SubscriptionInfo -> !sub.isEmbedded }
+                    .collect(Collectors.toList()))
+        }
+
+    private fun startChooseSimActivity(psimInserted: Boolean) {
+        val intent = ChooseSimActivity.getIntent(mContext)
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startSwitchSlotConfirmDialogActivity(subscriptionInfo: SubscriptionInfo) {
+        val intent = Intent(
+            mContext,
+            SwitchToEsimConfirmDialogActivity::class.java
+        )
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startDsdsDialogActivity() {
+        val intent = Intent(mContext, DsdsDialogActivity::class.java)
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startSimConfirmDialogActivity(subId: Int) {
+        if (!isSuwFinished(mContext!!)) {
+            Log.d(TAG, "Still in SUW. Do nothing")
+            return
+        }
+        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."
+        )
+        SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId, true, true)
+    }
+
+    private val isMultipleEnabledProfilesSupported: Boolean
+        get() {
+            val cardInfos = mTelMgr!!.uiccCardsInfo
+            if (cardInfos == null) {
+                Log.d(
+                    TAG,
+                    "UICC cards info list is empty."
+                )
+                return false
+            }
+            return cardInfos.stream()
+                .anyMatch { cardInfo: UiccCardInfo -> cardInfo.isMultipleEnabledProfilesSupported }
+        }
+
+    private fun isSuwFinished(context: Context): Boolean {
+        try {
+            // DEVICE_PROVISIONED is 0 if still in setup wizard. 1 if setup completed.
+            return (Settings.Global.getInt(
+                    context.contentResolver, Settings.Global.DEVICE_PROVISIONED)
+                    == 1)
+        } catch (e: SettingNotFoundException) {
+            Log.e(TAG, "Cannot get DEVICE_PROVISIONED from the device.", e)
+            return false
+        }
+    }
+
+    companion object {
+        private const val TAG = "SimSlotChangeHandler"
+
+        private const val EUICC_PREFS = "euicc_prefs"
+
+        // Shared preference keys
+        private const val KEY_REMOVABLE_SLOT_STATE = "removable_slot_state"
+        private const val KEY_SUW_PSIM_ACTION = "suw_psim_action"
+
+        // User's last removable SIM insertion / removal action during SUW.
+        private const val LAST_USER_ACTION_IN_SUW_NONE = 0
+        private const val LAST_USER_ACTION_IN_SUW_INSERT = 1
+        private const val LAST_USER_ACTION_IN_SUW_REMOVE = 2
+
+        private const val DEFAULT_WAIT_AFTER_SIM_INSERTED_TIMEOUT_MILLIS: Long = 25 * 1000L
+
+        @Volatile
+        private var slotChangeHandler: SimSlotChangeHandler? = null
+
+        /** Returns a SIM slot change handler singleton.  */
+        @JvmStatic
+        fun get(): SimSlotChangeHandler? {
+            if (slotChangeHandler == null) {
+                synchronized(SimSlotChangeHandler::class.java) {
+                    if (slotChangeHandler == null) {
+                        slotChangeHandler = SimSlotChangeHandler()
+                    }
+                }
+            }
+            return slotChangeHandler
+        }
+    }
+}
