From aa2891826c52cd59c1acd288042c4319804b438a Mon Sep 17 00:00:00 2001 From: Amy Date: Fri, 9 Aug 2019 16:34:55 -0700 Subject: [PATCH] Tuner HAL VTS for Tuner and Frontend Interface. Bug: 135708935 Test: Manual Change-Id: I5be2206ffe606ccc5464635f9a26e2c281930a0b Merged-In: I5be2206ffe606ccc5464635f9a26e2c281930a0b --- tv/tuner/1.0/vts/functional/Android.bp | 32 ++ .../VtsHalTvTunerV1_0TargetTest.cpp | 307 ++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 tv/tuner/1.0/vts/functional/Android.bp create mode 100644 tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp new file mode 100644 index 0000000000..faf566c847 --- /dev/null +++ b/tv/tuner/1.0/vts/functional/Android.bp @@ -0,0 +1,32 @@ +// +// Copyright (C) 2019 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. +// + +cc_test { + name: "VtsHalTvTunerV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalTvTunerV1_0TargetTest.cpp"], + static_libs: [ + "android.hardware.tv.tuner@1.0", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlallocatorutils", + "libhidlmemory", + ], + shared_libs: [ + "libbinder", + ], + test_suites: ["general-tests"], +} diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp new file mode 100644 index 0000000000..4840a02e25 --- /dev/null +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2019 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. + */ + +#define LOG_TAG "Tuner_hidl_hal_test" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WAIT_TIMEOUT 3000000000 + +using android::Condition; +using android::IMemory; +using android::IMemoryHeap; +using android::MemoryDealer; +using android::Mutex; +using android::sp; +using android::hardware::fromHeap; +using android::hardware::hidl_string; +using android::hardware::hidl_vec; +using android::hardware::HidlMemory; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::FrontendAtscModulation; +using android::hardware::tv::tuner::V1_0::FrontendAtscSettings; +using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; +using android::hardware::tv::tuner::V1_0::FrontendEventType; +using android::hardware::tv::tuner::V1_0::FrontendId; +using android::hardware::tv::tuner::V1_0::FrontendInnerFec; +using android::hardware::tv::tuner::V1_0::FrontendSettings; +using android::hardware::tv::tuner::V1_0::IFrontend; +using android::hardware::tv::tuner::V1_0::IFrontendCallback; +using android::hardware::tv::tuner::V1_0::ITuner; +using android::hardware::tv::tuner::V1_0::Result; + +namespace { + +class FrontendCallback : public IFrontendCallback { + public: + virtual Return onEvent(FrontendEventType frontendEventType) override { + android::Mutex::Autolock autoLock(mMsgLock); + mEventReceived = true; + mEventType = frontendEventType; + mMsgCondition.signal(); + return Void(); + } + + virtual Return onDiseqcMessage(const hidl_vec& diseqcMessage) override { + android::Mutex::Autolock autoLock(mMsgLock); + mDiseqcMessageReceived = true; + mEventMessage = diseqcMessage; + mMsgCondition.signal(); + return Void(); + } + + void testOnEvent(sp& frontend, FrontendSettings settings); + void testOnDiseqcMessage(sp& frontend, FrontendSettings settings); + + private: + bool mEventReceived = false; + bool mDiseqcMessageReceived = false; + FrontendEventType mEventType; + hidl_vec mEventMessage; + android::Mutex mMsgLock; + android::Condition mMsgCondition; +}; + +void FrontendCallback::testOnEvent(sp& frontend, FrontendSettings settings) { + Result result = frontend->tune(settings); + + EXPECT_TRUE(result == Result::SUCCESS); + + android::Mutex::Autolock autoLock(mMsgLock); + while (!mEventReceived) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "event not received within timeout"; + return; + } + } +} + +void FrontendCallback::testOnDiseqcMessage(sp& frontend, FrontendSettings settings) { + Result result = frontend->tune(settings); + + EXPECT_TRUE(result == Result::SUCCESS); + + android::Mutex::Autolock autoLock(mMsgLock); + while (!mDiseqcMessageReceived) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "diseqc message not received within timeout"; + return; + } + } +} + +// Test environment for Tuner HIDL HAL. +class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { + public: + // get the test environment singleton + static TunerHidlEnvironment* Instance() { + static TunerHidlEnvironment* instance = new TunerHidlEnvironment; + return instance; + } + + virtual void registerTestServices() override { registerTestService(); } +}; + +class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { + public: + virtual void SetUp() override { + mService = ::testing::VtsHalHidlTargetTestBase::getService( + TunerHidlEnvironment::Instance()->getServiceName()); + ASSERT_NE(mService, nullptr); + } + + sp mService; + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + sp mFrontend; + sp mFrontendCallback; + + ::testing::AssertionResult createFrontend(int32_t frontendId); + ::testing::AssertionResult tuneFrontend(int32_t frontendId); + ::testing::AssertionResult stopTuneFrontend(int32_t frontendId); + ::testing::AssertionResult closeFrontend(int32_t frontendId); +}; + +::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) { + Result status; + + mService->openFrontendById(frontendId, [&](Result result, const sp& frontend) { + mFrontend = frontend; + status = result; + }); + if (status != Result::SUCCESS) { + return ::testing::AssertionFailure(); + } + + mFrontendCallback = new FrontendCallback(); + auto callbackStatus = mFrontend->setCallback(mFrontendCallback); + + return ::testing::AssertionResult(callbackStatus.isOk()); +} + +::testing::AssertionResult TunerHidlTest::tuneFrontend(int32_t frontendId) { + if (createFrontend(frontendId) == ::testing::AssertionFailure()) { + return ::testing::AssertionFailure(); + } + + // Frontend Settings for testing + FrontendSettings frontendSettings; + FrontendAtscSettings frontendAtscSettings{ + .frequency = 0, + .modulation = FrontendAtscModulation::UNDEFINED, + }; + frontendSettings.atsc() = frontendAtscSettings; + mFrontendCallback->testOnEvent(mFrontend, frontendSettings); + + FrontendDvbtSettings frontendDvbtSettings{ + .frequency = 0, + .modulation = FrontendAtscModulation::UNDEFINED, + .fec = FrontendInnerFec::FEC_UNDEFINED, + }; + frontendSettings.dvbt(frontendDvbtSettings); + mFrontendCallback->testOnEvent(mFrontend, frontendSettings); + + return ::testing::AssertionResult(true); +} + +::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) { + Result status; + if (createFrontend(frontendId) == ::testing::AssertionFailure()) { + return ::testing::AssertionFailure(); + } + + status = mFrontend->stopTune(); + return ::testing::AssertionResult(status == Result::SUCCESS); +} + +::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) { + Result status; + if (createFrontend(frontendId) == ::testing::AssertionFailure()) { + return ::testing::AssertionFailure(); + } + + status = mFrontend->close(); + return ::testing::AssertionResult(status == Result::SUCCESS); +} + +TEST_F(TunerHidlTest, CreateFrontend) { + Result status; + hidl_vec feIds; + + description("Create Frontends"); + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + feIds = frontendIds; + }); + + if (feIds.size() == 0) { + ALOGW("[ WARN ] Frontend isn't available"); + return; + } + + for (size_t i = 0; i < feIds.size(); i++) { + ASSERT_TRUE(createFrontend(feIds[i])); + } +} + +TEST_F(TunerHidlTest, TuneFrontend) { + Result status; + hidl_vec feIds; + + description("Tune Frontends and check callback onEvent"); + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + feIds = frontendIds; + }); + + if (feIds.size() == 0) { + ALOGW("[ WARN ] Frontend isn't available"); + return; + } + + for (size_t i = 0; i < feIds.size(); i++) { + ASSERT_TRUE(tuneFrontend(feIds[i])); + } +} + +TEST_F(TunerHidlTest, StopTuneFrontend) { + Result status; + hidl_vec feIds; + + description("stopTune Frontends"); + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + feIds = frontendIds; + }); + + if (feIds.size() == 0) { + ALOGW("[ WARN ] Frontend isn't available"); + return; + } + + for (size_t i = 0; i < feIds.size(); i++) { + ASSERT_TRUE(stopTuneFrontend(feIds[i])); + } +} + +TEST_F(TunerHidlTest, CloseFrontend) { + Result status; + hidl_vec feIds; + + description("Close Frontends"); + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + feIds = frontendIds; + }); + + if (feIds.size() == 0) { + ALOGW("[ WARN ] Frontend isn't available"); + return; + } + + for (size_t i = 0; i < feIds.size(); i++) { + ASSERT_TRUE(closeFrontend(feIds[i])); + } +} + +} // namespace + +int main(int argc, char** argv) { + ::testing::AddGlobalTestEnvironment(TunerHidlEnvironment::Instance()); + ::testing::InitGoogleTest(&argc, argv); + TunerHidlEnvironment::Instance()->init(&argc, argv); + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + return status; +}