Loading tv/tuner/1.1/IFilter.hal +14 −10 Original line number Original line Diff line number Diff line Loading @@ -85,19 +85,23 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); 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. * 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, * 2. When the Scrambling status transits into different status, event should be sent. * event should be sent. * * * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to * The event for IP CID change should be sent at the following two scenarios: * stop monitoring. * 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. * @return result Result status of the operation. * SUCCESS if successful, * SUCCESS if successful, * INVALID_STATE if configure can't be applied, * INVALID_STATE if configure can't be applied, * UNKNOWN_ERROR if failed for other reasons. * UNKNOWN_ERROR if failed for other reasons. */ */ configureScramblingEvent(bitfield<ScramblingStatus> statuses) generates (Result result); configureMonitorEvent(bitfield<DemuxFilterMonitorEventType> monitorEventTypes) generates (Result result); }; }; tv/tuner/1.1/default/Filter.cpp +40 −16 Original line number Original line Diff line number Diff line Loading @@ -250,25 +250,49 @@ Return<Result> Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; return Result::SUCCESS; } } Return<Result> Filter::configureScramblingEvent(uint32_t statuses) { Return<Result> Filter::configureMonitorEvent(uint32_t monitorEventTypes) { ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__); mStatuses = statuses; DemuxFilterEvent emptyFilterEvent; V1_1::DemuxFilterMonitorEvent monitorEvent; V1_1::DemuxFilterEventExt eventExt; 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) { if (mCallback_1_1 != nullptr) { // Assuming current status is always NOT_SCRAMBLED // Assuming current status is always NOT_SCRAMBLED V1_1::DemuxFilterEventExt filterEventExt; monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); V1_1::DemuxFilterEventExt::Event event; eventExt.events.resize(1); event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); eventExt.events[0].monitorEvent(monitorEvent); int size = filterEventExt.events.size(); mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); filterEventExt.events.resize(size + 1); } else { filterEventExt.events[size] = event; return Result::INVALID_STATE; DemuxFilterEvent emptyFilterEvent; } } } mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); // if ip cid monitoring flipped, record the new state and send msg on enabling mFilterEventExt.events.resize(0); 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 { } else { return Result::INVALID_STATE; return Result::INVALID_STATE; } } } } return Result::SUCCESS; return Result::SUCCESS; } } Loading tv/tuner/1.1/default/Filter.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return<Result> configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; virtual Return<Result> configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; virtual Return<Result> configureScramblingEvent(uint32_t statuses) override; virtual Return<Result> configureMonitorEvent(uint32_t monitorEventTypes) override; /** /** * To create a FilterMQ and its Event Flag. * To create a FilterMQ and its Event Flag. Loading Loading @@ -238,6 +238,8 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; bool mConfigured = false; int mStartId = 0; int mStartId = 0; uint8_t mScramblingStatusMonitored = 0; uint8_t mIpCidMonitored = 0; }; }; } // namespace implementation } // namespace implementation Loading tv/tuner/1.1/types.hal +41 −3 Original line number Original line Diff line number Diff line Loading @@ -151,22 +151,42 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { struct DemuxFilterEventExt { safe_union Event { safe_union Event { /** /** * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event * No extended filter Event. * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. */ */ Monostate noinit; 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; 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; 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 * 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 * 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 * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. * 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; uint32_t startId; }; }; Loading Loading @@ -196,6 +216,24 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, 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; typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** /** Loading tv/tuner/1.1/vts/functional/FilterTests.cpp +26 −4 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); 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() { void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { while (!mStartIdReceived) { Loading Loading @@ -80,9 +92,18 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; break; case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: switch (eventExt.monitorEvent().getDiscriminator()) { case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: mScramblingStatusEvent++; mScramblingStatusEvent++; break; break; case DemuxFilterMonitorEvent::hidl_discriminator::cid: mIpCidEvent++; break; default: break; } break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); mStartIdReceived = true; mStartIdReceived = true; Loading Loading @@ -272,15 +293,16 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); 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."; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; Result status; sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 = sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { if (filter_v1_1 != NULL) { status = filter_v1_1->configureScramblingEvent(statuses); status = filter_v1_1->configureMonitorEvent(monitorEventTypes); mFilterCallbacks[filterId]->testFilterScramblingEvent(); mFilterCallbacks[filterId]->testFilterScramblingEvent(); mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { } else { ALOGW("[vts] Can't cast IFilter into v1_1."); ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); return failure(); Loading Loading
tv/tuner/1.1/IFilter.hal +14 −10 Original line number Original line Diff line number Diff line Loading @@ -85,19 +85,23 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); 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. * 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, * 2. When the Scrambling status transits into different status, event should be sent. * event should be sent. * * * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to * The event for IP CID change should be sent at the following two scenarios: * stop monitoring. * 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. * @return result Result status of the operation. * SUCCESS if successful, * SUCCESS if successful, * INVALID_STATE if configure can't be applied, * INVALID_STATE if configure can't be applied, * UNKNOWN_ERROR if failed for other reasons. * UNKNOWN_ERROR if failed for other reasons. */ */ configureScramblingEvent(bitfield<ScramblingStatus> statuses) generates (Result result); configureMonitorEvent(bitfield<DemuxFilterMonitorEventType> monitorEventTypes) generates (Result result); }; };
tv/tuner/1.1/default/Filter.cpp +40 −16 Original line number Original line Diff line number Diff line Loading @@ -250,25 +250,49 @@ Return<Result> Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; return Result::SUCCESS; } } Return<Result> Filter::configureScramblingEvent(uint32_t statuses) { Return<Result> Filter::configureMonitorEvent(uint32_t monitorEventTypes) { ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__); mStatuses = statuses; DemuxFilterEvent emptyFilterEvent; V1_1::DemuxFilterMonitorEvent monitorEvent; V1_1::DemuxFilterEventExt eventExt; 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) { if (mCallback_1_1 != nullptr) { // Assuming current status is always NOT_SCRAMBLED // Assuming current status is always NOT_SCRAMBLED V1_1::DemuxFilterEventExt filterEventExt; monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); V1_1::DemuxFilterEventExt::Event event; eventExt.events.resize(1); event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); eventExt.events[0].monitorEvent(monitorEvent); int size = filterEventExt.events.size(); mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); filterEventExt.events.resize(size + 1); } else { filterEventExt.events[size] = event; return Result::INVALID_STATE; DemuxFilterEvent emptyFilterEvent; } } } mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); // if ip cid monitoring flipped, record the new state and send msg on enabling mFilterEventExt.events.resize(0); 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 { } else { return Result::INVALID_STATE; return Result::INVALID_STATE; } } } } return Result::SUCCESS; return Result::SUCCESS; } } Loading
tv/tuner/1.1/default/Filter.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return<Result> configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; virtual Return<Result> configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; virtual Return<Result> configureScramblingEvent(uint32_t statuses) override; virtual Return<Result> configureMonitorEvent(uint32_t monitorEventTypes) override; /** /** * To create a FilterMQ and its Event Flag. * To create a FilterMQ and its Event Flag. Loading Loading @@ -238,6 +238,8 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; bool mConfigured = false; int mStartId = 0; int mStartId = 0; uint8_t mScramblingStatusMonitored = 0; uint8_t mIpCidMonitored = 0; }; }; } // namespace implementation } // namespace implementation Loading
tv/tuner/1.1/types.hal +41 −3 Original line number Original line Diff line number Diff line Loading @@ -151,22 +151,42 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { struct DemuxFilterEventExt { safe_union Event { safe_union Event { /** /** * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event * No extended filter Event. * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. */ */ Monostate noinit; 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; 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; 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 * 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 * 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 * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. * 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; uint32_t startId; }; }; Loading Loading @@ -196,6 +216,24 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, 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; typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** /** Loading
tv/tuner/1.1/vts/functional/FilterTests.cpp +26 −4 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); 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() { void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { while (!mStartIdReceived) { Loading Loading @@ -80,9 +92,18 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; break; case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: switch (eventExt.monitorEvent().getDiscriminator()) { case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: mScramblingStatusEvent++; mScramblingStatusEvent++; break; break; case DemuxFilterMonitorEvent::hidl_discriminator::cid: mIpCidEvent++; break; default: break; } break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); mStartIdReceived = true; mStartIdReceived = true; Loading Loading @@ -272,15 +293,16 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); 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."; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; Result status; sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 = sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { if (filter_v1_1 != NULL) { status = filter_v1_1->configureScramblingEvent(statuses); status = filter_v1_1->configureMonitorEvent(monitorEventTypes); mFilterCallbacks[filterId]->testFilterScramblingEvent(); mFilterCallbacks[filterId]->testFilterScramblingEvent(); mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { } else { ALOGW("[vts] Can't cast IFilter into v1_1."); ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); return failure(); Loading