1 /*
2  * Copyright (C) 2024 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 <broadcastradio-utils-aidl/Utils.h>
18 #include <broadcastradio-utils-aidl/UtilsV2.h>
19 #include <gtest/gtest.h>
20 
21 namespace aidl::android::hardware::broadcastradio {
22 
23 namespace {
24 constexpr int64_t kFmFrequencyKHz = 97900;
25 constexpr uint32_t kDabSid = 0x0000C221u;
26 constexpr int kDabEccCode = 0xE1u;
27 constexpr int kDabSCIdS = 0x1u;
28 constexpr uint64_t kDabSidExt = static_cast<uint64_t>(kDabSid) |
29                                 (static_cast<uint64_t>(kDabEccCode) << 32) |
30                                 (static_cast<uint64_t>(kDabSCIdS) << 40);
31 constexpr uint32_t kDabEnsemble = 0xCE15u;
32 constexpr uint64_t kDabFrequencyKhz = 225648u;
33 constexpr uint64_t kHdStationId = 0xA0000001u;
34 constexpr uint64_t kHdSubChannel = 1u;
35 constexpr uint64_t kHdStationLocation = 0x44E647003665CF6u;
36 constexpr uint64_t kHdStationLocationInvalid = 0x4E647007665CF6u;
37 constexpr uint64_t kHdFrequency = 97700u;
38 constexpr int64_t kRdsValue = 0xBEEF;
39 
40 struct IsValidIdentifierTestCase {
41     std::string name;
42     ProgramIdentifier id;
43     bool valid;
44 };
45 
getIsValidIdentifierTestCases()46 std::vector<IsValidIdentifierTestCase> getIsValidIdentifierTestCases() {
47     return std::vector<IsValidIdentifierTestCase>({
48             IsValidIdentifierTestCase{.name = "invalid_id_type",
49                                       .id = utils::makeIdentifier(IdentifierType::INVALID, 0),
50                                       .valid = false},
51             IsValidIdentifierTestCase{
52                     .name = "invalid_dab_frequency_high",
53                     .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 10000000u),
54                     .valid = false},
55             IsValidIdentifierTestCase{
56                     .name = "invalid_dab_frequency_low",
57                     .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 100000u),
58                     .valid = false},
59             IsValidIdentifierTestCase{
60                     .name = "valid_dab_frequency",
61                     .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 1000000u),
62                     .valid = true},
63             IsValidIdentifierTestCase{
64                     .name = "invalid_am_fm_frequency_high",
65                     .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 10000000u),
66                     .valid = false},
67             IsValidIdentifierTestCase{
68                     .name = "invalid_am_fm_frequency_low",
69                     .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 100u),
70                     .valid = false},
71             IsValidIdentifierTestCase{.name = "valid_am_fm_frequency",
72                                       .id = utils::makeIdentifier(
73                                               IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
74                                       .valid = true},
75             IsValidIdentifierTestCase{
76                     .name = "drmo_frequency_high",
77                     .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 10000000u),
78                     .valid = false},
79             IsValidIdentifierTestCase{
80                     .name = "drmo_frequency_low",
81                     .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 100u),
82                     .valid = false},
83             IsValidIdentifierTestCase{.name = "valid_drmo_frequency",
84                                       .id = utils::makeIdentifier(
85                                               IdentifierType::DRMO_FREQUENCY_KHZ, kFmFrequencyKHz),
86                                       .valid = true},
87             IsValidIdentifierTestCase{.name = "invalid_rds_low",
88                                       .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x0),
89                                       .valid = false},
90             IsValidIdentifierTestCase{.name = "invalid_rds_high",
91                                       .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x10000),
92                                       .valid = false},
93             IsValidIdentifierTestCase{.name = "valid_rds",
94                                       .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x1000),
95                                       .valid = true},
96             IsValidIdentifierTestCase{
97                     .name = "invalid_hd_id_zero",
98                     .id = utils::makeSelectorHd(/* stationId= */ 0u, kHdSubChannel, kHdFrequency)
99                                   .primaryId,
100                     .valid = false},
101             IsValidIdentifierTestCase{
102                     .name = "invalid_hd_suchannel",
103                     .id = utils::makeSelectorHd(kHdStationId, /* subChannel= */ 8u, kHdFrequency)
104                                   .primaryId,
105                     .valid = false},
106             IsValidIdentifierTestCase{
107                     .name = "invalid_hd_frequency_low",
108                     .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, /* frequency= */ 100u)
109                                   .primaryId,
110                     .valid = false},
111             IsValidIdentifierTestCase{
112                     .name = "valid_hd_id",
113                     .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency)
114                                   .primaryId,
115                     .valid = true},
116             IsValidIdentifierTestCase{
117                     .name = "invalid_hd_station_name",
118                     .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x41422D464D),
119                     .valid = false},
120             IsValidIdentifierTestCase{
121                     .name = "valid_hd_station_name",
122                     .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x414231464D),
123                     .valid = true},
124             IsValidIdentifierTestCase{
125                     .name = "invalid_dab_sid",
126                     .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0E100000000u),
127                     .valid = false},
128             IsValidIdentifierTestCase{
129                     .name = "invalid_dab_ecc_low",
130                     .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0F700000221u),
131                     .valid = false},
132             IsValidIdentifierTestCase{
133                     .name = "invalid_dab_ecc_high",
134                     .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x09900000221u),
135                     .valid = false},
136             IsValidIdentifierTestCase{
137                     .name = "valid_dab_sid_ext",
138                     .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, kDabSidExt),
139                     .valid = true},
140             IsValidIdentifierTestCase{
141                     .name = "invalid_dab_ensemble_zero",
142                     .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x0),
143                     .valid = false},
144             IsValidIdentifierTestCase{
145                     .name = "invalid_dab_ensemble_high",
146                     .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x10000),
147                     .valid = false},
148             IsValidIdentifierTestCase{
149                     .name = "valid_dab_ensemble",
150                     .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, kDabEnsemble),
151                     .valid = true},
152             IsValidIdentifierTestCase{.name = "invalid_dab_scid_low",
153                                       .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0xF),
154                                       .valid = false},
155             IsValidIdentifierTestCase{.name = "invalid_dab_scid_high",
156                                       .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x1000),
157                                       .valid = false},
158             IsValidIdentifierTestCase{.name = "valid_dab_scid",
159                                       .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x100),
160                                       .valid = true},
161             IsValidIdentifierTestCase{
162                     .name = "invalid_drmo_id_zero",
163                     .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x0),
164                     .valid = false},
165             IsValidIdentifierTestCase{
166                     .name = "invalid_drmo_id_high",
167                     .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x1000000),
168                     .valid = false},
169             IsValidIdentifierTestCase{
170                     .name = "valid_drmo_id",
171                     .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000),
172                     .valid = true},
173     });
174 }
175 
getIsValidIdentifierV2TestCases()176 std::vector<IsValidIdentifierTestCase> getIsValidIdentifierV2TestCases() {
177     std::vector<IsValidIdentifierTestCase> testcases = getIsValidIdentifierTestCases();
178     std::vector<IsValidIdentifierTestCase> testcasesNew = std::vector<IsValidIdentifierTestCase>({
179             IsValidIdentifierTestCase{
180                     .name = "invalid_hd_station_location_id",
181                     .id = utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION,
182                                                 kHdStationLocationInvalid),
183                     .valid = false},
184             IsValidIdentifierTestCase{
185                     .name = "valid_hd_station_location_id",
186                     .id = utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION,
187                                                 kHdStationLocation),
188                     .valid = true},
189     });
190     testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
191     return testcases;
192 }
193 
194 struct IsValidSelectorTestCase {
195     std::string name;
196     ProgramSelector sel;
197     bool valid;
198 };
199 
getIsValidSelectorTestCases()200 std::vector<IsValidSelectorTestCase> getIsValidSelectorTestCases() {
201     return std::vector<IsValidSelectorTestCase>({
202             IsValidSelectorTestCase{.name = "valid_am_fm_selector",
203                                     .sel = utils::makeSelectorAmfm(kFmFrequencyKHz),
204                                     .valid = true},
205             IsValidSelectorTestCase{
206                     .name = "valid_hd_selector",
207                     .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency),
208                     .valid = true},
209             IsValidSelectorTestCase{
210                     .name = "valid_dab_selector",
211                     .sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz),
212                     .valid = true},
213             IsValidSelectorTestCase{.name = "valid_rds_selector",
214                                     .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
215                                                                    IdentifierType::RDS_PI, 0x1000)},
216                                     .valid = true},
217             IsValidSelectorTestCase{.name = "selector_with_invalid_id",
218                                     .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel,
219                                                                  /* frequency= */ 100u),
220                                     .valid = false},
221             IsValidSelectorTestCase{
222                     .name = "selector_with_invalid_primary_id_type",
223                     .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
224                                                    IdentifierType::DAB_ENSEMBLE, kDabEnsemble)},
225                     .valid = false},
226             IsValidSelectorTestCase{
227                     .name = "selector_with_invalid_secondary_id",
228                     .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
229                                                    IdentifierType::DAB_SID_EXT, kDabSidExt),
230                                            .secondaryIds = {utils::makeIdentifier(
231                                                    IdentifierType::DAB_ENSEMBLE, 0x0)}},
232                     .valid = false},
233     });
234 }
235 
getIsValidSelectorV2TestCases()236 std::vector<IsValidSelectorTestCase> getIsValidSelectorV2TestCases() {
237     ProgramSelector validHdSel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
238     validHdSel.secondaryIds = {
239             utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION, kHdStationLocation)};
240     ProgramSelector invalidHdSel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
241     invalidHdSel.secondaryIds = {
242             utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION, kHdStationLocationInvalid)};
243     std::vector<IsValidSelectorTestCase> testcasesNew = std::vector<IsValidSelectorTestCase>(
244             {IsValidSelectorTestCase{.name = "hd_selector_with_valid_station_location",
245                                      .sel = validHdSel,
246                                      .valid = true},
247              IsValidSelectorTestCase{.name = "hd_selector_with_invalid_station_location",
248                                      .sel = invalidHdSel,
249                                      .valid = false}});
250     std::vector<IsValidSelectorTestCase> testcases = getIsValidSelectorTestCases();
251     testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
252     return testcases;
253 }
254 
255 struct IsValidMetadataTestCase {
256     std::string name;
257     Metadata metadata;
258     bool valid;
259 };
260 
getIsValidMetadataTestCases()261 std::vector<IsValidMetadataTestCase> getIsValidMetadataTestCases() {
262     return std::vector<IsValidMetadataTestCase>({
263             IsValidMetadataTestCase{.name = "valid_rds_pty",
264                                     .metadata = Metadata::make<Metadata::rdsPty>(1),
265                                     .valid = true},
266             IsValidMetadataTestCase{.name = "negative_rds_pty",
267                                     .metadata = Metadata::make<Metadata::rdsPty>(-1),
268                                     .valid = false},
269             IsValidMetadataTestCase{.name = "large_rds_pty",
270                                     .metadata = Metadata::make<Metadata::rdsPty>(256),
271                                     .valid = false},
272             IsValidMetadataTestCase{.name = "valid_rbds_pty",
273                                     .metadata = Metadata::make<Metadata::rbdsPty>(1),
274                                     .valid = true},
275             IsValidMetadataTestCase{.name = "negative_rbds_pty",
276                                     .metadata = Metadata::make<Metadata::rbdsPty>(-1),
277                                     .valid = false},
278             IsValidMetadataTestCase{.name = "large_rbds_pty",
279                                     .metadata = Metadata::make<Metadata::rbdsPty>(256),
280                                     .valid = false},
281             IsValidMetadataTestCase{
282                     .name = "valid_dab_ensemble_name_short",
283                     .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name"),
284                     .valid = true},
285             IsValidMetadataTestCase{
286                     .name = "too_long_dab_ensemble_name_short",
287                     .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name_long"),
288                     .valid = false},
289             IsValidMetadataTestCase{
290                     .name = "valid_dab_service_name_short",
291                     .metadata = Metadata::make<Metadata::dabServiceNameShort>("name"),
292                     .valid = true},
293             IsValidMetadataTestCase{
294                     .name = "too_long_dab_service_name_short",
295                     .metadata = Metadata::make<Metadata::dabServiceNameShort>("name_long"),
296                     .valid = false},
297             IsValidMetadataTestCase{
298                     .name = "valid_dab_component_name_short",
299                     .metadata = Metadata::make<Metadata::dabComponentNameShort>("name"),
300                     .valid = true},
301             IsValidMetadataTestCase{
302                     .name = "too_long_dab_component_name_short",
303                     .metadata = Metadata::make<Metadata::dabComponentNameShort>("name_long"),
304                     .valid = false},
305     });
306 }
307 
getIsValidMetadataV2TestCases()308 std::vector<IsValidMetadataTestCase> getIsValidMetadataV2TestCases() {
309     std::vector<IsValidMetadataTestCase> testcases = getIsValidMetadataTestCases();
310     std::vector<IsValidMetadataTestCase> testcasesNew = std::vector<IsValidMetadataTestCase>({
311             IsValidMetadataTestCase{
312                     .name = "valid_hd_station_name_short",
313                     .metadata = Metadata::make<Metadata::hdStationNameShort>("name_short"),
314                     .valid = true},
315             IsValidMetadataTestCase{
316                     .name = "too_long_hd_station_name_short",
317                     .metadata = Metadata::make<Metadata::hdStationNameShort>("name_too_long"),
318                     .valid = false},
319             IsValidMetadataTestCase{.name = "valid_hd_subchannel_available",
320                                     .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(1),
321                                     .valid = true},
322             IsValidMetadataTestCase{
323                     .name = "negative_subchannel_available",
324                     .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(-1),
325                     .valid = false},
326             IsValidMetadataTestCase{
327                     .name = "large_subchannel_available",
328                     .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(256),
329                     .valid = false},
330     });
331     testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
332     return testcases;
333 }
334 }  // namespace
335 
336 class IsValidIdentifierTest : public testing::TestWithParam<IsValidIdentifierTestCase> {};
337 
338 INSTANTIATE_TEST_SUITE_P(IsValidIdentifierTests, IsValidIdentifierTest,
339                          testing::ValuesIn(getIsValidIdentifierTestCases()),
__anone16d182e0202(const testing::TestParamInfo<IsValidIdentifierTest::ParamType>& info) 340                          [](const testing::TestParamInfo<IsValidIdentifierTest::ParamType>& info) {
341                              return info.param.name;
342                          });
343 
TEST_P(IsValidIdentifierTest,IsValid)344 TEST_P(IsValidIdentifierTest, IsValid) {
345     IsValidIdentifierTestCase testcase = GetParam();
346 
347     ASSERT_EQ(utils::isValid(testcase.id), testcase.valid);
348 }
349 
350 class IsValidIdentifierV2Test : public testing::TestWithParam<IsValidIdentifierTestCase> {};
351 
352 INSTANTIATE_TEST_SUITE_P(
353         IsValidIdentifierV2Tests, IsValidIdentifierV2Test,
354         testing::ValuesIn(getIsValidIdentifierV2TestCases()),
__anone16d182e0302(const testing::TestParamInfo<IsValidIdentifierV2Test::ParamType>& info) 355         [](const testing::TestParamInfo<IsValidIdentifierV2Test::ParamType>& info) {
356             return info.param.name;
357         });
358 
TEST_P(IsValidIdentifierV2Test,IsValidV2)359 TEST_P(IsValidIdentifierV2Test, IsValidV2) {
360     IsValidIdentifierTestCase testcase = GetParam();
361 
362     ASSERT_EQ(utils::isValidV2(testcase.id), testcase.valid);
363 }
364 
365 class IsValidSelectorTest : public testing::TestWithParam<IsValidSelectorTestCase> {};
366 
367 INSTANTIATE_TEST_SUITE_P(IsValidSelectorTests, IsValidSelectorTest,
368                          testing::ValuesIn(getIsValidSelectorTestCases()),
__anone16d182e0402(const testing::TestParamInfo<IsValidSelectorTest::ParamType>& info) 369                          [](const testing::TestParamInfo<IsValidSelectorTest::ParamType>& info) {
370                              return info.param.name;
371                          });
372 
TEST_P(IsValidSelectorTest,IsValid)373 TEST_P(IsValidSelectorTest, IsValid) {
374     IsValidSelectorTestCase testcase = GetParam();
375 
376     ASSERT_EQ(utils::isValid(testcase.sel), testcase.valid);
377 }
378 
379 class IsValidSelectorV2Test : public testing::TestWithParam<IsValidSelectorTestCase> {};
380 
381 INSTANTIATE_TEST_SUITE_P(IsValidSelectorV2Tests, IsValidSelectorV2Test,
382                          testing::ValuesIn(getIsValidSelectorV2TestCases()),
__anone16d182e0502(const testing::TestParamInfo<IsValidSelectorV2Test::ParamType>& info) 383                          [](const testing::TestParamInfo<IsValidSelectorV2Test::ParamType>& info) {
384                              return info.param.name;
385                          });
386 
TEST_P(IsValidSelectorV2Test,IsValidV2)387 TEST_P(IsValidSelectorV2Test, IsValidV2) {
388     IsValidSelectorTestCase testcase = GetParam();
389 
390     ASSERT_EQ(utils::isValidV2(testcase.sel), testcase.valid);
391 }
392 
393 class IsValidMetadataTest : public testing::TestWithParam<IsValidMetadataTestCase> {};
394 
395 INSTANTIATE_TEST_SUITE_P(IsValidMetadataTests, IsValidMetadataTest,
396                          testing::ValuesIn(getIsValidMetadataTestCases()),
__anone16d182e0602(const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) 397                          [](const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) {
398                              return info.param.name;
399                          });
400 
TEST_P(IsValidMetadataTest,IsValidMetadata)401 TEST_P(IsValidMetadataTest, IsValidMetadata) {
402     IsValidMetadataTestCase testParam = GetParam();
403 
404     ASSERT_EQ(utils::isValidMetadata(testParam.metadata), testParam.valid);
405 }
406 
407 class IsValidMetadataV2Test : public testing::TestWithParam<IsValidMetadataTestCase> {};
408 
409 INSTANTIATE_TEST_SUITE_P(IsValidMetadataV2Tests, IsValidMetadataV2Test,
410                          testing::ValuesIn(getIsValidMetadataV2TestCases()),
__anone16d182e0702(const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) 411                          [](const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) {
412                              return info.param.name;
413                          });
414 
TEST_P(IsValidMetadataV2Test,IsValidMetadataV2)415 TEST_P(IsValidMetadataV2Test, IsValidMetadataV2) {
416     IsValidMetadataTestCase testParam = GetParam();
417 
418     ASSERT_EQ(utils::isValidMetadataV2(testParam.metadata), testParam.valid);
419 }
420 
421 }  // namespace aidl::android::hardware::broadcastradio
422