Add CARD_ID in SubscriptionInfo database

Test: Basic telephony sanity
Bug: 64131518
Change-Id: I5771ab704830d060141e8346f698c6aa532083a8
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 2629b42..74f7541 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -46,6 +46,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.uicc.UiccController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -317,6 +319,8 @@
                 SubscriptionManager.MCC));
         int mnc = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.MNC));
+        String cardId = cursor.getString(cursor.getColumnIndexOrThrow(
+                SubscriptionManager.CARD_ID));
         // FIXME: consider stick this into database too
         String countryIso = getSubscriptionCountryIso(id);
         boolean isEmbedded = cursor.getInt(cursor.getColumnIndexOrThrow(
@@ -331,11 +335,13 @@
 
         if (VDBG) {
             String iccIdToPrint = SubscriptionInfo.givePrintableIccid(iccId);
+            String cardIdToPrint = SubscriptionInfo.givePrintableIccid(cardId);
             logd("[getSubInfoRecord] id:" + id + " iccid:" + iccIdToPrint + " simSlotIndex:"
                     + simSlotIndex + " displayName:" + displayName + " nameSource:" + nameSource
                     + " iconTint:" + iconTint + " dataRoaming:" + dataRoaming
                     + " mcc:" + mcc + " mnc:" + mnc + " countIso:" + countryIso + " isEmbedded:"
-                    + isEmbedded + " accessRules:" + Arrays.toString(accessRules));
+                    + isEmbedded + " accessRules:" + Arrays.toString(accessRules)
+                    + " cardId:" + cardIdToPrint);
         }
 
         // If line1number has been set to a different number, use it instead.
@@ -345,7 +351,7 @@
         }
         return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
                 nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
-                isEmbedded, accessRules);
+                isEmbedded, accessRules, cardId);
     }
 
     /**
@@ -911,7 +917,7 @@
             Cursor cursor = resolver.query(SubscriptionManager.CONTENT_URI,
                     new String[]{SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
                             SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.NAME_SOURCE,
-                            SubscriptionManager.ICC_ID},
+                            SubscriptionManager.ICC_ID, SubscriptionManager.CARD_ID},
                     SubscriptionManager.ICC_ID + "=?" + " OR " + SubscriptionManager.ICC_ID + "=?",
                             new String[]{iccId, IccUtils.getDecimalSubstring(iccId)}, null);
 
@@ -926,6 +932,7 @@
                     int oldSimInfoId = cursor.getInt(1);
                     int nameSource = cursor.getInt(2);
                     String oldIccId = cursor.getString(3);
+                    String oldCardId = cursor.getString(4);
                     ContentValues value = new ContentValues();
 
                     if (slotIndex != oldSimInfoId) {
@@ -941,6 +948,14 @@
                         value.put(SubscriptionManager.ICC_ID, iccId);
                     }
 
+                    UiccCard card = UiccController.getInstance().getUiccCardForPhone(slotIndex);
+                    if (card != null) {
+                        String cardId = card.getCardId();
+                        if (cardId != null && cardId != oldCardId) {
+                            value.put(SubscriptionManager.CARD_ID, cardId);
+                        }
+                    }
+
                     if (value.size() > 0) {
                         resolver.update(SubscriptionManager.CONTENT_URI, value,
                                 SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID +
@@ -1076,6 +1091,17 @@
         value.put(SubscriptionManager.COLOR, color);
         value.put(SubscriptionManager.SIM_SLOT_INDEX, slotIndex);
         value.put(SubscriptionManager.CARRIER_NAME, "");
+        UiccCard card = UiccController.getInstance().getUiccCardForPhone(slotIndex);
+        if (card != null) {
+            String cardId = card.getCardId();
+            if (cardId != null) {
+                value.put(SubscriptionManager.CARD_ID, cardId);
+            } else {
+                value.put(SubscriptionManager.CARD_ID, iccId);
+            }
+        } else {
+            value.put(SubscriptionManager.CARD_ID, iccId);
+        }
 
         Uri uri = resolver.insert(SubscriptionManager.CONTENT_URI, value);
 
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 6d6a882..4a14002 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -51,6 +51,7 @@
     private final Object mLock = new Object();
     private CardState mCardState;
     private String mIccid;
+    protected String mCardId;
     private UiccProfile mUiccProfile;
     private Context mContext;
     private CommandsInterface mCi;
@@ -81,6 +82,8 @@
             mContext = c;
             mCi = ci;
             mIccid = ics.iccid;
+            updateCardId();
+
 
             if (mCardState != CardState.CARDSTATE_ABSENT) {
                 if (mUiccProfile == null) {
@@ -100,6 +103,18 @@
     }
 
     /**
+     * Updates the ID of the SIM card.
+     *
+     * <p>Whenever the {@link UiccCard#update(Context, CommandsInterface, IccCardStatus)} is called,
+     * this function needs to be called to update the card ID. Subclasses of {@link UiccCard}
+     * could override this function to set the {@link UiccCard#mCardId} to be something else instead
+     * of {@link UiccCard#mIccid}.</p>
+     */
+    protected void updateCardId() {
+        mCardId = mIccid;
+    }
+
+    /**
      * Notifies handler when carrier privilege rules are loaded.
      * @deprecated Please use
      * {@link UiccProfile#registerForCarrierPrivilegeRulesLoaded(Handler, int, Object)} instead.
@@ -465,6 +480,20 @@
         }
     }
 
+    /**
+     * Returns the ID of this SIM card, it is the ICCID of the active profile on the card for a UICC
+     * card or the EID of the card for an eUICC card.
+     */
+    public String getCardId() {
+        if (mCardId != null) {
+            return mCardId;
+        } else if (mUiccProfile != null) {
+            return mUiccProfile.getIccId();
+        } else {
+            return null;
+        }
+    }
+
     private void log(String msg) {
         Rlog.d(LOG_TAG, msg);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 4ec7daf..ef9f7d4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -76,7 +76,8 @@
                 SubscriptionManager.ACCESS_RULES, SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
                 SubscriptionManager.VT_IMS_ENABLED, SubscriptionManager.WFC_IMS_ENABLED,
                 SubscriptionManager.WFC_IMS_MODE, SubscriptionManager.WFC_IMS_ROAMING_MODE,
-                SubscriptionManager.WFC_IMS_ROAMING_ENABLED};
+                SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
+                SubscriptionManager.CARD_ID};
 
         /* internal util function */
         private MatrixCursor convertFromContentToCursor(ContentValues initialValues,