From b61ee9eb3960a55040c658f403b24f1a69b24d81 Mon Sep 17 00:00:00 2001 From: Weilin Xu Date: Fri, 15 Dec 2023 16:05:31 -0800 Subject: [PATCH] Add tuner callback for default bcradio HAL Implemented mocked tuner callback and added unit test for getting and setting the default broadcast radio HAL implementation. Bug: 316630344 Test: atest DefaultBroadcastRadioHalTestCase Change-Id: I4d41746f7725a79a8d398a1fb798fbc7cab94e09 --- .../test/DefaultBroadcastRadioHalTest.cpp | 32 ++++++ .../test/MockBroadcastRadioCallback.cpp | 93 ++++++++++++++++ .../default/test/MockBroadcastRadioCallback.h | 103 ++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp create mode 100644 broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h diff --git a/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp index a3704365bb..f0cc9a2390 100644 --- a/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp +++ b/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp @@ -14,10 +14,13 @@ * limitations under the License. */ +#include "MockBroadcastRadioCallback.h" + #include #include #include +#include #include namespace aidl::android::hardware::broadcastradio { @@ -74,10 +77,19 @@ const VirtualRadio& getAmFmMockTestRadio() { class DefaultBroadcastRadioHalTest : public testing::Test { public: void SetUp() override { + ::android::base::SetDefaultTag("BcRadioAidlDef.test"); const VirtualRadio& amFmRadioMockTest = getAmFmMockTestRadio(); mBroadcastRadioHal = ::ndk::SharedRefBase::make(amFmRadioMockTest); + mTunerCallback = ndk::SharedRefBase::make(); } + + void TearDown() override { + mBroadcastRadioHal->unsetTunerCallback(); + EXPECT_FALSE(mTunerCallback->isTunerFailed()); + } + std::shared_ptr mBroadcastRadioHal; + std::shared_ptr mTunerCallback; }; TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfig) { @@ -136,4 +148,24 @@ TEST_F(DefaultBroadcastRadioHalTest, GetProperties) { } } +TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallback) { + auto halResult = mBroadcastRadioHal->setTunerCallback(mTunerCallback); + + ASSERT_TRUE(halResult.isOk()); +} + +TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallbackWithNull) { + auto halResult = mBroadcastRadioHal->setTunerCallback(nullptr); + + ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS)); +} + +TEST_F(DefaultBroadcastRadioHalTest, UnsetTunerCallbackWithNull) { + ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk()); + + auto halResult = mBroadcastRadioHal->unsetTunerCallback(); + + ASSERT_TRUE(halResult.isOk()); +} + } // namespace aidl::android::hardware::broadcastradio diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp new file mode 100644 index 0000000000..48f65fc9d8 --- /dev/null +++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 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 "MockBroadcastRadioCallback.h" + +#include + +namespace aidl::android::hardware::broadcastradio { + +namespace { +using std::vector; +} + +MockBroadcastRadioCallback::MockBroadcastRadioCallback() { + mAntennaConnectionState = true; +} + +ScopedAStatus MockBroadcastRadioCallback::onTuneFailed(Result result, + const ProgramSelector& selector) { + LOG(DEBUG) << "onTuneFailed with result with " << selector.toString().c_str(); + if (result != Result::CANCELED) { + std::lock_guard lk(mLock); + tunerFailed = true; + } + return ndk::ScopedAStatus::ok(); +} + +ScopedAStatus MockBroadcastRadioCallback::onCurrentProgramInfoChanged(const ProgramInfo& info) { + LOG(DEBUG) << "onCurrentProgramInfoChanged with " << info.toString().c_str(); + { + std::lock_guard lk(mLock); + mCurrentProgramInfo = info; + } + + mOnCurrentProgramInfoChangedFlag.notify(); + return ndk::ScopedAStatus::ok(); +} + +ScopedAStatus MockBroadcastRadioCallback::onProgramListUpdated( + [[maybe_unused]] const ProgramListChunk& chunk) { + return ndk::ScopedAStatus::ok(); +} + +ScopedAStatus MockBroadcastRadioCallback::onParametersUpdated( + [[maybe_unused]] const vector& parameters) { + return ndk::ScopedAStatus::ok(); +} + +ScopedAStatus MockBroadcastRadioCallback::onAntennaStateChange(bool connected) { + if (!connected) { + std::lock_guard lk(mLock); + mAntennaConnectionState = false; + } + return ndk::ScopedAStatus::ok(); +} + +ScopedAStatus MockBroadcastRadioCallback::onConfigFlagUpdated([[maybe_unused]] ConfigFlag in_flag, + [[maybe_unused]] bool in_value) { + return ndk::ScopedAStatus::ok(); +} + +bool MockBroadcastRadioCallback::waitOnCurrentProgramInfoChangedCallback() { + return mOnCurrentProgramInfoChangedFlag.wait(); +} + +void MockBroadcastRadioCallback::reset() { + mOnCurrentProgramInfoChangedFlag.reset(); +} + +bool MockBroadcastRadioCallback::isTunerFailed() { + std::lock_guard lk(mLock); + return tunerFailed; +} + +ProgramInfo MockBroadcastRadioCallback::getCurrentProgramInfo() { + std::lock_guard lk(mLock); + return mCurrentProgramInfo; +} + +} // namespace aidl::android::hardware::broadcastradio diff --git a/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h new file mode 100644 index 0000000000..2ae03e3f16 --- /dev/null +++ b/broadcastradio/aidl/default/test/MockBroadcastRadioCallback.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2024 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 +#include +#include +#include +#include + +#include + +#include + +#include + +namespace aidl::android::hardware::broadcastradio { + +namespace { +using ::ndk::ScopedAStatus; + +} // namespace + +class MockBroadcastRadioCallback final : public BnTunerCallback { + public: + explicit MockBroadcastRadioCallback(); + ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override; + ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override; + ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override; + ScopedAStatus onParametersUpdated(const std::vector& parameters) override; + ScopedAStatus onAntennaStateChange(bool connected) override; + ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override; + + bool waitOnCurrentProgramInfoChangedCallback(); + bool isTunerFailed(); + void reset(); + + ProgramInfo getCurrentProgramInfo(); + + private: + class CallbackFlag final { + public: + CallbackFlag(int timeoutMs) { mTimeoutMs = timeoutMs; } + /** + * Notify that the callback is called. + */ + void notify() { + std::unique_lock lock(mMutex); + mCalled = true; + lock.unlock(); + mCv.notify_all(); + }; + + /** + * Wait for the timeout passed into the constructor. + */ + bool wait() { + std::unique_lock lock(mMutex); + return mCv.wait_for(lock, std::chrono::milliseconds(mTimeoutMs), + [this] { return mCalled; }); + }; + + /** + * Reset the callback to not called. + */ + void reset() { + std::unique_lock lock(mMutex); + mCalled = false; + } + + private: + std::mutex mMutex; + bool mCalled GUARDED_BY(mMutex) = false; + std::condition_variable mCv; + int mTimeoutMs; + }; + + std::mutex mLock; + bool mAntennaConnectionState GUARDED_BY(mLock); + bool tunerFailed GUARDED_BY(mLock) = false; + ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock); + utils::ProgramInfoSet mProgramList GUARDED_BY(mLock); + CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS); +}; + +} // namespace aidl::android::hardware::broadcastradio