1 /*
2  * Copyright (C) 2022 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 <gtest/gtest.h>
18 
19 #include <optional>
20 #include <tuple>
21 
22 #include "BluetoothLeAudioCodecsProvider.h"
23 
24 using aidl::android::hardware::bluetooth::audio::BluetoothLeAudioCodecsProvider;
25 using aidl::android::hardware::bluetooth::audio::
26     LeAudioCodecCapabilitiesSetting;
27 using aidl::android::hardware::bluetooth::audio::setting::AudioLocation;
28 using aidl::android::hardware::bluetooth::audio::setting::CodecConfiguration;
29 using aidl::android::hardware::bluetooth::audio::setting::
30     CodecConfigurationList;
31 using aidl::android::hardware::bluetooth::audio::setting::CodecType;
32 using aidl::android::hardware::bluetooth::audio::setting::Configuration;
33 using aidl::android::hardware::bluetooth::audio::setting::ConfigurationList;
34 using aidl::android::hardware::bluetooth::audio::setting::LeAudioOffloadSetting;
35 using aidl::android::hardware::bluetooth::audio::setting::Scenario;
36 using aidl::android::hardware::bluetooth::audio::setting::ScenarioList;
37 using aidl::android::hardware::bluetooth::audio::setting::StrategyConfiguration;
38 using aidl::android::hardware::bluetooth::audio::setting::
39     StrategyConfigurationList;
40 
41 typedef std::tuple<std::vector<ScenarioList>, std::vector<ConfigurationList>,
42                    std::vector<CodecConfigurationList>,
43                    std::vector<StrategyConfigurationList>>
44     OffloadSetting;
45 
46 // Define valid components for each list
47 // Scenario
48 static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"),
49                                      std::make_optional("OneChanStereo_16_1"),
50                                      std::nullopt);
51 static const Scenario kValidBroadcastScenario(
52     std::nullopt, std::nullopt, std::make_optional("BcastStereo_16_2"));
53 
54 // Configuration
55 static const Configuration kValidConfigOneChanStereo_16_1(
56     std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"),
57     std::make_optional("STEREO_ONE_CIS_PER_DEVICE"));
58 // CodecConfiguration
59 static const CodecConfiguration kValidCodecLC3_16k_1(
60     std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
61     std::nullopt, std::make_optional(16000), std::make_optional(7500),
62     std::make_optional(30), std::nullopt);
63 // StrategyConfiguration
64 static const StrategyConfiguration kValidStrategyStereoOneCis(
65     std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
66     std::make_optional(AudioLocation::STEREO), std::make_optional(2),
67     std::make_optional(1));
68 static const StrategyConfiguration kValidStrategyStereoTwoCis(
69     std::make_optional("STEREO_TWO_CISES_PER_DEVICE"),
70     std::make_optional(AudioLocation::STEREO), std::make_optional(1),
71     std::make_optional(2));
72 static const StrategyConfiguration kValidStrategyMonoOneCis(
73     std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
74     std::make_optional(AudioLocation::MONO), std::make_optional(1),
75     std::make_optional(1));
76 static const StrategyConfiguration kValidStrategyBroadcastStereo(
77     std::make_optional("BROADCAST_STEREO"),
78     std::make_optional(AudioLocation::STEREO), std::make_optional(0),
79     std::make_optional(2));
80 
81 // Define valid test list built from above valid components
82 // Scenario, Configuration, CodecConfiguration, StrategyConfiguration
83 static const std::vector<ScenarioList> kValidScenarioList = {ScenarioList(
84     std::vector<Scenario>{kValidScenario, kValidBroadcastScenario})};
85 static const std::vector<ConfigurationList> kValidConfigurationList = {
86     ConfigurationList(
87         std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
88 static const std::vector<CodecConfigurationList> kValidCodecConfigurationList =
89     {CodecConfigurationList(
90         std::vector<CodecConfiguration>{kValidCodecLC3_16k_1})};
91 static const std::vector<StrategyConfigurationList>
92     kValidStrategyConfigurationList = {
93         StrategyConfigurationList(std::vector<StrategyConfiguration>{
94             kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
95             kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})};
96 
97 class BluetoothLeAudioCodecsProviderTest
98     : public ::testing::TestWithParam<OffloadSetting> {
99  public:
CreateTestCases(const std::vector<ScenarioList> & scenario_lists,const std::vector<ConfigurationList> & configuration_lists,const std::vector<CodecConfigurationList> & codec_configuration_lists,const std::vector<StrategyConfigurationList> & strategy_configuration_lists)100   static std::vector<OffloadSetting> CreateTestCases(
101       const std::vector<ScenarioList>& scenario_lists,
102       const std::vector<ConfigurationList>& configuration_lists,
103       const std::vector<CodecConfigurationList>& codec_configuration_lists,
104       const std::vector<StrategyConfigurationList>&
105           strategy_configuration_lists) {
106     // make each vector in output test_cases has only one element
107     // to match the input of test params
108     // normally only one vector in input has multiple elements
109     // we just split elements in this vector to several vector
110     std::vector<OffloadSetting> test_cases;
111     for (const auto& scenario_list : scenario_lists) {
112       for (const auto& configuration_list : configuration_lists) {
113         for (const auto& codec_configuration_list : codec_configuration_lists) {
114           for (const auto& strategy_configuration_list :
115                strategy_configuration_lists) {
116             test_cases.push_back(CreateTestCase(
117                 scenario_list, configuration_list, codec_configuration_list,
118                 strategy_configuration_list));
119           }
120         }
121       }
122     }
123     return test_cases;
124   }
125 
126  protected:
Initialize()127   void Initialize() {
128     BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities();
129   }
130 
RunTestCase()131   std::vector<LeAudioCodecCapabilitiesSetting> RunTestCase() {
132     auto& [scenario_lists, configuration_lists, codec_configuration_lists,
133            strategy_configuration_lists] = GetParam();
134     LeAudioOffloadSetting le_audio_offload_setting(
135         scenario_lists, configuration_lists, codec_configuration_lists,
136         strategy_configuration_lists);
137     auto le_audio_codec_capabilities =
138         BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
139             std::make_optional(le_audio_offload_setting));
140     return le_audio_codec_capabilities;
141   }
142 
143  private:
CreateTestCase(const ScenarioList & scenario_list,const ConfigurationList & configuration_list,const CodecConfigurationList & codec_configuration_list,const StrategyConfigurationList & strategy_configuration_list)144   static inline OffloadSetting CreateTestCase(
145       const ScenarioList& scenario_list,
146       const ConfigurationList& configuration_list,
147       const CodecConfigurationList& codec_configuration_list,
148       const StrategyConfigurationList& strategy_configuration_list) {
149     return std::make_tuple(
150         std::vector<ScenarioList>{scenario_list},
151         std::vector<ConfigurationList>{configuration_list},
152         std::vector<CodecConfigurationList>{codec_configuration_list},
153         std::vector<StrategyConfigurationList>{strategy_configuration_list});
154   }
155 };
156 
157 class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest {
158  public:
CreateInvalidScenarios()159   static std::vector<ScenarioList> CreateInvalidScenarios() {
160     std::vector<ScenarioList> invalid_scenario_test_cases;
161     invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
162         Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"),
163                  std::nullopt)}));
164 
165     invalid_scenario_test_cases.push_back(ScenarioList(
166         std::vector<Scenario>{Scenario(std::make_optional("OneChanStereo_16_1"),
167                                        std::nullopt, std::nullopt)}));
168 
169     invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
170         Scenario(std::nullopt, std::nullopt, std::nullopt)}));
171 
172     invalid_scenario_test_cases.push_back(
173         ScenarioList(std::vector<Scenario>{}));
174 
175     return invalid_scenario_test_cases;
176   }
177 };
178 
TEST_P(GetScenariosTest,InvalidScenarios)179 TEST_P(GetScenariosTest, InvalidScenarios) {
180   Initialize();
181   auto le_audio_codec_capabilities = RunTestCase();
182   ASSERT_TRUE(le_audio_codec_capabilities.empty());
183 }
184 
185 class UpdateConfigurationsToMapTest
186     : public BluetoothLeAudioCodecsProviderTest {
187  public:
CreateInvalidConfigurations()188   static std::vector<ConfigurationList> CreateInvalidConfigurations() {
189     std::vector<ConfigurationList> invalid_configuration_test_cases;
190     invalid_configuration_test_cases.push_back(
191         ConfigurationList(std::vector<Configuration>{
192             Configuration(std::nullopt, std::make_optional("LC3_16k_1"),
193                           std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
194 
195     invalid_configuration_test_cases.push_back(
196         ConfigurationList(std::vector<Configuration>{Configuration(
197             std::make_optional("OneChanStereo_16_1"), std::nullopt,
198             std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
199 
200     invalid_configuration_test_cases.push_back(
201         ConfigurationList(std::vector<Configuration>{
202             Configuration(std::make_optional("OneChanStereo_16_1"),
203                           std::make_optional("LC3_16k_1"), std::nullopt)}));
204 
205     invalid_configuration_test_cases.push_back(
206         ConfigurationList(std::vector<Configuration>{}));
207 
208     return invalid_configuration_test_cases;
209   }
210 };
211 
TEST_P(UpdateConfigurationsToMapTest,InvalidConfigurations)212 TEST_P(UpdateConfigurationsToMapTest, InvalidConfigurations) {
213   Initialize();
214   auto le_audio_codec_capabilities = RunTestCase();
215   ASSERT_TRUE(le_audio_codec_capabilities.empty());
216 }
217 
218 class UpdateCodecConfigurationsToMapTest
219     : public BluetoothLeAudioCodecsProviderTest {
220  public:
221   static std::vector<CodecConfigurationList>
CreateInvalidCodecConfigurations()222   CreateInvalidCodecConfigurations() {
223     std::vector<CodecConfigurationList> invalid_codec_configuration_test_cases;
224     invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
225         std::vector<CodecConfiguration>{CodecConfiguration(
226             std::nullopt, std::make_optional(CodecType::LC3), std::nullopt,
227             std::make_optional(16000), std::make_optional(7500),
228             std::make_optional(30), std::nullopt)}));
229 
230     invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
231         std::vector<CodecConfiguration>{CodecConfiguration(
232             std::make_optional("LC3_16k_1"), std::nullopt, std::nullopt,
233             std::make_optional(16000), std::make_optional(7500),
234             std::make_optional(30), std::nullopt)}));
235 
236     invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
237         std::vector<CodecConfiguration>{CodecConfiguration(
238             std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
239             std::nullopt, std::nullopt, std::make_optional(7500),
240             std::make_optional(30), std::nullopt)}));
241 
242     invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
243         std::vector<CodecConfiguration>{CodecConfiguration(
244             std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
245             std::nullopt, std::make_optional(16000), std::nullopt,
246             std::make_optional(30), std::nullopt)}));
247 
248     invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
249         std::vector<CodecConfiguration>{CodecConfiguration(
250             std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
251             std::nullopt, std::make_optional(16000), std::make_optional(7500),
252             std::nullopt, std::nullopt)}));
253 
254     invalid_codec_configuration_test_cases.push_back(
255         CodecConfigurationList(std::vector<CodecConfiguration>{}));
256 
257     return invalid_codec_configuration_test_cases;
258   }
259 };
260 
TEST_P(UpdateCodecConfigurationsToMapTest,InvalidCodecConfigurations)261 TEST_P(UpdateCodecConfigurationsToMapTest, InvalidCodecConfigurations) {
262   Initialize();
263   auto le_audio_codec_capabilities = RunTestCase();
264   ASSERT_TRUE(le_audio_codec_capabilities.empty());
265 }
266 
267 class UpdateStrategyConfigurationsToMapTest
268     : public BluetoothLeAudioCodecsProviderTest {
269  public:
270   static std::vector<StrategyConfigurationList>
CreateInvalidStrategyConfigurations()271   CreateInvalidStrategyConfigurations() {
272     std::vector<StrategyConfigurationList>
273         invalid_strategy_configuration_test_cases;
274     invalid_strategy_configuration_test_cases.push_back(
275         StrategyConfigurationList(
276             std::vector<StrategyConfiguration>{StrategyConfiguration(
277                 std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
278                 std::make_optional(AudioLocation::STEREO),
279                 std::make_optional(2), std::make_optional(2))}));
280 
281     invalid_strategy_configuration_test_cases.push_back(
282         StrategyConfigurationList(
283             std::vector<StrategyConfiguration>{StrategyConfiguration(
284                 std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
285                 std::make_optional(AudioLocation::STEREO),
286                 std::make_optional(2), std::make_optional(2))}));
287 
288     invalid_strategy_configuration_test_cases.push_back(
289         StrategyConfigurationList(
290             std::vector<StrategyConfiguration>{StrategyConfiguration(
291                 std::nullopt, std::make_optional(AudioLocation::STEREO),
292                 std::make_optional(2), std::make_optional(1))}));
293 
294     invalid_strategy_configuration_test_cases.push_back(
295         StrategyConfigurationList(
296             std::vector<StrategyConfiguration>{StrategyConfiguration(
297                 std::make_optional("STEREO_ONE_CIS_PER_DEVICE"), std::nullopt,
298                 std::make_optional(2), std::make_optional(1))}));
299 
300     invalid_strategy_configuration_test_cases.push_back(
301         StrategyConfigurationList(
302             std::vector<StrategyConfiguration>{StrategyConfiguration(
303                 std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
304                 std::make_optional(AudioLocation::STEREO), std::nullopt,
305                 std::make_optional(1))}));
306 
307     invalid_strategy_configuration_test_cases.push_back(
308         StrategyConfigurationList(
309             std::vector<StrategyConfiguration>{StrategyConfiguration(
310                 std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
311                 std::make_optional(AudioLocation::STEREO),
312                 std::make_optional(2), std::nullopt)}));
313 
314     invalid_strategy_configuration_test_cases.push_back(
315         StrategyConfigurationList(std::vector<StrategyConfiguration>{}));
316 
317     return invalid_strategy_configuration_test_cases;
318   }
319 };
320 
TEST_P(UpdateStrategyConfigurationsToMapTest,InvalidStrategyConfigurations)321 TEST_P(UpdateStrategyConfigurationsToMapTest, InvalidStrategyConfigurations) {
322   Initialize();
323   auto le_audio_codec_capabilities = RunTestCase();
324   ASSERT_TRUE(le_audio_codec_capabilities.empty());
325 }
326 
327 class ComposeLeAudioCodecCapabilitiesTest
328     : public BluetoothLeAudioCodecsProviderTest {
329  public:
330 };
331 
TEST_P(ComposeLeAudioCodecCapabilitiesTest,CodecCapabilitiesNotEmpty)332 TEST_P(ComposeLeAudioCodecCapabilitiesTest, CodecCapabilitiesNotEmpty) {
333   Initialize();
334   auto le_audio_codec_capabilities = RunTestCase();
335   ASSERT_TRUE(!le_audio_codec_capabilities.empty());
336 }
337 
338 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetScenariosTest);
339 INSTANTIATE_TEST_SUITE_P(
340     BluetoothLeAudioCodecsProviderTest, GetScenariosTest,
341     ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
342         GetScenariosTest::CreateInvalidScenarios(), kValidConfigurationList,
343         kValidCodecConfigurationList, kValidStrategyConfigurationList)));
344 
345 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UpdateConfigurationsToMapTest);
346 INSTANTIATE_TEST_SUITE_P(
347     BluetoothLeAudioCodecsProviderTest, UpdateConfigurationsToMapTest,
348     ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
349         kValidScenarioList,
350         UpdateConfigurationsToMapTest::CreateInvalidConfigurations(),
351         kValidCodecConfigurationList, kValidStrategyConfigurationList)));
352 
353 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
354     UpdateCodecConfigurationsToMapTest);
355 INSTANTIATE_TEST_SUITE_P(
356     BluetoothLeAudioCodecsProviderTest, UpdateCodecConfigurationsToMapTest,
357     ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
358         kValidScenarioList, kValidConfigurationList,
359         UpdateCodecConfigurationsToMapTest::CreateInvalidCodecConfigurations(),
360         kValidStrategyConfigurationList)));
361 
362 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
363     UpdateStrategyConfigurationsToMapTest);
364 INSTANTIATE_TEST_SUITE_P(
365     BluetoothLeAudioCodecsProviderTest, UpdateStrategyConfigurationsToMapTest,
366     ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
367         kValidScenarioList, kValidConfigurationList,
368         kValidCodecConfigurationList,
369         UpdateStrategyConfigurationsToMapTest::
370             CreateInvalidStrategyConfigurations())));
371 
372 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
373     ComposeLeAudioCodecCapabilitiesTest);
374 INSTANTIATE_TEST_SUITE_P(
375     BluetoothLeAudioCodecsProviderTest, ComposeLeAudioCodecCapabilitiesTest,
376     ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
377         kValidScenarioList, kValidConfigurationList,
378         kValidCodecConfigurationList, kValidStrategyConfigurationList)));
379 
main(int argc,char ** argv)380 int main(int argc, char** argv) {
381   ::testing::InitGoogleTest(&argc, argv);
382   return RUN_ALL_TESTS();
383 }
384