Merge changes from topics "MEP_Integrate_AIDL_SlotStatus", "telephonyApiForMep"

* changes:
  [MEP] Refactor PhoneInterfaceManager to integrate with latest MEP platform changes.
  [MEP] Adding getSimSlotMapping Telephony API
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 7e7ca07..402e7f8 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -224,6 +224,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -1511,9 +1512,9 @@
 
                 case CMD_SWITCH_SLOTS:
                     request = (MainThreadRequest) msg.obj;
-                    int[] physicalSlots = (int[]) request.argument;
+                    List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
-                    UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
+                    UiccController.getInstance().switchSlots(slotMapping, onCompleted);
                     break;
 
                 case EVENT_SWITCH_SLOTS_DONE:
@@ -8689,25 +8690,19 @@
         return isAllowed;
     }
 
-    private boolean haveCarrierPrivilegeAccess(UiccCard card, String callingPackage) {
-        // TODO once MEP API refactoring CL is merged, loop port list from UiccCardInfo,
-        //  and if find the matching UiccPort by UiccController.getUiccPortForSlot(slot, portIdx)
-        //  Update each UiccPort object based on privilege access
-        UiccPort[] uiccPorts = card.getUiccPortList();
-        for (UiccPort port : uiccPorts) {
-            UiccProfile profile = port.getUiccProfile();
-            if (profile == null ||
-                    profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
-                    != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
-                return false;
-            }
+    private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
+        UiccProfile profile = port.getUiccProfile();
+        if (profile == null ||
+                profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
+                != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            return false;
         }
         return true;
     }
 
     @Override
     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
-        // Verify that tha callingPackage belongs to the calling UID
+        // Verify that the callingPackage belongs to the calling UID
         mApp.getSystemService(AppOpsManager.class)
                 .checkPackage(Binder.getCallingUid(), callingPackage);
 
@@ -8745,19 +8740,39 @@
                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
                 // is available
                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
-                // TODO remove card.getUiccPortList().length once MEP API refactoring CL is merged
-                //  Get UiccPortInfo from CardInfo and process further based on each UiccPort
-                if (card == null || card.getUiccPortList().length == 0) {
-                    // assume no access if the card or ports are unavailable
+                if (card == null) {
+                    // assume no access if the card is unavailable
                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
                     continue;
                 }
-
-                if (haveCarrierPrivilegeAccess(card, callingPackage)) {
-                    filteredInfos.add(cardInfo);
-                } else {
+                Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
+                if (portInfos.isEmpty()) {
                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
+                    continue;
                 }
+                List<UiccPortInfo> uiccPortInfos = new  ArrayList<>();
+                for (UiccPortInfo portInfo : portInfos) {
+                    UiccPort port = uiccController.getUiccPortForSlot(
+                            cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
+                    if (port == null) {
+                        // assume no access if port is null
+                        uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
+                        continue;
+                    }
+                    if (haveCarrierPrivilegeAccess(port, callingPackage)) {
+                        uiccPortInfos.add(portInfo);
+                    } else {
+                        uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
+                    }
+                }
+                filteredInfos.add(new UiccCardInfo(
+                        cardInfo.isEuicc(),
+                        cardInfo.getCardId(),
+                        null,
+                        cardInfo.getPhysicalSlotIndex(),
+                        cardInfo.isRemovable(),
+                        cardInfo.isMultipleEnabledProfilesSupported(),
+                        uiccPortInfos));
             }
             return filteredInfos;
         } finally {
@@ -8804,13 +8819,12 @@
     }
     @Override
     public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
-        // Verify that tha callingPackage belongs to the calling UID
+        // Verify that the callingPackage belongs to the calling UID
         mApp.getSystemService(AppOpsManager.class)
                 .checkPackage(Binder.getCallingUid(), callingPackage);
 
         boolean hasReadPermission = false;
         boolean isLogicalSlotAccessRestricted = false;
-        String iccId;
 
         try {
             enforceReadPrivilegedPermission("getUiccSlotsInfo");
@@ -8845,24 +8859,16 @@
 
                 String cardId;
                 UiccCard card = slot.getUiccCard();
-                //if has read permission
-                if (hasReadPermission) {
-                    iccId = slot.getIccId();
-                } else {
-                    // if no read permission checking carrier
-                    if (haveCarrierPrivilegeAccess(card, callingPackage)) {
-                        iccId = slot.getIccId();
-                    } else {
-                        //if no carrier permission redact ICCID
-                        iccId = IccUtils.TEST_ICCID;
-                    }
-                }
                 if (card != null) {
                     cardId = card.getCardId();
                 } else {
                     cardId = slot.getEid();
                     if (TextUtils.isEmpty(cardId)) {
-                        cardId = iccId;
+                        // If cardId is null, use iccId of default port as cardId. Check if has
+                        // read permission otherwise set to null.(card is null which means no
+                        // carrier permission)
+                       cardId = hasReadPermission ? slot.getIccId(
+                               TelephonyManager.DEFAULT_PORT_INDEX) : null;
                     }
                 }
 
@@ -8890,17 +8896,25 @@
                         break;
 
                 }
+                List<UiccPortInfo> portInfos = new ArrayList<>();
+                int[] portIndexes = slot.getPortList();
+                for (int portIdx : portIndexes) {
+                    String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
+                            callingPackage, hasReadPermission));
+                    if (slot.isPortActive(portIdx)) {
+                        UiccPort port = slot.getUiccCard().getUiccPort(portIdx);
+                        portInfos.add(new UiccPortInfo(iccId, port.getPortIdx(),
+                                port.getPhoneId(), true));
+                    } else {
+                        portInfos.add(new UiccPortInfo(iccId, portIdx, -1, false));
+                    }
+                }
                 infos[i] = new UiccSlotInfo(
                         slot.isEuicc(),
                         cardId,
                         cardState,
                         slot.isExtendedApduSupported(),
-                        slot.isRemovable(), Collections.singletonList(
-                        new UiccPortInfo(
-                                iccId,
-                                0 /* TODO: to use portList from UiccSlots */,
-                                slot.getPhoneId(),
-                                slot.isActive())));
+                        slot.isRemovable(), portInfos);
                 //setting the value after compatibility check
                 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
             }
@@ -8910,15 +8924,39 @@
         }
     }
 
+    /* Returns null if doesn't have read permission or carrier privilege access. */
+    private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
+            boolean hasReadPermission) {
+        String iccId = slot.getIccId(portIndex);
+        if (hasReadPermission) { // if has read permission
+            return iccId;
+        } else {
+            if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
+                UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
+                // if no read permission, checking carrier privilege access
+                if (haveCarrierPrivilegeAccess(port, callingPackage)) {
+                    return iccId;
+                }
+            }
+        }
+        // No read permission or carrier privilege access.
+        return UiccPortInfo.ICCID_REDACTED;
+    }
+
     @Override
     @Deprecated
-    //TODO : once integrating with HAL Changes we can clean up this Internal API.
     public boolean switchSlots(int[] physicalSlots) {
         enforceModifyPermission();
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
+            List<UiccSlotMapping> slotMappings = new ArrayList<>();
+            for (int i = 0; i < physicalSlots.length; i++) {
+                // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
+                slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
+                        physicalSlots[i], i));
+            }
+            return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -8931,12 +8969,7 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            //TODO: once integrating the HAL changes we can proceed with to work on the parsing side
-            int[] physicalSlots = new int[slotMapping.size()];
-            for (int i = 0; i < physicalSlots.length; i++) {
-                physicalSlots[i] = slotMapping.get(i).getPhysicalSlotIndex();
-            }
-            return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
+            return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -9525,21 +9558,26 @@
     }
 
     @Override
-    public int[] getSlotsMapping(@NonNull String callingPackage) {
+    public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
         enforceReadPrivilegedPermission("getSlotsMapping");
-
+        // Verify that the callingPackage belongs to the calling UID
+        mApp.getSystemService(AppOpsManager.class)
+                .checkPackage(Binder.getCallingUid(), callingPackage);
         final long identity = Binder.clearCallingIdentity();
+        List<UiccSlotMapping> slotMap = new ArrayList<>();
         try {
-            int phoneCount = TelephonyManager.getDefault().getPhoneCount();
-            // All logical slots should have a mapping to a physical slot.
-            int[] logicalSlotsMapping = new int[phoneCount];
-            UiccSlotInfo[] slotInfos = getUiccSlotsInfo(callingPackage);
-            for (int i = 0; i < slotInfos.length; i++) {
-                if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
-                    logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
+            UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
+            if (slotInfos != null) {
+                for (int i = 0; i < slotInfos.length; i++) {
+                    for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
+                        if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
+                            slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
+                                    portInfo.getLogicalSlotIndex()));
+                        }
+                    }
                 }
             }
-            return logicalSlotsMapping;
+            return slotMap;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }