1 /*
2 * Copyright (C) 2023 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 "MockBroadcastRadioCallback.h"
18
19 #include <BroadcastRadio.h>
20 #include <VirtualRadio.h>
21 #include <broadcastradio-utils-aidl/Utils.h>
22
23 #include <android-base/logging.h>
24 #include <gtest/gtest.h>
25
26 namespace aidl::android::hardware::broadcastradio {
27
28 namespace {
29 using ::std::vector;
30
31 constexpr uint32_t kAmFreq1 = 560u;
32 constexpr uint32_t kAmFreq2 = 680u;
33 constexpr uint32_t kAmHdFreq = 1170u;
34 constexpr uint64_t kAmHdSid = 0xB0000001u;
35 constexpr uint32_t kFmFreq1 = 94900u;
36 constexpr uint64_t kFmHdSid1 = 0xA0000001u;
37 constexpr uint64_t kFmHdSid2 = 0xA0000002u;
38 constexpr uint32_t kFmHdFreq1 = 98500u;
39 constexpr uint32_t kFmHdSubChannel0 = 0u;
40 constexpr uint32_t kFmHdSubChannel1 = 1u;
41 constexpr uint32_t kFmFreq2 = 99100u;
42 constexpr uint32_t kFmHdFreq2 = 101100u;
43
44 const ProgramSelector kAmSel1 = utils::makeSelectorAmfm(kAmFreq1);
45 const ProgramSelector kAmSel2 = utils::makeSelectorAmfm(kAmFreq2);
46 const ProgramSelector kAmHdSel = utils::makeSelectorHd(kAmHdSid, kFmHdSubChannel0, kAmHdFreq);
47 const ProgramSelector kFmSel1 = utils::makeSelectorAmfm(kFmFreq1);
48 const ProgramSelector kFmSel2 = utils::makeSelectorAmfm(kFmFreq2);
49 const ProgramSelector kFmHdFreq1Sel1 =
50 utils::makeSelectorHd(kFmHdSid1, kFmHdSubChannel0, kFmHdFreq1);
51 const ProgramSelector kFmHdFreq1Sel2 =
52 utils::makeSelectorHd(kFmHdSid1, kFmHdSubChannel1, kFmHdFreq1);
53 const ProgramSelector kFmHdFreq2Sel1 =
54 utils::makeSelectorHd(kFmHdSid2, kFmHdSubChannel0, kFmHdFreq2);
55 const ProgramSelector kFmHdFreq2Sel2 =
56 utils::makeSelectorHd(kFmHdSid2, kFmHdSubChannel1, kFmHdFreq2);
57
getAmFmMockTestRadio()58 const VirtualRadio& getAmFmMockTestRadio() {
59 static VirtualRadio amFmRadioMockTestRadio(
60 "AM/FM radio mock for test",
61 {
62 {kAmSel1, "ProgramAm1", "ArtistAm1", "TitleAm1"},
63 {kAmSel2, "ProgramAm2", "ArtistAm2", "TitleAm2"},
64 {kFmSel1, "ProgramFm1", "ArtistFm1", "TitleFm1"},
65 {kFmSel2, "ProgramFm2", "ArtistFm2", "TitleFm2"},
66 {kAmHdSel, "ProgramAmHd1", "ArtistAmHd1", "TitleAmHd1"},
67 {kFmHdFreq1Sel1, "ProgramFmHd1", "ArtistFmHd1", "TitleFmHd1"},
68 {kFmHdFreq1Sel2, "ProgramFmHd2", "ArtistFmHd2", "TitleFmHd2"},
69 {kFmHdFreq2Sel1, "ProgramFmHd3", "ArtistFmHd3", "TitleFmHd3"},
70 {kFmHdFreq2Sel2, "ProgramFmHd4", "ArtistFmHd4", "TitleFmHd4"},
71 });
72 return amFmRadioMockTestRadio;
73 }
74
getSignalAcquisitionFlags(const ProgramInfo & info)75 int getSignalAcquisitionFlags(const ProgramInfo& info) {
76 return (info.infoFlags &
77 (ProgramInfo::FLAG_SIGNAL_ACQUISITION | ProgramInfo::FLAG_HD_SIS_ACQUISITION |
78 ProgramInfo::FLAG_HD_AUDIO_ACQUISITION)) >>
79 6;
80 }
81
82 } // namespace
83
84 class DefaultBroadcastRadioHalTest : public testing::Test {
85 public:
SetUp()86 void SetUp() override {
87 ::android::base::SetDefaultTag("BcRadioAidlDef.test");
88 const VirtualRadio& amFmRadioMockTest = getAmFmMockTestRadio();
89 mBroadcastRadioHal = ::ndk::SharedRefBase::make<BroadcastRadio>(amFmRadioMockTest);
90 mTunerCallback = ndk::SharedRefBase::make<MockBroadcastRadioCallback>();
91 }
92
TearDown()93 void TearDown() override {
94 mBroadcastRadioHal->unsetTunerCallback();
95 EXPECT_FALSE(mTunerCallback->isTunerFailed());
96 }
97
verifyUpdatedProgramInfo(const ProgramSelector & sel)98 void verifyUpdatedProgramInfo(const ProgramSelector& sel) {
99 ASSERT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
100 ProgramInfo infoCb1 = mTunerCallback->getCurrentProgramInfo();
101 mTunerCallback->reset();
102 if (sel.primaryId.type == IdentifierType::HD_STATION_ID_EXT) {
103 EXPECT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
104 ProgramInfo infoCb2 = mTunerCallback->getCurrentProgramInfo();
105 mTunerCallback->reset();
106 EXPECT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
107 ProgramInfo infoCb3 = mTunerCallback->getCurrentProgramInfo();
108 mTunerCallback->reset();
109 EXPECT_EQ(infoCb1.selector, sel);
110 EXPECT_EQ(getSignalAcquisitionFlags(infoCb1), 0b001);
111 EXPECT_EQ(infoCb2.selector, sel);
112 EXPECT_EQ(getSignalAcquisitionFlags(infoCb2), 0b011);
113 EXPECT_EQ(infoCb3.selector, sel);
114 EXPECT_EQ(getSignalAcquisitionFlags(infoCb3), 0b111);
115 } else {
116 EXPECT_EQ(infoCb1.selector, sel);
117 }
118 }
119
getAmFmBandRange(utils::FrequencyBand band,AmFmBandRange * res)120 bool getAmFmBandRange(utils::FrequencyBand band, AmFmBandRange* res) {
121 AmFmRegionConfig config;
122 auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ false, &config);
123 if (!halResult.isOk()) {
124 return false;
125 }
126 for (const auto& range : config.ranges) {
127 if (utils::getBand(range.lowerBound) == band) {
128 *res = range;
129 return true;
130 }
131 }
132 return false;
133 }
134
getProgramList()135 std::optional<utils::ProgramInfoSet> getProgramList() {
136 ProgramFilter emptyFilter = {};
137 return getProgramList(emptyFilter);
138 }
139
getProgramList(const ProgramFilter & filter)140 std::optional<utils::ProgramInfoSet> getProgramList(const ProgramFilter& filter) {
141 mTunerCallback->reset();
142
143 auto startResult = mBroadcastRadioHal->startProgramListUpdates(filter);
144
145 EXPECT_TRUE(startResult.isOk());
146
147 if (!startResult.isOk()) {
148 return std::nullopt;
149 }
150 EXPECT_TRUE(mTunerCallback->waitProgramReady());
151
152 auto stopResult = mBroadcastRadioHal->stopProgramListUpdates();
153
154 EXPECT_TRUE(stopResult.isOk());
155
156 return mTunerCallback->getProgramList();
157 }
158
switchToFmBand()159 void switchToFmBand() {
160 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
161 mTunerCallback->reset();
162 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
163 verifyUpdatedProgramInfo(kFmSel1);
164 }
165
166 std::shared_ptr<BroadcastRadio> mBroadcastRadioHal;
167 std::shared_ptr<MockBroadcastRadioCallback> mTunerCallback;
168 };
169
TEST_F(DefaultBroadcastRadioHalTest,GetAmFmRegionConfig)170 TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfig) {
171 AmFmRegionConfig config;
172
173 auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ false, &config);
174
175 ASSERT_TRUE(halResult.isOk());
176 EXPECT_EQ(config.fmDeemphasis, AmFmRegionConfig::DEEMPHASIS_D50);
177 EXPECT_EQ(config.fmRds, AmFmRegionConfig::RDS);
178 }
179
TEST_F(DefaultBroadcastRadioHalTest,GetAmFmRegionConfigWithFullBand)180 TEST_F(DefaultBroadcastRadioHalTest, GetAmFmRegionConfigWithFullBand) {
181 AmFmRegionConfig config;
182
183 auto halResult = mBroadcastRadioHal->getAmFmRegionConfig(/* full= */ true, &config);
184
185 ASSERT_TRUE(halResult.isOk());
186 EXPECT_EQ(config.fmDeemphasis,
187 AmFmRegionConfig::DEEMPHASIS_D50 | AmFmRegionConfig::DEEMPHASIS_D75);
188 EXPECT_EQ(config.fmRds, AmFmRegionConfig::RDS | AmFmRegionConfig::RBDS);
189 }
190
TEST_F(DefaultBroadcastRadioHalTest,GetDabRegionConfig)191 TEST_F(DefaultBroadcastRadioHalTest, GetDabRegionConfig) {
192 vector<DabTableEntry> config;
193
194 auto halResult = mBroadcastRadioHal->getDabRegionConfig(&config);
195
196 ASSERT_TRUE(halResult.isOk());
197 ASSERT_FALSE(config.empty());
198 }
199
TEST_F(DefaultBroadcastRadioHalTest,GetImage)200 TEST_F(DefaultBroadcastRadioHalTest, GetImage) {
201 vector<uint8_t> img;
202
203 auto halResult = mBroadcastRadioHal->getImage(BroadcastRadio::INVALID_IMAGE, &img);
204
205 ASSERT_TRUE(halResult.isOk());
206 ASSERT_TRUE(img.empty());
207 }
208
TEST_F(DefaultBroadcastRadioHalTest,GetProperties)209 TEST_F(DefaultBroadcastRadioHalTest, GetProperties) {
210 vector<VirtualProgram> mockPrograms = getAmFmMockTestRadio().getProgramList();
211 Properties prop;
212
213 auto halResult = mBroadcastRadioHal->getProperties(&prop);
214
215 ASSERT_TRUE(halResult.isOk());
216 ASSERT_FALSE(prop.supportedIdentifierTypes.empty());
217 std::unordered_set<IdentifierType> supportedTypeSet;
218 for (const auto& supportedType : prop.supportedIdentifierTypes) {
219 supportedTypeSet.insert(supportedType);
220 }
221 for (const auto& program : mockPrograms) {
222 EXPECT_NE(supportedTypeSet.find(program.selector.primaryId.type), supportedTypeSet.end());
223 }
224 }
225
TEST_F(DefaultBroadcastRadioHalTest,SetTunerCallback)226 TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallback) {
227 auto halResult = mBroadcastRadioHal->setTunerCallback(mTunerCallback);
228
229 ASSERT_TRUE(halResult.isOk());
230 }
231
TEST_F(DefaultBroadcastRadioHalTest,SetTunerCallbackWithNull)232 TEST_F(DefaultBroadcastRadioHalTest, SetTunerCallbackWithNull) {
233 auto halResult = mBroadcastRadioHal->setTunerCallback(nullptr);
234
235 ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS));
236 }
237
TEST_F(DefaultBroadcastRadioHalTest,UnsetTunerCallbackWithNull)238 TEST_F(DefaultBroadcastRadioHalTest, UnsetTunerCallbackWithNull) {
239 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
240
241 auto halResult = mBroadcastRadioHal->unsetTunerCallback();
242
243 ASSERT_TRUE(halResult.isOk());
244 }
245
TEST_F(DefaultBroadcastRadioHalTest,TuneWithAmFmSelectorInProgramList)246 TEST_F(DefaultBroadcastRadioHalTest, TuneWithAmFmSelectorInProgramList) {
247 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
248 mTunerCallback->reset();
249
250 auto halResult = mBroadcastRadioHal->tune(kFmSel1);
251
252 ASSERT_TRUE(halResult.isOk());
253 ASSERT_TRUE(mTunerCallback->waitOnCurrentProgramInfoChangedCallback());
254 ProgramInfo infoCb = mTunerCallback->getCurrentProgramInfo();
255 EXPECT_EQ(infoCb.selector, kFmSel1);
256 }
257
TEST_F(DefaultBroadcastRadioHalTest,TuneWithHdSelectorInProgramList)258 TEST_F(DefaultBroadcastRadioHalTest, TuneWithHdSelectorInProgramList) {
259 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
260 mTunerCallback->reset();
261
262 auto halResult = mBroadcastRadioHal->tune(kFmHdFreq1Sel2);
263
264 ASSERT_TRUE(halResult.isOk());
265 verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
266 }
267
TEST_F(DefaultBroadcastRadioHalTest,TuneWitFrequencyOfHdProgramInProgramList)268 TEST_F(DefaultBroadcastRadioHalTest, TuneWitFrequencyOfHdProgramInProgramList) {
269 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
270 mTunerCallback->reset();
271
272 auto halResult = mBroadcastRadioHal->tune(
273 utils::makeSelectorAmfm(utils::getHdFrequency(kFmHdFreq1Sel1)));
274
275 ASSERT_TRUE(halResult.isOk());
276 verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
277 }
278
TEST_F(DefaultBroadcastRadioHalTest,TuneWithInvalidSelector)279 TEST_F(DefaultBroadcastRadioHalTest, TuneWithInvalidSelector) {
280 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
281 ProgramSelector invalidSelector = {utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0),
282 {}};
283
284 auto halResult = mBroadcastRadioHal->tune(invalidSelector);
285
286 ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_ARGUMENTS));
287 }
288
TEST_F(DefaultBroadcastRadioHalTest,TuneWithoutTunerCallback)289 TEST_F(DefaultBroadcastRadioHalTest, TuneWithoutTunerCallback) {
290 auto halResult = mBroadcastRadioHal->tune(kFmSel1);
291
292 ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
293 }
294
TEST_F(DefaultBroadcastRadioHalTest,StepUp)295 TEST_F(DefaultBroadcastRadioHalTest, StepUp) {
296 AmFmBandRange fmRange;
297 ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
298 ProgramSelector nextChannelSel =
299 utils::makeSelectorAmfm(kFmSel1.primaryId.value + fmRange.spacing);
300 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
301 mTunerCallback->reset();
302 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
303 verifyUpdatedProgramInfo(kFmSel1);
304
305 auto halResult = mBroadcastRadioHal->step(/* in_directionUp= */ true);
306
307 ASSERT_TRUE(halResult.isOk());
308 verifyUpdatedProgramInfo(nextChannelSel);
309 }
310
TEST_F(DefaultBroadcastRadioHalTest,StepUpFromUpperBound)311 TEST_F(DefaultBroadcastRadioHalTest, StepUpFromUpperBound) {
312 AmFmBandRange fmRange;
313 ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
314 ProgramSelector upperBoundSel = utils::makeSelectorAmfm(fmRange.upperBound);
315 ProgramSelector lowerBoundSel = utils::makeSelectorAmfm(fmRange.lowerBound);
316 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
317 mTunerCallback->reset();
318 ASSERT_TRUE(mBroadcastRadioHal->tune(upperBoundSel).isOk());
319 verifyUpdatedProgramInfo(upperBoundSel);
320
321 auto halResult = mBroadcastRadioHal->step(/* in_directionUp= */ true);
322
323 ASSERT_TRUE(halResult.isOk());
324 verifyUpdatedProgramInfo(lowerBoundSel);
325 }
326
TEST_F(DefaultBroadcastRadioHalTest,StepDown)327 TEST_F(DefaultBroadcastRadioHalTest, StepDown) {
328 AmFmBandRange fmRange;
329 ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
330 ProgramSelector nextChannelSel =
331 utils::makeSelectorAmfm(kFmSel1.primaryId.value - fmRange.spacing);
332 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
333 mTunerCallback->reset();
334 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
335 verifyUpdatedProgramInfo(kFmSel1);
336
337 auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
338
339 ASSERT_TRUE(halResult.isOk());
340 verifyUpdatedProgramInfo(nextChannelSel);
341 }
342
TEST_F(DefaultBroadcastRadioHalTest,StepDownFromLowerBound)343 TEST_F(DefaultBroadcastRadioHalTest, StepDownFromLowerBound) {
344 AmFmBandRange fmRange;
345 ASSERT_TRUE(getAmFmBandRange(utils::FrequencyBand::FM, &fmRange));
346 ProgramSelector upperBoundSel = utils::makeSelectorAmfm(fmRange.upperBound);
347 ProgramSelector lowerBoundSel = utils::makeSelectorAmfm(fmRange.lowerBound);
348 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
349 mTunerCallback->reset();
350 ASSERT_TRUE(mBroadcastRadioHal->tune(lowerBoundSel).isOk());
351 verifyUpdatedProgramInfo(lowerBoundSel);
352
353 auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
354
355 ASSERT_TRUE(halResult.isOk());
356 verifyUpdatedProgramInfo(upperBoundSel);
357 }
358
TEST_F(DefaultBroadcastRadioHalTest,StepWithoutTunerCallback)359 TEST_F(DefaultBroadcastRadioHalTest, StepWithoutTunerCallback) {
360 switchToFmBand();
361 mBroadcastRadioHal->unsetTunerCallback();
362
363 auto halResult = mBroadcastRadioHal->step(/* directionUp= */ false);
364
365 ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
366 }
367
TEST_F(DefaultBroadcastRadioHalTest,SeekUpWithoutSkipSubchannel)368 TEST_F(DefaultBroadcastRadioHalTest, SeekUpWithoutSkipSubchannel) {
369 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
370 mTunerCallback->reset();
371 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel1).isOk());
372 verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
373
374 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ false);
375
376 ASSERT_TRUE(halResult.isOk());
377 verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
378 }
379
TEST_F(DefaultBroadcastRadioHalTest,SeekUpWithSkipSubchannel)380 TEST_F(DefaultBroadcastRadioHalTest, SeekUpWithSkipSubchannel) {
381 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
382 mTunerCallback->reset();
383 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel1).isOk());
384 verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
385
386 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ true);
387
388 ASSERT_TRUE(halResult.isOk());
389 verifyUpdatedProgramInfo(kFmSel2);
390 }
391
TEST_F(DefaultBroadcastRadioHalTest,SeekUpFromLastProgramInProgramList)392 TEST_F(DefaultBroadcastRadioHalTest, SeekUpFromLastProgramInProgramList) {
393 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
394 mTunerCallback->reset();
395 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq2Sel1).isOk());
396 verifyUpdatedProgramInfo(kFmHdFreq2Sel1);
397
398 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ true, /* skipSubChannel= */ true);
399
400 ASSERT_TRUE(halResult.isOk());
401 verifyUpdatedProgramInfo(kFmSel1);
402 }
403
TEST_F(DefaultBroadcastRadioHalTest,SeekDownWithoutSkipSubchannel)404 TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithoutSkipSubchannel) {
405 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
406 mTunerCallback->reset();
407 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel2).isOk());
408 verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
409
410 auto halResult =
411 mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ false);
412
413 ASSERT_TRUE(halResult.isOk());
414 verifyUpdatedProgramInfo(kFmHdFreq1Sel1);
415 }
416
TEST_F(DefaultBroadcastRadioHalTest,SeekDownWithSkipSubchannel)417 TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithSkipSubchannel) {
418 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
419 mTunerCallback->reset();
420 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmHdFreq1Sel2).isOk());
421 verifyUpdatedProgramInfo(kFmHdFreq1Sel2);
422
423 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
424
425 ASSERT_TRUE(halResult.isOk());
426 verifyUpdatedProgramInfo(kFmSel1);
427 }
428
TEST_F(DefaultBroadcastRadioHalTest,SeekDownWithFirstProgramInProgramList)429 TEST_F(DefaultBroadcastRadioHalTest, SeekDownWithFirstProgramInProgramList) {
430 switchToFmBand();
431
432 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
433
434 ASSERT_TRUE(halResult.isOk());
435 verifyUpdatedProgramInfo(kFmHdFreq2Sel1);
436 }
437
TEST_F(DefaultBroadcastRadioHalTest,SeekWithoutTunerCallback)438 TEST_F(DefaultBroadcastRadioHalTest, SeekWithoutTunerCallback) {
439 switchToFmBand();
440 mBroadcastRadioHal->unsetTunerCallback();
441
442 auto halResult = mBroadcastRadioHal->seek(/* directionUp= */ false, /* skipSubChannel= */ true);
443
444 ASSERT_EQ(halResult.getServiceSpecificError(), utils::resultToInt(Result::INVALID_STATE));
445 }
446
TEST_F(DefaultBroadcastRadioHalTest,Cancel)447 TEST_F(DefaultBroadcastRadioHalTest, Cancel) {
448 ASSERT_TRUE(mBroadcastRadioHal->setTunerCallback(mTunerCallback).isOk());
449 mTunerCallback->reset();
450 ASSERT_TRUE(mBroadcastRadioHal->tune(kFmSel1).isOk());
451
452 auto halResult = mBroadcastRadioHal->cancel();
453
454 ASSERT_TRUE(halResult.isOk());
455 mTunerCallback->reset();
456 }
457
TEST_F(DefaultBroadcastRadioHalTest,SetConfigFlag)458 TEST_F(DefaultBroadcastRadioHalTest, SetConfigFlag) {
459 ConfigFlag flag = ConfigFlag::FORCE_MONO;
460
461 auto setResult = mBroadcastRadioHal->setConfigFlag(flag, /* value= */ true);
462
463 ASSERT_TRUE(setResult.isOk());
464 }
465
TEST_F(DefaultBroadcastRadioHalTest,GetConfigFlag)466 TEST_F(DefaultBroadcastRadioHalTest, GetConfigFlag) {
467 bool gotValue = false;
468 ConfigFlag flag = ConfigFlag::FORCE_MONO;
469 mBroadcastRadioHal->setConfigFlag(flag, /* value= */ true);
470
471 auto getResult = mBroadcastRadioHal->isConfigFlagSet(flag, &gotValue);
472
473 ASSERT_TRUE(getResult.isOk());
474 ASSERT_TRUE(gotValue);
475 }
476
TEST_F(DefaultBroadcastRadioHalTest,StartProgramListUpdatesWithEmptyFilter)477 TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithEmptyFilter) {
478 switchToFmBand();
479
480 auto programList = getProgramList();
481
482 ASSERT_TRUE(programList.has_value());
483 for (auto it = programList->begin(); it != programList->end(); it++) {
484 EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
485 }
486 }
487
TEST_F(DefaultBroadcastRadioHalTest,StartProgramListUpdatesWithAmFmFilter)488 TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWithAmFmFilter) {
489 ProgramFilter amFmFilter = {.identifierTypes = {IdentifierType::AMFM_FREQUENCY_KHZ},
490 .identifiers = {},
491 .includeCategories = false,
492 .excludeModifications = false};
493 switchToFmBand();
494
495 auto programList = getProgramList(amFmFilter);
496
497 ASSERT_TRUE(programList.has_value());
498 for (auto it = programList->begin(); it != programList->end(); it++) {
499 EXPECT_TRUE(utils::hasId(it->selector, IdentifierType::AMFM_FREQUENCY_KHZ));
500 EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
501 }
502 }
503
TEST_F(DefaultBroadcastRadioHalTest,StartProgramListUpdatesWhenHdIsDisabled)504 TEST_F(DefaultBroadcastRadioHalTest, StartProgramListUpdatesWhenHdIsDisabled) {
505 switchToFmBand();
506 mBroadcastRadioHal->setConfigFlag(ConfigFlag::FORCE_ANALOG_FM, /* value= */ true);
507
508 auto programList = getProgramList();
509
510 ASSERT_TRUE(programList.has_value());
511 for (auto it = programList->begin(); it != programList->end(); it++) {
512 EXPECT_FALSE(utils::hasId(it->selector, IdentifierType::HD_STATION_ID_EXT));
513 EXPECT_EQ(utils::getBand(utils::getAmFmFrequency(it->selector)), utils::FrequencyBand::FM);
514 }
515 }
516
517 } // namespace aidl::android::hardware::broadcastradio
518