diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 1c6c33fe2b..1e941143df 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -85,19 +85,23 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); /** - * Configure the filter to monitor specific Scrambling Status. + * Configure the monitor event. * - * Scrambling Status should be sent through the filer callback at the following two scenarios: + * The event for Scrambling Status should be sent at the following two scenarios: * 1. When this method is called, the first detected scrambling status should be sent. - * 2. When the filter transits into the monitored statuses configured through this method, - * event should be sent. + * 2. When the Scrambling status transits into different status, event should be sent. * - * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to - * stop monitoring. + * The event for IP CID change should be sent at the following two scenarios: + * 1. When this method is called, the first detected CID for the IP should be sent. + * 2. When the CID is changed to different value for the IP filter, event should be sent. + * + * @param monitorEventypes the events to monitor. Set corresponding bit of the event to monitor. + * Reset to stop monitoring. * @return result Result status of the operation. - * SUCCESS if successful, - * INVALID_STATE if configure can't be applied, - * UNKNOWN_ERROR if failed for other reasons. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. */ - configureScramblingEvent(bitfield statuses) generates (Result result); + configureMonitorEvent(bitfield monitorEventTypes) + generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index e766a8af72..4fa1746dbe 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -250,25 +250,49 @@ Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; } -Return Filter::configureScramblingEvent(uint32_t statuses) { +Return Filter::configureMonitorEvent(uint32_t monitorEventTypes) { ALOGV("%s", __FUNCTION__); - mStatuses = statuses; - if (mCallback_1_1 != nullptr) { - // Assuming current status is always NOT_SCRAMBLED - V1_1::DemuxFilterEventExt filterEventExt; - V1_1::DemuxFilterEventExt::Event event; - event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); - int size = filterEventExt.events.size(); - filterEventExt.events.resize(size + 1); - filterEventExt.events[size] = event; - DemuxFilterEvent emptyFilterEvent; + DemuxFilterEvent emptyFilterEvent; + V1_1::DemuxFilterMonitorEvent monitorEvent; + V1_1::DemuxFilterEventExt eventExt; - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); - mFilterEventExt.events.resize(0); - } else { - return Result::INVALID_STATE; + uint32_t newScramblingStatus = + monitorEventTypes & V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS; + uint32_t newIpCid = monitorEventTypes & V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; + + // if scrambling status monitoring flipped, record the new state and send msg on enabling + if (newScramblingStatus ^ mScramblingStatusMonitored) { + mScramblingStatusMonitored = newScramblingStatus; + if (mScramblingStatusMonitored) { + if (mCallback_1_1 != nullptr) { + // Assuming current status is always NOT_SCRAMBLED + monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } } + + // if ip cid monitoring flipped, record the new state and send msg on enabling + if (newIpCid ^ mIpCidMonitored) { + mIpCidMonitored = newIpCid; + if (mIpCidMonitored) { + if (mCallback_1_1 != nullptr) { + // Return random cid + monitorEvent.cid(1); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } + } + return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 1ebc1351a0..3a4246e095 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; - virtual Return configureScramblingEvent(uint32_t statuses) override; + virtual Return configureMonitorEvent(uint32_t monitorEventTypes) override; /** * To create a FilterMQ and its Event Flag. @@ -238,6 +238,8 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; int mStartId = 0; + uint8_t mScramblingStatusMonitored = 0; + uint8_t mIpCidMonitored = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 09b87f2ac8..938cb6e493 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -151,22 +151,42 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { safe_union Event { /** - * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event - * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. + * No extended filter Event. */ Monostate noinit; + /** + * Extended TS Record event sent along with @1.0::DemuxFilterEvent::Event::tsRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterTsRecordEventExt tsRecord; + /** + * Extended MMTP Record event sent along with @1.0::DemuxFilterEvent::Event::mmtpRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterMmtpRecordEventExt mmtpRecord; - ScramblingStatus scramblingStatus; + /** + * Monitor event to notify monitored status change. + * + * When sending monitorEvent, DemuxFilterEventExt.events should only contain one + * monitorEvent. MonitorEvent should be sent with an empty @1.0::DemuxFilterEvent. + */ + DemuxFilterMonitorEvent monitorEvent; /** * An unique ID to mark the start point of receiving the valid filter events after * reconfiguring the filter. It must be sent at least once in the first event after the * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. + * + * When sending starId, DemuxFilterEventExt.events should only contain one startId event. + * StardId event should be sent with an empty @1.0::DemuxFilterEvent. */ uint32_t startId; }; @@ -196,6 +216,24 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, }; +@export +enum DemuxFilterMonitorEventType : uint32_t { + SCRAMBLING_STATUS = 1 << 0, + IP_CID_CHANGE = 1 << 1, +}; + +safe_union DemuxFilterMonitorEvent { + /** + * New scrambling status. + */ + ScramblingStatus scramblingStatus; + + /** + * New cid for the IP filter. + */ + uint32_t cid; +}; + typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index cdf3b6998b..d8fad3d5d2 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); } +void FilterCallback::testFilterIpCidEvent() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mIpCidEvent < 1) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "ip cid change event does not output within timeout"; + return; + } + } + mIpCidEvent = 0; + ALOGW("[vts] pass and stop"); +} + void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { @@ -80,8 +92,17 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; - case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: - mScramblingStatusEvent++; + case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: + switch (eventExt.monitorEvent().getDiscriminator()) { + case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: + mScramblingStatusEvent++; + break; + case DemuxFilterMonitorEvent::hidl_discriminator::cid: + mIpCidEvent++; + break; + default: + break; + } break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); @@ -272,15 +293,16 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) { +AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; sp filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { - status = filter_v1_1->configureScramblingEvent(statuses); + status = filter_v1_1->configureMonitorEvent(monitorEventTypes); mFilterCallbacks[filterId]->testFilterScramblingEvent(); + mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index ae57659a38..6749265661 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -56,6 +56,7 @@ using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; +using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -118,6 +119,7 @@ class FilterCallback : public IFilterCallback { void testFilterDataOutput(); void testFilterScramblingEvent(); + void testFilterIpCidEvent(); void testStartIdAfterReconfigure(); void readFilterEventData(); @@ -139,6 +141,7 @@ class FilterCallback : public IFilterCallback { int mPidFilterOutputCount = 0; int mScramblingStatusEvent = 0; + int mIpCidEvent = 0; bool mStartIdReceived = false; }; @@ -157,7 +160,7 @@ class FilterTests { AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); - AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses); + AssertionResult configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index dda8b60087..e87276275a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -46,8 +46,8 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } - if (filterConf.statuses > 0) { - ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses)); + if (filterConf.monitorEventTypes > 0) { + ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 76bf765909..beae223e4b 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -96,7 +96,7 @@ struct FilterConfig { DemuxFilterSettings settings; AvStreamType streamType; uint32_t ipCid; - uint32_t statuses; + uint32_t monitorEventTypes; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -188,7 +188,9 @@ inline void initFilterConfig() { filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO0].settings.ts().tpid = 256; filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO0].statuses = 1; + filterArray[TS_VIDEO0].monitorEventTypes = + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;