Add isN1ModeEnabled and setN1ModeEnabled to IRadioNetwork

Bug: 255450196
Test: atest VtsHalRadioTargetTest
Change-Id: If8a9e1e1d3dccfa4867c9c7d597c09936abeaa5e
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 8e5d2be..9761900 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -78,4 +78,6 @@
   oneway void cancelEmergencyNetworkScan(int serial, boolean resetScan);
   oneway void exitEmergencyMode(in int serial);
   oneway void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+  oneway void isN1ModeEnabled(in int serial);
+  oneway void setN1ModeEnabled(in int serial, boolean enable);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 7151f22..c228bc1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -77,4 +77,6 @@
   oneway void exitEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void cancelEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
+  oneway void setN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 3c84a84..4d35742 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -504,4 +504,30 @@
      * Response callback is IRadioResponse.setNullCipherAndIntegrityEnabledResponse()
      */
     void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+
+    /**
+     * Checks whether N1 mode (access to 5G core network) is enabled or not.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response function is IRadioNetworkResponse.isN1ModeEnabledResponse()
+     */
+    void isN1ModeEnabled(in int serial);
+
+    /**
+     * Enables or disables N1 mode (access to 5G core network) in accordance with
+     * 3GPP TS 24.501 4.9.
+     *
+     * Note: The default value of N1 mode shall be based on the modem's internal configuration
+     * as per device or carrier. This API may be invoked on demand first to disable N1 mode and
+     * later to re-enable for certain use case. This setting shall not be persisted by modem.
+     * This setting shall not interfere with the allowed network type bitmap set using
+     * {@link IRadioNetwork#setAllowedNetworkTypesBitmap()} API.
+     *
+     * @param serial Serial number of request.
+     * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode.
+     *
+     * Response function is IRadioNetworkResponse.setN1ModeEnabledResponse()
+     */
+    void setN1ModeEnabled(in int serial, boolean enable);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 956b82e..3802bd6 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -624,4 +624,34 @@
      *   RadioError:MODEM_ERR
      */
     void setNullCipherAndIntegrityEnabledResponse(in RadioResponseInfo info);
+
+    /**
+     * Response of isN1ModeEnabled.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param isEnabled Indicates whether N1 mode is enabled or not.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     */
+    void isN1ModeEnabledResponse(in RadioResponseInfo info, boolean isEnabled);
+
+    /**
+     * Response of setN1ModeEnabled.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
+     */
+    void setN1ModeEnabledResponse(in RadioResponseInfo info);
 }
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 2e0488d..f9f3c6c 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -99,6 +99,8 @@
                     scanTrigger) override;
     ::ndk::ScopedAStatus cancelEmergencyNetworkScan(int32_t serial, bool resetScan) override;
     ::ndk::ScopedAStatus exitEmergencyMode(int32_t serial) override;
+    ::ndk::ScopedAStatus isN1ModeEnabled(int32_t serial) override;
+    ::ndk::ScopedAStatus setN1ModeEnabled(int32_t serial, bool enable) override;
 
     ::ndk::ScopedAStatus setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) override;
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index bbe7fd7..005deae 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -347,4 +347,17 @@
     return ok();
 }
 
+ScopedAStatus RadioNetwork::isN1ModeEnabled(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " isN1ModeEnabled is unsupported by HIDL HALs";
+    respond()->isN1ModeEnabledResponse(notSupported(serial), false);
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setN1ModeEnabled(int32_t serial, bool /*enable*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setN1ModeEnabled is unsupported by HIDL HALs";
+    respond()->setN1ModeEnabledResponse(notSupported(serial));
+    return ok();
+}
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 82aaa1b..c890df0 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -300,3 +300,16 @@
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioNetworkResponse::isN1ModeEnabledResponse(
+        const RadioResponseInfo& info, bool /*isEnabled*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setN1ModeEnabledResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 31f4aca..8b8eda6 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -1914,3 +1914,50 @@
              RadioError::MODEM_ERR}));
     LOG(DEBUG) << "exitEmergencyMode finished";
 }
+
+/*
+ * Test IRadioNetwork.setN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setN1ModeEnabled) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_network->setN1ModeEnabled(serial, false);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::INVALID_STATE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.isN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isN1ModeEnabled) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->isN1ModeEnabled(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 67654b1..e6a320b 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -161,6 +161,11 @@
 
     virtual ndk::ScopedAStatus setNullCipherAndIntegrityEnabledResponse(
             const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus isN1ModeEnabledResponse(
+            const RadioResponseInfo& info, bool isEnabled) override;
+
+    virtual ndk::ScopedAStatus setN1ModeEnabledResponse(const RadioResponseInfo& info) override;
 };
 
 /* Callback class for radio network indication */