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 <gtest/gtest.h>
18 
19 #include <optional>
20 #include <tuple>
21 
22 #include "BluetoothHfpCodecsProvider.h"
23 #include "gtest/gtest.h"
24 
25 using aidl::android::hardware::bluetooth::audio::BluetoothHfpCodecsProvider;
26 using aidl::android::hardware::bluetooth::audio::CodecInfo;
27 using aidl::android::hardware::bluetooth::audio::hfp::setting::CodecType;
28 using aidl::android::hardware::bluetooth::audio::hfp::setting::Configuration;
29 using aidl::android::hardware::bluetooth::audio::hfp::setting::
30     HfpOffloadSetting;
31 using aidl::android::hardware::bluetooth::audio::hfp::setting::
32     PathConfiguration;
33 using aidl::android::hardware::bluetooth::audio::hfp::setting::
34     TransportConfiguration;
35 
36 typedef std::tuple<std::vector<PathConfiguration>,
37                    std::vector<TransportConfiguration>,
38                    std::vector<Configuration>>
39     HfpOffloadSettingTuple;
40 
41 // Define valid components for each list
42 // PathConfiguration
43 static const PathConfiguration kValidPathConfigurationCVSD("CVSD_IO", 16000,
44                                                            CodecType::CVSD, 16,
45                                                            2, 0, 1, 0);
46 static const PathConfiguration kInvalidPathConfigurationNULL(std::nullopt,
47                                                              16000,
48                                                              CodecType::CVSD,
49                                                              16, 2, 0, 1, 0);
50 static const PathConfiguration kInvalidPathConfigurationNoPath(
51     "CVSD_NULL", 16000, CodecType::CVSD, 16, 2, 0, std::nullopt, 0);
52 
53 // Configuration
54 static const Configuration kValidConfigurationCVSD("CVSD", CodecType::CVSD,
55                                                    65535, 7, 0, true, "CVSD_IO",
56                                                    "CVSD_IO", std::nullopt,
57                                                    std::nullopt);
58 static const Configuration kInvalidConfigurationCVSDNoPath(
59     "CVSD", CodecType::CVSD, 65535, 7, 0, true, "CVSD_NULL", "CVSD_NULL",
60     std::nullopt, std::nullopt);
61 static const Configuration kInvalidConfigurationCVSDNotFound(
62     "CVSD", CodecType::CVSD, 65535, 7, 0, true, "CVSD_N", "CVSD_N",
63     std::nullopt, std::nullopt);
64 
65 class BluetoothHfpCodecsProviderTest : public ::testing::Test {
66  public:
CreateTestCases(const std::vector<std::vector<PathConfiguration>> path_configs_list,const std::vector<std::vector<TransportConfiguration>> transport_configs_list,const std::vector<std::vector<Configuration>> configs_list)67   static std::vector<HfpOffloadSettingTuple> CreateTestCases(
68       const std::vector<std::vector<PathConfiguration>> path_configs_list,
69       const std::vector<std::vector<TransportConfiguration>>
70           transport_configs_list,
71       const std::vector<std::vector<Configuration>> configs_list) {
72     std::vector<HfpOffloadSettingTuple> test_cases;
73     for (const auto& path_configs : path_configs_list) {
74       for (const auto& transport_configs : transport_configs_list) {
75         for (const auto& configs : configs_list)
76           test_cases.push_back(
77               CreateTestCase(path_configs, transport_configs, configs));
78       }
79     }
80     return test_cases;
81   }
82 
83  protected:
RunTestCase(HfpOffloadSettingTuple test_case)84   std::vector<CodecInfo> RunTestCase(HfpOffloadSettingTuple test_case) {
85     auto& [path_configuration_list, transport_configuration_list,
86            configuration_list] = test_case;
87     HfpOffloadSetting hfp_offload_setting(path_configuration_list,
88                                           transport_configuration_list,
89                                           configuration_list);
90     auto capabilities =
91         BluetoothHfpCodecsProvider::GetHfpAudioCodecInfo(hfp_offload_setting);
92     return capabilities;
93   }
94 
95  private:
CreateTestCase(const std::vector<PathConfiguration> path_config_list,const std::vector<TransportConfiguration> transport_config_list,const std::vector<Configuration> config_list)96   static inline HfpOffloadSettingTuple CreateTestCase(
97       const std::vector<PathConfiguration> path_config_list,
98       const std::vector<TransportConfiguration> transport_config_list,
99       const std::vector<Configuration> config_list) {
100     return std::make_tuple(path_config_list, transport_config_list,
101                            config_list);
102   }
103 };
104 
105 class GetHfpCodecInfoTest : public BluetoothHfpCodecsProviderTest {
106  public:
107   static std::vector<std::vector<PathConfiguration>>
GetInvalidPathConfigurationLists()108   GetInvalidPathConfigurationLists() {
109     std::vector<std::vector<PathConfiguration>> result;
110     result.push_back({kInvalidPathConfigurationNULL});
111     result.push_back({kInvalidPathConfigurationNoPath});
112     result.push_back({});
113     return result;
114   }
115 
116   static std::vector<std::vector<Configuration>>
GetInvalidConfigurationLists()117   GetInvalidConfigurationLists() {
118     std::vector<std::vector<Configuration>> result;
119     result.push_back({kInvalidConfigurationCVSDNotFound});
120     result.push_back({kInvalidConfigurationCVSDNoPath});
121     result.push_back({});
122     return result;
123   }
124 };
125 
TEST_F(GetHfpCodecInfoTest,InvalidPathConfiguration)126 TEST_F(GetHfpCodecInfoTest, InvalidPathConfiguration) {
127   auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
128       GetHfpCodecInfoTest::GetInvalidPathConfigurationLists(), {{}},
129       {{kValidConfigurationCVSD}});
130   for (auto& test_case : test_cases) {
131     auto hfp_codec_capabilities = RunTestCase(test_case);
132     ASSERT_TRUE(hfp_codec_capabilities.empty());
133   }
134 }
135 
TEST_F(GetHfpCodecInfoTest,InvalidConfigurationName)136 TEST_F(GetHfpCodecInfoTest, InvalidConfigurationName) {
137   auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
138       GetHfpCodecInfoTest::GetInvalidPathConfigurationLists(), {{}},
139       {GetHfpCodecInfoTest::GetInvalidConfigurationLists()});
140   for (auto& test_case : test_cases) {
141     auto hfp_codec_capabilities = RunTestCase(test_case);
142     ASSERT_TRUE(hfp_codec_capabilities.empty());
143   }
144 }
145 
TEST_F(GetHfpCodecInfoTest,ValidConfiguration)146 TEST_F(GetHfpCodecInfoTest, ValidConfiguration) {
147   auto test_cases = BluetoothHfpCodecsProviderTest::CreateTestCases(
148       {{kValidPathConfigurationCVSD}}, {{}}, {{kValidConfigurationCVSD}});
149   for (auto& test_case : test_cases) {
150     auto hfp_codec_capabilities = RunTestCase(test_case);
151     ASSERT_FALSE(hfp_codec_capabilities.empty());
152   }
153 }
154