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