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