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 "FrontendTests.h"
18
onEvent(FrontendEventType frontendEventType)19 Return<void> FrontendCallback::onEvent(FrontendEventType frontendEventType) {
20 android::Mutex::Autolock autoLock(mMsgLock);
21 ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
22 mEventReceived = true;
23 mMsgCondition.signal();
24 switch (frontendEventType) {
25 case FrontendEventType::LOCKED:
26 mLockMsgReceived = true;
27 mLockMsgCondition.signal();
28 return Void();
29 default:
30 // do nothing
31 return Void();
32 }
33 }
34
onScanMessage(FrontendScanMessageType type,const FrontendScanMessage & message)35 Return<void> FrontendCallback::onScanMessage(FrontendScanMessageType type,
36 const FrontendScanMessage& message) {
37 android::Mutex::Autolock autoLock(mMsgLock);
38 while (!mScanMsgProcessed) {
39 mMsgCondition.wait(mMsgLock);
40 }
41 ALOGD("[vts] frontend scan message. Type: %d", type);
42 mScanMessageReceived = true;
43 mScanMsgProcessed = false;
44 mScanMessageType = type;
45 mScanMessage = message;
46 mMsgCondition.signal();
47 return Void();
48 }
49
onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,const FrontendScanMessageExt1_1 & message)50 Return<void> FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
51 const FrontendScanMessageExt1_1& message) {
52 android::Mutex::Autolock autoLock(mMsgLock);
53 ALOGD("[vts] frontend ext1_1 scan message. Type: %d", type);
54 switch (message.getDiscriminator()) {
55 case FrontendScanMessageExt1_1::hidl_discriminator::modulation:
56 readFrontendScanMessageExt1_1Modulation(message.modulation());
57 break;
58 case FrontendScanMessageExt1_1::hidl_discriminator::isHighPriority:
59 ALOGD("[vts] frontend ext1_1 scan message high priority: %d", message.isHighPriority());
60 break;
61 case FrontendScanMessageExt1_1::hidl_discriminator::annex:
62 ALOGD("[vts] frontend ext1_1 scan message dvbc annex: %hhu", message.annex());
63 break;
64 default:
65 break;
66 }
67 return Void();
68 }
69
readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation)70 void FrontendCallback::readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation) {
71 switch (modulation.getDiscriminator()) {
72 case FrontendModulation::hidl_discriminator::dvbc:
73 ALOGD("[vts] frontend ext1_1 scan message modulation dvbc: %d", modulation.dvbc());
74 break;
75 case FrontendModulation::hidl_discriminator::dvbs:
76 ALOGD("[vts] frontend ext1_1 scan message modulation dvbs: %d", modulation.dvbs());
77 break;
78 case FrontendModulation::hidl_discriminator::isdbs:
79 ALOGD("[vts] frontend ext1_1 scan message modulation isdbs: %d", modulation.isdbs());
80 break;
81 case FrontendModulation::hidl_discriminator::isdbs3:
82 ALOGD("[vts] frontend ext1_1 scan message modulation isdbs3: %d", modulation.isdbs3());
83 break;
84 case FrontendModulation::hidl_discriminator::isdbt:
85 ALOGD("[vts] frontend ext1_1 scan message modulation isdbt: %d", modulation.isdbt());
86 break;
87 case FrontendModulation::hidl_discriminator::atsc:
88 ALOGD("[vts] frontend ext1_1 scan message modulation atsc: %d", modulation.atsc());
89 break;
90 case FrontendModulation::hidl_discriminator::atsc3:
91 ALOGD("[vts] frontend ext1_1 scan message modulation atsc3: %d", modulation.atsc3());
92 break;
93 case FrontendModulation::hidl_discriminator::dvbt:
94 ALOGD("[vts] frontend ext1_1 scan message modulation dvbt: %d", modulation.dvbt());
95 break;
96 default:
97 break;
98 }
99 }
100
tuneTestOnLock(sp<IFrontend> & frontend,FrontendSettings settings,FrontendSettingsExt1_1 settingsExt1_1)101 void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
102 FrontendSettingsExt1_1 settingsExt1_1) {
103 sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
104 frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend);
105 if (frontend_1_1 == nullptr) {
106 EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
107 return;
108 }
109
110 Result result = frontend_1_1->tune_1_1(settings, settingsExt1_1);
111 EXPECT_TRUE(result == Result::SUCCESS);
112
113 android::Mutex::Autolock autoLock(mMsgLock);
114 while (!mLockMsgReceived) {
115 if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
116 EXPECT_TRUE(false) << "Event LOCKED not received within timeout";
117 mLockMsgReceived = false;
118 return;
119 }
120 }
121 mLockMsgReceived = false;
122 }
123
scanTest(sp<IFrontend> & frontend,FrontendConfig1_1 config,FrontendScanType type)124 void FrontendCallback::scanTest(sp<IFrontend>& frontend, FrontendConfig1_1 config,
125 FrontendScanType type) {
126 sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
127 frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend);
128 if (frontend_1_1 == nullptr) {
129 EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
130 return;
131 }
132
133 uint32_t targetFrequency = getTargetFrequency(config.config1_0.settings);
134 if (type == FrontendScanType::SCAN_BLIND) {
135 // reset the frequency in the scan configuration to test blind scan. The settings param of
136 // passed in means the real input config on the transponder connected to the DUT.
137 // We want the blind the test to start from lower frequency than this to check the blind
138 // scan implementation.
139 resetBlindScanStartingFrequency(config, targetFrequency - 100 * 1000);
140 }
141
142 Result result = frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1);
143 EXPECT_TRUE(result == Result::SUCCESS);
144
145 bool scanMsgLockedReceived = false;
146 bool targetFrequencyReceived = false;
147
148 android::Mutex::Autolock autoLock(mMsgLock);
149 wait:
150 while (!mScanMessageReceived) {
151 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
152 EXPECT_TRUE(false) << "Scan message not received within timeout";
153 mScanMessageReceived = false;
154 mScanMsgProcessed = true;
155 return;
156 }
157 }
158
159 if (mScanMessageType != FrontendScanMessageType::END) {
160 if (mScanMessageType == FrontendScanMessageType::LOCKED) {
161 scanMsgLockedReceived = true;
162 Result result =
163 frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1);
164 EXPECT_TRUE(result == Result::SUCCESS);
165 }
166
167 if (mScanMessageType == FrontendScanMessageType::FREQUENCY) {
168 targetFrequencyReceived = mScanMessage.frequencies().size() > 0 &&
169 mScanMessage.frequencies()[0] == targetFrequency;
170 }
171
172 if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) {
173 ALOGD("[vts] Scan in progress...[%d%%]", mScanMessage.progressPercent());
174 }
175
176 mScanMessageReceived = false;
177 mScanMsgProcessed = true;
178 mMsgCondition.signal();
179 goto wait;
180 }
181
182 EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
183 if (type == FrontendScanType::SCAN_BLIND)
184 EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
185 mScanMessageReceived = false;
186 mScanMsgProcessed = true;
187 }
188
getTargetFrequency(FrontendSettings settings)189 uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings) {
190 switch (settings.getDiscriminator()) {
191 case FrontendSettings::hidl_discriminator::analog:
192 return settings.analog().frequency;
193 case FrontendSettings::hidl_discriminator::atsc:
194 return settings.atsc().frequency;
195 case FrontendSettings::hidl_discriminator::atsc3:
196 return settings.atsc3().frequency;
197 case FrontendSettings::hidl_discriminator::dvbc:
198 return settings.dvbc().frequency;
199 case FrontendSettings::hidl_discriminator::dvbs:
200 return settings.dvbs().frequency;
201 case FrontendSettings::hidl_discriminator::dvbt:
202 return settings.dvbt().frequency;
203 case FrontendSettings::hidl_discriminator::isdbs:
204 return settings.isdbs().frequency;
205 case FrontendSettings::hidl_discriminator::isdbs3:
206 return settings.isdbs3().frequency;
207 case FrontendSettings::hidl_discriminator::isdbt:
208 return settings.isdbt().frequency;
209 }
210 }
211
resetBlindScanStartingFrequency(FrontendConfig1_1 & config,uint32_t resetingFreq)212 void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig1_1& config,
213 uint32_t resetingFreq) {
214 switch (config.config1_0.settings.getDiscriminator()) {
215 case FrontendSettings::hidl_discriminator::analog:
216 config.config1_0.settings.analog().frequency = resetingFreq;
217 break;
218 case FrontendSettings::hidl_discriminator::atsc:
219 config.config1_0.settings.atsc().frequency = resetingFreq;
220 break;
221 case FrontendSettings::hidl_discriminator::atsc3:
222 config.config1_0.settings.atsc3().frequency = resetingFreq;
223 break;
224 case FrontendSettings::hidl_discriminator::dvbc:
225 config.config1_0.settings.dvbc().frequency = resetingFreq;
226 break;
227 case FrontendSettings::hidl_discriminator::dvbs:
228 config.config1_0.settings.dvbs().frequency = resetingFreq;
229 break;
230 case FrontendSettings::hidl_discriminator::dvbt:
231 config.config1_0.settings.dvbt().frequency = resetingFreq;
232 break;
233 case FrontendSettings::hidl_discriminator::isdbs:
234 config.config1_0.settings.isdbs().frequency = resetingFreq;
235 break;
236 case FrontendSettings::hidl_discriminator::isdbs3:
237 config.config1_0.settings.isdbs3().frequency = resetingFreq;
238 break;
239 case FrontendSettings::hidl_discriminator::isdbt:
240 config.config1_0.settings.isdbt().frequency = resetingFreq;
241 break;
242 }
243 }
244
getFrontendIds()245 AssertionResult FrontendTests::getFrontendIds() {
246 Result status;
247 mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
248 status = result;
249 mFeIds = frontendIds;
250 });
251 return AssertionResult(status == Result::SUCCESS);
252 }
253
getFrontendInfo(uint32_t frontendId)254 AssertionResult FrontendTests::getFrontendInfo(uint32_t frontendId) {
255 Result status;
256 mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) {
257 mFrontendInfo = frontendInfo;
258 status = result;
259 });
260 return AssertionResult(status == Result::SUCCESS);
261 }
262
openFrontendById(uint32_t frontendId)263 AssertionResult FrontendTests::openFrontendById(uint32_t frontendId) {
264 Result status;
265 mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
266 mFrontend = frontend;
267 status = result;
268 });
269 return AssertionResult(status == Result::SUCCESS);
270 }
271
setFrontendCallback()272 AssertionResult FrontendTests::setFrontendCallback() {
273 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
274 mFrontendCallback = new FrontendCallback();
275 auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
276 return AssertionResult(callbackStatus.isOk());
277 }
278
scanFrontend(FrontendConfig1_1 config,FrontendScanType type)279 AssertionResult FrontendTests::scanFrontend(FrontendConfig1_1 config, FrontendScanType type) {
280 EXPECT_TRUE(mFrontendCallback)
281 << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
282
283 EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type)
284 << "FrontendConfig does not match the frontend info of the given id.";
285
286 mFrontendCallback->scanTest(mFrontend, config, type);
287 return AssertionResult(true);
288 }
289
stopScanFrontend()290 AssertionResult FrontendTests::stopScanFrontend() {
291 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
292 Result status;
293 status = mFrontend->stopScan();
294
295 return AssertionResult(status == Result::SUCCESS);
296 }
297
getFrontendDtmbCaps(uint32_t id)298 AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) {
299 Result status;
300 mService->getFrontendDtmbCapabilities(
301 id, [&](Result result, const FrontendDtmbCapabilities& /*caps*/) { status = result; });
302 return AssertionResult(status == Result::SUCCESS);
303 }
304
linkCiCam(uint32_t ciCamId)305 AssertionResult FrontendTests::linkCiCam(uint32_t ciCamId) {
306 sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
307 frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
308 if (frontend_1_1 == nullptr) {
309 EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
310 return failure();
311 }
312
313 Result status;
314 uint32_t ltsId;
315 frontend_1_1->linkCiCam(ciCamId, [&](Result r, uint32_t id) {
316 status = r;
317 ltsId = id;
318 });
319
320 return AssertionResult(status == Result::SUCCESS);
321 }
322
unlinkCiCam(uint32_t ciCamId)323 AssertionResult FrontendTests::unlinkCiCam(uint32_t ciCamId) {
324 sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
325 frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
326 if (frontend_1_1 == nullptr) {
327 EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
328 return failure();
329 }
330
331 Result status = frontend_1_1->unlinkCiCam(ciCamId);
332 return AssertionResult(status == Result::SUCCESS);
333 }
334
verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,vector<FrontendStatusExt1_1> expectStatuses)335 void FrontendTests::verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
336 vector<FrontendStatusExt1_1> expectStatuses) {
337 ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
338 Result status;
339 vector<FrontendStatusExt1_1> realStatuses;
340
341 sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
342 frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
343 if (frontend_1_1 == nullptr) {
344 EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation.";
345 return;
346 }
347
348 frontend_1_1->getStatusExt1_1(
349 statusTypes, [&](Result result, const hidl_vec<FrontendStatusExt1_1>& statuses) {
350 status = result;
351 realStatuses = statuses;
352 });
353
354 ASSERT_TRUE(realStatuses.size() == statusTypes.size());
355 for (int i = 0; i < statusTypes.size(); i++) {
356 FrontendStatusTypeExt1_1 type = statusTypes[i];
357 switch (type) {
358 case FrontendStatusTypeExt1_1::MODULATIONS: {
359 // TODO: verify modulations
360 break;
361 }
362 case FrontendStatusTypeExt1_1::BERS: {
363 ASSERT_TRUE(std::equal(realStatuses[i].bers().begin(), realStatuses[i].bers().end(),
364 expectStatuses[i].bers().begin()));
365 break;
366 }
367 case FrontendStatusTypeExt1_1::CODERATES: {
368 ASSERT_TRUE(std::equal(realStatuses[i].codeRates().begin(),
369 realStatuses[i].codeRates().end(),
370 expectStatuses[i].codeRates().begin()));
371 break;
372 }
373 case FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
374 // TODO: verify interval
375 break;
376 }
377 case FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
378 // TODO: verify tranmission mode
379 break;
380 }
381 case FrontendStatusTypeExt1_1::UEC: {
382 ASSERT_TRUE(realStatuses[i].uec() >= 0 );
383 break;
384 }
385 case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
386 ASSERT_TRUE(realStatuses[i].systemId() == expectStatuses[i].systemId());
387 break;
388 }
389 case FrontendStatusTypeExt1_1::INTERLEAVINGS: {
390 ASSERT_TRUE(std::equal(realStatuses[i].interleaving().begin(),
391 realStatuses[i].interleaving().end(),
392 expectStatuses[i].interleaving().begin()));
393 break;
394 }
395 case FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
396 ASSERT_TRUE(std::equal(realStatuses[i].isdbtSegment().begin(),
397 realStatuses[i].isdbtSegment().end(),
398 expectStatuses[i].isdbtSegment().begin()));
399 break;
400 }
401 case FrontendStatusTypeExt1_1::TS_DATA_RATES: {
402 ASSERT_TRUE(std::equal(realStatuses[i].tsDataRate().begin(),
403 realStatuses[i].tsDataRate().end(),
404 expectStatuses[i].tsDataRate().begin()));
405 break;
406 }
407 case FrontendStatusTypeExt1_1::ROLL_OFF: {
408 // TODO: verify roll off
409 break;
410 }
411 case FrontendStatusTypeExt1_1::IS_MISO: {
412 ASSERT_TRUE(realStatuses[i].isMiso() == expectStatuses[i].isMiso());
413 break;
414 }
415 case FrontendStatusTypeExt1_1::IS_LINEAR: {
416 ASSERT_TRUE(realStatuses[i].isLinear() == expectStatuses[i].isLinear());
417 break;
418 }
419 case FrontendStatusTypeExt1_1::IS_SHORT_FRAMES: {
420 ASSERT_TRUE(realStatuses[i].isShortFrames() == expectStatuses[i].isShortFrames());
421 break;
422 }
423 default: {
424 continue;
425 }
426 }
427 }
428 ASSERT_TRUE(status == Result::SUCCESS);
429 }
430
tuneFrontend(FrontendConfig1_1 config,bool testWithDemux)431 AssertionResult FrontendTests::tuneFrontend(FrontendConfig1_1 config, bool testWithDemux) {
432 EXPECT_TRUE(mFrontendCallback)
433 << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
434
435 EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type)
436 << "FrontendConfig does not match the frontend info of the given id.";
437
438 mIsSoftwareFe = config.config1_0.isSoftwareFe;
439 bool result = true;
440 if (mIsSoftwareFe && testWithDemux) {
441 result &=
442 getDvrTests()->openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success();
443 result &= getDvrTests()->configDvrPlayback(mDvrConfig.settings) == success();
444 result &= getDvrTests()->getDvrPlaybackMQDescriptor() == success();
445 getDvrTests()->startPlaybackInputThread(mDvrConfig.playbackInputFile,
446 mDvrConfig.settings.playback());
447 getDvrTests()->startDvrPlayback();
448 if (!result) {
449 ALOGW("[vts] Software frontend dvr configure failed.");
450 return failure();
451 }
452 }
453 mFrontendCallback->tuneTestOnLock(mFrontend, config.config1_0.settings, config.settingsExt1_1);
454 return AssertionResult(true);
455 }
456
stopTuneFrontend(bool testWithDemux)457 AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) {
458 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
459 Result status;
460 status = mFrontend->stopTune();
461 if (mIsSoftwareFe && testWithDemux) {
462 getDvrTests()->stopPlaybackThread();
463 getDvrTests()->stopDvrPlayback();
464 getDvrTests()->closeDvrPlayback();
465 }
466 return AssertionResult(status == Result::SUCCESS);
467 }
468
closeFrontend()469 AssertionResult FrontendTests::closeFrontend() {
470 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
471 Result status;
472 status = mFrontend->close();
473 mFrontend = nullptr;
474 mFrontendCallback = nullptr;
475 return AssertionResult(status == Result::SUCCESS);
476 }
477
getFrontendIdByType(FrontendType feType,uint32_t & feId)478 void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) {
479 ASSERT_TRUE(getFrontendIds());
480 for (size_t i = 0; i < mFeIds.size(); i++) {
481 ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
482 if (mFrontendInfo.type != feType) {
483 continue;
484 }
485 feId = mFeIds[i];
486 return;
487 }
488 feId = INVALID_ID;
489 }
490
tuneTest(FrontendConfig1_1 frontendConf)491 void FrontendTests::tuneTest(FrontendConfig1_1 frontendConf) {
492 uint32_t feId;
493 getFrontendIdByType(frontendConf.config1_0.type, feId);
494 ASSERT_TRUE(feId != INVALID_ID);
495 ASSERT_TRUE(openFrontendById(feId));
496 ASSERT_TRUE(setFrontendCallback());
497 if (frontendConf.canConnectToCiCam) {
498 ASSERT_TRUE(linkCiCam(frontendConf.ciCamId));
499 ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId));
500 }
501 ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
502 verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
503 ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
504 ASSERT_TRUE(closeFrontend());
505 }
506
scanTest(FrontendConfig1_1 frontendConf,FrontendScanType scanType)507 void FrontendTests::scanTest(FrontendConfig1_1 frontendConf, FrontendScanType scanType) {
508 uint32_t feId;
509 getFrontendIdByType(frontendConf.config1_0.type, feId);
510 ASSERT_TRUE(feId != INVALID_ID);
511 ASSERT_TRUE(openFrontendById(feId));
512 ASSERT_TRUE(setFrontendCallback());
513 ASSERT_TRUE(scanFrontend(frontendConf, scanType));
514 ASSERT_TRUE(stopScanFrontend());
515 ASSERT_TRUE(closeFrontend());
516 }
517
getFrontendDtmbCapsTest()518 void FrontendTests::getFrontendDtmbCapsTest() {
519 uint32_t feId;
520 getFrontendIdByType(
521 static_cast<FrontendType>(android::hardware::tv::tuner::V1_1::FrontendType::DTMB),
522 feId);
523 if (feId != INVALID_ID) {
524 ALOGD("[vts] Found DTMB Frontend");
525 ASSERT_TRUE(getFrontendDtmbCaps(feId));
526 }
527 }
528