Add program list test for default bcradio HAL

Added unit tests for methods related to program list updates
in the default AIDL broadcast radio HAL implementation and the
corresponding mock tuner callback methods.

Bug: 316630344
Test: atest DefaultBroadcastRadioHalTestCase
Change-Id: I0bde2b9cc376315320521a1d13ec521781a77cca
This commit is contained in:
Weilin Xu
2023-12-15 16:05:31 -08:00
parent e2d1465d55
commit ed44150e86
3 changed files with 84 additions and 14 deletions

View File

@@ -132,6 +132,37 @@ class DefaultBroadcastRadioHalTest : public testing::Test {
return false;
}
std::optional<utils::ProgramInfoSet> getProgramList() {
ProgramFilter emptyFilter = {};
return getProgramList(emptyFilter);
}
std::optional<utils::ProgramInfoSet> getProgramList(const ProgramFilter& filter) {
mTunerCallback->reset();
auto startResult = mBroadcastRadioHal->startProgramListUpdates(filter);
EXPECT_TRUE(startResult.isOk());
if (!startResult.isOk()) {
return std::nullopt;
}
EXPECT_TRUE(mTunerCallback->waitProgramReady());
auto stopResult = mBroadcastRadioHal->stopProgramListUpdates();
EXPECT_TRUE(stopResult.isOk());
return mTunerCallback->getProgramList();
}
void switchToFmBand() {
ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
mTunerCallback->reset();
ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
verifyUpdatedProgramInfo(kFmSel1);
}
std::shared_ptr<BroadcastRadio> mBroadcastRadioHal;
std::shared_ptr<MockBroadcastRadioCallback> mTunerCallback;
};
@@ -326,10 +357,7 @@ TEST_F(DefaultBroadcastRadioHalTest, StepDownFromLowerBound) {
}
TEST_F(DefaultBroadcastRadioHalTest, StepWithoutTunerCallback) {
ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
mTunerCallback->reset();
ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
verifyUpdatedProgramInfo(kFmSel1);
switchToFmBand();
mBroadcastRadioHal->unsetTunerCallback();
auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
@@ -399,10 +427,7 @@ TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithSkipSubchannel) {
}
TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithFirstProgramInProgramList) {
ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
mTunerCallback->reset();
ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
verifyUpdatedProgramInfo(kFmSel1);
switchToFmBand();
auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
@@ -411,10 +436,7 @@ TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithFirstProgramInProgramList) {
}
TEST_F(DefaultBroadcastRadioHalTest, SeekWithoutTunerCallback) {
ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
mTunerCallback->reset();
ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
verifyUpdatedProgramInfo(kFmSel1);
switchToFmBand();
mBroadcastRadioHal->unsetTunerCallback();
auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
@@ -433,4 +455,31 @@ TEST_F(DefaultBroadcastRadioHalTest, Cancel) {
mTunerCallback->reset();
}
TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithEmptyFilter) {
switchToFmBand();
auto programList = getProgramList();
ASSERT_TRUE(programList.has_value());
for (auto it = programList->begin(); it != programList->end(); it++) {
EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
}
}
TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithAmFmFilter) {
ProgramFilter amFmFilter = {.identifierTypes = {IdentifierType::AMFM_FREQUENCY_KHZ},
.identifiers = {},
.includeCategories = false,
.excludeModifications = false};
switchToFmBand();
auto programList = getProgramList(amFmFilter);
ASSERT_TRUE(programList.has_value());
for (auto it = programList->begin(); it != programList->end(); it++) {
EXPECT_TRUE(utils::hasId(it->selector, IdentifierType::AMFM_FREQUENCY_KHZ));
EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
}
}
} // namespace aidl::android::hardware::broadcastradio

View File

@@ -49,8 +49,16 @@ ScopedAStatus MockBroadcastRadioCallback::onCurrentProgramInfoChanged(const Prog
return ndk::ScopedAStatus::ok();
}
ScopedAStatus MockBroadcastRadioCallback::onProgramListUpdated(
[[maybe_unused]] const ProgramListChunk& chunk) {
ScopedAStatus MockBroadcastRadioCallback::onProgramListUpdated(const ProgramListChunk& chunk) {
{
std::lock_guard<std::mutex> lk(mLock);
updateProgramList(chunk, &mProgramList);
}
if (chunk.complete) {
mOnProgramListReadyFlag.notify();
}
return ndk::ScopedAStatus::ok();
}
@@ -76,8 +84,13 @@ bool MockBroadcastRadioCallback::waitOnCurrentProgramInfoChangedCallback() {
return mOnCurrentProgramInfoChangedFlag.wait();
}
bool MockBroadcastRadioCallback::waitProgramReady() {
return mOnProgramListReadyFlag.wait();
}
void MockBroadcastRadioCallback::reset() {
mOnCurrentProgramInfoChangedFlag.reset();
mOnProgramListReadyFlag.reset();
}
bool MockBroadcastRadioCallback::isTunerFailed() {
@@ -90,4 +103,9 @@ ProgramInfo MockBroadcastRadioCallback::getCurrentProgramInfo() {
return mCurrentProgramInfo;
}
utils::ProgramInfoSet MockBroadcastRadioCallback::getProgramList() {
std::lock_guard<std::mutex> lk(mLock);
return mProgramList;
}
} // namespace aidl::android::hardware::broadcastradio

View File

@@ -49,10 +49,12 @@ class MockBroadcastRadioCallback final : public BnTunerCallback {
ScopedAStatus onConfigFlagUpdated(ConfigFlag in_flag, bool in_value) override;
bool waitOnCurrentProgramInfoChangedCallback();
bool waitProgramReady();
bool isTunerFailed();
void reset();
ProgramInfo getCurrentProgramInfo();
utils::ProgramInfoSet getProgramList();
private:
class CallbackFlag final {
@@ -98,6 +100,7 @@ class MockBroadcastRadioCallback final : public BnTunerCallback {
ProgramInfo mCurrentProgramInfo GUARDED_BY(mLock);
utils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
CallbackFlag mOnCurrentProgramInfoChangedFlag = CallbackFlag(IBroadcastRadio::TUNER_TIMEOUT_MS);
CallbackFlag mOnProgramListReadyFlag = CallbackFlag(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS);
};
} // namespace aidl::android::hardware::broadcastradio