1 /*
2 * Copyright 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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 #include <tuple>
21 #include <vector>
22
23 #include "bta/ag/bta_ag_int.h"
24 #include "bta/include/bta_le_audio_api.h"
25 #include "hci/controller_interface_mock.h"
26 #include "stack/btm/btm_int_types.h"
27 #include "stack/btm/btm_sco.h"
28 #include "test/mock/mock_device_esco_parameters.h"
29 #include "test/mock/mock_main_shim_entry.h"
30
31 tBTM_CB btm_cb;
Get()32 LeAudioClient* LeAudioClient::Get() { return nullptr; }
IsLeAudioClientInStreaming()33 bool LeAudioClient::IsLeAudioClientInStreaming() { return false; }
34
35 const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
36
37 class BtaAgScoParameterSelectionTest
38 : public ::testing::TestWithParam<std::tuple<tBTA_AG_FEAT, tBTA_AG_PEER_FEAT, bool>> {
39 protected:
SetUp()40 void SetUp() override {
41 test::mock::device_esco_parameters::esco_parameters_for_codec.body =
42 [this](esco_codec_t codec, bool /* offload */) {
43 this->codec = codec;
44 return enh_esco_params_t{};
45 };
46 bluetooth::hci::testing::mock_controller_ =
47 std::make_unique<bluetooth::hci::testing::MockControllerInterface>();
48 }
TearDown()49 void TearDown() override {
50 test::mock::device_esco_parameters::esco_parameters_for_codec = {};
51 bluetooth::hci::testing::mock_controller_.reset();
52 }
53 esco_codec_t codec;
54 };
55
TEST_P(BtaAgScoParameterSelectionTest,create_sco_cvsd)56 TEST_P(BtaAgScoParameterSelectionTest, create_sco_cvsd) {
57 bta_ag_api_set_active_device(kRawAddress);
58
59 const auto [feature, peer_feature, is_local] = GetParam();
60 tBTA_AG_SCB scb{
61 .peer_addr = kRawAddress,
62 .features = feature,
63 .peer_features = peer_feature,
64 .sco_idx = BTM_INVALID_SCO_INDEX,
65 .inuse_codec = tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD,
66 };
67
68 this->codec = ESCO_CODEC_UNKNOWN;
69 bta_ag_create_sco(&scb, is_local);
70 if ((scb.features & BTA_AG_FEAT_ESCO_S4) && (scb.peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
71 ASSERT_EQ(this->codec, ESCO_CODEC_CVSD_S4);
72 } else {
73 ASSERT_EQ(this->codec, ESCO_CODEC_CVSD_S3);
74 }
75 }
76
TEST_P(BtaAgScoParameterSelectionTest,create_pending_sco_cvsd)77 TEST_P(BtaAgScoParameterSelectionTest, create_pending_sco_cvsd) {
78 bta_ag_api_set_active_device(kRawAddress);
79
80 const auto [feature, peer_feature, is_local] = GetParam();
81 tBTA_AG_SCB scb{
82 .peer_addr = kRawAddress,
83 .features = feature,
84 .peer_features = peer_feature,
85 .sco_idx = BTM_INVALID_SCO_INDEX,
86 .inuse_codec = tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD,
87 };
88
89 this->codec = ESCO_CODEC_UNKNOWN;
90 if (is_local) {
91 bta_ag_create_sco(&scb, true);
92 } else {
93 // empty data, not used in the function
94 tBTM_ESCO_CONN_REQ_EVT_DATA data;
95 bta_ag_sco_conn_rsp(&scb, &data);
96 }
97 if ((scb.features & BTA_AG_FEAT_ESCO_S4) && (scb.peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
98 ASSERT_EQ(this->codec, ESCO_CODEC_CVSD_S4);
99 } else {
100 ASSERT_EQ(this->codec, ESCO_CODEC_CVSD_S3);
101 }
102 }
103
104 static std::vector<std::tuple<tBTA_AG_FEAT, tBTA_AG_PEER_FEAT, bool>>
BtaAgScoParameterSelectionTestParameters()105 BtaAgScoParameterSelectionTestParameters() {
106 tBTA_AG_FEAT features[] = {0, BTA_AG_FEAT_ESCO_S4};
107 tBTA_AG_PEER_FEAT peer_features[] = {0, BTA_AG_PEER_FEAT_ESCO_S4};
108 bool is_local_or_orig[] = {false, true};
109 std::vector<std::tuple<tBTA_AG_FEAT, tBTA_AG_PEER_FEAT, bool>> params;
110
111 for (auto i : features) {
112 for (auto j : peer_features) {
113 for (auto k : is_local_or_orig) {
114 params.push_back({i, j, k});
115 }
116 }
117 }
118 return params;
119 }
120
121 INSTANTIATE_TEST_SUITE_P(BtaAgScoParameterSelectionTests, BtaAgScoParameterSelectionTest,
122 ::testing::ValuesIn(BtaAgScoParameterSelectionTestParameters()));
123