Add HAL APIs to support sim type switching on 2pSIM+1eSIM configured devices

Test: build
Bug: 373798864
Change-Id: I1ca0c3ed6df7479c104c84df87e5e24944b26f16
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
index bba6bdd..ded4835 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
@@ -53,4 +53,6 @@
   oneway void setResponseFunctions(in android.hardware.radio.config.IRadioConfigResponse radioConfigResponse, in android.hardware.radio.config.IRadioConfigIndication radioConfigIndication);
   oneway void setSimSlotsMapping(in int serial, in android.hardware.radio.config.SlotPortMapping[] slotMap);
   oneway void getSimultaneousCallingSupport(in int serial);
+  oneway void getSimTypeInfo(in int serial);
+  oneway void setSimType(in int serial, in android.hardware.radio.config.SimType[] simTypes);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
index 6ff7bd0..4e0e133 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -43,4 +43,6 @@
   oneway void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getSimultaneousCallingSupportResponse(in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
+  oneway void getSimTypeInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.SimTypeInfo[] simTypeInfo);
+  oneway void setSimTypeResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl
new file mode 100644
index 0000000..b27c86f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.config;
+/* @hide */
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SimType {
+  UNKNOWN = 0,
+  PHYSICAL = (1 << 0) /* 1 */,
+  ESIM = (1 << 1) /* 2 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
new file mode 100644
index 0000000..cba5dd9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.config;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable SimTypeInfo {
+  android.hardware.radio.config.SimType currentSimType = android.hardware.radio.config.SimType.UNKNOWN;
+  int supportedSimTypes;
+}
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
index 936315c..e819fe0 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
@@ -27,6 +27,7 @@
 
 import android.hardware.radio.config.IRadioConfigIndication;
 import android.hardware.radio.config.IRadioConfigResponse;
+import android.hardware.radio.config.SimType;
 import android.hardware.radio.config.SlotPortMapping;
 
 /** @hide */
@@ -208,4 +209,39 @@
      * This is available when android.hardware.telephony is defined.
      */
     void getSimultaneousCallingSupport(in int serial);
+
+    /**
+     * Get the sim type information.
+     *
+     * Response provides the current active sim type and supported sim types associated with each
+     * active physical slot ids.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response callback is IRadioConfigResponse.getSimTypeInfoResponse()
+     *
+     * This is available when android.hardware.telephony.subscription is defined.
+     */
+    void getSimTypeInfo(in int serial);
+
+    /**
+     * Set the sim type associated with the physical slot id and activate if the sim type is
+     * currently inactive.
+     *
+     * Example: There are 2 active physical slot ids and 3 physical sims(2 pSIM and 1 eSIM). First
+     * physical slot id is always linked pSIM and 2nd physical slot id supports either pSIM/eSIM one
+     * at a time. In order to activate eSIM on 2nd physical slot id, caller should pass
+     * corresponding sim type.
+     *
+     * simTypes[0] = pSIM
+     * simTypes[1] = eSIM
+     *
+     * @param serial Serial number of request.
+     * @param simTypes SimType to be activated on each logical slot
+     *
+     * Response callback is IRadioConfigResponse.setSimTypeResponse()
+     *
+     * This is available when android.hardware.telephony.subscription is defined.
+     */
+    void setSimType(in int serial, in SimType[] simTypes);
 }
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index 8182cd1..d526c51 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.radio.config.PhoneCapability;
 import android.hardware.radio.config.SimSlotStatus;
+import android.hardware.radio.config.SimTypeInfo;
 
 /**
  * Interface declaring response functions to solicited radio config requests.
@@ -152,4 +153,40 @@
      */
     void getSimultaneousCallingSupportResponse(
             in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
+
+    /**
+     * Response to the asynchronous {@link IRadioConfig#getSimTypeInfo} request.
+     *
+     * @param info Response info struct containing response type, serial number and error
+     * @param simTypeInfos Currently active and supported sim types associated with active
+     * physical slot ids.
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.subscription is not
+     *                                    defined
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:NO_MEMORY
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:MODEM_ERR
+     */
+    void getSimTypeInfoResponse(
+            in android.hardware.radio.RadioResponseInfo info, in SimTypeInfo[] simTypeInfo);
+
+    /**
+     * Response to the asynchronous {@link IRadioConfig#setSimType} request.
+     *
+     * @param info Response info struct containing response type, serial number and error
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.subscription is not
+     *                                    defined
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:NO_MEMORY
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     */
+    void setSimTypeResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/android/hardware/radio/config/SimType.aidl b/radio/aidl/android/hardware/radio/config/SimType.aidl
new file mode 100644
index 0000000..fc9915e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/SimType.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 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 android.hardware.radio.config;
+
+/** @hide */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum SimType {
+    /**
+     * Unknown
+     **/
+    UNKNOWN = 0,
+    /**
+     * Physical SIM (can be eUICC capable)
+     **/
+    PHYSICAL = 1 << 0,
+    /**
+     * Embedded SIM
+     **/
+    ESIM = 1 << 1,
+}
diff --git a/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
new file mode 100644
index 0000000..0534626
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 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 android.hardware.radio.config;
+
+import android.hardware.radio.config.SimType;
+
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SimTypeInfo {
+    /**
+     * Current SimType on the physical slot id.
+     **/
+    SimType currentSimType = SimType.UNKNOWN;
+    /**
+     * Bitmask of the sim types supported by the physical slot id. Physical slot can support more
+     * than one SimType.
+     * Example:
+     * if the physical slot id supports either pSIM/eSIM and currently pSIM is active,
+     * currentSimType will be SimType::PHYSICAL and supportedSimTypes will be
+     * SimType::PHYSICAL | SimType::ESIM.
+     **/
+    int supportedSimTypes;
+}
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index 837c626..3834ecc 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -109,4 +109,19 @@
     return ok();
 }
 
+ScopedAStatus RadioConfig::getSimTypeInfo(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " getSimTypeInfo is unsupported by HIDL HALs";
+    respond()->getSimTypeInfoResponse(notSupported(serial), {});
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setSimType(
+        int32_t serial, const std::vector<aidl::SimType>& /*simTypes*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setSimType is unsupported by HIDL HALs";
+    respond()->setSimTypeResponse(notSupported(serial));
+    return ok();
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
index 17d5985..a1e48dc 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -55,7 +55,11 @@
             int32_t serial,
             const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
             override;
-
+    ::ndk::ScopedAStatus getSimTypeInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus setSimType(
+            int32_t serial,
+            const std::vector<aidl::android::hardware::radio::config::SimType>& simTypes)
+            override;
   protected:
     std::shared_ptr<::aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index c532440..49439fa 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -75,3 +75,17 @@
     parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioConfigResponse::getSimTypeInfoResponse(const RadioResponseInfo& info,
+        const std::vector<SimTypeInfo>& /* simTypeInfo */) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setSimTypeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
index 84c74fc..cdcc1bc 100644
--- a/radio/aidl/vts/radio_config_utils.h
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -62,6 +62,11 @@
 
     virtual ndk::ScopedAStatus getHalDeviceCapabilitiesResponse(
             const RadioResponseInfo& info, bool modemReducedFeatureSet1) override;
+
+    virtual ndk::ScopedAStatus getSimTypeInfoResponse(
+            const RadioResponseInfo& info, const std::vector<SimTypeInfo>& simTypeInfo) override;
+
+    virtual ndk::ScopedAStatus setSimTypeResponse(const RadioResponseInfo& info) override;
 };
 
 /* Callback class for radio config indication */