xref: /aosp_15_r20/hardware/interfaces/broadcastradio/aidl/default/test/DefaultBroadcastRadioHalTest.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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