1 /*
2 * Copyright 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 "btif/include/btif_hh.h"
18
19 #include <gtest/gtest.h>
20
21 #include <algorithm>
22 #include <array>
23 #include <future>
24 #include <vector>
25
26 #include "bta/include/bta_ag_api.h"
27 #include "bta/include/bta_hh_api.h"
28 #include "btcore/include/module.h"
29 #include "include/hardware/bt_hh.h"
30 #include "test/common/core_interface.h"
31 #include "test/common/mock_functions.h"
32
33 using namespace std::chrono_literals;
34
35 namespace bluetooth::testing {
36 void set_hal_cbacks(bt_callbacks_t* callbacks);
37 } // namespace bluetooth::testing
38
39 // Used the legacy stack manager
40 module_t bt_utils_module;
41 module_t gd_controller_module;
42 module_t gd_shim_module;
43 module_t osi_module;
44 module_t rust_module;
45
46 const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {};
47
48 namespace bluetooth {
49 namespace legacy {
50 namespace testing {
51
52 void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data);
53
54 } // namespace testing
55 } // namespace legacy
56 } // namespace bluetooth
57
58 namespace test {
59 namespace mock {
60 extern bool bluetooth_shim_is_gd_stack_started_up;
61 }
62 } // namespace test
63
64 namespace {
65 std::array<uint8_t, 32> data32 = {
66 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
67 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
68 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
69 };
70
71 const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
72 const RawAddress kDeviceAddressConnecting({0x66, 0x55, 0x44, 0x33, 0x22, 0x11});
73 const uint16_t kHhHandle = 123;
74 const tBLE_ADDR_TYPE kDeviceAddrType = BLE_ADDR_PUBLIC;
75 const tBT_TRANSPORT kDeviceTransport = BT_TRANSPORT_AUTO;
76 const tAclLinkSpec kDeviceConnecting = {.addrt.type = kDeviceAddrType,
77 .addrt.bda = kDeviceAddressConnecting,
78 .transport = kDeviceTransport};
79 // Callback parameters grouped into a structure
80 struct get_report_cb_t {
81 RawAddress raw_address;
82 bthh_status_t status;
83 std::vector<uint8_t> data;
84 } get_report_cb_;
85
86 struct connection_state_cb_t {
87 RawAddress raw_address;
88 bthh_connection_state_t state;
89 };
90
91 // Globals allow usage within function pointers
92 std::promise<bt_cb_thread_evt> g_thread_evt_promise;
93 std::promise<bt_status_t> g_status_promise;
94 std::promise<get_report_cb_t> g_bthh_callbacks_get_report_promise;
95 std::promise<connection_state_cb_t> g_bthh_connection_state_promise;
96
97 } // namespace
98
99 bt_callbacks_t bt_callbacks = {
100 .size = sizeof(bt_callbacks_t),
101 .adapter_state_changed_cb = nullptr, // adapter_state_changed_callback
102 .adapter_properties_cb = nullptr, // adapter_properties_callback
103 .remote_device_properties_cb = nullptr, // remote_device_properties_callback
104 .device_found_cb = nullptr, // device_found_callback
105 .discovery_state_changed_cb = nullptr, // discovery_state_changed_callback
106 .pin_request_cb = nullptr, // pin_request_callback
107 .ssp_request_cb = nullptr, // ssp_request_callback
108 .bond_state_changed_cb = nullptr, // bond_state_changed_callback
109 .address_consolidate_cb = nullptr, // address_consolidate_callback
110 .le_address_associate_cb = nullptr, // le_address_associate_callback
111 .acl_state_changed_cb = nullptr, // acl_state_changed_callback
112 .thread_evt_cb = nullptr, // callback_thread_event
113 .dut_mode_recv_cb = nullptr, // dut_mode_recv_callback
114 .le_test_mode_cb = nullptr, // le_test_mode_callback
115 .energy_info_cb = nullptr, // energy_info_callback
116 .link_quality_report_cb = nullptr, // link_quality_report_callback
117 .generate_local_oob_data_cb = nullptr, // generate_local_oob_data_callback
118 .switch_buffer_size_cb = nullptr, // switch_buffer_size_callback
119 .switch_codec_cb = nullptr, // switch_codec_callback
120 .le_rand_cb = nullptr, // le_rand_callback
121 };
122
123 bthh_callbacks_t bthh_callbacks = {
124 .size = sizeof(bthh_callbacks_t),
125 .connection_state_cb = nullptr, // bthh_connection_state_callback
126 .hid_info_cb = nullptr, // bthh_hid_info_callback
127 .protocol_mode_cb = nullptr, // bthh_protocol_mode_callback
128 .idle_time_cb = nullptr, // bthh_idle_time_callback
129 .get_report_cb = nullptr, // bthh_get_report_callback
130 .virtual_unplug_cb = nullptr, // bthh_virtual_unplug_callback
131 .handshake_cb = nullptr, // bthh_handshake_callback
132 };
133
134 class BtifHhWithMockTest : public ::testing::Test {
135 protected:
SetUp()136 void SetUp() override { reset_mock_function_count_map(); }
137
TearDown()138 void TearDown() override {}
139 };
140
141 class BtifHhWithHalCallbacksTest : public BtifHhWithMockTest {
142 protected:
SetUp()143 void SetUp() override {
144 BtifHhWithMockTest::SetUp();
145 g_thread_evt_promise = std::promise<bt_cb_thread_evt>();
146 auto future = g_thread_evt_promise.get_future();
147 bt_callbacks.thread_evt_cb = [](bt_cb_thread_evt evt) { g_thread_evt_promise.set_value(evt); };
148 bluetooth::testing::set_hal_cbacks(&bt_callbacks);
149 // Start the jni callback thread
150 InitializeCoreInterface();
151 ASSERT_EQ(std::future_status::ready, future.wait_for(2s));
152 ASSERT_EQ(ASSOCIATE_JVM, future.get());
153
154 bt_callbacks.thread_evt_cb = [](bt_cb_thread_evt /* evt */) {};
155 }
156
TearDown()157 void TearDown() override {
158 g_thread_evt_promise = std::promise<bt_cb_thread_evt>();
159 auto future = g_thread_evt_promise.get_future();
160 bt_callbacks.thread_evt_cb = [](bt_cb_thread_evt evt) { g_thread_evt_promise.set_value(evt); };
161 CleanCoreInterface();
162 ASSERT_EQ(std::future_status::ready, future.wait_for(2s));
163 ASSERT_EQ(DISASSOCIATE_JVM, future.get());
164
165 bt_callbacks.thread_evt_cb = [](bt_cb_thread_evt /* evt */) {};
166 BtifHhWithMockTest::TearDown();
167 }
168 };
169
170 class BtifHhAdapterReady : public BtifHhWithHalCallbacksTest {
171 protected:
SetUp()172 void SetUp() override {
173 BtifHhWithHalCallbacksTest::SetUp();
174 test::mock::bluetooth_shim_is_gd_stack_started_up = true;
175 ASSERT_EQ(BT_STATUS_SUCCESS, btif_hh_get_interface()->init(&bthh_callbacks));
176 }
177
TearDown()178 void TearDown() override {
179 test::mock::bluetooth_shim_is_gd_stack_started_up = false;
180 BtifHhWithHalCallbacksTest::TearDown();
181 }
182 };
183
184 class BtifHhWithDevice : public BtifHhAdapterReady {
185 protected:
SetUp()186 void SetUp() override {
187 BtifHhAdapterReady::SetUp();
188
189 // Short circuit a connected device
190 btif_hh_cb.devices[0].link_spec.addrt.bda = kDeviceAddress;
191 btif_hh_cb.devices[0].link_spec.addrt.type = kDeviceAddrType;
192 btif_hh_cb.devices[0].link_spec.transport = kDeviceTransport;
193 btif_hh_cb.devices[0].dev_status = BTHH_CONN_STATE_CONNECTED;
194 btif_hh_cb.devices[0].dev_handle = kHhHandle;
195 }
196
TearDown()197 void TearDown() override { BtifHhAdapterReady::TearDown(); }
198 };
199
TEST_F(BtifHhAdapterReady,lifecycle)200 TEST_F(BtifHhAdapterReady, lifecycle) {}
201
202 static uint8_t report_data[sizeof(BT_HDR) + data32.size()];
203
TEST_F(BtifHhWithDevice,BTA_HH_GET_RPT_EVT)204 TEST_F(BtifHhWithDevice, BTA_HH_GET_RPT_EVT) {
205 tBTA_HH data = {
206 .hs_data =
207 {
208 .status = BTA_HH_OK,
209 .handle = kHhHandle,
210 .rsp_data =
211 {
212 .p_rpt_data = reinterpret_cast<BT_HDR*>(report_data),
213 },
214 },
215 };
216
217 // Fill out the deep copy data
218 data.hs_data.rsp_data.p_rpt_data->len = static_cast<uint16_t>(data32.size());
219 std::copy(data32.begin(), data32.begin() + data32.size(),
220 reinterpret_cast<uint8_t*>(data.hs_data.rsp_data.p_rpt_data + 1));
221
222 g_bthh_callbacks_get_report_promise = std::promise<get_report_cb_t>();
223 auto future = g_bthh_callbacks_get_report_promise.get_future();
224 bthh_callbacks.get_report_cb = [](RawAddress* bd_addr, tBLE_ADDR_TYPE /* addr_type */,
225 tBT_TRANSPORT /* transport */, bthh_status_t hh_status,
226 uint8_t* rpt_data, int rpt_size) {
227 get_report_cb_t report = {
228 .raw_address = *bd_addr,
229 .status = hh_status,
230 .data = std::vector<uint8_t>(),
231 };
232 report.data.assign(rpt_data, rpt_data + rpt_size),
233 g_bthh_callbacks_get_report_promise.set_value(report);
234 };
235
236 bluetooth::legacy::testing::bte_hh_evt(BTA_HH_GET_RPT_EVT, &data);
237
238 ASSERT_EQ(std::future_status::ready, future.wait_for(2s));
239 auto report = future.get();
240
241 // Verify data was delivered
242 ASSERT_STREQ(kDeviceAddress.ToString().c_str(), report.raw_address.ToString().c_str());
243 ASSERT_EQ(BTHH_OK, report.status);
244 int i = 0;
245 for (const auto& data : data32) {
246 ASSERT_EQ(data, report.data[i++]);
247 }
248 }
249
250 class BtifHHVirtualUnplugTest : public BtifHhAdapterReady {
251 protected:
SetUp()252 void SetUp() override {
253 BtifHhAdapterReady::SetUp();
254 bthh_callbacks.connection_state_cb = [](RawAddress* bd_addr, tBLE_ADDR_TYPE /* addr_type */,
255 tBT_TRANSPORT /* transport */,
256 bthh_connection_state_t state) {
257 connection_state_cb_t connection_state = {
258 .raw_address = *bd_addr,
259 .state = state,
260 };
261 g_bthh_connection_state_promise.set_value(connection_state);
262 };
263 }
264
TearDown()265 void TearDown() override {
266 bthh_callbacks.connection_state_cb =
267 [](RawAddress* /* bd_addr */, tBLE_ADDR_TYPE /* addr_type */,
268 tBT_TRANSPORT /* transport */, bthh_connection_state_t /* state */) {};
269 BtifHhAdapterReady::TearDown();
270 }
271 };
272
TEST_F(BtifHHVirtualUnplugTest,test_btif_hh_virtual_unplug_device_not_open)273 TEST_F(BtifHHVirtualUnplugTest, test_btif_hh_virtual_unplug_device_not_open) {
274 g_bthh_connection_state_promise = std::promise<connection_state_cb_t>();
275
276 auto future = g_bthh_connection_state_promise.get_future();
277
278 /* Make device in connecting state */
279 ASSERT_EQ(btif_hh_connect(kDeviceConnecting), BT_STATUS_SUCCESS);
280
281 ASSERT_EQ(std::future_status::ready, future.wait_for(2s));
282
283 auto res = future.get();
284 ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str());
285 ASSERT_EQ(BTHH_CONN_STATE_CONNECTING, res.state);
286
287 g_bthh_connection_state_promise = std::promise<connection_state_cb_t>();
288 future = g_bthh_connection_state_promise.get_future();
289 btif_hh_virtual_unplug(kDeviceConnecting);
290
291 ASSERT_EQ(std::future_status::ready, future.wait_for(2s));
292
293 // Verify data was delivered
294 res = future.get();
295 ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str());
296 ASSERT_EQ(BTHH_CONN_STATE_DISCONNECTED, res.state);
297 }
298