1 /*
2 * Copyright 2021 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 <base/functional/bind.h>
18 #include <base/location.h>
19 #include <bluetooth/log.h>
20 #include <com_android_bluetooth_flags.h>
21 #include <flag_macros.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24
25 #include <format>
26 #include <string>
27
28 #include "bta/dm/bta_dm_device_search_int.h"
29 #include "bta/dm/bta_dm_disc.h"
30 #include "bta/dm/bta_dm_int.h"
31 #include "bta/dm/bta_dm_pm.cc"
32 #include "bta/dm/bta_dm_sec_int.h"
33 #include "bta/hf_client/bta_hf_client_int.h"
34 #include "bta/include/bta_api.h"
35 #include "bta/test/bta_test_fixtures.h"
36 #include "hci/controller_interface_mock.h"
37 #include "hci/le_rand_callback.h"
38 #include "stack/include/btm_status.h"
39 #include "test/common/main_handler.h"
40 #include "test/common/mock_functions.h"
41 #include "test/mock/mock_main_shim_entry.h"
42 #include "test/mock/mock_osi_alarm.h"
43 #include "test/mock/mock_osi_allocator.h"
44 #include "test/mock/mock_osi_properties.h"
45 #include "test/mock/mock_stack_acl.h"
46 #include "test/mock/mock_stack_btm_interface.h"
47
48 #define TEST_BT com::android::bluetooth::flags
49
50 using namespace std::chrono_literals;
51 using namespace bluetooth;
52
53 namespace {
54 constexpr uint8_t kUnusedTimer = BTA_ID_MAX;
55 const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
56 const RawAddress kRawAddress2({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
57
58 constexpr char kRemoteName[] = "TheRemoteName";
59
60 } // namespace
61
62 namespace bluetooth::legacy::testing {
63
64 tBTA_DM_SEARCH_CB& bta_dm_disc_search_cb();
65 void bta_dm_deinit_cb();
66 void bta_dm_init_cb();
67 void bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME& remote_name_msg);
68
69 } // namespace bluetooth::legacy::testing
70
71 class BtaDmTest : public BtaWithContextTest {
72 protected:
SetUp()73 void SetUp() override {
74 BtaWithContextTest::SetUp();
75 ON_CALL(controller_, LeRand).WillByDefault([](bluetooth::hci::LeRandCallback cb) {
76 cb(0x1234);
77 });
78 bluetooth::hci::testing::mock_controller_ = &controller_;
79
80 BTA_dm_init();
81 bluetooth::legacy::testing::bta_dm_init_cb();
82
83 for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
84 for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
85 bta_dm_cb.pm_timer[i].srvc_id[j] = kUnusedTimer;
86 }
87 }
88 }
TearDown()89 void TearDown() override {
90 bluetooth::legacy::testing::bta_dm_deinit_cb();
91 BtaWithContextTest::TearDown();
92 bluetooth::hci::testing::mock_controller_ = nullptr;
93 }
94 bluetooth::hci::testing::MockControllerInterface controller_;
95 };
96
97 class BtaDmCustomAlarmTest : public BtaDmTest {
98 protected:
SetUp()99 void SetUp() override {
100 BtaDmTest::SetUp();
101 test::mock::osi_alarm::alarm_set_on_mloop.body =
102 [this](alarm_t* alarm, uint64_t /*interval_ms*/, alarm_callback_t cb, void* data) {
103 ASSERT_TRUE(alarm != nullptr);
104 this->alarm_callback = cb;
105 this->alarm_data = data;
106 };
107 }
TearDown()108 void TearDown() override {
109 test::mock::osi_alarm::alarm_set_on_mloop = {};
110 BtaDmTest::TearDown();
111 }
112 alarm_callback_t alarm_callback;
113 void* alarm_data{nullptr};
114 };
115
TEST_F(BtaDmTest,nop)116 TEST_F(BtaDmTest, nop) {
117 bool status = true;
118 ASSERT_EQ(true, status);
119 }
120
TEST_F(BtaDmCustomAlarmTest,disable_no_acl_links)121 TEST_F(BtaDmCustomAlarmTest, disable_no_acl_links) {
122 bta_dm_cb.disabling = true;
123
124 bta_dm_disable(); // Waiting for all ACL connections to drain
125 ASSERT_EQ(0, get_func_call_count("btm_remove_acl"));
126 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
127
128 // Execute timer callback
129 alarm_callback(this->alarm_data);
130 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
131 ASSERT_EQ(0, get_func_call_count("BTIF_dm_disable"));
132 ASSERT_EQ(1, get_func_call_count("future_ready"));
133 ASSERT_TRUE(!bta_dm_cb.disabling);
134 }
135
TEST_F(BtaDmCustomAlarmTest,disable_first_pass_with_acl_links)136 TEST_F(BtaDmCustomAlarmTest, disable_first_pass_with_acl_links) {
137 test::mock::stack_acl::BTM_GetNumAclLinks.body = []() { return 1; };
138 bta_dm_cb.disabling = true;
139 // ACL link is open
140 bta_dm_cb.device_list.count = 1;
141
142 bta_dm_disable(); // Waiting for all ACL connections to drain
143 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
144 ASSERT_EQ(0, get_func_call_count("BTIF_dm_disable"));
145
146 test::mock::stack_acl::BTM_GetNumAclLinks.body = []() { return 0; };
147 // First disable pass
148 alarm_callback(this->alarm_data);
149 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
150 ASSERT_EQ(1, get_func_call_count("BTIF_dm_disable"));
151 ASSERT_TRUE(!bta_dm_cb.disabling);
152
153 test::mock::stack_acl::BTM_GetNumAclLinks = {};
154 }
155
TEST_F(BtaDmCustomAlarmTest,disable_second_pass_with_acl_links)156 TEST_F(BtaDmCustomAlarmTest, disable_second_pass_with_acl_links) {
157 test::mock::stack_acl::BTM_GetNumAclLinks.body = []() { return 1; };
158 bta_dm_cb.disabling = true;
159 // ACL link is open
160 bta_dm_cb.device_list.count = 1;
161
162 bta_dm_disable(); // Waiting for all ACL connections to drain
163 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
164 ASSERT_EQ(0, get_func_call_count("BTIF_dm_disable"));
165
166 // First disable pass
167 alarm_callback(alarm_data);
168 ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
169 ASSERT_EQ(0, get_func_call_count("BTIF_dm_disable"));
170 ASSERT_EQ(1, get_func_call_count("btm_remove_acl"));
171
172 // Second disable pass
173 alarm_callback(alarm_data);
174 ASSERT_EQ(1, get_func_call_count("BTIF_dm_disable"));
175 ASSERT_TRUE(!bta_dm_cb.disabling);
176
177 test::mock::stack_acl::BTM_GetNumAclLinks = {};
178 }
179
180 namespace {
181
182 struct BTA_DM_ENCRYPT_CBACK_parms {
183 const RawAddress bd_addr;
184 tBT_TRANSPORT transport;
185 tBTA_STATUS result;
186 };
187
188 std::queue<BTA_DM_ENCRYPT_CBACK_parms> BTA_DM_ENCRYPT_CBACK_queue;
189
BTA_DM_ENCRYPT_CBACK(const RawAddress & bd_addr,tBT_TRANSPORT transport,tBTA_STATUS result)190 void BTA_DM_ENCRYPT_CBACK(const RawAddress& bd_addr, tBT_TRANSPORT transport, tBTA_STATUS result) {
191 BTA_DM_ENCRYPT_CBACK_queue.push({bd_addr, transport, result});
192 }
193
194 } // namespace
195
196 namespace bluetooth {
197 namespace legacy {
198 namespace testing {
199 tBTA_DM_PEER_DEVICE* allocate_device_for(const RawAddress& bd_addr, tBT_TRANSPORT transport);
200
201 void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p);
202
203 tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& remote_bd_addr);
204
205 tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);
206
207 void BTA_dm_on_hw_on();
208
209 } // namespace testing
210 } // namespace legacy
211 } // namespace bluetooth
212
TEST_F(BtaDmTest,bta_dm_set_encryption)213 TEST_F(BtaDmTest, bta_dm_set_encryption) {
214 const tBT_TRANSPORT transport{BT_TRANSPORT_LE};
215 const tBTM_BLE_SEC_ACT sec_act{BTM_BLE_SEC_NONE};
216
217 // Callback not provided
218 bta_dm_set_encryption(kRawAddress, transport, nullptr, sec_act);
219
220 // Device connection does not exist
221 bta_dm_set_encryption(kRawAddress, transport, BTA_DM_ENCRYPT_CBACK, sec_act);
222
223 // Setup a connected device
224 tBTA_DM_PEER_DEVICE* device =
225 bluetooth::legacy::testing::allocate_device_for(kRawAddress, transport);
226 ASSERT_TRUE(device != nullptr);
227 device->p_encrypt_cback = nullptr;
228
229 // Setup a device that is busy with another encryption
230 // Fake indication that the encryption is in progress with non-null callback
231 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
232 bta_dm_set_encryption(kRawAddress, transport, BTA_DM_ENCRYPT_CBACK, sec_act);
233 ASSERT_EQ(0, get_func_call_count("BTM_SetEncryption"));
234 ASSERT_EQ(1UL, BTA_DM_ENCRYPT_CBACK_queue.size());
235 auto params = BTA_DM_ENCRYPT_CBACK_queue.front();
236 BTA_DM_ENCRYPT_CBACK_queue.pop();
237 ASSERT_EQ(BTA_BUSY, params.result);
238 device->p_encrypt_cback = nullptr;
239
240 // Setup a device that fails encryption
241 mock_btm_client_interface.security.BTM_SetEncryption =
242 [](const RawAddress& /*bd_addr*/, tBT_TRANSPORT /*transport*/,
243 tBTM_SEC_CALLBACK* /*p_callback*/, void* /*p_ref_data*/,
244 tBTM_BLE_SEC_ACT /*sec_act*/) -> tBTM_STATUS {
245 inc_func_call_count("BTM_SetEncryption");
246 return tBTM_STATUS::BTM_MODE_UNSUPPORTED;
247 };
248
249 bta_dm_set_encryption(kRawAddress, transport, BTA_DM_ENCRYPT_CBACK, sec_act);
250 ASSERT_EQ(1, get_func_call_count("BTM_SetEncryption"));
251 ASSERT_EQ(0UL, BTA_DM_ENCRYPT_CBACK_queue.size());
252 device->p_encrypt_cback = nullptr;
253
254 // Setup a device that successfully starts encryption
255 mock_btm_client_interface.security.BTM_SetEncryption =
256 [](const RawAddress& /*bd_addr*/, tBT_TRANSPORT /*transport*/,
257 tBTM_SEC_CALLBACK* /*p_callback*/, void* /*p_ref_data*/,
258 tBTM_BLE_SEC_ACT /*sec_act*/) -> tBTM_STATUS {
259 inc_func_call_count("BTM_SetEncryption");
260 return tBTM_STATUS::BTM_CMD_STARTED;
261 };
262
263 bta_dm_set_encryption(kRawAddress, transport, BTA_DM_ENCRYPT_CBACK, sec_act);
264 ASSERT_EQ(2, get_func_call_count("BTM_SetEncryption"));
265 ASSERT_EQ(0UL, BTA_DM_ENCRYPT_CBACK_queue.size());
266 ASSERT_NE(nullptr, device->p_encrypt_cback);
267
268 BTA_DM_ENCRYPT_CBACK_queue = {};
269 }
270
271 void bta_dm_encrypt_cback(RawAddress bd_addr, tBT_TRANSPORT transport, void* /* p_ref_data */,
272 tBTM_STATUS result);
273
TEST_F(BtaDmTest,bta_dm_encrypt_cback)274 TEST_F(BtaDmTest, bta_dm_encrypt_cback) {
275 const tBT_TRANSPORT transport{BT_TRANSPORT_LE};
276
277 // Setup a connected device
278 tBTA_DM_PEER_DEVICE* device =
279 bluetooth::legacy::testing::allocate_device_for(kRawAddress, transport);
280 ASSERT_TRUE(device != nullptr);
281
282 // Encryption with no callback set
283 device->p_encrypt_cback = nullptr;
284 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_SUCCESS);
285 ASSERT_EQ(0UL, BTA_DM_ENCRYPT_CBACK_queue.size());
286
287 // Encryption with callback
288 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
289 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_SUCCESS);
290 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
291 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_WRONG_MODE);
292 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
293 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_NO_RESOURCES);
294 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
295 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_BUSY);
296 device->p_encrypt_cback = BTA_DM_ENCRYPT_CBACK;
297 bta_dm_encrypt_cback(kRawAddress, transport, nullptr, tBTM_STATUS::BTM_ILLEGAL_VALUE);
298
299 ASSERT_EQ(5UL, BTA_DM_ENCRYPT_CBACK_queue.size());
300
301 auto params_BTM_SUCCESS = BTA_DM_ENCRYPT_CBACK_queue.front();
302 BTA_DM_ENCRYPT_CBACK_queue.pop();
303 ASSERT_EQ(BTA_SUCCESS, params_BTM_SUCCESS.result);
304 auto params_BTM_WRONG_MODE = BTA_DM_ENCRYPT_CBACK_queue.front();
305 BTA_DM_ENCRYPT_CBACK_queue.pop();
306 ASSERT_EQ(BTA_WRONG_MODE, params_BTM_WRONG_MODE.result);
307 auto params_BTM_NO_RESOURCES = BTA_DM_ENCRYPT_CBACK_queue.front();
308 BTA_DM_ENCRYPT_CBACK_queue.pop();
309 ASSERT_EQ(BTA_NO_RESOURCES, params_BTM_NO_RESOURCES.result);
310 auto params_BTM_BUSY = BTA_DM_ENCRYPT_CBACK_queue.front();
311 BTA_DM_ENCRYPT_CBACK_queue.pop();
312 ASSERT_EQ(BTA_BUSY, params_BTM_BUSY.result);
313 auto params_BTM_ILLEGAL_VALUE = BTA_DM_ENCRYPT_CBACK_queue.front();
314 BTA_DM_ENCRYPT_CBACK_queue.pop();
315 ASSERT_EQ(BTA_FAILURE, params_BTM_ILLEGAL_VALUE.result);
316 }
317
TEST_F(BtaDmTest,bta_dm_remname_cback__typical)318 TEST_F(BtaDmTest, bta_dm_remname_cback__typical) {
319 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
320 search_cb.peer_bdaddr = kRawAddress;
321 search_cb.name_discover_done = false;
322
323 tBTM_REMOTE_DEV_NAME name = {
324 .bd_addr = kRawAddress,
325 .remote_bd_name = {},
326 .btm_status = tBTM_STATUS::BTM_SUCCESS,
327 .hci_status = HCI_SUCCESS,
328 };
329 bd_name_from_char_pointer(name.remote_bd_name, kRemoteName);
330
331 bluetooth::legacy::testing::bta_dm_remname_cback(&name);
332
333 sync_main_handler();
334
335 ASSERT_TRUE(bluetooth::legacy::testing::bta_dm_disc_search_cb().name_discover_done);
336 }
337
TEST_F(BtaDmTest,bta_dm_remname_cback__wrong_address)338 TEST_F(BtaDmTest, bta_dm_remname_cback__wrong_address) {
339 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
340 search_cb.p_device_search_cback = nullptr;
341 search_cb.peer_bdaddr = kRawAddress;
342 search_cb.name_discover_done = false;
343
344 tBTM_REMOTE_DEV_NAME name = {
345 .bd_addr = kRawAddress2,
346 .remote_bd_name = {},
347 .btm_status = tBTM_STATUS::BTM_SUCCESS,
348 .hci_status = HCI_SUCCESS,
349 };
350 bd_name_from_char_pointer(name.remote_bd_name, kRemoteName);
351
352 bluetooth::legacy::testing::bta_dm_remname_cback(&name);
353
354 sync_main_handler();
355 }
356
TEST_F(BtaDmTest,bta_dm_remname_cback__HCI_ERR_CONNECTION_EXISTS)357 TEST_F(BtaDmTest, bta_dm_remname_cback__HCI_ERR_CONNECTION_EXISTS) {
358 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
359 search_cb.peer_bdaddr = kRawAddress;
360 search_cb.name_discover_done = false;
361
362 tBTM_REMOTE_DEV_NAME name = {
363 .bd_addr = RawAddress::kEmpty,
364 .remote_bd_name = {},
365 .btm_status = tBTM_STATUS::BTM_SUCCESS,
366 .hci_status = HCI_ERR_CONNECTION_EXISTS,
367 };
368 bd_name_from_char_pointer(name.remote_bd_name, kRemoteName);
369
370 bluetooth::legacy::testing::bta_dm_remname_cback(&name);
371
372 sync_main_handler();
373
374 ASSERT_TRUE(bluetooth::legacy::testing::bta_dm_disc_search_cb().name_discover_done);
375 }
376
TEST_F(BtaDmTest,bta_dm_determine_discovery_transport__BR_EDR)377 TEST_F(BtaDmTest, bta_dm_determine_discovery_transport__BR_EDR) {
378 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
379
380 mock_btm_client_interface.peer.BTM_ReadDevInfo = [](const RawAddress& /*remote_bda*/,
381 tBT_DEVICE_TYPE* p_dev_type,
382 tBLE_ADDR_TYPE* p_addr_type) {
383 *p_dev_type = BT_DEVICE_TYPE_BREDR;
384 *p_addr_type = BLE_ADDR_PUBLIC;
385 };
386
387 ASSERT_EQ(BT_TRANSPORT_BR_EDR,
388 bluetooth::legacy::testing::bta_dm_determine_discovery_transport(kRawAddress));
389 }
390
TEST_F(BtaDmTest,bta_dm_determine_discovery_transport__BLE__PUBLIC)391 TEST_F(BtaDmTest, bta_dm_determine_discovery_transport__BLE__PUBLIC) {
392 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
393
394 mock_btm_client_interface.peer.BTM_ReadDevInfo = [](const RawAddress& /*remote_bda*/,
395 tBT_DEVICE_TYPE* p_dev_type,
396 tBLE_ADDR_TYPE* p_addr_type) {
397 *p_dev_type = BT_DEVICE_TYPE_BLE;
398 *p_addr_type = BLE_ADDR_PUBLIC;
399 };
400
401 ASSERT_EQ(BT_TRANSPORT_LE,
402 bluetooth::legacy::testing::bta_dm_determine_discovery_transport(kRawAddress));
403 }
404
TEST_F(BtaDmTest,bta_dm_determine_discovery_transport__DUMO)405 TEST_F(BtaDmTest, bta_dm_determine_discovery_transport__DUMO) {
406 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
407
408 mock_btm_client_interface.peer.BTM_ReadDevInfo = [](const RawAddress& /*remote_bda*/,
409 tBT_DEVICE_TYPE* p_dev_type,
410 tBLE_ADDR_TYPE* p_addr_type) {
411 *p_dev_type = BT_DEVICE_TYPE_DUMO;
412 *p_addr_type = BLE_ADDR_PUBLIC;
413 };
414
415 ASSERT_EQ(BT_TRANSPORT_BR_EDR,
416 bluetooth::legacy::testing::bta_dm_determine_discovery_transport(kRawAddress));
417 }
418
TEST_F(BtaDmTest,bta_dm_search_evt_text)419 TEST_F(BtaDmTest, bta_dm_search_evt_text) {
420 std::vector<std::pair<tBTA_DM_SEARCH_EVT, std::string>> events = {
421 std::make_pair(BTA_DM_INQ_RES_EVT, "BTA_DM_INQ_RES_EVT"),
422 std::make_pair(BTA_DM_INQ_CMPL_EVT, "BTA_DM_INQ_CMPL_EVT"),
423 std::make_pair(BTA_DM_DISC_CMPL_EVT, "BTA_DM_DISC_CMPL_EVT"),
424 std::make_pair(BTA_DM_SEARCH_CANCEL_CMPL_EVT, "BTA_DM_SEARCH_CANCEL_CMPL_EVT"),
425 std::make_pair(BTA_DM_NAME_READ_EVT, "BTA_DM_NAME_READ_EVT"),
426 };
427 for (const auto& event : events) {
428 ASSERT_STREQ(event.second.c_str(), bta_dm_search_evt_text(event.first).c_str());
429 }
430 ASSERT_STREQ(std::format("UNKNOWN[{}]", std::numeric_limits<uint8_t>::max()).c_str(),
431 bta_dm_search_evt_text(
432 static_cast<tBTA_DM_SEARCH_EVT>(std::numeric_limits<uint8_t>::max()))
433 .c_str());
434 }
435
TEST_F(BtaDmTest,bta_dm_remote_name_cmpl)436 TEST_F(BtaDmTest, bta_dm_remote_name_cmpl) {
437 reset_mock_btm_client_interface();
438 mock_btm_client_interface.db.BTM_InqDbRead = [](const RawAddress& /*bd_addr*/) -> tBTM_INQ_INFO* {
439 inc_func_call_count("BTM_InqDbRead");
440 return nullptr;
441 };
442 tBTA_DM_REMOTE_NAME remote_name_msg{
443 // tBTA_DM_REMOTE_NAME
444 .bd_addr = kRawAddress,
445 .bd_name = {0},
446 .hci_status = HCI_SUCCESS,
447 };
448 bluetooth::legacy::testing::bta_dm_remote_name_cmpl(remote_name_msg);
449 ASSERT_EQ(1, get_func_call_count("BTM_InqDbRead"));
450 }
451
TEST_F(BtaDmTest,bta_dm_disc_start__true)452 TEST_F(BtaDmTest, bta_dm_disc_start__true) { bta_dm_disc_start(true); }
TEST_F(BtaDmTest,bta_dm_disc_start__false)453 TEST_F(BtaDmTest, bta_dm_disc_start__false) { bta_dm_disc_start(false); }
454
TEST_F(BtaDmTest,bta_dm_disc_stop)455 TEST_F(BtaDmTest, bta_dm_disc_stop) { bta_dm_disc_stop(); }
456
TEST_F(BtaDmCustomAlarmTest,bta_dm_sniff_cback)457 TEST_F(BtaDmCustomAlarmTest, bta_dm_sniff_cback) {
458 // Setup a connected device
459 const tBT_TRANSPORT transport{BT_TRANSPORT_BR_EDR};
460 tBTA_DM_PEER_DEVICE* device =
461 bluetooth::legacy::testing::allocate_device_for(kRawAddress, transport);
462 ASSERT_TRUE(device != nullptr);
463
464 // Trigger a sniff timer
465 bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[0], bta_pm_action_to_timer_idx(BTA_DM_PM_SNIFF), 10, 1,
466 BTA_DM_PM_SNIFF);
467 bta_dm_cb.pm_timer[0].peer_bdaddr = kRawAddress;
468 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
469
470 // Trigger reset sniff
471 bta_dm_sniff_cback(BTA_ID_JV, 1, kRawAddress);
472 ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
473 ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
474 }
475
TEST_F(BtaDmCustomAlarmTest,sniff_offload_feature__test_sysprop)476 TEST_F(BtaDmCustomAlarmTest, sniff_offload_feature__test_sysprop) {
477 bool is_property_enabled = true;
478 test::mock::osi_properties::osi_property_get_bool.body =
479 [&](const char* /*key*/, bool /*default_value*/) -> int { return is_property_enabled; };
480
481 // Expect not to trigger bta_dm_init_pm due to sysprop enabled
482 // and reset the value of .srvc_id.
483 is_property_enabled = true;
484 bluetooth::legacy::testing::BTA_dm_on_hw_on();
485 ASSERT_EQ(0, bta_dm_cb.pm_timer[0].srvc_id[0]);
486
487 // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to
488 // BTA_ID_MAX due to sysprop disabled.
489 is_property_enabled = false;
490 bluetooth::legacy::testing::BTA_dm_on_hw_on();
491 ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]);
492
493 // Shouldn't crash even there's no active timer when calling
494 // bta_dm_disable_pm.
495 bta_dm_cb.pm_timer[0].in_use = false;
496 bta_dm_cb.pm_timer[0].srvc_id[0] = kUnusedTimer;
497 bta_dm_disable_pm();
498 }
499