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

Commit 90f5171c authored by Roshan Pius's avatar Roshan Pius
Browse files

uwb: Add vts tests for UWB HAL

No target to run the tests yet. So, just starting the VTS test suite for
UWB with some simple tests.

Also, modified the reference HAL implementation to emulate the startuo
flow.

Bug: 191175259
Test: atest VtsHalUwbTargetTest (using reference HAL on cuttlefish)
Change-Id: I2f01a3fec3324e85123d1d17e1b03dd284aee7b1
parent 0e4e5e11
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -16,13 +16,17 @@

#include "uwb.h"

namespace {
constexpr static int kVendorUciVersion = 1;
}

namespace android {
namespace hardware {
namespace uwb {
namespace impl {
using namespace ::aidl::android::hardware::uwb;

UwbChip::UwbChip(const std::string& name) : name_(name) {}
UwbChip::UwbChip(const std::string& name) : name_(name), mClientCallback(nullptr) {}
UwbChip::~UwbChip() {}

::ndk::ScopedAStatus UwbChip::getName(std::string* name) {
@@ -30,25 +34,30 @@ UwbChip::~UwbChip() {}
    return ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus UwbChip::open(
        const std::shared_ptr<IUwbClientCallback>& /* clientCallback */) {
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
::ndk::ScopedAStatus UwbChip::open(const std::shared_ptr<IUwbClientCallback>& clientCallback) {
    mClientCallback = clientCallback;
    mClientCallback->onHalEvent(UwbEvent::OPEN_CPLT, UwbStatus::OK);
    return ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus UwbChip::close() {
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    mClientCallback->onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK);
    mClientCallback = nullptr;
    return ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus UwbChip::coreInit() {
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    return ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus UwbChip::getSupportedVendorUciVersion(int32_t* /* version */) {
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
::ndk::ScopedAStatus UwbChip::getSupportedVendorUciVersion(int32_t* version) {
    *version = kVendorUciVersion;
    return ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus UwbChip::sendUciMessage(const std::vector<uint8_t>& /* data */,
                                             int32_t* /* bytes_written */) {
    // TODO(b/195992658): Need emulator support for UCI stack.
    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}  // namespace impl
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ class UwbChip : public BnUwbChip {

  private:
    std::string name_;
    std::shared_ptr<IUwbClientCallback> mClientCallback;
};
}  // namespace impl
}  // namespace uwb
+28 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "hardware_interfaces_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["hardware_interfaces_license"],
}

cc_test {
    name: "VtsHalUwbTargetTest",
    defaults: [
        "VtsHalTargetTestDefaults",
        "use_libaidlvintf_gtest_helper_static",
    ],
    srcs: ["VtsHalUwbTargetTest.cpp"],
    shared_libs: [
        "libbinder",
        "libbinder_ndk",
    ],
    static_libs: [
        "android.hardware.uwb-V1-ndk",
    ],
    test_suites: [
        "general-tests",
        "vts",
    ],
}

uwb/aidl/vts/OWNERS

0 → 100644
+2 −0
Original line number Diff line number Diff line
# Bug component: 1042770
include platform/packages/modules/Uwb:/OWNERS
+210 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 std::shared_ptrecific language governing permissions and
 * limitations under the License.
 */
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/uwb/BnUwbClientCallback.h>
#include <aidl/android/hardware/uwb/IUwb.h>
#include <aidl/android/hardware/uwb/IUwbChip.h>
#include <aidl/android/hardware/uwb/IUwbClientCallback.h>
#include <android/binder_auto_utils.h>
#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>

#include <future>

using aidl::android::hardware::uwb::BnUwbClientCallback;
using aidl::android::hardware::uwb::IUwb;
using aidl::android::hardware::uwb::IUwbChip;
using aidl::android::hardware::uwb::IUwbClientCallback;
using aidl::android::hardware::uwb::UwbEvent;
using aidl::android::hardware::uwb::UwbStatus;
using android::ProcessState;
using android::String16;
using ndk::ScopedAStatus;
using ndk::SpAIBinder;

namespace {
constexpr static int kCallbackTimeoutMs = 250;
}  // namespace

class UwbClientCallback : public BnUwbClientCallback {
  public:
    UwbClientCallback(const std::function<void(const std::vector<uint8_t>&)>& on_uci_message_cb,
                      const std::function<void(UwbEvent, UwbStatus)>& on_hal_event_cb)
        : on_uci_message_cb_(on_uci_message_cb), on_hal_event_cb_(on_hal_event_cb) {}

    ScopedAStatus onUciMessage(const std::vector<uint8_t>& data) override {
        on_uci_message_cb_(data);
        return ScopedAStatus::ok();
    }

    ScopedAStatus onHalEvent(UwbEvent uwb_event, UwbStatus uwb_status) override {
        on_hal_event_cb_(uwb_event, uwb_status);
        return ScopedAStatus::ok();
    }

  private:
    std::function<void(const std::vector<uint8_t>&)> on_uci_message_cb_;
    std::function<void(UwbEvent, UwbStatus)> on_hal_event_cb_;
};

class UwbAidl : public testing::TestWithParam<std::string> {
  public:
    virtual void SetUp() override {
        iuwb_ = IUwb::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
        ASSERT_NE(iuwb_, nullptr);
    }
    std::shared_ptr<IUwb> iuwb_;

    // TODO (b/197638976): We pick the first chip here. Need to fix this
    // for supporting multiple chips in the future.
    std::string getAnyChipName() {
        std::vector<std::string> chip_names;
        ScopedAStatus status = iuwb_->getChips(&chip_names);
        EXPECT_TRUE(status.isOk());
        EXPECT_FALSE(chip_names.empty());
        return chip_names[0];
    }

    // TODO (b/197638976): We pick the first chip here. Need to fix this
    // for supporting multiple chips in the future.
    std::shared_ptr<IUwbChip> getAnyChip() {
        std::shared_ptr<IUwbChip> iuwb_chip;
        ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip);
        EXPECT_TRUE(status.isOk());
        EXPECT_NE(iuwb_chip, nullptr);
        return iuwb_chip;
    }

    std::shared_ptr<IUwbChip> getAnyChipAndOpen() {
        std::promise<void> open_cb_promise;
        std::future<void> open_cb_future{open_cb_promise.get_future()};
        std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
                [](auto /* data */) {},
                [&open_cb_promise](auto event, auto /* status */) {
                    if (event == UwbEvent::OPEN_CPLT) {
                        open_cb_promise.set_value();
                    }
                });
        std::chrono::milliseconds timeout{kCallbackTimeoutMs};
        const auto iuwb_chip = getAnyChip();
        EXPECT_TRUE(iuwb_chip->open(callback).isOk());
        EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
        return iuwb_chip;
    }
};

TEST_P(UwbAidl, GetChips) {
    std::vector<std::string> chip_names;
    ScopedAStatus status = iuwb_->getChips(&chip_names);
    EXPECT_TRUE(status.isOk());
    EXPECT_FALSE(chip_names.empty());
}

TEST_P(UwbAidl, GetChip) {
    std::shared_ptr<IUwbChip> iuwb_chip;
    ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip);
    EXPECT_TRUE(status.isOk());
    EXPECT_NE(iuwb_chip, nullptr);
}

TEST_P(UwbAidl, ChipOpen) {
    std::promise<void> open_cb_promise;
    std::future<void> open_cb_future{open_cb_promise.get_future()};
    std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
            [](auto /* data */) {},
            [&open_cb_promise](auto event, auto /* status */) {
                if (event == UwbEvent::OPEN_CPLT) {
                    open_cb_promise.set_value();
                }
            });
    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
    const auto iuwb_chip = getAnyChip();
    EXPECT_TRUE(iuwb_chip->open(callback).isOk());
    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
}

TEST_P(UwbAidl, ChipClose) {
    std::promise<void> open_cb_promise;
    std::future<void> open_cb_future{open_cb_promise.get_future()};
    std::promise<void> close_cb_promise;
    std::future<void> close_cb_future{close_cb_promise.get_future()};
    std::shared_ptr<UwbClientCallback> callback = ndk::SharedRefBase::make<UwbClientCallback>(
            [](auto /* data */) {},
            [&open_cb_promise, &close_cb_promise](auto event, auto /* status */) {
                if (event == UwbEvent::OPEN_CPLT) {
                    open_cb_promise.set_value();
                }
                if (event == UwbEvent::CLOSE_CPLT) {
                    close_cb_promise.set_value();
                }
            });
    std::chrono::milliseconds timeout{kCallbackTimeoutMs};
    const auto iuwb_chip = getAnyChip();
    EXPECT_TRUE(iuwb_chip->open(callback).isOk());
    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
    EXPECT_TRUE(iuwb_chip->close().isOk());
    EXPECT_EQ(close_cb_future.wait_for(timeout), std::future_status::ready);
}

TEST_P(UwbAidl, ChipCoreInit) {
    const auto iuwb_chip = getAnyChipAndOpen();
    EXPECT_TRUE(iuwb_chip->coreInit().isOk());
}

TEST_P(UwbAidl, ChipGetSupportedVendorUciVersion) {
    const auto iuwb_chip = getAnyChipAndOpen();
    EXPECT_TRUE(iuwb_chip->coreInit().isOk());

    int version;
    EXPECT_TRUE(iuwb_chip->getSupportedVendorUciVersion(&version).isOk());
    EXPECT_GT(version, 0);
}

TEST_P(UwbAidl, ChipGetName) {
    std::string chip_name = getAnyChipName();
    std::shared_ptr<IUwbChip> iuwb_chip;
    ScopedAStatus status = iuwb_->getChip(chip_name, &iuwb_chip);
    EXPECT_TRUE(status.isOk());
    EXPECT_NE(iuwb_chip, nullptr);

    std::string retrieved_chip_name;
    status = iuwb_chip->getName(&retrieved_chip_name);
    EXPECT_TRUE(status.isOk());
    EXPECT_EQ(retrieved_chip_name, chip_name);
}

/**
TEST_P(UwbAidl, ChipSendUciMessage_GetDeviceInfo) {
const auto iuwb_chip = getAnyChipAndOpen(callback);
EXPECT_TRUE(iuwb_chip->coreInit(callback).isOk());

const std::vector<uint8_t>
EXPECT_TRUE(iuwb_chip->sendUciMessage().isOk());
} */

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UwbAidl);
INSTANTIATE_TEST_SUITE_P(Uwb, UwbAidl,
                         testing::ValuesIn(android::getAidlHalInstanceNames(IUwb::descriptor)),
                         android::PrintInstanceNameToString);

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    ProcessState::self()->setThreadPoolMaxThreadCount(1);
    ProcessState::self()->startThreadPool();
    return RUN_ALL_TESTS();
}