Manual network selection by RAN type

Support updated API for setNetworkSelectionModeManual

Bug: 68116277
Test: atest FrameworksTelephonyTests
Change-Id: I7076da1734d2d020adef568188cb4f4b4914f379
diff --git a/current.txt b/current.txt
index f2b632a..02a4733 100644
--- a/current.txt
+++ b/current.txt
@@ -666,10 +666,10 @@
 ##
 # BEGIN Radio HAL Merge Conflict Avoidance Buffer - STOPSHIP if present
 ##
-558660693d7df3b740562bcca71e9f6db314a2e87408f5533076fac9bc0e4867 android.hardware.radio@1.5::types
-6268d208631b21d1e85bfad338642ac5ca7ac6c83b411283515a4342b5d673f7 android.hardware.radio@1.5::IRadio
+616456d7ce4435d88995f9fe0025a76bca14bd70799e4ca3ff4bae74d54d1166 android.hardware.radio@1.5::types
+c68f5bd87f747f8e7968ff66ecc548b2d26f8e186b7bb805c11d6c883a838fc6 android.hardware.radio@1.5::IRadio
 e96ae1c3a9c0689002ec2318e9c587f4f607c16a75a3cd38788b77eb91072021 android.hardware.radio@1.5::IRadioIndication
-64e06cd5251bec38c402f71d05a6d52b89819a20c9099a192a694059ce4336fc android.hardware.radio@1.5::IRadioResponse
+9e962eff568dc8c712d83846f8c27460de5005ed9b836d3e08390e8aa56b5a46 android.hardware.radio@1.5::IRadioResponse
 5971a891d7d8843e9fb9f44583a9a0a265ec42fd5e4e1c95c9803454d21fabf7 android.hardware.radio.config@1.3::types
 a2977755bc5f1ef47f04b7f2400632efda6218e1515dba847da487145cfabc4f android.hardware.radio.config@1.3::IRadioConfig
 742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 52e579a..ee4438d 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -25,6 +25,7 @@
 import @1.5::IndicationFilter;
 import @1.5::LinkAddress;
 import @1.5::NetworkScanRequest;
+import @1.5::RadioAccessNetworks;
 import @1.5::RadioAccessSpecifier;
 import @1.5::SignalThresholdInfo;
 
@@ -263,4 +264,22 @@
      * Response function is IRadioResponse.getDataRegistrationStateResponse_1_5()
      */
     oneway getDataRegistrationState_1_5(int32_t serial);
+
+    /*
+     * Manually select a specified network.
+     * This request must not respond until the new operator is selected and registered.
+     * Per TS 23.122, the RAN is just the initial suggested value.
+     * If registration fails, the RAN is not available afterwards, or the RAN is not within
+     * the network types specified by IRadio::setPreferredNetworkTypeBitmap, then the modem
+     * will need to select the next best RAN for network registration.
+     *
+     * @param serial Serial number of request.
+     * @param operatorNumeric String specifying MCCMNC of network to select (eg "310170").
+     * @param ran Initial suggested radio access network type. If value is UNKNOWN, the modem
+     *     will select the next best RAN for network registration.
+     *
+     * Response function is IRadioResponse.setNetworkSelectionModeManualResponse_1_5()
+     */
+    oneway setNetworkSelectionModeManual_1_5(int32_t serial, string operatorNumeric,
+            RadioAccessNetworks ran);
 };
diff --git a/radio/1.5/IRadioResponse.hal b/radio/1.5/IRadioResponse.hal
index 4bdafbd..e66e00b 100644
--- a/radio/1.5/IRadioResponse.hal
+++ b/radio/1.5/IRadioResponse.hal
@@ -212,4 +212,28 @@
      *   RadioError:INTERNAL_ERR
      */
     oneway getCellInfoListResponse_1_5(RadioResponseInfo info, vec<CellInfo> cellInfo);
+
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:ILLEGAL_SIM_OR_ME
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:INVALID_STATE
+     *   RadioError:NO_MEMORY
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:SYSTEM_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NO_RESOURCES
+     *   RadioError:CANCELLED
+     *
+     * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and
+     * no retries needed, such as illegal SIM or ME.
+     */
+    oneway setNetworkSelectionModeManualResponse_1_5(RadioResponseInfo info);
 };
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index ad4df6d..5482aca 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -166,7 +166,11 @@
 };
 
 enum RadioAccessNetworks : @1.1::RadioAccessNetworks {
+    UNKNOWN = 0,
+    /** Next Generation Radio Access Network */
     NGRAN = 4,
+    /** CDMA 2000 Network */
+    CDMA2000 = 5,
 };
 
 /**
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 01258cf..a4095b7 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -879,6 +879,9 @@
     }
 }
 
+/*
+ * Test IRadio.setInitialAttachApn_1_5() for the response returned.
+ */
 TEST_F(RadioHidlTest_v1_5, setInitialAttachApn_1_5) {
     serial = GetRandomSerialNumber();
 
@@ -919,6 +922,9 @@
     }
 }
 
+/*
+ * Test IRadio.setDataProfile_1_5() for the response returned.
+ */
 TEST_F(RadioHidlTest_v1_5, setDataProfile_1_5) {
     serial = GetRandomSerialNumber();
 
@@ -989,4 +995,30 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.setNetworkSelectionModeManual_1_5() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_5, setNetworkSelectionModeManual_1_5) {
+    serial = GetRandomSerialNumber();
+
+    // can't camp on nonexistent MCCMNC, so we expect this to fail.
+    Return<void> res = radio_v1_5->setNetworkSelectionModeManual_1_5(
+            serial, "123456", android::hardware::radio::V1_5::RadioAccessNetworks::GERAN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+
+    if (cardStatus.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+                                     {RadioError::NONE, RadioError::ILLEGAL_SIM_OR_ME,
+                                      RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 1e806fa..abab452 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -571,6 +571,8 @@
             const RadioResponseInfo& info,
             const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::CellInfo>&
                     cellInfo);
+
+    Return<void> setNetworkSelectionModeManualResponse_1_5(const RadioResponseInfo& info);
 };
 
 /* Callback class for radio indication */
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 01556f5..d7197d5 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -992,3 +992,10 @@
                 ::android::hardware::radio::V1_5::CellInfo>& /*cellInfo*/) {
     return Void();
 }
+
+Return<void> RadioResponse_v1_5::setNetworkSelectionModeManualResponse_1_5(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_5.notify(info.serial);
+    return Void();
+}