Merge "Update HAL APIs interface to support sim type switching on 2pSIM+1eSIM configured devices" into main
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index e39e135..8f0060b 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -397,6 +397,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.PortUtils;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
+import com.android.internal.telephony.uicc.SimTypeInfo;
 import com.android.telephony.Rlog;
 
 import java.io.ByteArrayInputStream;
@@ -5879,6 +5880,23 @@
                 securityAlgorithmUpdate.isUnprotectedEmergency);
     }
 
+    /** Convert an AIDL-based SimTypeInfo to its Java wrapper. */
+    public static ArrayList<SimTypeInfo> convertAidlSimTypeInfo(
+            android.hardware.radio.config.SimTypeInfo[] simTypeInfos) {
+        ArrayList<SimTypeInfo> response = new ArrayList<>();
+        if (simTypeInfos == null) {
+            loge("convertAidlSimTypeInfo received NULL simTypeInfos");
+            return response;
+        }
+        for (android.hardware.radio.config.SimTypeInfo simTypeInfo : simTypeInfos) {
+            SimTypeInfo info = new SimTypeInfo();
+            info.mSupportedSimTypes = simTypeInfo.supportedSimTypes;
+            info.setCurrentSimType(simTypeInfo.currentSimType);
+            response.add(info);
+        }
+        return response;
+    }
+
     private static void logd(String log) {
         Rlog.d("RILUtils", log);
     }
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java b/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
index 0a41b11..6142fc2 100644
--- a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
+++ b/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
@@ -21,10 +21,10 @@
 import android.telephony.PhoneCapability;
 
 import com.android.internal.telephony.uicc.IccSlotStatus;
+import com.android.internal.telephony.uicc.SimTypeInfo;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Set;
 
 /**
@@ -47,8 +47,7 @@
      */
     @Override
     public void getHalDeviceCapabilitiesResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            boolean modemReducedFeatureSet1) throws RemoteException {
+            RadioResponseInfo info, boolean modemReducedFeatureSet1) throws RemoteException {
         // convert hal device capabilities to RadioInterfaceCapabilities
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
@@ -71,8 +70,7 @@
      */
     @Override
     public void getNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info, byte numOfLiveModems)
-            throws RemoteException {
+            RadioResponseInfo info, byte numOfLiveModems) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -93,9 +91,8 @@
      */
     @Override
     public void getPhoneCapabilityResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            android.hardware.radio.config.PhoneCapability phoneCapability)
-            throws RemoteException {
+            RadioResponseInfo info,
+            android.hardware.radio.config.PhoneCapability phoneCapability) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             PhoneCapability ret = RILUtils.convertHalPhoneCapability(
@@ -118,9 +115,7 @@
      */
     @Override
     public void getSimultaneousCallingSupportResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            int[] enabledLogicalSlots)
-            throws RemoteException {
+            RadioResponseInfo info, int[] enabledLogicalSlots) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             ArrayList<Integer> ret = RILUtils.primitiveArrayToArrayList(enabledLogicalSlots);
@@ -142,7 +137,7 @@
      */
     @Override
     public void getSimSlotsStatusResponse(
-            android.hardware.radio.RadioResponseInfo info,
+            RadioResponseInfo info,
             android.hardware.radio.config.SimSlotStatus[] slotStatus)
             throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
@@ -166,8 +161,7 @@
      * Currently this is being used as the callback for RadioConfig.setNumOfLiveModems() method
      */
     @Override
-    public void setNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setNumOfLiveModemsResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -187,8 +181,7 @@
      * Response function for IRadioConfig.setPreferredDataModem().
      */
     @Override
-    public void setPreferredDataModemResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setPreferredDataModemResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -208,8 +201,7 @@
      * Response function for IRadioConfig.setSimSlotsMapping().
      */
     @Override
-    public void setSimSlotsMappingResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setSimSlotsMappingResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -225,6 +217,48 @@
         }
     }
 
+    /**
+     * Response function for IRadioConfig.getSimTypeInfo().
+     */
+    @Override
+    public void getSimTypeInfoResponse(
+            RadioResponseInfo info,
+            android.hardware.radio.config.SimTypeInfo[] simTypeInfo) throws RemoteException {
+        RILRequest rr = mRadioConfig.processResponse(info);
+        if (rr != null) {
+            ArrayList<SimTypeInfo> ret = RILUtils.convertAidlSimTypeInfo(simTypeInfo);
+            if (info.error == android.hardware.radio.RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
+            } else {
+                rr.onError(info.error, null);
+                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
+            }
+        } else {
+            loge("getSimTypeInfoResponse: Error " + info.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.setSimTypeResponse().
+     */
+    @Override
+    public void setSimTypeResponse(RadioResponseInfo info) throws RemoteException {
+        RILRequest rr = mRadioConfig.processResponse(info);
+        if (rr != null) {
+            if (info.error == android.hardware.radio.RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, null);
+                logd(rr, RILUtils.requestToString(rr.mRequest));
+            } else {
+                rr.onError(info.error, null);
+                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
+            }
+        } else {
+            loge("setSimTypeResponse: Error " + info.toString());
+        }
+    }
     private static void logd(String log) {
         Rlog.d(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java b/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java
new file mode 100644
index 0000000..b19e42a
--- /dev/null
+++ b/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2024 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 com.android.internal.telephony.uicc;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class contains the sim type information of active physical slot ids.
+ */
+public class SimTypeInfo {
+
+    /**
+     * SimType (bit mask)
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            SimType.SIM_TYPE_UNKNOWN,
+            SimType.SIM_TYPE_PHYSICAL,
+            SimType.SIM_TYPE_ESIM,
+    })
+    public @interface SimType {
+        /** Unknown SIM */
+        int SIM_TYPE_UNKNOWN = 0;
+        /** Physical SIM (Can have eUICC capabilities) */
+        int SIM_TYPE_PHYSICAL = 1 << 0;
+        /** Embedded SIM*/
+        int SIM_TYPE_ESIM = 1 << 1;
+    }
+
+    public @SimType int mCurrentSimType = SimType.SIM_TYPE_UNKNOWN;
+    // Bitmask of the supported {@code SimType}s
+    public int mSupportedSimTypes;
+
+    /**
+     * Set the current SimType according to the input type.
+     */
+    public void setCurrentSimType(int simType) {
+        switch(simType) {
+            case android.hardware.radio.config.SimType.UNKNOWN:
+                mCurrentSimType = SimType.SIM_TYPE_UNKNOWN;
+                break;
+            case android.hardware.radio.config.SimType.PHYSICAL:
+                mCurrentSimType = SimType.SIM_TYPE_PHYSICAL;
+                break;
+            case android.hardware.radio.config.SimType.ESIM:
+                mCurrentSimType = SimType.SIM_TYPE_ESIM;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_SimType: " + simType);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("SimTypeInfo {activeSimType=").append(mCurrentSimType).append(",")
+                .append("supportedSimType=").append(mSupportedSimTypes);
+        sb.append("}");
+        return sb.toString();
+    }
+}