UiccPortInfo and SimSlotMapping CTS tests

Test: atest TelephonyManagerTest
Test: atest UiccPortInfoTest
Bug: 159354974
Change-Id: I5c01626b4b2a6866adceaaaf4a0cd2d129492b3f
Merged-In: I5c01626b4b2a6866adceaaaf4a0cd2d129492b3f
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index d04f25f..3802888 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -89,7 +89,9 @@
 import android.telephony.TelephonyManager;
 import android.telephony.ThermalMitigationRequest;
 import android.telephony.UiccCardInfo;
+import android.telephony.UiccPortInfo;
 import android.telephony.UiccSlotInfo;
+import android.telephony.UiccSlotMapping;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.NetworkSlicingConfig;
 import android.telephony.emergency.EmergencyNumber;
@@ -2252,12 +2254,13 @@
         // test that these methods don't crash
         if (infos.size() > 0) {
             UiccCardInfo info = infos.get(0);
-            info.getIccId();
             info.getEid();
             info.isRemovable();
             info.isEuicc();
             info.getCardId();
-            info.getSlotIndex();
+            info.getPorts();
+            info.getPhysicalSlotIndex();
+            info.isRemovable();
         }
     }
 
@@ -4485,7 +4488,8 @@
                     List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
                     Set<String> presentCards = Arrays.stream(mTelephonyManager.getUiccSlotsInfo())
                             .filter(Objects::nonNull)
-                            .filter(UiccSlotInfo::getIsActive)
+                            .filter(port -> port.getPorts().stream().anyMatch(portInfo ->
+                                    portInfo.isActive()))
                             .map(UiccSlotInfo::getCardId)
                             .filter(Objects::nonNull)
                             // hack around getUiccSlotsInfo not stripping trailing F
@@ -4493,10 +4497,12 @@
                             .collect(Collectors.toSet());
                     int slotIndex = -1;
                     for (UiccCardInfo cardInfo : cardInfos) {
-                        if (presentCards.contains(cardInfo.getIccId())
-                                || presentCards.contains(cardInfo.getEid())) {
-                            slotIndex = cardInfo.getSlotIndex();
-                            break;
+                        for (UiccPortInfo portInfo : cardInfo.getPorts()) {
+                            if (presentCards.contains(portInfo.getIccId())
+                                    || presentCards.contains(cardInfo.getEid())) {
+                                slotIndex = cardInfo.getPhysicalSlotIndex();
+                                break;
+                            }
                         }
                     }
                     if (slotIndex < 0) {
@@ -4815,5 +4821,91 @@
             // expected
         }
     }
+
+    @Test
+    public void testSimSlotMapping() {
+        if (!hasCellular()) return;
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity("android.permission.MODIFY_PHONE_STATE");
+        // passing slotMapping combination
+        UiccSlotMapping slotMapping1 = new UiccSlotMapping(0, 1, 1);
+        UiccSlotMapping slotMapping2 = new UiccSlotMapping(1, 0, 0);
+        List<UiccSlotMapping> slotMappingList = new ArrayList<UiccSlotMapping>();
+        slotMappingList.add(slotMapping1);
+        slotMappingList.add(slotMapping2);
+        try {
+            mTelephonyManager.setSimSlotMapping(slotMappingList);
+        } catch (Exception e) {
+            fail("Not Expected Fail, Error in setSimSlotMapping :" + e);
+        }
+        slotMappingList.clear();
+
+        // Duplicate logicalSlotIndex - Fail
+        UiccSlotMapping slotMapping3 = new UiccSlotMapping(0, 1, 0);
+        UiccSlotMapping slotMapping4 = new UiccSlotMapping(1, 0, 0);
+        slotMappingList.add(slotMapping3);
+        slotMappingList.add(slotMapping4);
+        try {
+            mTelephonyManager.setSimSlotMapping(slotMappingList);
+            fail("Expected IllegalArgumentException, Duplicate UiccSlotMapping data found");
+        } catch (IllegalArgumentException e) {
+            //expected
+        }
+        slotMappingList.clear();
+
+        // Duplicate {portIndex+physicalSlotIndex} - Fail
+        UiccSlotMapping slotMapping5 = new UiccSlotMapping(0, 1, 0);
+        UiccSlotMapping slotMapping6 = new UiccSlotMapping(0, 1, 1);
+        slotMappingList.add(slotMapping5);
+        slotMappingList.add(slotMapping6);
+        try {
+            mTelephonyManager.setSimSlotMapping(slotMappingList);
+            fail("Expected IllegalArgumentException, Duplicate UiccSlotMapping data found");
+        } catch (IllegalArgumentException e) {
+            //expected
+        }
+        slotMappingList.clear();
+
+        // Duplicate {portIndex+physicalSlotIndex+logicalSlotIndex} - Fail
+        UiccSlotMapping slotMapping7 = new UiccSlotMapping(0, 1, 0);
+        UiccSlotMapping slotMapping8 = new UiccSlotMapping(0, 1, 0);
+        slotMappingList.add(slotMapping7);
+        slotMappingList.add(slotMapping8);
+        try {
+            mTelephonyManager.setSimSlotMapping(slotMappingList);
+            fail("Expected IllegalArgumentException, Duplicate UiccSlotMapping data found");
+        } catch (IllegalArgumentException e) {
+            //expected
+        }
+        slotMappingList.clear();
+
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+
+    }
+
+    @Test
+    public void getUiccSlotInfoTest() {
+        UiccSlotInfo[] slotInfos = mTelephonyManager.getUiccSlotsInfo();
+
+        if (slotInfos == null) {
+            return;
+        }
+
+        // Call below methods to make sure it doesn't crash.
+        for (UiccSlotInfo slotInfo : slotInfos) {
+            slotInfo.getIsEuicc();
+            slotInfo.getCardId();
+            slotInfo.getCardStateInfo();
+            slotInfo.getIsExtendedApduSupported();
+            slotInfo.isRemovable();
+            for (UiccPortInfo portInfo :slotInfo.getPorts()) {
+                portInfo.isActive();
+                portInfo.getIccId();
+                portInfo.getLogicalSlotIndex();
+                portInfo.getPortIndex();
+            }
+        }
+    }
 }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/UiccPortInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/UiccPortInfoTest.java
new file mode 100644
index 0000000..c9820c7
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/UiccPortInfoTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 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 android.telephony.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.telephony.UiccPortInfo;
+import android.test.AndroidTestCase;
+
+public class UiccPortInfoTest extends AndroidTestCase {
+    /**
+     * Create fake UiccPortInfo objects run basic tests.
+     */
+    public void testFakeUiccSlotInfoObject() {
+        String iccId = "FAKE_ICC_ID";
+        int portIndex = 0;
+        int logicalSlotIndex = 0;
+        boolean isActive = true;
+        UiccPortInfo uiccPortInfo = new UiccPortInfo(
+                iccId,            /* ICCID */
+                portIndex,      /* portIndex */
+                logicalSlotIndex, /* logicalSlotIndex */
+                isActive     /* isActive */
+        );
+
+        //Getters.
+        assertThat(uiccPortInfo.getIccId()).isEqualTo(iccId);
+        assertThat(uiccPortInfo.getPortIndex()).isEqualTo(portIndex);
+        assertThat(uiccPortInfo.getLogicalSlotIndex()).isEqualTo(logicalSlotIndex);
+        assertThat(uiccPortInfo.isActive()).isEqualTo(isActive);
+
+        // Other common methods.
+        assertThat(uiccPortInfo.describeContents()).isEqualTo(0);
+        assertThat(uiccPortInfo.hashCode()).isNotEqualTo(0);
+        assertThat(uiccPortInfo.toString()).isNotEmpty();
+
+        // Parcel read and write.
+        Parcel parcel = Parcel.obtain();
+        uiccPortInfo.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        UiccPortInfo toCompare = uiccPortInfo.CREATOR.createFromParcel(parcel);
+        assertThat(uiccPortInfo.hashCode()).isEqualTo(toCompare.hashCode());
+        assertThat(uiccPortInfo).isEqualTo(toCompare);
+    }
+}