From f3ce10bd6c94e57587987f497e1914903d1030ce Mon Sep 17 00:00:00 2001 From: Pomai Ahlo Date: Mon, 12 Dec 2022 13:58:55 -0800 Subject: [PATCH] [ISap hidl2aidl] VTS Tests Add VTS tests for the new AIDL interface Test: atest VtsHalRadioTargetTest:PerInstance/SapTest Bug: 241969533 Change-Id: Ia4a6be9aa0fd61c310fb539b44cc4d6a2e6e3852 Merged-In: Ia4a6be9aa0fd61c310fb539b44cc4d6a2e6e3852 --- radio/aidl/vts/Android.bp | 3 + radio/aidl/vts/VtsHalRadioTargetTest.cpp | 6 + radio/aidl/vts/radio_sap_callback.cpp | 95 +++++++++ radio/aidl/vts/radio_sap_test.cpp | 233 +++++++++++++++++++++++ radio/aidl/vts/radio_sap_utils.h | 99 ++++++++++ 5 files changed, 436 insertions(+) create mode 100644 radio/aidl/vts/radio_sap_callback.cpp create mode 100644 radio/aidl/vts/radio_sap_test.cpp create mode 100644 radio/aidl/vts/radio_sap_utils.h diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp index 021ee89f6d..97964b4fd7 100644 --- a/radio/aidl/vts/Android.bp +++ b/radio/aidl/vts/Android.bp @@ -50,6 +50,8 @@ cc_test { "radio_network_indication.cpp", "radio_network_response.cpp", "radio_network_test.cpp", + "radio_sap_callback.cpp", + "radio_sap_test.cpp", "radio_sim_indication.cpp", "radio_sim_response.cpp", "radio_sim_test.cpp", @@ -69,6 +71,7 @@ cc_test { "android.hardware.radio.messaging-V1-ndk", "android.hardware.radio.modem-V1-ndk", "android.hardware.radio.network-V1-ndk", + "android.hardware.radio.sap-V1-ndk", "android.hardware.radio.sim-V1-ndk", "android.hardware.radio.voice-V1-ndk", ], diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp index 1ebc6afa8a..03d3c5a33c 100644 --- a/radio/aidl/vts/VtsHalRadioTargetTest.cpp +++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp @@ -21,6 +21,7 @@ #include "radio_messaging_utils.h" #include "radio_modem_utils.h" #include "radio_network_utils.h" +#include "radio_sap_utils.h" #include "radio_sim_utils.h" #include "radio_voice_utils.h" @@ -54,6 +55,11 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::getAidlHalInstanceNames(IRadioNetwork::descriptor)), android::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSapTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, SapTest, + testing::ValuesIn(android::getAidlHalInstanceNames(ISap::descriptor)), + android::PrintInstanceNameToString); + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSimTest); INSTANTIATE_TEST_SUITE_P(PerInstance, RadioSimTest, testing::ValuesIn(android::getAidlHalInstanceNames(IRadioSim::descriptor)), diff --git a/radio/aidl/vts/radio_sap_callback.cpp b/radio/aidl/vts/radio_sap_callback.cpp new file mode 100644 index 0000000000..3b21ede831 --- /dev/null +++ b/radio/aidl/vts/radio_sap_callback.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2022 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. + */ +#include "radio_sap_utils.h" + +#include + +SapCallback::SapCallback(SapTest& parent) : parent_sap(parent) {} + +::ndk::ScopedAStatus SapCallback::apduResponse(int32_t serialNumber, SapResultCode resultCode, + const std::vector& /*apduRsp*/) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} +::ndk::ScopedAStatus SapCallback::connectResponse(int32_t serialNumber, + SapConnectRsp /*sapConnectRsp*/, + int32_t /*maxMsgSize*/) { + sapResponseSerial = serialNumber; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::disconnectIndication(int32_t /*serialNumber*/, + SapDisconnectType /*sapDisconnectType*/) { + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::disconnectResponse(int32_t serialNumber) { + sapResponseSerial = serialNumber; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::errorResponse(int32_t /*serialNumber*/) { + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::powerResponse(int32_t serialNumber, SapResultCode resultCode) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::resetSimResponse(int32_t serialNumber, SapResultCode resultCode) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::statusIndication(int32_t /*serialNumber*/, + SapStatus /*sapStatus*/) { + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::transferAtrResponse(int32_t serialNumber, + SapResultCode resultCode, + const std::vector& /*atr*/) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::transferCardReaderStatusResponse(int32_t serialNumber, + SapResultCode resultCode, + int32_t /*cardReaderStatus*/) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus SapCallback::transferProtocolResponse(int32_t serialNumber, + SapResultCode resultCode) { + sapResponseSerial = serialNumber; + sapResultCode = resultCode; + parent_sap.notify(serialNumber); + return ndk::ScopedAStatus::ok(); +} diff --git a/radio/aidl/vts/radio_sap_test.cpp b/radio/aidl/vts/radio_sap_test.cpp new file mode 100644 index 0000000000..c94379c934 --- /dev/null +++ b/radio/aidl/vts/radio_sap_test.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2022 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. + */ +#include +#include + +#include "radio_sap_utils.h" + +#define ASSERT_OK(ret) ASSERT_TRUE((ret).isOk()) +#define TIMEOUT_PERIOD 40 + +void SapTest::SetUp() { + std::string serviceName = GetParam(); + if (!isServiceValidForDeviceConfiguration(serviceName)) { + LOG(DEBUG) << "Skipped the test due to device configuration."; + GTEST_SKIP(); + } + sap = ISap::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str()))); + ASSERT_NE(sap.get(), nullptr); + + sapCb = ndk::SharedRefBase::make(*this); + ASSERT_NE(sapCb.get(), nullptr); + + count = 0; + + ndk::ScopedAStatus res = sap->setCallback(sapCb); + ASSERT_OK(res) << res; +} + +void SapTest::TearDown() {} + +::testing::AssertionResult SapTest::CheckAnyOfErrors(SapResultCode err, + std::vector errors) { + for (size_t i = 0; i < errors.size(); i++) { + if (err == errors[i]) { + return testing::AssertionSuccess(); + } + } + return testing::AssertionFailure() << "SapError:" + toString(err) + " is returned"; +} + +void SapTest::notify(int receivedSerial) { + std::unique_lock lock(mtx); + count++; + if (serial == receivedSerial) { + cv.notify_one(); + } +} + +std::cv_status SapTest::wait() { + std::unique_lock lock(mtx); + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count == 0) { + status = cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) { + return status; + } + } + count--; + return status; +} + +/* + * Test ISap.connectReq() for the response returned. + */ +TEST_P(SapTest, connectReq) { + LOG(DEBUG) << "connectReq"; + serial = GetRandomSerialNumber(); + int32_t maxMsgSize = 100; + + ndk::ScopedAStatus res = sap->connectReq(serial, maxMsgSize); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + // Modem side need time for connect to finish. Adding a waiting time to prevent + // disconnect being requested right after connect request. + sleep(1); +} + +/* + * Test ISap.disconnectReq() for the response returned + */ +TEST_P(SapTest, disconnectReq) { + LOG(DEBUG) << "disconnectReq"; + serial = GetRandomSerialNumber(); + + ndk::ScopedAStatus res = sap->disconnectReq(serial); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + LOG(DEBUG) << "disconnectReq finished"; +} + +/* + * Test ISap.apduReq() for the response returned. + */ +TEST_P(SapTest, apduReq) { + LOG(DEBUG) << "apduReq"; + serial = GetRandomSerialNumber(); + SapApduType sapApduType = SapApduType::APDU; + std::vector command = {}; + + ndk::ScopedAStatus res = sap->apduReq(serial, sapApduType, command); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE(CheckAnyOfErrors( + sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF, + SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED, + SapResultCode::SUCCESS})); + LOG(DEBUG) << "apduReq finished"; +} + +/* + * Test ISap.transferAtrReq() for the response returned. + */ +TEST_P(SapTest, transferAtrReq) { + LOG(DEBUG) << "transferAtrReq"; + serial = GetRandomSerialNumber(); + + ndk::ScopedAStatus res = sap->transferAtrReq(serial); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, + SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS})); + LOG(DEBUG) << "transferAtrReq finished"; +} + +/* + * Test ISap.powerReq() for the response returned. + */ +TEST_P(SapTest, powerReq) { + LOG(DEBUG) << "powerReq"; + serial = GetRandomSerialNumber(); + bool state = true; + + ndk::ScopedAStatus res = sap->powerReq(serial, state); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE( + CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, + SapResultCode::CARD_ALREADY_POWERED_ON, SapResultCode::SUCCESS})); + LOG(DEBUG) << "powerReq finished"; +} + +/* + * Test ISap.resetSimReq() for the response returned. + */ +TEST_P(SapTest, resetSimReq) { + LOG(DEBUG) << "resetSimReq"; + serial = GetRandomSerialNumber(); + + ndk::ScopedAStatus res = sap->resetSimReq(serial); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE( + CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, + SapResultCode::SUCCESS})); + LOG(DEBUG) << "resetSimReq finished"; +} + +/* + * Test ISap.transferCardReaderStatusReq() for the response returned. + */ +TEST_P(SapTest, transferCardReaderStatusReq) { + LOG(DEBUG) << "transferCardReaderStatusReq"; + serial = GetRandomSerialNumber(); + + ndk::ScopedAStatus res = sap->transferCardReaderStatusReq(serial); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, + SapResultCode::SUCCESS})); + LOG(DEBUG) << "transferCardReaderStatusReq finished"; +} + +/* + * Test ISap.setTransferProtocolReq() for the response returned. + */ +TEST_P(SapTest, setTransferProtocolReq) { + LOG(DEBUG) << "setTransferProtocolReq"; + serial = GetRandomSerialNumber(); + SapTransferProtocol sapTransferProtocol = SapTransferProtocol::T0; + + ndk::ScopedAStatus res = sap->setTransferProtocolReq(serial, sapTransferProtocol); + ASSERT_OK(res) << res; + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(sapCb->sapResponseSerial, serial); + + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::NOT_SUPPORTED, SapResultCode::SUCCESS})); + LOG(DEBUG) << "setTransferProtocolReq finished"; +} diff --git a/radio/aidl/vts/radio_sap_utils.h b/radio/aidl/vts/radio_sap_utils.h new file mode 100644 index 0000000000..bf17006d66 --- /dev/null +++ b/radio/aidl/vts/radio_sap_utils.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022 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. + */ +#pragma once + +#include +#include +#include + +#include "radio_aidl_hal_utils.h" + +using namespace aidl::android::hardware::radio::sap; + +class SapTest; + +/* Callback class for radio sap response */ +class SapCallback : public BnSapCallback { + protected: + SapTest& parent_sap; + + public: + SapCallback(SapTest& parent_config); + virtual ~SapCallback() = default; + + int32_t sapResponseSerial; + SapResultCode sapResultCode; + + virtual ::ndk::ScopedAStatus apduResponse(int32_t serial, SapResultCode resultCode, + const std::vector& adpuRsp) override; + + virtual ::ndk::ScopedAStatus connectResponse(int32_t serial, SapConnectRsp sapConnectRsp, + int32_t maxMsgSize) override; + + virtual ::ndk::ScopedAStatus disconnectIndication(int32_t serial, + SapDisconnectType sapDisconnectType) override; + + virtual ::ndk::ScopedAStatus disconnectResponse(int32_t serial) override; + + virtual ::ndk::ScopedAStatus errorResponse(int32_t serial) override; + + virtual ::ndk::ScopedAStatus powerResponse(int32_t serial, SapResultCode resultCode) override; + + virtual ::ndk::ScopedAStatus resetSimResponse(int32_t serial, + SapResultCode resultCode) override; + + virtual ::ndk::ScopedAStatus statusIndication(int32_t serial, SapStatus sapStatus) override; + + virtual ::ndk::ScopedAStatus transferAtrResponse(int32_t serial, SapResultCode resultCode, + const std::vector& atr) override; + + virtual ::ndk::ScopedAStatus transferCardReaderStatusResponse( + int32_t serial, SapResultCode resultCode, int32_t cardReaderStatus) override; + + virtual ::ndk::ScopedAStatus transferProtocolResponse(int32_t serial, + SapResultCode resultCode) override; +}; + +// The main test class for AIDL SAP. +class SapTest : public ::testing::TestWithParam { + private: + std::mutex mtx; + std::condition_variable cv; + int count; + + public: + virtual void SetUp() override; + + virtual void TearDown() override; + + ::testing::AssertionResult CheckAnyOfErrors(SapResultCode err, + std::vector errors); + + /* Used as a mechanism to inform the test about data/event callback */ + void notify(int receivedSerial); + + /* Test code calls this function to wait for response */ + std::cv_status wait(); + + /* Sap service */ + std::shared_ptr sap; + + /* Sap Callback object */ + std::shared_ptr sapCb; + + /* Serial for sap request */ + int32_t serial; +};