Loading broadcastradio/1.1/default/Tuner.cpp +20 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ void Tuner::tuneInternalLocked(const ProgramSelector& sel) { mCallback->tuneComplete(Result::OK, mCurrentProgramInfo.base); } else { mCallback1_1->tuneComplete_1_1(Result::OK, mCurrentProgramInfo.selector); mCallback1_1->currentProgramInfoChanged(); } } Loading Loading @@ -214,8 +215,10 @@ Return<Result> Tuner::step(Direction direction, bool skipSubChannel) { return Result::NOT_INITIALIZED; } ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set"); if (!mIsAmfmConfigSet) return Result::INVALID_STATE; if (!mIsAmfmConfigSet) { ALOGW("AM/FM config not set"); return Result::INVALID_STATE; } mIsTuneCompleted = false; auto task = [this, direction]() { Loading Loading @@ -256,14 +259,26 @@ Return<Result> Tuner::tuneByProgramSelector(const ProgramSelector& sel) { lock_guard<mutex> lk(mMut); if (mIsClosed) return Result::NOT_INITIALIZED; if (utils::isAmFm(utils::getType(mCurrentProgram))) { ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set"); if (!mIsAmfmConfigSet) return Result::INVALID_STATE; // checking if ProgramSelector is valid auto programType = utils::getType(sel); if (utils::isAmFm(programType)) { if (!mIsAmfmConfigSet) { ALOGW("AM/FM config not set"); return Result::INVALID_STATE; } auto freq = utils::getId(sel, IdentifierType::AMFM_FREQUENCY); if (freq < mAmfmConfig.lowerLimit || freq > mAmfmConfig.upperLimit) { return Result::INVALID_ARGUMENTS; } } else if (programType == ProgramType::DAB) { if (!utils::hasId(sel, IdentifierType::DAB_SIDECC)) return Result::INVALID_ARGUMENTS; } else if (programType == ProgramType::DRMO) { if (!utils::hasId(sel, IdentifierType::DRMO_SERVICE_ID)) return Result::INVALID_ARGUMENTS; } else if (programType == ProgramType::SXM) { if (!utils::hasId(sel, IdentifierType::SXM_SERVICE_ID)) return Result::INVALID_ARGUMENTS; } else { return Result::INVALID_ARGUMENTS; } mIsTuneCompleted = false; Loading broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp +74 −6 Original line number Diff line number Diff line Loading @@ -62,8 +62,17 @@ using std::this_thread::sleep_for; static constexpr auto kConfigTimeout = 10s; static constexpr auto kConnectModuleTimeout = 1s; static constexpr auto kTuneTimeout = 30s; static constexpr auto kEventPropagationTimeout = 1s; static constexpr auto kFullScanTimeout = 1min; static constexpr ProgramType kStandardProgramTypes[] = { ProgramType::AM, ProgramType::FM, ProgramType::AM_HD, ProgramType::FM_HD, ProgramType::DAB, ProgramType::DRMO, ProgramType::SXM}; static constexpr IdentifierType kVendorPrimartIds[] = { IdentifierType::VENDOR1_PRIMARY, IdentifierType::VENDOR2_PRIMARY, IdentifierType::VENDOR3_PRIMARY, IdentifierType::VENDOR4_PRIMARY}; static void printSkipped(std::string msg) { std::cout << "[ SKIPPED ] " << msg << std::endl; } Loading @@ -84,7 +93,7 @@ struct TunerCallbackMock : public ITunerCallback { MOCK_METHOD1(backgroundScanAvailable, Return<void>(bool)); MOCK_TIMEOUT_METHOD1(backgroundScanComplete, Return<void>(ProgramListResult)); MOCK_METHOD0(programListChanged, Return<void>()); MOCK_METHOD0(currentProgramInfoChanged, Return<void>()); MOCK_TIMEOUT_METHOD0(currentProgramInfoChanged, Return<void>()); }; class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase, Loading Loading @@ -315,7 +324,8 @@ TEST_P(BroadcastRadioHalTest, OpenTunerTwice) { * - getProgramList either succeeds or returns NOT_STARTED/NOT_READY status; * - if the program list is NOT_STARTED, startBackgroundScan makes it completed * within a full scan timeout and the next getProgramList call succeeds; * - if the program list is not empty, tuneByProgramSelector call succeeds. * - if the program list is not empty, tuneByProgramSelector call succeeds; * - getProgramInformation_1_1 returns the same selector as returned in tuneComplete_1_1 call. */ TEST_P(BroadcastRadioHalTest, TuneFromProgramList) { if (skipped) return; Loading @@ -340,12 +350,70 @@ TEST_P(BroadcastRadioHalTest, TuneFromProgramList) { EXPECT_CALL(*mCallback, tuneComplete(_, _)).Times(0); EXPECT_TIMEOUT_CALL(*mCallback, tuneComplete_1_1, Result::OK, _) .WillOnce(DoAll(SaveArg<1>(&selCb), testing::Return(ByMove(Void())))); EXPECT_TIMEOUT_CALL(*mCallback, currentProgramInfoChanged); auto tuneResult = mTuner->tuneByProgramSelector(firstProgram.selector); ASSERT_EQ(Result::OK, tuneResult); EXPECT_TIMEOUT_CALL_WAIT(*mCallback, tuneComplete_1_1, kTuneTimeout); EXPECT_TIMEOUT_CALL_WAIT(*mCallback, currentProgramInfoChanged, kEventPropagationTimeout); EXPECT_EQ(firstProgram.selector.primaryId, selCb.primaryId); bool called = false; auto getResult = mTuner->getProgramInformation_1_1([&](Result result, ProgramInfo info) { called = true; EXPECT_EQ(Result::OK, result); EXPECT_EQ(selCb, info.selector); }); ASSERT_TRUE(getResult.isOk()); ASSERT_TRUE(called); } /** * Test that primary vendor identifier isn't used for standard program types. * * Verifies that: * - tuneByProgramSelector fails when VENDORn_PRIMARY is set as a primary * identifier for program types other than VENDORn. */ TEST_P(BroadcastRadioHalTest, TuneFailsForPrimaryVendor) { if (skipped) return; ASSERT_TRUE(openTuner()); for (auto ptype : kStandardProgramTypes) { ALOGD("Checking %s...", toString(ptype).c_str()); for (auto idtype : kVendorPrimartIds) { ALOGD("...with %s", toString(idtype).c_str()); ProgramSelector sel = {}; sel.programType = static_cast<uint32_t>(ptype); sel.primaryId.type = static_cast<uint32_t>(idtype); auto tuneResult = mTuner->tuneByProgramSelector(sel); ASSERT_NE(Result::OK, tuneResult); } } } /** * Test that tune with unknown program type fails. * * Verifies that: * - tuneByProgramSelector fails with INVALID_ARGUMENT when unknown program type is passed. */ TEST_P(BroadcastRadioHalTest, TuneFailsForUnknownProgram) { if (skipped) return; ASSERT_TRUE(openTuner()); // Program type is 1-based, so 0 will be always invalid. ProgramSelector sel = {}; auto tuneResult = mTuner->tuneByProgramSelector(sel); ASSERT_EQ(Result::INVALID_ARGUMENTS, tuneResult); } /** * Test cancelling announcement. * * Verifies that: * - cancelAnnouncement succeeds either when there is an announcement or there is none. */ TEST_P(BroadcastRadioHalTest, CancelAnnouncement) { if (skipped) return; ASSERT_TRUE(openTuner()); Loading @@ -358,7 +426,7 @@ TEST_P(BroadcastRadioHalTest, CancelAnnouncement) { * Test getImage call with invalid image ID. * * Verifies that: * - getImage call handles argument 0 gracefully * - getImage call handles argument 0 gracefully. */ TEST_P(BroadcastRadioHalTest, GetNoImage) { if (skipped) return; Loading @@ -375,8 +443,8 @@ TEST_P(BroadcastRadioHalTest, GetNoImage) { * Test proper image format in metadata. * * Verifies that: * - all images in metadata are provided out-of-band (by id, not as a binary blob) * - images are available for getImage call * - all images in metadata are provided out-of-band (by id, not as a binary blob); * - images are available for getImage call. */ TEST_P(BroadcastRadioHalTest, OobImagesOnly) { if (skipped) return; Loading Loading @@ -420,7 +488,7 @@ TEST_P(BroadcastRadioHalTest, OobImagesOnly) { * Test AnalogForced switch. * * Verifies that: * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same. */ TEST_P(BroadcastRadioHalTest, AnalogForcedSwitch) { if (skipped) return; Loading broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h +8 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,14 @@ } \ return ret; /** * Gmock MOCK_METHOD0 timeout-capable extension. */ #define MOCK_TIMEOUT_METHOD0(Method, ...) \ MOCK_METHOD0(egmock_##Method, __VA_ARGS__); \ EGMOCK_TIMEOUT_METHOD_DEF_(Method); \ virtual GMOCK_RESULT_(, __VA_ARGS__) Method() { EGMOCK_TIMEOUT_METHOD_BODY_(Method); } /** * Gmock MOCK_METHOD1 timeout-capable extension. */ Loading Loading
broadcastradio/1.1/default/Tuner.cpp +20 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ void Tuner::tuneInternalLocked(const ProgramSelector& sel) { mCallback->tuneComplete(Result::OK, mCurrentProgramInfo.base); } else { mCallback1_1->tuneComplete_1_1(Result::OK, mCurrentProgramInfo.selector); mCallback1_1->currentProgramInfoChanged(); } } Loading Loading @@ -214,8 +215,10 @@ Return<Result> Tuner::step(Direction direction, bool skipSubChannel) { return Result::NOT_INITIALIZED; } ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set"); if (!mIsAmfmConfigSet) return Result::INVALID_STATE; if (!mIsAmfmConfigSet) { ALOGW("AM/FM config not set"); return Result::INVALID_STATE; } mIsTuneCompleted = false; auto task = [this, direction]() { Loading Loading @@ -256,14 +259,26 @@ Return<Result> Tuner::tuneByProgramSelector(const ProgramSelector& sel) { lock_guard<mutex> lk(mMut); if (mIsClosed) return Result::NOT_INITIALIZED; if (utils::isAmFm(utils::getType(mCurrentProgram))) { ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set"); if (!mIsAmfmConfigSet) return Result::INVALID_STATE; // checking if ProgramSelector is valid auto programType = utils::getType(sel); if (utils::isAmFm(programType)) { if (!mIsAmfmConfigSet) { ALOGW("AM/FM config not set"); return Result::INVALID_STATE; } auto freq = utils::getId(sel, IdentifierType::AMFM_FREQUENCY); if (freq < mAmfmConfig.lowerLimit || freq > mAmfmConfig.upperLimit) { return Result::INVALID_ARGUMENTS; } } else if (programType == ProgramType::DAB) { if (!utils::hasId(sel, IdentifierType::DAB_SIDECC)) return Result::INVALID_ARGUMENTS; } else if (programType == ProgramType::DRMO) { if (!utils::hasId(sel, IdentifierType::DRMO_SERVICE_ID)) return Result::INVALID_ARGUMENTS; } else if (programType == ProgramType::SXM) { if (!utils::hasId(sel, IdentifierType::SXM_SERVICE_ID)) return Result::INVALID_ARGUMENTS; } else { return Result::INVALID_ARGUMENTS; } mIsTuneCompleted = false; Loading
broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp +74 −6 Original line number Diff line number Diff line Loading @@ -62,8 +62,17 @@ using std::this_thread::sleep_for; static constexpr auto kConfigTimeout = 10s; static constexpr auto kConnectModuleTimeout = 1s; static constexpr auto kTuneTimeout = 30s; static constexpr auto kEventPropagationTimeout = 1s; static constexpr auto kFullScanTimeout = 1min; static constexpr ProgramType kStandardProgramTypes[] = { ProgramType::AM, ProgramType::FM, ProgramType::AM_HD, ProgramType::FM_HD, ProgramType::DAB, ProgramType::DRMO, ProgramType::SXM}; static constexpr IdentifierType kVendorPrimartIds[] = { IdentifierType::VENDOR1_PRIMARY, IdentifierType::VENDOR2_PRIMARY, IdentifierType::VENDOR3_PRIMARY, IdentifierType::VENDOR4_PRIMARY}; static void printSkipped(std::string msg) { std::cout << "[ SKIPPED ] " << msg << std::endl; } Loading @@ -84,7 +93,7 @@ struct TunerCallbackMock : public ITunerCallback { MOCK_METHOD1(backgroundScanAvailable, Return<void>(bool)); MOCK_TIMEOUT_METHOD1(backgroundScanComplete, Return<void>(ProgramListResult)); MOCK_METHOD0(programListChanged, Return<void>()); MOCK_METHOD0(currentProgramInfoChanged, Return<void>()); MOCK_TIMEOUT_METHOD0(currentProgramInfoChanged, Return<void>()); }; class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase, Loading Loading @@ -315,7 +324,8 @@ TEST_P(BroadcastRadioHalTest, OpenTunerTwice) { * - getProgramList either succeeds or returns NOT_STARTED/NOT_READY status; * - if the program list is NOT_STARTED, startBackgroundScan makes it completed * within a full scan timeout and the next getProgramList call succeeds; * - if the program list is not empty, tuneByProgramSelector call succeeds. * - if the program list is not empty, tuneByProgramSelector call succeeds; * - getProgramInformation_1_1 returns the same selector as returned in tuneComplete_1_1 call. */ TEST_P(BroadcastRadioHalTest, TuneFromProgramList) { if (skipped) return; Loading @@ -340,12 +350,70 @@ TEST_P(BroadcastRadioHalTest, TuneFromProgramList) { EXPECT_CALL(*mCallback, tuneComplete(_, _)).Times(0); EXPECT_TIMEOUT_CALL(*mCallback, tuneComplete_1_1, Result::OK, _) .WillOnce(DoAll(SaveArg<1>(&selCb), testing::Return(ByMove(Void())))); EXPECT_TIMEOUT_CALL(*mCallback, currentProgramInfoChanged); auto tuneResult = mTuner->tuneByProgramSelector(firstProgram.selector); ASSERT_EQ(Result::OK, tuneResult); EXPECT_TIMEOUT_CALL_WAIT(*mCallback, tuneComplete_1_1, kTuneTimeout); EXPECT_TIMEOUT_CALL_WAIT(*mCallback, currentProgramInfoChanged, kEventPropagationTimeout); EXPECT_EQ(firstProgram.selector.primaryId, selCb.primaryId); bool called = false; auto getResult = mTuner->getProgramInformation_1_1([&](Result result, ProgramInfo info) { called = true; EXPECT_EQ(Result::OK, result); EXPECT_EQ(selCb, info.selector); }); ASSERT_TRUE(getResult.isOk()); ASSERT_TRUE(called); } /** * Test that primary vendor identifier isn't used for standard program types. * * Verifies that: * - tuneByProgramSelector fails when VENDORn_PRIMARY is set as a primary * identifier for program types other than VENDORn. */ TEST_P(BroadcastRadioHalTest, TuneFailsForPrimaryVendor) { if (skipped) return; ASSERT_TRUE(openTuner()); for (auto ptype : kStandardProgramTypes) { ALOGD("Checking %s...", toString(ptype).c_str()); for (auto idtype : kVendorPrimartIds) { ALOGD("...with %s", toString(idtype).c_str()); ProgramSelector sel = {}; sel.programType = static_cast<uint32_t>(ptype); sel.primaryId.type = static_cast<uint32_t>(idtype); auto tuneResult = mTuner->tuneByProgramSelector(sel); ASSERT_NE(Result::OK, tuneResult); } } } /** * Test that tune with unknown program type fails. * * Verifies that: * - tuneByProgramSelector fails with INVALID_ARGUMENT when unknown program type is passed. */ TEST_P(BroadcastRadioHalTest, TuneFailsForUnknownProgram) { if (skipped) return; ASSERT_TRUE(openTuner()); // Program type is 1-based, so 0 will be always invalid. ProgramSelector sel = {}; auto tuneResult = mTuner->tuneByProgramSelector(sel); ASSERT_EQ(Result::INVALID_ARGUMENTS, tuneResult); } /** * Test cancelling announcement. * * Verifies that: * - cancelAnnouncement succeeds either when there is an announcement or there is none. */ TEST_P(BroadcastRadioHalTest, CancelAnnouncement) { if (skipped) return; ASSERT_TRUE(openTuner()); Loading @@ -358,7 +426,7 @@ TEST_P(BroadcastRadioHalTest, CancelAnnouncement) { * Test getImage call with invalid image ID. * * Verifies that: * - getImage call handles argument 0 gracefully * - getImage call handles argument 0 gracefully. */ TEST_P(BroadcastRadioHalTest, GetNoImage) { if (skipped) return; Loading @@ -375,8 +443,8 @@ TEST_P(BroadcastRadioHalTest, GetNoImage) { * Test proper image format in metadata. * * Verifies that: * - all images in metadata are provided out-of-band (by id, not as a binary blob) * - images are available for getImage call * - all images in metadata are provided out-of-band (by id, not as a binary blob); * - images are available for getImage call. */ TEST_P(BroadcastRadioHalTest, OobImagesOnly) { if (skipped) return; Loading Loading @@ -420,7 +488,7 @@ TEST_P(BroadcastRadioHalTest, OobImagesOnly) { * Test AnalogForced switch. * * Verifies that: * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same. */ TEST_P(BroadcastRadioHalTest, AnalogForcedSwitch) { if (skipped) return; Loading
broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h +8 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,14 @@ } \ return ret; /** * Gmock MOCK_METHOD0 timeout-capable extension. */ #define MOCK_TIMEOUT_METHOD0(Method, ...) \ MOCK_METHOD0(egmock_##Method, __VA_ARGS__); \ EGMOCK_TIMEOUT_METHOD_DEF_(Method); \ virtual GMOCK_RESULT_(, __VA_ARGS__) Method() { EGMOCK_TIMEOUT_METHOD_BODY_(Method); } /** * Gmock MOCK_METHOD1 timeout-capable extension. */ Loading