[MEP] disable enabled esim profile before set simSlotMapping

This is the modem request to disable enabled esim profile before
set simSlotMapping.
Since the framework still do API refactor ag/16494924. The
switchToSub API will be changed, so here modify two callback.
the one of callback will be removed after the framework complete
the API refactor.

Bug: 210063749
Test: Build pass. Local test: do sim switch in SS mode and DSDS mode.
Change-Id: Iee650897b81c96b5febb0413649629b1a1971b18
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index d88a189..9b0105b 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -20,6 +20,7 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotMapping;
 import android.telephony.euicc.EuiccManager;
@@ -34,7 +35,7 @@
 
 /** A headless fragment encapsulating long-running eSIM enabling/disabling operations. */
 public class SwitchToEuiccSubscriptionSidecar extends EuiccOperationSidecar {
-    private static final String TAG = "SwitchToEuiccSubscriptionSidecar";
+    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;
@@ -42,6 +43,8 @@
     private PendingIntent mCallbackIntent;
     private int mSubId;
     private int mPort;
+    private SubscriptionInfo mRemovedSubInfo;
+    private boolean mIsDuringSimSlotMapping;
 
     /** Returns a SwitchToEuiccSubscriptionSidecar sidecar instance. */
     public static SwitchToEuiccSubscriptionSidecar get(FragmentManager fm) {
@@ -93,9 +96,34 @@
         // 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;
-        Log.i(TAG, "The SubId is " + mSubId + "The port is " + mPort);
+        mRemovedSubInfo = removedSubInfo;
+        Log.i(TAG, "The SubId is " + mSubId + ". The port is " + mPort);
 
-        mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, removedSubInfo);
+        if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null
+                && removedSubInfo.isEmbedded()) {
+            // In DSDS mode+MEP, if the replaced esim is active, then it should be disabled esim
+            // profile before changing SimSlotMapping process.
+            // Use INVALID_SUBSCRIPTION_ID to disable the esim profile.
+            // The SimSlotMapping is ready, then to execute activate/inactivate esim.
+            mIsDuringSimSlotMapping = true;
+            EuiccManager.ResultListener callback = new EuiccManager.ResultListener() {
+                @Override
+                public void onComplete(int resultCode, Intent resultIntent) {
+                    Log.i(TAG, String.format("Result code : %d;", resultCode));
+                    if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                        mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort,
+                                removedSubInfo);
+                    } else {
+                        setState(State.ERROR, resultCode);
+                    }
+                }
+            };
+            mEuiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mPort,
+                    getContext().getMainExecutor(),
+                    callback);
+        } else {
+            mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, removedSubInfo);
+        }
     }
 
     private int getTargetPortId(SubscriptionInfo removedSubInfo) {
@@ -136,8 +164,7 @@
         switch (mSwitchSlotSidecar.getState()) {
             case State.SUCCESS:
                 mSwitchSlotSidecar.reset();
-                Log.i(TAG,
-                        "Successfully SimSlotMapping. Start to enable/disable esim");
+                Log.i(TAG, "Successfully SimSlotMapping. Start to enable/disable esim");
                 switchToSubscription();
                 break;
             case State.ERROR:
@@ -174,4 +201,16 @@
         mEuiccManager.switchToSubscription(mSubId, mPort, getContext().getMainExecutor(),
                 callback);
     }
+
+    @Override
+    protected void onActionReceived() {
+        if (getResultCode() == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK
+                && mIsDuringSimSlotMapping) {
+            // Continue to switch the SimSlotMapping, after the esim is disabled.
+            mIsDuringSimSlotMapping = false;
+            mSwitchSlotSidecar.runSwitchToEuiccSlot(getTargetSlot(), mPort, mRemovedSubInfo);
+        } else {
+            super.onActionReceived();
+        }
+    }
 }
diff --git a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
index 2c184c6..9b9c0dd 100644
--- a/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
+++ b/src/com/android/settings/network/SwitchToRemovableSlotSidecar.java
@@ -31,8 +31,7 @@
  */
 public class SwitchToRemovableSlotSidecar extends EuiccOperationSidecar
         implements SidecarFragment.Listener {
-
-    private static final String TAG = "DisableSubscriptionAndSwitchSlotSidecar";
+    private static final String TAG = "SwitchRemovableSidecar";
     private static final String ACTION_DISABLE_SUBSCRIPTION_AND_SWITCH_SLOT =
             "disable_subscription_and_switch_slot_sidecar";
 
@@ -115,9 +114,25 @@
     public void run(int physicalSlotId, SubscriptionInfo removedSubInfo) {
         mPhysicalSlotId = physicalSlotId;
         mRemovedSubInfo = removedSubInfo;
-
-        Log.i(TAG, "Start to switch to removable slot.");
-        mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, mRemovedSubInfo);
+        SubscriptionManager subscriptionManager =
+                getContext().getSystemService(SubscriptionManager.class);
+        if (!mTelephonyManager.isMultiSimEnabled()
+                && 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 if (mTelephonyManager.isMultiSimEnabled() && mRemovedSubInfo != null) {
+            // In DSDS mode+MEP, if the replaced esim is active, then it should be disabled esim
+            // profile before changing SimSlotMapping process.
+            // Use INVALID_SUBSCRIPTION_ID to disable the esim profile.
+            mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                    mRemovedSubInfo.getPortIndex(), null);
+        } else {
+            Log.i(TAG, "Start to switch to removable slot.");
+            mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId, mRemovedSubInfo);
+        }
     }
 
     private void onSwitchToSubscriptionSidecarStateChange() {