Fixed port index not updated on inactive eSIM

The port index should be set to -1 when an embedded
subscription is inactive.

Also fixed the debug messages in the dump.

Fix: 270177138
Test: Manually activate/deactivate eSIM
Test: atest SubscriptionManagerServiceTest
Change-Id: I8567714c87c8ca6ee313ead2119264c2a038e116
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
index aa3ecf6..263fbe5 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionDatabaseManager.java
@@ -1815,13 +1815,14 @@
      * Load the database from content provider to the cache.
      */
     private void loadDatabaseInternal() {
-        logl("loadDatabaseInternal");
+        log("loadDatabaseInternal");
         try (Cursor cursor = mContext.getContentResolver().query(
                 SimInfo.CONTENT_URI, null, null, null, null)) {
             mReadWriteLock.writeLock().lock();
             try {
                 Map<Integer, SubscriptionInfoInternal> newAllSubscriptionInfoInternalCache =
                         new HashMap<>();
+                boolean changed = false;
                 while (cursor != null && cursor.moveToNext()) {
                     SubscriptionInfoInternal subInfo = createSubscriptionInfoFromCursor(cursor);
                     newAllSubscriptionInfoInternalCache.put(subInfo.getSubscriptionId(), subInfo);
@@ -1829,16 +1830,19 @@
                             .get(subInfo.getSubscriptionId()), subInfo)) {
                         mCallback.invokeFromExecutor(() -> mCallback.onSubscriptionChanged(
                                 subInfo.getSubscriptionId()));
+                        changed = true;
                     }
                 }
 
-                mAllSubscriptionInfoInternalCache.clear();
-                mAllSubscriptionInfoInternalCache.putAll(newAllSubscriptionInfoInternalCache);
+                if (changed) {
+                    mAllSubscriptionInfoInternalCache.clear();
+                    mAllSubscriptionInfoInternalCache.putAll(newAllSubscriptionInfoInternalCache);
 
-                logl("Loaded " + mAllSubscriptionInfoInternalCache.size()
-                        + " records from the subscription database.");
-                mAllSubscriptionInfoInternalCache.forEach(
-                        (subId, subInfo) -> log("  " + subInfo.toString()));
+                    logl("Loaded " + mAllSubscriptionInfoInternalCache.size()
+                            + " records from the subscription database.");
+                    mAllSubscriptionInfoInternalCache.forEach(
+                            (subId, subInfo) -> log("  " + subInfo.toString()));
+                }
             } finally {
                 mReadWriteLock.writeLock().unlock();
             }
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 246446f..6867ed8 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -392,6 +392,7 @@
      * @param looper The looper for the handler.
      */
     public SubscriptionManagerService(@NonNull Context context, @NonNull Looper looper) {
+        logl("Created SubscriptionManagerService");
         sInstance = this;
         mContext = context;
         mTelephonyManager = context.getSystemService(TelephonyManager.class);
@@ -551,16 +552,16 @@
             }
         });
 
+        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
+        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
+
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 updateEmbeddedSubscriptions();
             }
         }, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-
-        SubscriptionManager.invalidateSubscriptionManagerServiceCaches();
-        SubscriptionManager.invalidateSubscriptionManagerServiceEnabledCaches();
-        logl("created");
+        logl("Registered iSub service");
     }
 
     /**
@@ -923,9 +924,11 @@
                 .forEach(subInfo -> {
                     mSubscriptionDatabaseManager.setSimSlotIndex(subInfo.getSubscriptionId(),
                             SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+                    mSubscriptionDatabaseManager.setPortIndex(subInfo.getSubscriptionId(),
+                            TelephonyManager.INVALID_PORT_INDEX);
                 });
         updateGroupDisabled();
-        logl("markSubscriptionsInactive: " + slotMappingToString());
+        logl("markSubscriptionsInactive: current mapping " + slotMappingToString());
     }
 
     /**
@@ -961,17 +964,19 @@
     }
 
     /**
-     * Get the embedded profile port index by ICCID.
+     * Get the port index by ICCID.
      *
      * @param iccId The ICCID.
      * @return The port index.
      */
-    private int getEmbeddedProfilePortIndex(String iccId) {
-        UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
+    private int getPortIndex(@NonNull String iccId) {
+        UiccSlot[] slots = mUiccController.getUiccSlots();
         for (UiccSlot slot : slots) {
-            if (slot != null && slot.isEuicc()
-                    && slot.getPortIndexFromIccId(iccId) != TelephonyManager.INVALID_PORT_INDEX) {
-                return slot.getPortIndexFromIccId(iccId);
+            if (slot != null) {
+                int portIndex = slot.getPortIndexFromIccId(iccId);
+                if (portIndex != TelephonyManager.INVALID_PORT_INDEX) {
+                    return portIndex;
+                }
             }
         }
         return TelephonyManager.INVALID_PORT_INDEX;
@@ -1029,6 +1034,13 @@
 
             Set<Integer> embeddedSubs = new ArraySet<>();
             log("updateEmbeddedSubscriptions: start to get euicc profiles.");
+
+            for (UiccSlot slot : mUiccController.getUiccSlots()) {
+                if (slot != null) {
+                    log("  " + slot.toString());
+                }
+            }
+
             for (int cardId : cardIds) {
                 GetEuiccProfileInfoListResult result = mEuiccController
                         .blockingGetEuiccProfileInfoList(cardId);
@@ -1080,7 +1092,7 @@
                         builder.setDisplayNameSource(SubscriptionManager.NAME_SOURCE_CARRIER);
                     }
                     builder.setProfileClass(embeddedProfile.getProfileClass());
-                    builder.setPortIndex(getEmbeddedProfilePortIndex(embeddedProfile.getIccid()));
+                    builder.setPortIndex(getPortIndex(embeddedProfile.getIccid()));
 
                     CarrierIdentifier cid = embeddedProfile.getCarrierIdentifier();
                     if (cid != null) {
@@ -1221,7 +1233,7 @@
             }
 
             if (mSimState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN) {
-                log("areAllSubscriptionsLoaded: SIM state is still unknown.");
+                log("areAllSubscriptionsLoaded: SIM " + phoneId + " state is still unknown.");
                 return false;
             }
         }
@@ -1230,20 +1242,26 @@
     }
 
     /**
-     * Update the subscriptions on the logical SIM slot index (i.e. phone id).
+     * Update the subscription on the logical SIM slot index (i.e. phone id).
      *
      * @param phoneId The phone id (i.e. Logical SIM slot index)
      */
-    private void updateSubscriptions(int phoneId) {
+    private void updateSubscription(int phoneId) {
         int simState = mSimState[phoneId];
-        log("updateSubscriptions: phoneId=" + phoneId + ", simState="
+        log("updateSubscription: phoneId=" + phoneId + ", simState="
                 + TelephonyManager.simStateToString(simState));
+        for (UiccSlot slot : mUiccController.getUiccSlots()) {
+            if (slot != null) {
+                log("  " + slot.toString());
+            }
+        }
+
         if (simState == TelephonyManager.SIM_STATE_ABSENT) {
             if (mSlotIndexToSubId.containsKey(phoneId)) {
                 int subId = mSlotIndexToSubId.get(phoneId);
                 // Re-enable the SIM when it's removed, so it will be in enabled state when it gets
                 // re-inserted again. (pre-U behavior)
-                log("updateSubscriptions: Re-enable Uicc application on sub " + subId);
+                log("updateSubscription: Re-enable Uicc application on sub " + subId);
                 mSubscriptionDatabaseManager.setUiccApplicationsEnabled(subId, true);
                 // When sim is absent, set the port index to invalid port index. (pre-U behavior)
                 mSubscriptionDatabaseManager.setPortIndex(subId,
@@ -1255,45 +1273,49 @@
             // final state.
             IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
             if (!iccCard.isEmptyProfile() && areUiccAppsEnabledOnCard(phoneId)) {
-                log("updateSubscriptions: SIM_STATE_NOT_READY is not a final state. Will update "
+                log("updateSubscription: SIM_STATE_NOT_READY is not a final state. Will update "
                         + "subscription later.");
                 return;
             }
 
             if (!areUiccAppsEnabledOnCard(phoneId)) {
-                logl("updateSubscriptions: UICC app disabled on slot " + phoneId);
+                logl("updateSubscription: UICC app disabled on slot " + phoneId);
                 markSubscriptionsInactive(phoneId);
             }
         }
 
         String iccId = getIccId(phoneId);
-        log("updateSubscriptions: Found iccId=" + SubscriptionInfo.givePrintableIccid(iccId)
+        log("updateSubscription: Found iccId=" + SubscriptionInfo.givePrintableIccid(iccId)
                 + " on phone " + phoneId);
 
         // For eSIM switching, SIM absent will not happen. Below is to exam if we find ICCID
-        // mismatch on the SIM slot, we need to mark all subscriptions on that logical slot invalid
-        // first. The correct subscription will be assigned the correct slot later.
-        if (mSubscriptionDatabaseManager.getAllSubscriptions().stream()
-                .anyMatch(subInfo -> subInfo.getSimSlotIndex() == phoneId
-                        && !iccId.equals(subInfo.getIccId()))) {
-            log("updateSubscriptions: iccId changed for phone " + phoneId);
+        // mismatch on the SIM slot. If that's the case, we need to mark all subscriptions on that
+        // logical slot invalid first. The correct subscription will be assigned the correct slot
+        // later.
+        SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager.getAllSubscriptions()
+                .stream()
+                .filter(sub -> sub.getSimSlotIndex() == phoneId && !iccId.equals(sub.getIccId()))
+                .findFirst()
+                .orElse(null);
+        if (subInfo != null) {
+            log("updateSubscription: Found previous active sub " + subInfo.getSubscriptionId()
+                    + " that doesn't match current iccid on slot " + phoneId + ".");
             markSubscriptionsInactive(phoneId);
         }
 
         if (!TextUtils.isEmpty(iccId)) {
             // Check if the subscription already existed.
-            SubscriptionInfoInternal subInfo = mSubscriptionDatabaseManager
-                    .getSubscriptionInfoInternalByIccId(iccId);
+            subInfo = mSubscriptionDatabaseManager.getSubscriptionInfoInternalByIccId(iccId);
             int subId;
             if (subInfo == null) {
                 // This is a new SIM card. Insert a new record.
                 subId = insertSubscriptionInfo(iccId, phoneId, null,
                         SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
-                logl("updateSubscriptions: Inserted a new subscription. subId=" + subId
+                logl("updateSubscription: Inserted a new subscription. subId=" + subId
                         + ", phoneId=" + phoneId);
             } else {
                 subId = subInfo.getSubscriptionId();
-                log("updateSubscriptions: Found existing subscription. subId= " + subId
+                log("updateSubscription: Found existing subscription. subId= " + subId
                         + ", phoneId=" + phoneId);
             }
 
@@ -1302,7 +1324,7 @@
                 mSlotIndexToSubId.put(phoneId, subId);
                 // Update the SIM slot index. This will make the subscription active.
                 mSubscriptionDatabaseManager.setSimSlotIndex(subId, phoneId);
-                logl("updateSubscriptions: " + slotMappingToString());
+                logl("updateSubscription: current mapping " + slotMappingToString());
             }
 
             // Update the card id.
@@ -1315,11 +1337,7 @@
             }
 
             // Update the port index.
-            UiccSlot slot = mUiccController.getUiccSlotForPhone(phoneId);
-            if (slot != null && !slot.isEuicc()) {
-                int portIndex = slot.getPortIndexFromIccId(iccId);
-                mSubscriptionDatabaseManager.setPortIndex(subId, portIndex);
-            }
+            mSubscriptionDatabaseManager.setPortIndex(subId, getPortIndex(iccId));
 
             if (simState == TelephonyManager.SIM_STATE_LOADED) {
                 String mccMnc = mTelephonyManager.getSimOperatorNumeric(subId);
@@ -1329,7 +1347,7 @@
                     }
                     setMccMnc(subId, mccMnc);
                 } else {
-                    loge("updateSubscriptions: mcc/mnc is empty");
+                    loge("updateSubscription: mcc/mnc is empty");
                 }
 
                 String iso = TelephonyManager.getSimCountryIsoForPhone(phoneId);
@@ -1337,7 +1355,7 @@
                 if (!TextUtils.isEmpty(iso)) {
                     setCountryIso(subId, iso);
                 } else {
-                    loge("updateSubscriptions: sim country iso is null");
+                    loge("updateSubscription: sim country iso is null");
                 }
 
                 String msisdn = mTelephonyManager.getLine1Number(subId);
@@ -1363,10 +1381,10 @@
                             mSubscriptionDatabaseManager.setHplmns(subId, hplmns);
                         }
                     } else {
-                        loge("updateSubscriptions: ICC records are not available.");
+                        loge("updateSubscription: ICC records are not available.");
                     }
                 } else {
-                    loge("updateSubscriptions: ICC card is not available.");
+                    loge("updateSubscription: ICC card is not available.");
                 }
 
                 // Attempt to restore SIM specific settings when SIM is loaded.
@@ -1374,12 +1392,16 @@
                         SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
                         SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
                         iccId, null);
+                log("Reload the database.");
                 mSubscriptionDatabaseManager.reloadDatabase();
             }
+
+            log("updateSubscription: " + mSubscriptionDatabaseManager
+                    .getSubscriptionInfoInternal(subId));
         } else {
-            log("updateSubscriptions: No ICCID available for phone " + phoneId);
+            log("updateSubscription: No ICCID available for phone " + phoneId);
             mSlotIndexToSubId.remove(phoneId);
-            logl("updateSubscriptions: " + slotMappingToString());
+            logl("updateSubscription: current mapping " + slotMappingToString());
         }
 
         if (areAllSubscriptionsLoaded()) {
@@ -1946,7 +1968,7 @@
                 int subId = insertSubscriptionInfo(iccId, slotIndex, displayName, subscriptionType);
                 updateGroupDisabled();
                 mSlotIndexToSubId.put(slotIndex, subId);
-                logl("addSubInfo: " + slotMappingToString());
+                logl("addSubInfo: current mapping " + slotMappingToString());
             } else {
                 // Record already exists.
                 loge("Subscription record already existed.");
@@ -3741,7 +3763,7 @@
                 // active again. (pre-U behavior)
                 mSubscriptionDatabaseManager.setUiccApplicationsEnabled(
                         mSlotIndexToSubId.get(slotIndex), true);
-                updateSubscriptions(slotIndex);
+                updateSubscription(slotIndex);
             }
         });
     }
@@ -3773,7 +3795,7 @@
                 case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
                 case TelephonyManager.SIM_STATE_LOADED:
                 case TelephonyManager.SIM_STATE_NOT_READY:
-                    updateSubscriptions(slotIndex);
+                    updateSubscription(slotIndex);
                     break;
                 case TelephonyManager.SIM_STATE_CARD_RESTRICTED:
                 default:
@@ -3844,9 +3866,9 @@
      */
     @NonNull
     private String slotMappingToString() {
-        return mSlotIndexToSubId.entrySet().stream()
-                .map(e -> "Slot " + e.getKey() + ": subId=" + e.getValue())
-                .collect(Collectors.joining(", "));
+        return "[" + mSlotIndexToSubId.entrySet().stream()
+                .map(e -> "slot " + e.getKey() + ": subId=" + e.getValue())
+                .collect(Collectors.joining(", ")) + "]";
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/uicc/PinStorage.java b/src/java/com/android/internal/telephony/uicc/PinStorage.java
index 87fb4ab..23769ad 100644
--- a/src/java/com/android/internal/telephony/uicc/PinStorage.java
+++ b/src/java/com/android/internal/telephony/uicc/PinStorage.java
@@ -55,6 +55,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.SimState;
 import android.util.Base64;
+import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
 
 import com.android.internal.R;
@@ -1209,16 +1210,18 @@
         Rlog.e(TAG, msg, tr);
     }
 
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("PinStorage:");
-        pw.println(" mIsDeviceSecure=" + mIsDeviceSecure);
-        pw.println(" mIsDeviceLocked=" + mIsDeviceLocked);
-        pw.println(" isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null));
-        pw.println(" isShortTermSecretKey=" + (boolean) (mShortTermSecretKey != null));
-        pw.println(" isCacheAllowedByDevice=" + isCacheAllowedByDevice());
+        pw.increaseIndent();
+        pw.println("mIsDeviceSecure=" + mIsDeviceSecure);
+        pw.println("mIsDeviceLocked=" + mIsDeviceLocked);
+        pw.println("isLongTermSecretKey=" + (boolean) (mLongTermSecretKey != null));
+        pw.println("isShortTermSecretKey=" + (boolean) (mShortTermSecretKey != null));
+        pw.println("isCacheAllowedByDevice=" + isCacheAllowedByDevice());
         int slotCount = getSlotCount();
         for (int i = 0; i < slotCount; i++) {
-            pw.println(" isCacheAllowedByCarrier[" + i + "]=" + isCacheAllowedByCarrier(i));
+            pw.println("isCacheAllowedByCarrier[" + i + "]=" + isCacheAllowedByCarrier(i));
         }
         if (VDBG) {
             SparseArray<StoredPin> storedPins = loadPinInformation();
@@ -1226,5 +1229,6 @@
                 pw.println(" pin=" + storedPins.valueAt(i).toString());
             }
         }
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 856bc99..6ed3a79 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -21,6 +21,7 @@
 import android.os.Build;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
@@ -213,15 +214,20 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("UiccCard:");
-        pw.println(" mCardState=" + mCardState);
-        pw.println(" mCardId=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mCardId));
-        pw.println(" mNumberOfPorts=" + mUiccPorts.size());
-        pw.println(" mSupportedMepMode=" + mSupportedMepMode);
-        pw.println();
+        pw.increaseIndent();
+        pw.println("mCardState=" + mCardState);
+        pw.println("mCardId=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mCardId));
+        pw.println("mNumberOfPorts=" + mUiccPorts.size());
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
+        pw.println("mUiccPorts= size=" + mUiccPorts.size());
+        pw.increaseIndent();
         for (UiccPort uiccPort : mUiccPorts.values()) {
             uiccPort.dump(fd, pw, args);
         }
+        pw.decreaseIndent();
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 9454ade..08573b9 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -24,6 +24,7 @@
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
@@ -984,40 +985,27 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccCardApplication: " + this);
-        pw.println(" mUiccProfile=" + mUiccProfile);
-        pw.println(" mAppState=" + mAppState);
-        pw.println(" mAppType=" + mAppType);
-        pw.println(" mPersoSubState=" + mPersoSubState);
-        pw.println(" mAid=" + mAid);
-        pw.println(" mAppLabel=" + mAppLabel);
-        pw.println(" mPin1Replaced=" + mPin1Replaced);
-        pw.println(" mPin1State=" + mPin1State);
-        pw.println(" mPin2State=" + mPin2State);
-        pw.println(" mIccFdnEnabled=" + mIccFdnEnabled);
-        pw.println(" mDesiredFdnEnabled=" + mDesiredFdnEnabled);
-        pw.println(" mIccLockEnabled=" + mIccLockEnabled);
-        pw.println(" mDesiredPinLocked=" + mDesiredPinLocked);
-        pw.println(" mCi=" + mCi);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mIccFh=" + mIccFh);
-        pw.println(" mDestroyed=" + mDestroyed);
-        pw.println(" mReadyRegistrants: size=" + mReadyRegistrants.size());
-        for (int i = 0; i < mReadyRegistrants.size(); i++) {
-            pw.println("  mReadyRegistrants[" + i + "]="
-                    + ((Registrant)mReadyRegistrants.get(i)).getHandler());
-        }
-        pw.println(" mPinLockedRegistrants: size=" + mPinLockedRegistrants.size());
-        for (int i = 0; i < mPinLockedRegistrants.size(); i++) {
-            pw.println("  mPinLockedRegistrants[" + i + "]="
-                    + ((Registrant)mPinLockedRegistrants.get(i)).getHandler());
-        }
-        pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
-        for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
-            pw.println("  mNetworkLockedRegistrants[" + i + "]="
-                    + ((Registrant)mNetworkLockedRegistrants.get(i)).getHandler());
-        }
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UiccCardApplication: ");
+        pw.increaseIndent();
+        pw.println("mUiccProfile=" + mUiccProfile);
+        pw.println("mAppState=" + mAppState);
+        pw.println("mAppType=" + mAppType);
+        pw.println("mPersoSubState=" + mPersoSubState);
+        pw.println("mAid=" + mAid);
+        pw.println("mAppLabel=" + mAppLabel);
+        pw.println("mPin1Replaced=" + mPin1Replaced);
+        pw.println("mPin1State=" + mPin1State);
+        pw.println("mPin2State=" + mPin2State);
+        pw.println("mIccFdnEnabled=" + mIccFdnEnabled);
+        pw.println("mDesiredFdnEnabled=" + mDesiredFdnEnabled);
+        pw.println("mIccLockEnabled=" + mIccLockEnabled);
+        pw.println("mDesiredPinLocked=" + mDesiredPinLocked);
+        pw.println("mIccRecords=" + mIccRecords);
+        pw.println("mIccFh=" + mIccFh);
+        pw.println("mDestroyed=" + mDestroyed);
+        pw.decreaseIndent();
         pw.flush();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 0c88e0b..596ccf6 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -28,6 +28,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -693,16 +694,20 @@
     /**
      * Dumps info to Dumpsys - useful for debugging.
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccCarrierPrivilegeRules: " + this);
-        pw.println(" mState=" + getStateString(mState.get()));
-        pw.println(" mStatusMessage=");
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UiccCarrierPrivilegeRules:");
+        pw.increaseIndent();
+        pw.println("mState=" + getStateString(mState.get()));
+        pw.println("mStatusMessage=");
         mStatusMessage.dump(fd, pw, args);
         if (mAccessRules != null) {
-            pw.println(" mAccessRules: ");
+            pw.println("mAccessRules: ");
+            pw.increaseIndent();
             for (UiccAccessRule ar : mAccessRules) {
                 pw.println("  rule='" + ar + "'");
             }
+            pw.decreaseIndent();
         } else {
             pw.println(" mAccessRules: null");
         }
@@ -712,6 +717,7 @@
         } else {
             pw.println(" mUiccPkcs15: null");
         }
+        pw.decreaseIndent();
         pw.flush();
     }
 
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 98c22a5..93ae883 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -34,7 +34,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.os.Registrant;
 import android.os.RegistrantList;
 import android.preference.PreferenceManager;
 import android.sysprop.TelephonyProperties;
@@ -49,6 +48,7 @@
 import android.telephony.UiccSlotMapping;
 import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
 import android.util.Log;
 
@@ -1802,35 +1802,32 @@
         return mCardStrings;
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccController: " + this);
-        pw.println(" mContext=" + mContext);
-        pw.println(" mInstance=" + mInstance);
-        pw.println(" mIccChangedRegistrants: size=" + mIccChangedRegistrants.size());
-        for (int i = 0; i < mIccChangedRegistrants.size(); i++) {
-            pw.println("  mIccChangedRegistrants[" + i + "]="
-                    + ((Registrant)mIccChangedRegistrants.get(i)).getHandler());
-        }
-        pw.println();
-        pw.flush();
-        pw.println(" mIsCdmaSupported=" + isCdmaSupported(mContext));
-        pw.println(" mHasBuiltInEuicc=" + mHasBuiltInEuicc);
-        pw.println(" mHasActiveBuiltInEuicc=" + mHasActiveBuiltInEuicc);
-        pw.println(" mCardStrings=" + getPrintableCardStrings());
-        pw.println(" mDefaultEuiccCardId=" + mDefaultEuiccCardId);
-        pw.println(" mPhoneIdToSlotId=" + Arrays.toString(mPhoneIdToSlotId));
-        pw.println(" mUseRemovableEsimAsDefault=" + mUseRemovableEsimAsDefault);
-        pw.println(" mUiccSlots: size=" + mUiccSlots.length);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("mIsCdmaSupported=" + isCdmaSupported(mContext));
+        pw.println("mHasBuiltInEuicc=" + mHasBuiltInEuicc);
+        pw.println("mHasActiveBuiltInEuicc=" + mHasActiveBuiltInEuicc);
+        pw.println("mCardStrings=" + getPrintableCardStrings());
+        pw.println("mDefaultEuiccCardId=" + mDefaultEuiccCardId);
+        pw.println("mPhoneIdToSlotId=" + Arrays.toString(mPhoneIdToSlotId));
+        pw.println("mUseRemovableEsimAsDefault=" + mUseRemovableEsimAsDefault);
+        pw.println("mUiccSlots: size=" + mUiccSlots.length);
+        pw.increaseIndent();
         for (int i = 0; i < mUiccSlots.length; i++) {
             if (mUiccSlots[i] == null) {
-                pw.println("  mUiccSlots[" + i + "]=null");
+                pw.println("mUiccSlots[" + i + "]=null");
             } else {
-                pw.println("  mUiccSlots[" + i + "]=" + mUiccSlots[i]);
+                pw.println("mUiccSlots[" + i + "]:");
+                pw.increaseIndent();
                 mUiccSlots[i].dump(fd, pw, args);
+                pw.decreaseIndent();
             }
         }
-        pw.println(" sLocalLog= ");
-        sLocalLog.dump(fd, pw, args);
+        pw.decreaseIndent();
+        pw.println();
+        pw.println("sLocalLog= ");
+        pw.increaseIndent();
         mPinStorage.dump(fd, pw, args);
+        sLocalLog.dump(fd, pw, args);
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPort.java b/src/java/com/android/internal/telephony/uicc/UiccPort.java
index 1f22aa1..fc33c6e 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPort.java
@@ -22,6 +22,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.SubscriptionInfo;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -358,18 +359,19 @@
         Rlog.e(LOG_TAG, msg);
     }
 
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("UiccPort:");
-        pw.println(" this=" + this);
-        pw.println(" mPortIdx=" + mPortIdx);
-        pw.println(" mCi=" + mCi);
-        pw.println(" mIccid=" + SubscriptionInfo.givePrintableIccid(mIccid));
-        pw.println(" mPhoneId=" + mPhoneId);
-        pw.println(" mPhysicalSlotIndex=" + mPhysicalSlotIndex);
+        pw.increaseIndent();
+        pw.println("mPortIdx=" + mPortIdx);
+        pw.println("mCi=" + mCi);
+        pw.println("mIccid=" + SubscriptionInfo.givePrintableIccid(mIccid));
+        pw.println("mPhoneId=" + mPhoneId);
+        pw.println("mPhysicalSlotIndex=" + mPhysicalSlotIndex);
         synchronized (mOpenChannelRecords) {
-            pw.println(" mOpenChannelRecords=" + mOpenChannelRecords);
+            pw.println("mOpenChannelRecords=" + mOpenChannelRecords);
         }
-        pw.println();
+        pw.println("mUiccProfile");
         if (mUiccProfile != null) {
             mUiccProfile.dump(fd, pw, args);
         }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index e4a9b5c..d2f9b39 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -51,6 +51,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CarrierAppUtils;
@@ -1879,27 +1880,29 @@
     /**
      * Dump
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccProfile:");
-        pw.println(" mCi=" + mCi);
-        pw.println(" mCatService=" + mCatService);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.increaseIndent();
+        pw.println("mCatService=" + mCatService);
         for (int i = 0; i < mOperatorBrandOverrideRegistrants.size(); i++) {
-            pw.println("  mOperatorBrandOverrideRegistrants[" + i + "]="
+            pw.println("mOperatorBrandOverrideRegistrants[" + i + "]="
                     + ((Registrant) mOperatorBrandOverrideRegistrants.get(i)).getHandler());
         }
-        pw.println(" mUniversalPinState=" + mUniversalPinState);
-        pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
-        pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
-        pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
-        pw.println(" mUiccApplications: length=" + mUiccApplications.length);
+        pw.println("mUniversalPinState=" + mUniversalPinState);
+        pw.println("mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
+        pw.println("mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
+        pw.println("mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
+        pw.println("mUiccApplications: length=" + mUiccApplications.length);
+        pw.increaseIndent();
         for (int i = 0; i < mUiccApplications.length; i++) {
             if (mUiccApplications[i] == null) {
-                pw.println("  mUiccApplications[" + i + "]=" + null);
+                pw.println("mUiccApplications[" + i + "]=" + null);
             } else {
-                pw.println("  mUiccApplications[" + i + "]="
+                pw.println("mUiccApplications[" + i + "]="
                         + mUiccApplications[i].getType() + " " + mUiccApplications[i]);
             }
         }
+        pw.decreaseIndent();
         pw.println();
         // Print details of all applications
         for (UiccCardApplication app : mUiccApplications) {
@@ -1920,28 +1923,31 @@
         }
         // Print UiccCarrierPrivilegeRules and registrants.
         if (mCarrierPrivilegeRules == null) {
-            pw.println(" mCarrierPrivilegeRules: null");
+            pw.println("mCarrierPrivilegeRules: null");
         } else {
-            pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules);
+            pw.println("mCarrierPrivilegeRules: ");
+            pw.increaseIndent();
             mCarrierPrivilegeRules.dump(fd, pw, args);
+            pw.decreaseIndent();
         }
         if (mTestOverrideCarrierPrivilegeRules != null) {
-            pw.println(" mTestOverrideCarrierPrivilegeRules: "
+            pw.println("mTestOverrideCarrierPrivilegeRules: "
                     + mTestOverrideCarrierPrivilegeRules);
             mTestOverrideCarrierPrivilegeRules.dump(fd, pw, args);
         }
         pw.flush();
 
-        pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
+        pw.println("mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
         for (int i = 0; i < mNetworkLockedRegistrants.size(); i++) {
             pw.println("  mNetworkLockedRegistrants[" + i + "]="
                     + ((Registrant) mNetworkLockedRegistrants.get(i)).getHandler());
         }
-        pw.println(" mCurrentAppType=" + mCurrentAppType);
-        pw.println(" mUiccCard=" + mUiccCard);
-        pw.println(" mUiccApplication=" + mUiccApplication);
-        pw.println(" mIccRecords=" + mIccRecords);
-        pw.println(" mExternalState=" + mExternalState);
+        pw.println("mCurrentAppType=" + mCurrentAppType);
+        pw.println("mUiccCard=" + mUiccCard);
+        pw.println("mUiccApplication=" + mUiccApplication);
+        pw.println("mIccRecords=" + mIccRecords);
+        pw.println("mExternalState=" + mExternalState);
+        pw.decreaseIndent();
         pw.flush();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 94d3fda..d299908 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -33,6 +33,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.view.WindowManager;
 
@@ -673,26 +674,34 @@
     /**
      * Dump
      */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccSlot:");
-        pw.println(" mActive=" + mActive);
-        pw.println(" mIsEuicc=" + mIsEuicc);
-        pw.println(" isEuiccSupportsMultipleEnabledProfiles="
-                + isMultipleEnabledProfileSupported());
-        pw.println(" mIsRemovable=" + mIsRemovable);
-        pw.println(" mLastRadioState=" + mLastRadioState);
-        pw.println(" mIccIds=" + getPrintableIccIds());
-        pw.println(" mPortIdxToPhoneId=" + mPortIdxToPhoneId);
-        pw.println(" mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid));
-        pw.println(" mCardState=" + mCardState);
-        pw.println(" mSupportedMepMode=" + mSupportedMepMode);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("mActive=" + mActive);
+        pw.println("mIsEuicc=" + mIsEuicc);
+        pw.println("isEuiccSupportsMultipleEnabledProfiles=" + isMultipleEnabledProfileSupported());
+        pw.println("mIsRemovable=" + mIsRemovable);
+        pw.println("mLastRadioState=" + mLastRadioState);
+        pw.println("mIccIds=" + getPrintableIccIds());
+        pw.println("mPortIdxToPhoneId=" + mPortIdxToPhoneId);
+        pw.println("mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid));
+        pw.println("mCardState=" + mCardState);
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
         if (mUiccCard != null) {
-            pw.println(" mUiccCard=" + mUiccCard);
+            pw.println("mUiccCard=");
             mUiccCard.dump(fd, pw, args);
         } else {
-            pw.println(" mUiccCard=null");
+            pw.println("mUiccCard=null");
         }
         pw.println();
         pw.flush();
     }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "[UiccSlot: mActive=" + mActive + ", mIccId=" + getPrintableIccIds() + ", mIsEuicc="
+                + mIsEuicc + ", MEP=" + isMultipleEnabledProfileSupported() + ", mPortIdxToPhoneId="
+                + mPortIdxToPhoneId + ", mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid)
+                + ", mCardState=" + mCardState + " mSupportedMepMode=" + mSupportedMepMode + "]";
+    }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
index 8dbbe66..698fbc8 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc.euicc;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -23,6 +24,7 @@
 import android.os.RegistrantList;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
@@ -176,10 +178,14 @@
         }
     }
 
+    @NonNull
     @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        super.dump(fd, printWriter, args);
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("EuiccCard:");
-        pw.println(" mEid=" + mEid);
+        pw.increaseIndent();
+        pw.println("mEid=" + mEid);
+        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
index 8dca5f4..4c86373 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
@@ -28,6 +28,7 @@
 import android.telephony.euicc.EuiccNotification;
 import android.telephony.euicc.EuiccRulesAuthTable;
 import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
@@ -1423,10 +1424,13 @@
     }
 
     @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        super.dump(fd, printWriter, args);
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("EuiccPort:");
-        pw.println(" mEid=" + mEid);
-        pw.println(" mSupportedMepMode=" + mSupportedMepMode);
+        pw.increaseIndent();
+        pw.println("mEid=" + mEid);
+        pw.println("mSupportedMepMode=" + mSupportedMepMode);
+        pw.decreaseIndent();
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
index 16c09fa..765a62e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.subscription;
 
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_ID1;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_ID2;
 import static com.android.internal.telephony.subscription.SubscriptionDatabaseManagerTest.FAKE_CARRIER_NAME1;
@@ -92,6 +91,8 @@
 import android.util.Base64;
 
 import com.android.internal.telephony.ContextFixture;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyTest;
@@ -114,6 +115,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.Arrays;
@@ -149,6 +151,14 @@
         logd("SubscriptionManagerServiceTest +Setup!");
         super.setUp(getClass().getSimpleName());
         enableSubscriptionManagerService(true);
+
+        // Dual-SIM configuration
+        mPhones = new Phone[] {mPhone, mPhone2};
+        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
+        doReturn(2).when(mTelephonyManager).getSupportedModemCount();
+        doReturn(mUiccProfile).when(mPhone2).getIccCard();
+
         mContextFixture.putBooleanResource(com.android.internal.R.bool
                 .config_subscription_database_async_update, true);
         mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[0]);
@@ -182,8 +192,6 @@
         }).when(mMockedSubscriptionManagerServiceCallback).invokeFromExecutor(any(Runnable.class));
 
         mSubscriptionManagerServiceUT.registerCallback(mMockedSubscriptionManagerServiceCallback);
-        // Database loading is on a different thread. Need to wait a bit.
-        waitForMs(100);
         processAllFutureMessages();
 
         // Revoke all permissions.
@@ -227,7 +235,8 @@
     }
 
     /**
-     * Insert the subscription info to the database.
+     * Insert the subscription info to the database. This is an instant insertion method. For real
+     * insertion sequence please use {@link #testInsertNewSim()}.
      *
      * @param subInfo The subscription to be inserted.
      * @return The new sub id.
@@ -251,9 +260,13 @@
             cArgs[0] = Object.class;
             cArgs[1] = Object.class;
 
-            Method method = WatchedMapClass.getDeclaredMethod("put", cArgs);
-            method.setAccessible(true);
-            method.invoke(map, subInfo.getSimSlotIndex(), subId);
+            if (subInfo.getSimSlotIndex() >= 0) {
+                // Change the slot -> subId mapping
+                Method method = WatchedMapClass.getDeclaredMethod("put", cArgs);
+                method.setAccessible(true);
+                method.invoke(map, subInfo.getSimSlotIndex(), subId);
+            }
+
             mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
             processAllMessages();
             verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(subId));
@@ -261,6 +274,12 @@
 
             if (subInfo.getSimSlotIndex() >= 0) {
                 mActiveSubs.add(subId);
+
+                // Change the SIM state
+                field = SubscriptionManagerService.class.getDeclaredField("mSimState");
+                field.setAccessible(true);
+                Object array = field.get(mSubscriptionManagerServiceUT);
+                Array.set(array, subInfo.getSimSlotIndex(), TelephonyManager.SIM_STATE_LOADED);
             } else {
                 mActiveSubs.remove(subId);
             }
@@ -763,6 +782,8 @@
         doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(2));
         doReturn(FAKE_ICCID1).when(mUiccController).convertToCardString(eq(1));
         doReturn(FAKE_ICCID2).when(mUiccController).convertToCardString(eq(2));
+        doReturn(TelephonyManager.INVALID_PORT_INDEX).when(mUiccSlot)
+                .getPortIndexFromIccId(anyString());
 
         mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1, 2), null);
         processAllMessages();
@@ -771,6 +792,7 @@
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -786,6 +808,7 @@
         subInfo = mSubscriptionManagerServiceUT.getSubscriptionInfoInternal(2);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(2);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID2);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME2);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -942,7 +965,6 @@
         assertThrows(IllegalArgumentException.class, () -> mSubscriptionManagerServiceUT
                 .getEnabledSubscriptionId(SubscriptionManager.INVALID_SIM_SLOT_INDEX));
 
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
         assertThat(mSubscriptionManagerServiceUT.getEnabledSubscriptionId(0)).isEqualTo(1);
         assertThat(mSubscriptionManagerServiceUT.getEnabledSubscriptionId(1)).isEqualTo(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
@@ -1715,6 +1737,8 @@
         doReturn(true).when(mUiccSlot).isEuicc();
         doReturn(1).when(mUiccController).convertToPublicCardId(FAKE_ICCID1);
         doReturn(new UiccSlot[]{mUiccSlot}).when(mUiccController).getUiccSlots();
+        doReturn(TelephonyManager.INVALID_PORT_INDEX).when(mUiccSlot)
+                .getPortIndexFromIccId(anyString());
 
         EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
                 .setIccid(FAKE_ICCID1)
@@ -1740,6 +1764,7 @@
                 .getSubscriptionInfoInternal(1);
         assertThat(subInfo.getSubscriptionId()).isEqualTo(1);
         assertThat(subInfo.getSimSlotIndex()).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
         assertThat(subInfo.getIccId()).isEqualTo(FAKE_ICCID1);
         assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1);
         assertThat(subInfo.getDisplayNameSource()).isEqualTo(
@@ -1836,9 +1861,12 @@
 
     @Test
     public void testDeleteEsim() {
-        // pSIM
-        insertSubscription(FAKE_SUBSCRIPTION_INFO2);
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
+        // pSIM with ICCID2
+        insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2)
+                .setSimSlotIndex(0).build());
 
+        // eSIM with ICCID1
         EuiccProfileInfo profileInfo1 = new EuiccProfileInfo.Builder(FAKE_ICCID1)
                 .setIccid(FAKE_ICCID1)
                 .setNickname(FAKE_CARRIER_NAME1)
@@ -1857,6 +1885,13 @@
         mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
         processAllMessages();
 
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_READY, null, null);
+
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_LOADED, null, null);
+        processAllMessages();
+
         // Now we should have two subscriptions in the database. One for pSIM, one for eSIM.
         assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1).isEmbedded()).isFalse();
         assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isEmbedded()).isTrue();
@@ -1865,14 +1900,20 @@
         result = new GetEuiccProfileInfoListResult(
                 EuiccService.RESULT_OK, new EuiccProfileInfo[0], false);
         doReturn(result).when(mEuiccController).blockingGetEuiccProfileInfoList(eq(1));
+        doReturn("").when(mUiccPort).getIccId();
 
         mSubscriptionManagerServiceUT.updateEmbeddedSubscriptions(List.of(1), null);
+        mSubscriptionManagerServiceUT.updateSimState(
+                1, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+
         processAllMessages();
 
         // The original pSIM is still pSIM
         assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(1).isEmbedded()).isFalse();
         // The original eSIM becomes removed pSIM ¯\_(ツ)_/¯
         assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).isEmbedded()).isFalse();
+        assertThat(mSubscriptionManagerServiceUT.getSubscriptionInfo(2).getPortIndex())
+                .isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
     }
 
     @Test
@@ -1914,7 +1955,14 @@
 
         assertThat(subInfoList).hasSize(1);
         assertThat(subInfoList.get(0).isActive()).isTrue();
+        assertThat(subInfoList.get(0).getSubscriptionId()).isEqualTo(2);
         assertThat(subInfoList.get(0).getIccId()).isEqualTo(FAKE_ICCID2);
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.getSimSlotIndex()).isEqualTo(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        assertThat(subInfo.getPortIndex()).isEqualTo(TelephonyManager.INVALID_PORT_INDEX);
     }
 
     @Test
@@ -1965,4 +2013,22 @@
         processAllMessages();
         assertThat(latch.getCount()).isEqualTo(0);
     }
+
+    @Test
+    public void testDeactivatePsim() {
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        testInsertNewSim();
+
+        mSubscriptionManagerServiceUT.setUiccApplicationsEnabled(false, 1);
+        mSubscriptionManagerServiceUT.updateSimState(
+                0, TelephonyManager.SIM_STATE_NOT_READY, null, null);
+
+        processAllMessages();
+        assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty();
+
+        SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT
+                .getSubscriptionInfoInternal(1);
+        assertThat(subInfo.isActive()).isFalse();
+        assertThat(subInfo.areUiccApplicationsEnabled()).isFalse();
+    }
 }