Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc1e6193 authored by Pomai Ahlo's avatar Pomai Ahlo
Browse files

[ISap hidl2aidl] VTS Tests

Add VTS tests for the new AIDL interface

Test: atest VtsHalRadioTargetTest:PerInstance/SapTest
Bug: 241969533
Change-Id: Ia4a6be9aa0fd61c310fb539b44cc4d6a2e6e3852
parent 25fb3aac
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -53,6 +53,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",
@@ -73,6 +75,7 @@ cc_test {
        "android.hardware.radio.messaging-V2-ndk",
        "android.hardware.radio.modem-V2-ndk",
        "android.hardware.radio.network-V2-ndk",
        "android.hardware.radio.sap-V1-ndk",
        "android.hardware.radio.sim-V2-ndk",
        "android.hardware.radio.voice-V2-ndk",
    ],
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,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"

@@ -55,6 +56,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)),
+95 −0
Original line number Diff line number Diff line
/*
 * 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 <android-base/logging.h>

SapCallback::SapCallback(SapTest& parent) : parent_sap(parent) {}

::ndk::ScopedAStatus SapCallback::apduResponse(int32_t serialNumber, SapResultCode resultCode,
                                               const std::vector<uint8_t>& /*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<uint8_t>& /*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();
}
+233 −0
Original line number Diff line number Diff line
/*
 * 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 <android-base/logging.h>
#include <android/binder_manager.h>

#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<SapCallback>(*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<SapResultCode> 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<std::mutex> lock(mtx);
    count++;
    if (serial == receivedSerial) {
        cv.notify_one();
    }
}

std::cv_status SapTest::wait() {
    std::unique_lock<std::mutex> 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<uint8_t> 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";
}
+99 −0
Original line number Diff line number Diff line
/*
 * 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 <aidl/Gtest.h>
#include <aidl/android/hardware/radio/sap/BnSapCallback.h>
#include <aidl/android/hardware/radio/sap/ISap.h>

#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<uint8_t>& 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<uint8_t>& 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<std::string> {
  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<SapResultCode> 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<ISap> sap;

    /* Sap Callback object */
    std::shared_ptr<SapCallback> sapCb;

    /* Serial for sap request */
    int32_t serial;
};