1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "FilterTests.h"
18
testFilterDataOutput()19 void FilterCallback::testFilterDataOutput() {
20 android::Mutex::Autolock autoLock(mMsgLock);
21 while (mPidFilterOutputCount < 1) {
22 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
23 EXPECT_TRUE(false) << "filter output matching pid does not output within timeout";
24 return;
25 }
26 }
27 mPidFilterOutputCount = 0;
28 ALOGW("[vts] pass and stop");
29 }
30
testFilterScramblingEvent()31 void FilterCallback::testFilterScramblingEvent() {
32 android::Mutex::Autolock autoLock(mMsgLock);
33 while (mScramblingStatusEvent < 1) {
34 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
35 EXPECT_TRUE(false) << "scrambling event does not output within timeout";
36 return;
37 }
38 }
39 mScramblingStatusEvent = 0;
40 ALOGW("[vts] pass and stop");
41 }
42
testFilterIpCidEvent()43 void FilterCallback::testFilterIpCidEvent() {
44 android::Mutex::Autolock autoLock(mMsgLock);
45 while (mIpCidEvent < 1) {
46 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
47 EXPECT_TRUE(false) << "ip cid change event does not output within timeout";
48 return;
49 }
50 }
51 mIpCidEvent = 0;
52 ALOGW("[vts] pass and stop");
53 }
54
testStartIdAfterReconfigure()55 void FilterCallback::testStartIdAfterReconfigure() {
56 android::Mutex::Autolock autoLock(mMsgLock);
57 while (!mStartIdReceived) {
58 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
59 EXPECT_TRUE(false) << "does not receive start id within timeout";
60 return;
61 }
62 }
63 mStartIdReceived = false;
64 ALOGW("[vts] pass and stop");
65 }
66
readFilterEventData()67 void FilterCallback::readFilterEventData() {
68 ALOGW("[vts] reading filter event");
69 // todo separate filter handlers
70 for (int i = 0; i < mFilterEvent.events.size(); i++) {
71 auto event = mFilterEvent.events[i];
72 switch (event.getDiscriminator()) {
73 case DemuxFilterEvent::Event::hidl_discriminator::media:
74 ALOGD("[vts] Media filter event, avMemHandle numFds=%d.",
75 event.media().avMemory.getNativeHandle()->numFds);
76 dumpAvData(event.media());
77 break;
78 default:
79 break;
80 }
81 }
82 for (int i = 0; i < mFilterEventExt.events.size(); i++) {
83 auto eventExt = mFilterEventExt.events[i];
84 switch (eventExt.getDiscriminator()) {
85 case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord:
86 ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ", firstMbInSlice=%d",
87 eventExt.tsRecord().pts, eventExt.tsRecord().firstMbInSlice);
88 break;
89 case DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord:
90 ALOGD("[vts] Extended MMTP record filter event, pts=%" PRIu64
91 ", firstMbInSlice=%d, mpuSequenceNumber=%d, tsIndexMask=%d",
92 eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice,
93 eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask);
94 break;
95 case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent:
96 switch (eventExt.monitorEvent().getDiscriminator()) {
97 case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus:
98 mScramblingStatusEvent++;
99 break;
100 case DemuxFilterMonitorEvent::hidl_discriminator::cid:
101 mIpCidEvent++;
102 break;
103 default:
104 break;
105 }
106 break;
107 case DemuxFilterEventExt::Event::hidl_discriminator::startId:
108 ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId());
109 mStartIdReceived = true;
110 break;
111 default:
112 break;
113 }
114 }
115 }
116
dumpAvData(DemuxFilterMediaEvent event)117 bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) {
118 uint32_t length = event.dataLength;
119 uint32_t offset = event.offset;
120 // read data from buffer pointed by a handle
121 hidl_handle handle = event.avMemory;
122 if (handle.getNativeHandle()->numFds == 0) {
123 if (mAvSharedHandle == NULL) {
124 return false;
125 }
126 handle = mAvSharedHandle;
127 }
128
129 int av_fd = handle.getNativeHandle()->data[0];
130 uint8_t* buffer = static_cast<uint8_t*>(
131 mmap(NULL, length + offset, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0));
132 if (buffer == MAP_FAILED) {
133 ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
134 return false;
135 }
136 uint8_t output[length + 1];
137 memcpy(output, buffer + offset, length);
138 // print buffer and check with golden output.
139 ::close(av_fd);
140 return true;
141 }
142
openFilterInDemux(DemuxFilterType type,uint32_t bufferSize)143 AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) {
144 Result status;
145 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
146
147 // Create demux callback
148 mFilterCallback = new FilterCallback();
149
150 // Add filter to the local demux
151 mDemux->openFilter(type, bufferSize, mFilterCallback,
152 [&](Result result, const sp<IFilter>& filter) {
153 mFilter = filter;
154 status = result;
155 });
156
157 return AssertionResult(status == Result::SUCCESS);
158 }
159
getNewlyOpenedFilterId_64bit(uint64_t & filterId)160 AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(uint64_t& filterId) {
161 Result status;
162 EXPECT_TRUE(mDemux) << "Test with openDemux first.";
163 EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
164 EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
165
166 sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
167 android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilter);
168 if (filter_v1_1 != NULL) {
169 filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
170 mFilterId = filterId;
171 status = result;
172 });
173 } else {
174 ALOGW("[vts] Can't cast IFilter into v1_1.");
175 return failure();
176 }
177
178 if (status == Result::SUCCESS) {
179 mFilterCallback->setFilterId(mFilterId);
180 mFilterCallback->setFilterInterface(mFilter);
181 mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
182 mFilters[mFilterId] = mFilter;
183 mFilterCallbacks[mFilterId] = mFilterCallback;
184 filterId = mFilterId;
185 }
186
187 return AssertionResult(status == Result::SUCCESS);
188 }
189
getSharedAvMemoryHandle(uint64_t filterId)190 AssertionResult FilterTests::getSharedAvMemoryHandle(uint64_t filterId) {
191 EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
192 Result status = Result::UNKNOWN_ERROR;
193 sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
194 android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
195 if (filter_v1_1 != NULL) {
196 filter_v1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) {
197 status = r;
198 if (status == Result::SUCCESS) {
199 mFilterCallbacks[mFilterId]->setSharedHandle(avMemory);
200 mFilterCallbacks[mFilterId]->setMemSize(avMemSize);
201 mAvSharedHandle = avMemory;
202 }
203 });
204 }
205 return AssertionResult(status == Result::SUCCESS);
206 }
207
releaseShareAvHandle(uint64_t filterId)208 AssertionResult FilterTests::releaseShareAvHandle(uint64_t filterId) {
209 Result status;
210 EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
211 EXPECT_TRUE(mAvSharedHandle) << "No shared av handle to release.";
212 status = mFilters[filterId]->releaseAvHandle(mAvSharedHandle, 0 /*dataId*/);
213
214 return AssertionResult(status == Result::SUCCESS);
215 }
216
configFilter(DemuxFilterSettings setting,uint64_t filterId)217 AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t filterId) {
218 Result status;
219 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
220 status = mFilters[filterId]->configure(setting);
221
222 return AssertionResult(status == Result::SUCCESS);
223 }
224
configAvFilterStreamType(AvStreamType type,uint64_t filterId)225 AssertionResult FilterTests::configAvFilterStreamType(AvStreamType type, uint64_t filterId) {
226 Result status;
227 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
228 sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
229 android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
230 if (filter_v1_1 != NULL) {
231 status = filter_v1_1->configureAvStreamType(type);
232 } else {
233 ALOGW("[vts] Can't cast IFilter into v1_1.");
234 return failure();
235 }
236 return AssertionResult(status == Result::SUCCESS);
237 }
238
configIpFilterCid(uint32_t ipCid,uint64_t filterId)239 AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId) {
240 Result status;
241 EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first.";
242
243 sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
244 android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
245 if (filter_v1_1 != NULL) {
246 status = filter_v1_1->configureIpCid(ipCid);
247 } else {
248 ALOGW("[vts] Can't cast IFilter into v1_1.");
249 return failure();
250 }
251
252 return AssertionResult(status == Result::SUCCESS);
253 }
254
getFilterMQDescriptor(uint64_t filterId,bool getMqDesc)255 AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId, bool getMqDesc) {
256 if (!getMqDesc) {
257 ALOGE("[vts] Filter does not need FMQ.");
258 return success();
259 }
260 Result status;
261 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
262 EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
263
264 mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
265 mFilterMQDescriptor = filterMQDesc;
266 status = result;
267 });
268
269 return AssertionResult(status == Result::SUCCESS);
270 }
271
startFilter(uint64_t filterId)272 AssertionResult FilterTests::startFilter(uint64_t filterId) {
273 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
274 Result status = mFilters[filterId]->start();
275 return AssertionResult(status == Result::SUCCESS);
276 }
277
stopFilter(uint64_t filterId)278 AssertionResult FilterTests::stopFilter(uint64_t filterId) {
279 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
280 Result status = mFilters[filterId]->stop();
281
282 return AssertionResult(status == Result::SUCCESS);
283 }
284
closeFilter(uint64_t filterId)285 AssertionResult FilterTests::closeFilter(uint64_t filterId) {
286 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
287 Result status = mFilters[filterId]->close();
288 if (status == Result::SUCCESS) {
289 for (int i = 0; i < mUsedFilterIds.size(); i++) {
290 if (mUsedFilterIds[i] == filterId) {
291 mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
292 break;
293 }
294 }
295 mFilterCallbacks.erase(filterId);
296 mFilters.erase(filterId);
297 }
298 return AssertionResult(status == Result::SUCCESS);
299 }
300
configureMonitorEvent(uint64_t filterId,uint32_t monitorEventTypes)301 AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) {
302 EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
303 Result status;
304
305 sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
306 android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
307 if (filter_v1_1 != NULL) {
308 status = filter_v1_1->configureMonitorEvent(monitorEventTypes);
309 if (monitorEventTypes & DemuxFilterMonitorEventType::SCRAMBLING_STATUS) {
310 mFilterCallbacks[filterId]->testFilterScramblingEvent();
311 }
312 if (monitorEventTypes & DemuxFilterMonitorEventType::IP_CID_CHANGE) {
313 mFilterCallbacks[filterId]->testFilterIpCidEvent();
314 }
315 } else {
316 ALOGW("[vts] Can't cast IFilter into v1_1.");
317 return failure();
318 }
319 return AssertionResult(status == Result::SUCCESS);
320 }
321
startIdTest(uint64_t filterId)322 AssertionResult FilterTests::startIdTest(uint64_t filterId) {
323 EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
324 mFilterCallbacks[filterId]->testStartIdAfterReconfigure();
325 return AssertionResult(true);
326 }
327