blob: b7b01859b2428266a69a26a23bef610f355d0045 [file] [log] [blame]
Hongguang600a6ae2021-07-08 18:51:51 -07001/*
2 * Copyright 2021 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
Frankie Lizcanof09587c2022-05-24 23:06:43 +000019#include <aidl/android/hardware/tv/tuner/Result.h>
20
Hongguang600a6ae2021-07-08 18:51:51 -070021ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
22 android::Mutex::Autolock autoLock(mMsgLock);
23 ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
24 mEventReceived = true;
25 mMsgCondition.signal();
26 switch (frontendEventType) {
27 case FrontendEventType::LOCKED:
28 mLockMsgReceived = true;
29 mLockMsgCondition.signal();
30 break;
31 default:
32 // do nothing
33 break;
34 }
35 return ndk::ScopedAStatus::ok();
36}
37
38ndk::ScopedAStatus FrontendCallback::onScanMessage(FrontendScanMessageType type,
39 const FrontendScanMessage& message) {
40 android::Mutex::Autolock autoLock(mMsgLock);
41 while (!mScanMsgProcessed) {
42 mMsgCondition.wait(mMsgLock);
43 }
44 ALOGD("[vts] frontend scan message. Type: %d", type);
45 switch (message.getTag()) {
46 case FrontendScanMessage::modulation:
47 readFrontendScanMessage_Modulation(message.get<FrontendScanMessage::Tag::modulation>());
48 break;
49 case FrontendScanMessage::Tag::isHighPriority:
50 ALOGD("[vts] frontend scan message high priority: %d",
51 message.get<FrontendScanMessage::Tag::isHighPriority>());
52 break;
53 case FrontendScanMessage::Tag::annex:
54 ALOGD("[vts] frontend scan message dvbc annex: %hhu",
55 message.get<FrontendScanMessage::Tag::annex>());
56 break;
57 default:
58 break;
59 }
60 mScanMessageReceived = true;
61 mScanMsgProcessed = false;
62 mScanMessageType = type;
63 mScanMessage = message;
64 mMsgCondition.signal();
65 return ndk::ScopedAStatus::ok();
66}
67
68void FrontendCallback::readFrontendScanMessage_Modulation(FrontendModulation modulation) {
69 switch (modulation.getTag()) {
70 case FrontendModulation::Tag::dvbc:
71 ALOGD("[vts] frontend scan message modulation dvbc: %d",
72 modulation.get<FrontendModulation::Tag::dvbc>());
73 break;
74 case FrontendModulation::Tag::dvbs:
75 ALOGD("[vts] frontend scan message modulation dvbs: %d",
76 modulation.get<FrontendModulation::Tag::dvbs>());
77 break;
78 case FrontendModulation::Tag::isdbs:
79 ALOGD("[vts] frontend scan message modulation isdbs: %d",
80 modulation.get<FrontendModulation::Tag::isdbs>());
81 break;
82 case FrontendModulation::Tag::isdbs3:
83 ALOGD("[vts] frontend scan message modulation isdbs3: %d",
84 modulation.get<FrontendModulation::Tag::isdbs3>());
85 break;
86 case FrontendModulation::Tag::isdbt:
87 ALOGD("[vts] frontend scan message modulation isdbt: %d",
88 modulation.get<FrontendModulation::Tag::isdbt>());
89 break;
90 case FrontendModulation::Tag::atsc:
91 ALOGD("[vts] frontend scan message modulation atsc: %d",
92 modulation.get<FrontendModulation::Tag::atsc>());
93 break;
94 case FrontendModulation::Tag::atsc3:
95 ALOGD("[vts] frontend scan message modulation atsc3: %d",
96 modulation.get<FrontendModulation::Tag::atsc3>());
97 break;
98 case FrontendModulation::Tag::dvbt:
99 ALOGD("[vts] frontend scan message modulation dvbt: %d",
100 modulation.get<FrontendModulation::Tag::dvbt>());
101 break;
102 default:
103 break;
104 }
105}
106
107void FrontendCallback::tuneTestOnLock(std::shared_ptr<IFrontend>& frontend,
108 FrontendSettings settings) {
109 ndk::ScopedAStatus result = frontend->tune(settings);
110 EXPECT_TRUE(result.isOk());
111
112 android::Mutex::Autolock autoLock(mMsgLock);
113 while (!mLockMsgReceived) {
114 if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
115 EXPECT_TRUE(false) << "Event LOCKED not received within timeout";
116 mLockMsgReceived = false;
117 return;
118 }
119 }
120 mLockMsgReceived = false;
121}
122
123void FrontendCallback::scanTest(std::shared_ptr<IFrontend>& frontend, FrontendConfig config,
124 FrontendScanType type) {
Hongguang11da2cb2021-08-05 19:05:12 -0700125 int64_t targetFrequency = getTargetFrequency(config.settings);
Hongguang600a6ae2021-07-08 18:51:51 -0700126 if (type == FrontendScanType::SCAN_BLIND) {
127 // reset the frequency in the scan configuration to test blind scan. The settings param of
128 // passed in means the real input config on the transponder connected to the DUT.
129 // We want the blind the test to start from lower frequency than this to check the blind
130 // scan implementation.
Gareth Fenn282fb372021-09-27 15:14:11 +0100131 resetBlindScanStartingFrequency(config, targetFrequency - 100 * 1000);
Hongguang600a6ae2021-07-08 18:51:51 -0700132 }
133
134 ndk::ScopedAStatus result = frontend->scan(config.settings, type);
135 EXPECT_TRUE(result.isOk());
136
137 bool scanMsgLockedReceived = false;
138 bool targetFrequencyReceived = false;
139
140 android::Mutex::Autolock autoLock(mMsgLock);
141wait:
142 while (!mScanMessageReceived) {
143 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
144 EXPECT_TRUE(false) << "Scan message not received within timeout";
145 mScanMessageReceived = false;
146 mScanMsgProcessed = true;
147 return;
148 }
149 }
150
151 if (mScanMessageType != FrontendScanMessageType::END) {
152 if (mScanMessageType == FrontendScanMessageType::LOCKED) {
153 scanMsgLockedReceived = true;
154 result = frontend->scan(config.settings, type);
155 EXPECT_TRUE(result.isOk());
156 }
157
158 if (mScanMessageType == FrontendScanMessageType::FREQUENCY) {
159 targetFrequencyReceived =
160 mScanMessage.get<FrontendScanMessage::Tag::frequencies>().size() > 0 &&
161 mScanMessage.get<FrontendScanMessage::Tag::frequencies>()[0] == targetFrequency;
162 }
163
164 if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) {
165 ALOGD("[vts] Scan in progress...[%d%%]",
166 mScanMessage.get<FrontendScanMessage::Tag::progressPercent>());
167 }
168
169 mScanMessageReceived = false;
170 mScanMsgProcessed = true;
171 mMsgCondition.signal();
172 goto wait;
173 }
174
175 EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
ming.lod4c22d82021-11-05 16:22:38 +0800176 if (type == FrontendScanType::SCAN_BLIND)
177 EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
Hongguang600a6ae2021-07-08 18:51:51 -0700178 mScanMessageReceived = false;
179 mScanMsgProcessed = true;
180}
181
Hongguang11da2cb2021-08-05 19:05:12 -0700182int64_t FrontendCallback::getTargetFrequency(FrontendSettings& settings) {
Hongguang600a6ae2021-07-08 18:51:51 -0700183 switch (settings.getTag()) {
184 case FrontendSettings::Tag::analog:
185 return settings.get<FrontendSettings::Tag::analog>().frequency;
186 case FrontendSettings::Tag::atsc:
187 return settings.get<FrontendSettings::Tag::atsc>().frequency;
188 case FrontendSettings::Tag::atsc3:
189 return settings.get<FrontendSettings::Tag::atsc3>().frequency;
190 case FrontendSettings::Tag::dvbc:
191 return settings.get<FrontendSettings::Tag::dvbc>().frequency;
192 case FrontendSettings::Tag::dvbs:
193 return settings.get<FrontendSettings::Tag::dvbs>().frequency;
194 case FrontendSettings::Tag::dvbt:
195 return settings.get<FrontendSettings::Tag::dvbt>().frequency;
196 case FrontendSettings::Tag::isdbs:
197 return settings.get<FrontendSettings::Tag::isdbs>().frequency;
198 case FrontendSettings::Tag::isdbs3:
199 return settings.get<FrontendSettings::Tag::isdbs3>().frequency;
200 case FrontendSettings::Tag::isdbt:
201 return settings.get<FrontendSettings::Tag::isdbt>().frequency;
202 default:
203 return 0;
204 }
205}
206
207void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config,
Hongguang11da2cb2021-08-05 19:05:12 -0700208 int64_t resetingFreq) {
Hongguang600a6ae2021-07-08 18:51:51 -0700209 switch (config.settings.getTag()) {
210 case FrontendSettings::Tag::analog:
211 config.settings.get<FrontendSettings::Tag::analog>().frequency = resetingFreq;
212 break;
213 case FrontendSettings::Tag::atsc:
214 config.settings.get<FrontendSettings::Tag::atsc>().frequency = resetingFreq;
215 break;
216 case FrontendSettings::Tag::atsc3:
217 config.settings.get<FrontendSettings::Tag::atsc3>().frequency = resetingFreq;
218 break;
219 case FrontendSettings::Tag::dvbc:
220 config.settings.get<FrontendSettings::Tag::dvbc>().frequency = resetingFreq;
221 break;
222 case FrontendSettings::Tag::dvbs:
223 config.settings.get<FrontendSettings::Tag::dvbs>().frequency = resetingFreq;
224 break;
225 case FrontendSettings::Tag::dvbt:
226 config.settings.get<FrontendSettings::Tag::dvbt>().frequency = resetingFreq;
227 break;
228 case FrontendSettings::Tag::isdbs:
229 config.settings.get<FrontendSettings::Tag::isdbs>().frequency = resetingFreq;
230 break;
231 case FrontendSettings::Tag::isdbs3:
232 config.settings.get<FrontendSettings::Tag::isdbs3>().frequency = resetingFreq;
233 break;
234 case FrontendSettings::Tag::isdbt:
235 config.settings.get<FrontendSettings::Tag::isdbt>().frequency = resetingFreq;
236 break;
237 default:
238 break;
239 }
240}
241
242AssertionResult FrontendTests::getFrontendIds() {
243 ndk::ScopedAStatus status;
244 status = mService->getFrontendIds(&mFeIds);
245 return AssertionResult(status.isOk());
246}
247
248AssertionResult FrontendTests::getFrontendInfo(int32_t frontendId) {
249 ndk::ScopedAStatus status;
250 status = mService->getFrontendInfo(frontendId, &mFrontendInfo);
251 return AssertionResult(status.isOk());
252}
253
254AssertionResult FrontendTests::openFrontendById(int32_t frontendId) {
255 ndk::ScopedAStatus status;
256 status = mService->openFrontendById(frontendId, &mFrontend);
257 return AssertionResult(status.isOk());
258}
259
260AssertionResult FrontendTests::setFrontendCallback() {
261 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
262 mFrontendCallback = ndk::SharedRefBase::make<FrontendCallback>();
263 auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
264 return AssertionResult(callbackStatus.isOk());
265}
266
267AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) {
268 EXPECT_TRUE(mFrontendCallback)
269 << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
270
271 EXPECT_TRUE(mFrontendInfo.type == config.type)
272 << "FrontendConfig does not match the frontend info of the given id.";
273
274 mFrontendCallback->scanTest(mFrontend, config, type);
275 return AssertionResult(true);
276}
277
278AssertionResult FrontendTests::stopScanFrontend() {
279 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
280 ndk::ScopedAStatus status;
281 status = mFrontend->stopScan();
282
283 return AssertionResult(status.isOk());
284}
285
286AssertionResult FrontendTests::setLnb(int32_t lnbId) {
287 if (!mFrontendCallback) {
288 ALOGW("[vts] open and set frontend callback first.");
289 return failure();
290 }
291 return AssertionResult(mFrontend->setLnb(lnbId).isOk());
292}
293
294AssertionResult FrontendTests::linkCiCam(int32_t ciCamId) {
295 ndk::ScopedAStatus status;
296 int32_t ltsId;
297 status = mFrontend->linkCiCam(ciCamId, &ltsId);
298 return AssertionResult(status.isOk());
299}
300
Hongguange106f472022-01-11 12:09:22 -0800301AssertionResult FrontendTests::removeOutputPid(int32_t removePid) {
302 ndk::ScopedAStatus status;
303 status = mFrontend->removeOutputPid(removePid);
304 return AssertionResult(status.isOk() || status.getServiceSpecificError() ==
305 static_cast<int32_t>(Result::UNAVAILABLE));
306}
307
Hongguang600a6ae2021-07-08 18:51:51 -0700308AssertionResult FrontendTests::unlinkCiCam(int32_t ciCamId) {
309 ndk::ScopedAStatus status = mFrontend->unlinkCiCam(ciCamId);
310 return AssertionResult(status.isOk());
311}
312
313void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
314 vector<FrontendStatus> expectStatuses) {
315 ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
316 ndk::ScopedAStatus status;
317 vector<FrontendStatus> realStatuses;
318
319 status = mFrontend->getStatus(statusTypes, &realStatuses);
320 ASSERT_TRUE(status.isOk() && realStatuses.size() == statusTypes.size());
321
322 for (int i = 0; i < statusTypes.size(); i++) {
323 FrontendStatusType type = statusTypes[i];
324 switch (type) {
325 case FrontendStatusType::MODULATIONS: {
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000326 ASSERT_TRUE(std::equal(
327 realStatuses[i].get<FrontendStatus::Tag::modulations>().begin(),
328 realStatuses[i].get<FrontendStatus::Tag::modulations>().end(),
329 expectStatuses[i].get<FrontendStatus::Tag::modulations>().begin()));
Hongguang600a6ae2021-07-08 18:51:51 -0700330 break;
331 }
332 case FrontendStatusType::BERS: {
333 ASSERT_TRUE(std::equal(realStatuses[i].get<FrontendStatus::Tag::bers>().begin(),
334 realStatuses[i].get<FrontendStatus::Tag::bers>().end(),
335 expectStatuses[i].get<FrontendStatus::Tag::bers>().begin()));
336 break;
337 }
338 case FrontendStatusType::CODERATES: {
339 ASSERT_TRUE(std::equal(
340 realStatuses[i].get<FrontendStatus::Tag::codeRates>().begin(),
341 realStatuses[i].get<FrontendStatus::Tag::codeRates>().end(),
342 expectStatuses[i].get<FrontendStatus::Tag::codeRates>().begin()));
343 break;
344 }
345 case FrontendStatusType::GUARD_INTERVAL: {
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000346 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::interval>() ==
347 expectStatuses[i].get<FrontendStatus::Tag::interval>());
Hongguang600a6ae2021-07-08 18:51:51 -0700348 break;
349 }
350 case FrontendStatusType::TRANSMISSION_MODE: {
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000351 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::transmissionMode>() ==
352 expectStatuses[i].get<FrontendStatus::Tag::transmissionMode>());
Hongguang600a6ae2021-07-08 18:51:51 -0700353 break;
354 }
355 case FrontendStatusType::UEC: {
356 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::uec>() ==
357 expectStatuses[i].get<FrontendStatus::Tag::uec>());
358 break;
359 }
360 case FrontendStatusType::T2_SYSTEM_ID: {
361 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::systemId>() ==
362 expectStatuses[i].get<FrontendStatus::Tag::systemId>());
363 break;
364 }
365 case FrontendStatusType::INTERLEAVINGS: {
366 ASSERT_TRUE(std::equal(
367 realStatuses[i].get<FrontendStatus::Tag::interleaving>().begin(),
368 realStatuses[i].get<FrontendStatus::Tag::interleaving>().end(),
369 expectStatuses[i].get<FrontendStatus::Tag::interleaving>().begin()));
370 break;
371 }
372 case FrontendStatusType::ISDBT_SEGMENTS: {
373 ASSERT_TRUE(std::equal(
374 realStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().begin(),
375 realStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().end(),
376 expectStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().begin()));
377 break;
378 }
379 case FrontendStatusType::TS_DATA_RATES: {
380 ASSERT_TRUE(std::equal(
381 realStatuses[i].get<FrontendStatus::Tag::tsDataRate>().begin(),
382 realStatuses[i].get<FrontendStatus::Tag::tsDataRate>().end(),
383 expectStatuses[i].get<FrontendStatus::Tag::tsDataRate>().begin()));
384 break;
385 }
386 case FrontendStatusType::ROLL_OFF: {
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000387 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::rollOff>() ==
388 expectStatuses[i].get<FrontendStatus::Tag::rollOff>());
Hongguang600a6ae2021-07-08 18:51:51 -0700389 break;
390 }
391 case FrontendStatusType::IS_MISO: {
392 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isMiso>() ==
393 expectStatuses[i].get<FrontendStatus::Tag::isMiso>());
394 break;
395 }
396 case FrontendStatusType::IS_LINEAR: {
397 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isLinear>() ==
398 expectStatuses[i].get<FrontendStatus::Tag::isLinear>());
399 break;
400 }
401 case FrontendStatusType::IS_SHORT_FRAMES: {
402 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isShortFrames>() ==
403 expectStatuses[i].get<FrontendStatus::Tag::isShortFrames>());
404 break;
405 }
Hongguang788284f2021-10-28 15:03:29 -0700406 case FrontendStatusType::ISDBT_MODE: {
407 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isdbtMode>() ==
408 expectStatuses[i].get<FrontendStatus::Tag::isdbtMode>());
409 break;
410 }
411 case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
412 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>() ==
413 expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
414 break;
415 }
Hongguang2ecfc392021-11-23 10:29:15 -0800416 case FrontendStatusType::STREAM_ID_LIST: {
417 ASSERT_TRUE(std::equal(
418 realStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin(),
419 realStatuses[i].get<FrontendStatus::Tag::streamIdList>().end(),
420 expectStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin()));
421 break;
422 }
Hongguang7eda7822021-12-20 14:48:14 -0800423 case FrontendStatusType::DVBT_CELL_IDS: {
424 ASSERT_TRUE(std::equal(
425 realStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().begin(),
426 realStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().end(),
427 expectStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().begin()));
428 break;
429 }
Hongguangd99c82d2022-01-13 12:42:52 -0800430 case FrontendStatusType::ATSC3_ALL_PLP_INFO: {
431 ASSERT_TRUE(std::equal(
432 realStatuses[i].get<FrontendStatus::Tag::allPlpInfo>().begin(),
433 realStatuses[i].get<FrontendStatus::Tag::allPlpInfo>().end(),
434 expectStatuses[i].get<FrontendStatus::Tag::allPlpInfo>().begin()));
435 break;
436 }
sadiqsadaaff01d72023-01-12 11:02:34 -0800437 case FrontendStatusType::IPTV_CONTENT_URL: {
438 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>() ==
439 expectStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>());
440 break;
441 }
442 case FrontendStatusType::IPTV_PACKETS_LOST: {
443 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>() ==
444 expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>());
445 break;
446 }
447 case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
448 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>() ==
449 expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>());
450 break;
451 }
452 case FrontendStatusType::IPTV_WORST_JITTER_MS: {
453 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>() ==
454 expectStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>());
455 break;
456 }
457 case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
458 ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>() ==
459 expectStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>());
460 break;
461 }
Hongguang600a6ae2021-07-08 18:51:51 -0700462 default: {
463 continue;
464 }
465 }
466 }
467 ASSERT_TRUE(status.isOk());
468}
469
470AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) {
471 EXPECT_TRUE(mFrontendCallback)
472 << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
473
474 EXPECT_TRUE(mFrontendInfo.type == config.type)
475 << "FrontendConfig does not match the frontend info of the given id.";
476
477 mIsSoftwareFe = config.isSoftwareFe;
sadiqsada7a191392023-11-07 16:09:09 -0800478 std::unique_ptr<IpStreamer> ipThread = std::make_unique<IpStreamer>();
479 if (config.type == FrontendType::IPTV) {
480 ipThread->startIpStream();
481 }
Hongguang600a6ae2021-07-08 18:51:51 -0700482 if (mIsSoftwareFe && testWithDemux) {
483 if (getDvrTests()->openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) != success()) {
484 ALOGW("[vts] Software frontend dvr configure openDvr failed.");
485 return failure();
486 }
487 if (getDvrTests()->configDvrPlayback(mDvrConfig.settings) != success()) {
488 ALOGW("[vts] Software frontend dvr configure Dvr playback failed.");
489 return failure();
490 }
491 if (getDvrTests()->getDvrPlaybackMQDescriptor() != success()) {
492 ALOGW("[vts] Software frontend dvr configure get MQDesc failed.");
493 return failure();
494 }
495 getDvrTests()->startPlaybackInputThread(
496 mDvrConfig.playbackInputFile,
497 mDvrConfig.settings.get<DvrSettings::Tag::playback>());
Treehugger Robot4cdc4f22021-12-17 00:28:32 +0000498 getDvrTests()->startDvrPlayback();
Hongguang600a6ae2021-07-08 18:51:51 -0700499 }
500 mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
sadiqsada7a191392023-11-07 16:09:09 -0800501 if (config.type == FrontendType::IPTV) {
502 ipThread->stopIpStream();
503 }
Hongguang600a6ae2021-07-08 18:51:51 -0700504 return AssertionResult(true);
505}
506
507AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) {
508 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
509 ndk::ScopedAStatus status;
510 status = mFrontend->stopTune();
511 if (mIsSoftwareFe && testWithDemux) {
512 getDvrTests()->stopPlaybackThread();
Treehugger Robot4cdc4f22021-12-17 00:28:32 +0000513 getDvrTests()->stopDvrPlayback();
Hongguang600a6ae2021-07-08 18:51:51 -0700514 getDvrTests()->closeDvrPlayback();
515 }
516 return AssertionResult(status.isOk());
517}
518
519AssertionResult FrontendTests::closeFrontend() {
520 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
521 ndk::ScopedAStatus status;
522 status = mFrontend->close();
523 mFrontend = nullptr;
524 mFrontendCallback = nullptr;
525 return AssertionResult(status.isOk());
526}
527
528void FrontendTests::getFrontendIdByType(FrontendType feType, int32_t& feId) {
529 ASSERT_TRUE(getFrontendIds());
Hongguang600a6ae2021-07-08 18:51:51 -0700530 for (size_t i = 0; i < mFeIds.size(); i++) {
531 ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
532 if (mFrontendInfo.type != feType) {
533 continue;
534 }
535 feId = mFeIds[i];
536 return;
537 }
538 feId = INVALID_ID;
539}
540
Hongguangfcedda02021-12-13 17:08:02 -0800541AssertionResult FrontendTests::verifyHardwareInfo() {
542 EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
543 std::string info;
544 ndk::ScopedAStatus status = mFrontend->getHardwareInfo(&info);
545 return AssertionResult(status.isOk() && !info.empty());
546}
547
Hongguang600a6ae2021-07-08 18:51:51 -0700548void FrontendTests::tuneTest(FrontendConfig frontendConf) {
549 int32_t feId;
550 getFrontendIdByType(frontendConf.type, feId);
551 ASSERT_TRUE(feId != INVALID_ID);
552 ASSERT_TRUE(openFrontendById(feId));
553 ASSERT_TRUE(setFrontendCallback());
554 if (frontendConf.canConnectToCiCam) {
555 ASSERT_TRUE(linkCiCam(frontendConf.ciCamId));
Hongguange106f472022-01-11 12:09:22 -0800556 ASSERT_TRUE(removeOutputPid(frontendConf.removePid));
Hongguang600a6ae2021-07-08 18:51:51 -0700557 ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId));
558 }
559 ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
560 verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
561 ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
562 ASSERT_TRUE(closeFrontend());
563}
564
Hongguangfcedda02021-12-13 17:08:02 -0800565void FrontendTests::debugInfoTest(FrontendConfig frontendConf) {
566 int32_t feId;
567 getFrontendIdByType(frontendConf.type, feId);
568 ASSERT_TRUE(feId != INVALID_ID);
569 ASSERT_TRUE(openFrontendById(feId));
570 ASSERT_TRUE(setFrontendCallback());
571 ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
572 ASSERT_TRUE(verifyHardwareInfo());
573 ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
574 ASSERT_TRUE(closeFrontend());
575}
576
Hongguang5766ddf2021-12-23 11:40:37 -0800577void FrontendTests::maxNumberOfFrontendsTest() {
578 ASSERT_TRUE(getFrontendIds());
579 for (size_t i = 0; i < mFeIds.size(); i++) {
580 ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
581 int32_t defaultMax = -1;
582 ndk::ScopedAStatus status;
583 // Check default value
584 status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &defaultMax);
585 ASSERT_TRUE(status.isOk());
586 ASSERT_TRUE(defaultMax > 0);
587 // Set to -1
588 status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, -1);
589 ASSERT_TRUE(status.getServiceSpecificError() ==
590 static_cast<int32_t>(Result::INVALID_ARGUMENT));
591 // Set to defaultMax + 1
592 status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, defaultMax + 1);
593 ASSERT_TRUE(status.getServiceSpecificError() ==
594 static_cast<int32_t>(Result::INVALID_ARGUMENT));
595 // Set to 0
596 status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, 0);
597 ASSERT_TRUE(status.isOk());
598 // Check after set
599 int32_t currentMax = -1;
600 status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &currentMax);
601 ASSERT_TRUE(status.isOk());
602 ASSERT_TRUE(currentMax == 0);
603 // Reset to default
604 status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, defaultMax);
605 ASSERT_TRUE(status.isOk());
606 status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &currentMax);
607 ASSERT_TRUE(status.isOk());
608 ASSERT_TRUE(defaultMax == currentMax);
609 }
610}
611
Hongguang600a6ae2021-07-08 18:51:51 -0700612void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
613 int32_t feId;
614 getFrontendIdByType(frontendConf.type, feId);
615 ASSERT_TRUE(feId != INVALID_ID);
616 ASSERT_TRUE(openFrontendById(feId));
617 ASSERT_TRUE(setFrontendCallback());
618 ASSERT_TRUE(scanFrontend(frontendConf, scanType));
619 ASSERT_TRUE(stopScanFrontend());
620 ASSERT_TRUE(closeFrontend());
621}
Hongguang881190f2022-01-14 13:23:37 -0800622
623void FrontendTests::statusReadinessTest(FrontendConfig frontendConf) {
624 int32_t feId;
625 vector<FrontendStatusType> allTypes;
626 vector<FrontendStatusReadiness> readiness;
627 getFrontendIdByType(frontendConf.type, feId);
628 ASSERT_TRUE(feId != INVALID_ID);
629 ASSERT_TRUE(openFrontendById(feId));
630 ASSERT_TRUE(setFrontendCallback());
631 if (frontendConf.canConnectToCiCam) {
632 ASSERT_TRUE(linkCiCam(frontendConf.ciCamId));
633 ASSERT_TRUE(removeOutputPid(frontendConf.removePid));
634 ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId));
635 }
636 ASSERT_TRUE(getFrontendInfo(feId));
637 ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
638
639 // TODO: find a better way to push all frontend status types
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000640 for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
Hongguang881190f2022-01-14 13:23:37 -0800641 allTypes.push_back(static_cast<FrontendStatusType>(i));
642 }
Frankie Lizcanof09587c2022-05-24 23:06:43 +0000643
Hongguang881190f2022-01-14 13:23:37 -0800644 ndk::ScopedAStatus status = mFrontend->getFrontendStatusReadiness(allTypes, &readiness);
645 ASSERT_TRUE(status.isOk());
646 ASSERT_TRUE(readiness.size() == allTypes.size());
647 for (int32_t i = 0; i < readiness.size(); i++) {
648 int32_t j = 0;
649 while (j < mFrontendInfo.statusCaps.size()) {
650 if (allTypes[i] == mFrontendInfo.statusCaps[j]) {
651 ASSERT_TRUE(readiness[i] == FrontendStatusReadiness::UNAVAILABLE ||
652 readiness[i] == FrontendStatusReadiness::UNSTABLE ||
653 readiness[i] == FrontendStatusReadiness::STABLE);
654 break;
655 }
656 j++;
657 }
658
659 if (j >= mFrontendInfo.statusCaps.size()) {
660 ASSERT_TRUE(readiness[i] == FrontendStatusReadiness::UNSUPPORTED);
661 }
662 }
663
664 ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
665 ASSERT_TRUE(closeFrontend());
666}