From 90f5171cb88b8f384b731b6eaf6a7922261bcf57 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 21 Sep 2021 11:09:12 -0700 Subject: [PATCH] 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 --- uwb/aidl/default/uwb_chip.cpp | 25 +++- uwb/aidl/default/uwb_chip.h | 1 + uwb/aidl/vts/Android.bp | 28 ++++ uwb/aidl/vts/OWNERS | 2 + uwb/aidl/vts/VtsHalUwbTargetTest.cpp | 210 +++++++++++++++++++++++++++ 5 files changed, 258 insertions(+), 8 deletions(-) create mode 100644 uwb/aidl/vts/Android.bp create mode 100644 uwb/aidl/vts/OWNERS create mode 100644 uwb/aidl/vts/VtsHalUwbTargetTest.cpp diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp index 727bcf133a..fe64fa7125 100644 --- a/uwb/aidl/default/uwb_chip.cpp +++ b/uwb/aidl/default/uwb_chip.cpp @@ -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& /* clientCallback */) { - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +::ndk::ScopedAStatus UwbChip::open(const std::shared_ptr& 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& /* data */, int32_t* /* bytes_written */) { + // TODO(b/195992658): Need emulator support for UCI stack. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } } // namespace impl diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h index 5d3f55cff8..ef1d5b634e 100644 --- a/uwb/aidl/default/uwb_chip.h +++ b/uwb/aidl/default/uwb_chip.h @@ -43,6 +43,7 @@ class UwbChip : public BnUwbChip { private: std::string name_; + std::shared_ptr mClientCallback; }; } // namespace impl } // namespace uwb diff --git a/uwb/aidl/vts/Android.bp b/uwb/aidl/vts/Android.bp new file mode 100644 index 0000000000..4d9f65307b --- /dev/null +++ b/uwb/aidl/vts/Android.bp @@ -0,0 +1,28 @@ +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", + ], +} diff --git a/uwb/aidl/vts/OWNERS b/uwb/aidl/vts/OWNERS new file mode 100644 index 0000000000..c4ad4164e1 --- /dev/null +++ b/uwb/aidl/vts/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 1042770 +include platform/packages/modules/Uwb:/OWNERS diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp new file mode 100644 index 0000000000..9ac2678d3f --- /dev/null +++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp @@ -0,0 +1,210 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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&)>& on_uci_message_cb, + const std::function& 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& 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&)> on_uci_message_cb_; + std::function on_hal_event_cb_; +}; + +class UwbAidl : public testing::TestWithParam { + public: + virtual void SetUp() override { + iuwb_ = IUwb::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); + ASSERT_NE(iuwb_, nullptr); + } + std::shared_ptr 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 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 getAnyChip() { + std::shared_ptr iuwb_chip; + ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip); + EXPECT_TRUE(status.isOk()); + EXPECT_NE(iuwb_chip, nullptr); + return iuwb_chip; + } + + std::shared_ptr getAnyChipAndOpen() { + std::promise open_cb_promise; + std::future open_cb_future{open_cb_promise.get_future()}; + std::shared_ptr callback = ndk::SharedRefBase::make( + [](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 chip_names; + ScopedAStatus status = iuwb_->getChips(&chip_names); + EXPECT_TRUE(status.isOk()); + EXPECT_FALSE(chip_names.empty()); +} + +TEST_P(UwbAidl, GetChip) { + std::shared_ptr iuwb_chip; + ScopedAStatus status = iuwb_->getChip(getAnyChipName(), &iuwb_chip); + EXPECT_TRUE(status.isOk()); + EXPECT_NE(iuwb_chip, nullptr); +} + +TEST_P(UwbAidl, ChipOpen) { + std::promise open_cb_promise; + std::future open_cb_future{open_cb_promise.get_future()}; + std::shared_ptr callback = ndk::SharedRefBase::make( + [](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 open_cb_promise; + std::future open_cb_future{open_cb_promise.get_future()}; + std::promise close_cb_promise; + std::future close_cb_future{close_cb_promise.get_future()}; + std::shared_ptr callback = ndk::SharedRefBase::make( + [](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 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 +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(); +}