Loading system/bta/dm/bta_dm_disc.cc +75 −24 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "main/shim/dumpsys.h" #include "os/logging/log_adapter.h" #include "osi/include/allocator.h" #include "stack/btm/btm_dev.h" #include "stack/include/bt_name.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_client_interface.h" Loading Loading @@ -72,6 +73,17 @@ base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = default_sdp_performer; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = default_gatt_performer; static bool is_same_device(const RawAddress& a, const RawAddress& b) { if (a == b) return true; auto devA = btm_find_dev(a); if (devA != nullptr && devA == btm_find_dev(b)) { return true; } return false; } } // namespace static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event, Loading Loading @@ -284,8 +296,10 @@ static void bta_dm_read_dis_cmpl(const RawAddress& addr, p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.product_version); } if (!bta_dm_discovery_cb.transports) { bta_dm_execute_queued_discovery_request(); } } #endif /******************************************************************************* Loading @@ -303,6 +317,8 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { /* if any BR/EDR service discovery has been done, report the event */ if (!disc_result.is_gatt_over_ble) { bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_BR_EDR; auto& r = disc_result; if (!r.gatt_uuids.empty()) { log::info("Sending GATT services discovered using SDP"); Loading @@ -313,6 +329,7 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { bta_dm_discovery_cb.service_search_cbacks.on_service_discovery_results( r.bd_addr, r.uuids, r.result); } else { bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_LE; GAP_BleReadPeerPrefConnParams(bta_dm_discovery_cb.peer_bdaddr); bta_dm_discovery_cb.service_search_cbacks.on_gatt_results( Loading @@ -320,7 +337,9 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { /* transport_le */ true); } if (!bta_dm_discovery_cb.transports) { bta_dm_discovery_set_state(BTA_DM_DISCOVER_IDLE); } #if TARGET_FLOSS if (bta_dm_discovery_cb.conn_id != GATT_INVALID_CONN_ID && Loading @@ -330,8 +349,10 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { } #endif if (!bta_dm_discovery_cb.transports) { bta_dm_execute_queued_discovery_request(); } } /******************************************************************************* * Loading @@ -343,8 +364,8 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { * ******************************************************************************/ static void bta_dm_queue_disc(tBTA_DM_API_DISCOVER& discovery) { log::info("bta_dm_discovery: queuing service discovery to {}", discovery.bd_addr); log::info("bta_dm_discovery: queuing service discovery to {} [{}]", discovery.bd_addr, bt_transport_text(discovery.transport)); bta_dm_discovery_cb.pending_discovery_queue.push(discovery); } Loading @@ -358,7 +379,8 @@ static void bta_dm_execute_queued_discovery_request() { tBTA_DM_API_DISCOVER pending_discovery = bta_dm_discovery_cb.pending_discovery_queue.front(); bta_dm_discovery_cb.pending_discovery_queue.pop(); log::info("Start pending discovery"); log::info("Start pending discovery {} [{}]", pending_discovery.bd_addr, pending_discovery.transport); post_disc_evt( BTA_DM_API_DISCOVER_EVT, std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{pending_discovery})); Loading Loading @@ -428,14 +450,25 @@ static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) { base::StringPrintf("Transport:%s", bt_transport_text(transport).c_str())); if (transport == BT_TRANSPORT_LE) { if (bta_dm_discovery_cb.transports & BT_TRANSPORT_LE) { log::info("won't start GATT discovery - already started {}", bd_addr); return; } else { log::info("starting GATT discovery on {}", bd_addr); /* start GATT for service discovery */ bta_dm_discovery_cb.transports |= BT_TRANSPORT_LE; gatt_performer.Run(bd_addr); return; } // transport == BT_TRANSPORT_BR_EDR } // transport == BT_TRANSPORT_BR_EDR if (bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR) { log::info("won't start SDP - already started {}", bd_addr); } else { log::info("starting SDP discovery on {}", bd_addr); bta_dm_discovery_cb.transports |= BT_TRANSPORT_BR_EDR; bta_dm_discovery_cb.sdp_state = std::make_unique<tBTA_DM_SDP_STATE>(tBTA_DM_SDP_STATE{ .bd_addr = bd_addr, Loading @@ -443,9 +476,9 @@ static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) { .services_found = 0, .service_index = 0, }); sdp_performer.Run(bta_dm_discovery_cb.sdp_state.get()); } } void bta_dm_disc_override_sdp_performer_for_testing( base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> test_sdp_performer) { Loading Loading @@ -527,7 +560,19 @@ void bta_dm_gatt_finished(RawAddress bda, tBTA_STATUS result, * ******************************************************************************/ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { log::verbose("conn_id = {}", conn_id); bool sdp_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR; bool le_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_LE; log::verbose("conn_id = {}, status = {}, sdp_pending = {}, le_pending = {}", conn_id, status, sdp_pending, le_pending); if (com::android::bluetooth::flags::bta_dm_discover_both() && sdp_pending && !le_pending) { /* LE Service discovery finished, and services were reported, but SDP is not * finished yet. gatt_close_timer closed the connection, and we received * this callback because of disconnnection */ return; } std::vector<Uuid> gatt_services; Loading Loading @@ -806,12 +851,18 @@ static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event, bta_dm_disc_result(std::get<tBTA_DM_SVC_RES>(*msg)); break; case BTA_DM_API_DISCOVER_EVT: case BTA_DM_API_DISCOVER_EVT: { log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg), "bad message type: {}", msg->index()); auto req = std::get<tBTA_DM_API_DISCOVER>(*msg); if (com::android::bluetooth::flags::bta_dm_discover_both() && is_same_device(req.bd_addr, bta_dm_discovery_cb.peer_bdaddr)) { bta_dm_discover_services(std::get<tBTA_DM_API_DISCOVER>(*msg)); } else { bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg)); break; } } break; case BTA_DM_DISC_CLOSE_TOUT_EVT: bta_dm_close_gatt_conn(); break; Loading system/bta/dm/bta_dm_disc_int.h +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ typedef struct { std::queue<tBTA_DM_API_DISCOVER> pending_discovery_queue; RawAddress peer_bdaddr; uint8_t transports; /* This covers service discovery state - callers of BTA_DmDiscover. That is * initial service discovery after bonding and * BluetoothDevice.fetchUuidsWithSdp(). Responsible for LE GATT Service Loading system/bta/test/bta_disc_test.cc +130 −0 Original line number Diff line number Diff line Loading @@ -14,8 +14,11 @@ * limitations under the License. */ #define LOG_TAG "bt_bta_dm_test" #include <base/strings/stringprintf.h> #include <base/test/bind_test_util.h> #include <bluetooth/log.h> #include <com_android_bluetooth_flags.h> #include <flag_macros.h> #include <gmock/gmock.h> Loading @@ -35,6 +38,8 @@ #define TEST_BT com::android::bluetooth::flags using namespace bluetooth; namespace { const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); } Loading Loading @@ -255,6 +260,131 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_override_gatt_performer_for_testing({}); } // must be global, as capturing lambda can't be treated as function int service_cb_both_call_cnt = 0; int gatt_service_cb_both_call_cnt = 0; /* This test exercises the usual service discovery flow when bonding to * dual-mode, CTKD capable device on LE transport. */ TEST_F_WITH_FLAGS( BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, separate_service_and_device_discovery)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) { bta_dm_disc_start(true); std::promise<void> gatt_triggered; int gatt_call_cnt = 0; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = base::BindLambdaForTesting([&](const RawAddress& bd_addr) { gatt_call_cnt++; gatt_triggered.set_value(); }); bta_dm_disc_override_gatt_performer_for_testing(gatt_performer); int sdp_call_cnt = 0; base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = base::BindLambdaForTesting( [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; }); bta_dm_disc_override_sdp_performer_for_testing(sdp_performer); gatt_service_cb_both_call_cnt = 0; service_cb_both_call_cnt = 0; bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {}, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_BR_EDR); EXPECT_EQ(sdp_call_cnt, 1); bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { }}, kRawAddress, BT_TRANSPORT_LE); // GATT discovery is queued, until SDP finishes EXPECT_EQ(gatt_call_cnt, 0); bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {}); EXPECT_EQ(service_cb_both_call_cnt, 1); // SDP finished, wait until GATT is triggered. EXPECT_EQ(std::future_status::ready, gatt_triggered.get_future().wait_for(std::chrono::seconds(1))); bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS); EXPECT_EQ(gatt_service_cb_both_call_cnt, 1); bta_dm_disc_override_sdp_performer_for_testing({}); bta_dm_disc_override_gatt_performer_for_testing({}); } /* This test exercises the usual service discovery flow when bonding to * dual-mode, CTKD capable device on LE transport. */ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_enabled, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) { bta_dm_disc_start(true); int gatt_call_cnt = 0; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = base::BindLambdaForTesting( [&](const RawAddress& bd_addr) { gatt_call_cnt++; }); bta_dm_disc_override_gatt_performer_for_testing(gatt_performer); int sdp_call_cnt = 0; base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = base::BindLambdaForTesting( [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; }); bta_dm_disc_override_sdp_performer_for_testing(sdp_performer); gatt_service_cb_both_call_cnt = 0; service_cb_both_call_cnt = 0; bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_BR_EDR); EXPECT_EQ(sdp_call_cnt, 1); bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_LE); // GATT discovery on same device is immediately started EXPECT_EQ(gatt_call_cnt, 1); // GATT finished first bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS); EXPECT_EQ(gatt_service_cb_both_call_cnt, 1); // SDP finishes too bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {}); EXPECT_EQ(service_cb_both_call_cnt, 1); bta_dm_disc_override_sdp_performer_for_testing({}); bta_dm_disc_override_gatt_performer_for_testing({}); } TEST_F(BtaInitializedTest, init_bta_dm_search_cb__conn_id) { // Set the global search block target field to some non-reset value tBTA_DM_SEARCH_CB& search_cb = Loading system/btif/src/btif_dm.cc +39 −10 Original line number Diff line number Diff line Loading @@ -1745,8 +1745,26 @@ static void btif_on_service_discovery_results( } Uuid existing_uuids[BT_MAX_NUM_UUIDS] = {}; btif_get_existing_uuids(&bd_addr, existing_uuids); bt_status_t existing_lookup_result = btif_get_existing_uuids(&pairing_cb.bd_addr, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; if (btif_should_ignore_uuid(uuid)) { continue; } if (btif_is_interesting_le_service(uuid)) { log::info("interesting le service {} insert", uuid.ToString()); uuids.insert(uuid); } } } existing_lookup_result = btif_get_existing_uuids(&pairing_cb.static_bdaddr, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; if (btif_should_ignore_uuid(uuid)) { Loading @@ -1757,6 +1775,8 @@ static void btif_on_service_discovery_results( uuids.insert(uuid); } } } for (auto& uuid : uuids) { auto uuid_128bit = uuid.To128BitBE(); property_value.insert(property_value.end(), uuid_128bit.begin(), Loading Loading @@ -2005,10 +2025,19 @@ void btif_on_gatt_results(RawAddress bd_addr, BD_NAME bd_name, num_properties++; } if (!transport_le) { /* If services were returned as part of SDP discovery, we will immediately * send them with rest of SDP results in on_service_discovery_results */ if (!transport_le) { return; } else { if (pairing_cb.sdp_over_classic == btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED && com::android::bluetooth::flags::bta_dm_discover_both()) { /* Don't report services yet, they will be reported together once SDP * finishes. */ log::info("will report services later, with SDP results {}", bd_addr); return; } } /* Send the event to the BTIF */ Loading Loading
system/bta/dm/bta_dm_disc.cc +75 −24 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "main/shim/dumpsys.h" #include "os/logging/log_adapter.h" #include "osi/include/allocator.h" #include "stack/btm/btm_dev.h" #include "stack/include/bt_name.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_client_interface.h" Loading Loading @@ -72,6 +73,17 @@ base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = default_sdp_performer; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = default_gatt_performer; static bool is_same_device(const RawAddress& a, const RawAddress& b) { if (a == b) return true; auto devA = btm_find_dev(a); if (devA != nullptr && devA == btm_find_dev(b)) { return true; } return false; } } // namespace static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event, Loading Loading @@ -284,8 +296,10 @@ static void bta_dm_read_dis_cmpl(const RawAddress& addr, p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.product_version); } if (!bta_dm_discovery_cb.transports) { bta_dm_execute_queued_discovery_request(); } } #endif /******************************************************************************* Loading @@ -303,6 +317,8 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { /* if any BR/EDR service discovery has been done, report the event */ if (!disc_result.is_gatt_over_ble) { bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_BR_EDR; auto& r = disc_result; if (!r.gatt_uuids.empty()) { log::info("Sending GATT services discovered using SDP"); Loading @@ -313,6 +329,7 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { bta_dm_discovery_cb.service_search_cbacks.on_service_discovery_results( r.bd_addr, r.uuids, r.result); } else { bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_LE; GAP_BleReadPeerPrefConnParams(bta_dm_discovery_cb.peer_bdaddr); bta_dm_discovery_cb.service_search_cbacks.on_gatt_results( Loading @@ -320,7 +337,9 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { /* transport_le */ true); } if (!bta_dm_discovery_cb.transports) { bta_dm_discovery_set_state(BTA_DM_DISCOVER_IDLE); } #if TARGET_FLOSS if (bta_dm_discovery_cb.conn_id != GATT_INVALID_CONN_ID && Loading @@ -330,8 +349,10 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { } #endif if (!bta_dm_discovery_cb.transports) { bta_dm_execute_queued_discovery_request(); } } /******************************************************************************* * Loading @@ -343,8 +364,8 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) { * ******************************************************************************/ static void bta_dm_queue_disc(tBTA_DM_API_DISCOVER& discovery) { log::info("bta_dm_discovery: queuing service discovery to {}", discovery.bd_addr); log::info("bta_dm_discovery: queuing service discovery to {} [{}]", discovery.bd_addr, bt_transport_text(discovery.transport)); bta_dm_discovery_cb.pending_discovery_queue.push(discovery); } Loading @@ -358,7 +379,8 @@ static void bta_dm_execute_queued_discovery_request() { tBTA_DM_API_DISCOVER pending_discovery = bta_dm_discovery_cb.pending_discovery_queue.front(); bta_dm_discovery_cb.pending_discovery_queue.pop(); log::info("Start pending discovery"); log::info("Start pending discovery {} [{}]", pending_discovery.bd_addr, pending_discovery.transport); post_disc_evt( BTA_DM_API_DISCOVER_EVT, std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{pending_discovery})); Loading Loading @@ -428,14 +450,25 @@ static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) { base::StringPrintf("Transport:%s", bt_transport_text(transport).c_str())); if (transport == BT_TRANSPORT_LE) { if (bta_dm_discovery_cb.transports & BT_TRANSPORT_LE) { log::info("won't start GATT discovery - already started {}", bd_addr); return; } else { log::info("starting GATT discovery on {}", bd_addr); /* start GATT for service discovery */ bta_dm_discovery_cb.transports |= BT_TRANSPORT_LE; gatt_performer.Run(bd_addr); return; } // transport == BT_TRANSPORT_BR_EDR } // transport == BT_TRANSPORT_BR_EDR if (bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR) { log::info("won't start SDP - already started {}", bd_addr); } else { log::info("starting SDP discovery on {}", bd_addr); bta_dm_discovery_cb.transports |= BT_TRANSPORT_BR_EDR; bta_dm_discovery_cb.sdp_state = std::make_unique<tBTA_DM_SDP_STATE>(tBTA_DM_SDP_STATE{ .bd_addr = bd_addr, Loading @@ -443,9 +476,9 @@ static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) { .services_found = 0, .service_index = 0, }); sdp_performer.Run(bta_dm_discovery_cb.sdp_state.get()); } } void bta_dm_disc_override_sdp_performer_for_testing( base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> test_sdp_performer) { Loading Loading @@ -527,7 +560,19 @@ void bta_dm_gatt_finished(RawAddress bda, tBTA_STATUS result, * ******************************************************************************/ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { log::verbose("conn_id = {}", conn_id); bool sdp_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR; bool le_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_LE; log::verbose("conn_id = {}, status = {}, sdp_pending = {}, le_pending = {}", conn_id, status, sdp_pending, le_pending); if (com::android::bluetooth::flags::bta_dm_discover_both() && sdp_pending && !le_pending) { /* LE Service discovery finished, and services were reported, but SDP is not * finished yet. gatt_close_timer closed the connection, and we received * this callback because of disconnnection */ return; } std::vector<Uuid> gatt_services; Loading Loading @@ -806,12 +851,18 @@ static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event, bta_dm_disc_result(std::get<tBTA_DM_SVC_RES>(*msg)); break; case BTA_DM_API_DISCOVER_EVT: case BTA_DM_API_DISCOVER_EVT: { log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg), "bad message type: {}", msg->index()); auto req = std::get<tBTA_DM_API_DISCOVER>(*msg); if (com::android::bluetooth::flags::bta_dm_discover_both() && is_same_device(req.bd_addr, bta_dm_discovery_cb.peer_bdaddr)) { bta_dm_discover_services(std::get<tBTA_DM_API_DISCOVER>(*msg)); } else { bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg)); break; } } break; case BTA_DM_DISC_CLOSE_TOUT_EVT: bta_dm_close_gatt_conn(); break; Loading
system/bta/dm/bta_dm_disc_int.h +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ typedef struct { std::queue<tBTA_DM_API_DISCOVER> pending_discovery_queue; RawAddress peer_bdaddr; uint8_t transports; /* This covers service discovery state - callers of BTA_DmDiscover. That is * initial service discovery after bonding and * BluetoothDevice.fetchUuidsWithSdp(). Responsible for LE GATT Service Loading
system/bta/test/bta_disc_test.cc +130 −0 Original line number Diff line number Diff line Loading @@ -14,8 +14,11 @@ * limitations under the License. */ #define LOG_TAG "bt_bta_dm_test" #include <base/strings/stringprintf.h> #include <base/test/bind_test_util.h> #include <bluetooth/log.h> #include <com_android_bluetooth_flags.h> #include <flag_macros.h> #include <gmock/gmock.h> Loading @@ -35,6 +38,8 @@ #define TEST_BT com::android::bluetooth::flags using namespace bluetooth; namespace { const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); } Loading Loading @@ -255,6 +260,131 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_override_gatt_performer_for_testing({}); } // must be global, as capturing lambda can't be treated as function int service_cb_both_call_cnt = 0; int gatt_service_cb_both_call_cnt = 0; /* This test exercises the usual service discovery flow when bonding to * dual-mode, CTKD capable device on LE transport. */ TEST_F_WITH_FLAGS( BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, separate_service_and_device_discovery)), REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) { bta_dm_disc_start(true); std::promise<void> gatt_triggered; int gatt_call_cnt = 0; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = base::BindLambdaForTesting([&](const RawAddress& bd_addr) { gatt_call_cnt++; gatt_triggered.set_value(); }); bta_dm_disc_override_gatt_performer_for_testing(gatt_performer); int sdp_call_cnt = 0; base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = base::BindLambdaForTesting( [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; }); bta_dm_disc_override_sdp_performer_for_testing(sdp_performer); gatt_service_cb_both_call_cnt = 0; service_cb_both_call_cnt = 0; bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {}, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_BR_EDR); EXPECT_EQ(sdp_call_cnt, 1); bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { }}, kRawAddress, BT_TRANSPORT_LE); // GATT discovery is queued, until SDP finishes EXPECT_EQ(gatt_call_cnt, 0); bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {}); EXPECT_EQ(service_cb_both_call_cnt, 1); // SDP finished, wait until GATT is triggered. EXPECT_EQ(std::future_status::ready, gatt_triggered.get_future().wait_for(std::chrono::seconds(1))); bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS); EXPECT_EQ(gatt_service_cb_both_call_cnt, 1); bta_dm_disc_override_sdp_performer_for_testing({}); bta_dm_disc_override_gatt_performer_for_testing({}); } /* This test exercises the usual service discovery flow when bonding to * dual-mode, CTKD capable device on LE transport. */ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_enabled, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) { bta_dm_disc_start(true); int gatt_call_cnt = 0; base::RepeatingCallback<void(const RawAddress&)> gatt_performer = base::BindLambdaForTesting( [&](const RawAddress& bd_addr) { gatt_call_cnt++; }); bta_dm_disc_override_gatt_performer_for_testing(gatt_performer); int sdp_call_cnt = 0; base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer = base::BindLambdaForTesting( [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; }); bta_dm_disc_override_sdp_performer_for_testing(sdp_performer); gatt_service_cb_both_call_cnt = 0; service_cb_both_call_cnt = 0; bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_BR_EDR); EXPECT_EQ(sdp_call_cnt, 1); bta_dm_disc_start_service_discovery( {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; }, nullptr, nullptr, [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) { service_cb_both_call_cnt++; }}, kRawAddress, BT_TRANSPORT_LE); // GATT discovery on same device is immediately started EXPECT_EQ(gatt_call_cnt, 1); // GATT finished first bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS); EXPECT_EQ(gatt_service_cb_both_call_cnt, 1); // SDP finishes too bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {}); EXPECT_EQ(service_cb_both_call_cnt, 1); bta_dm_disc_override_sdp_performer_for_testing({}); bta_dm_disc_override_gatt_performer_for_testing({}); } TEST_F(BtaInitializedTest, init_bta_dm_search_cb__conn_id) { // Set the global search block target field to some non-reset value tBTA_DM_SEARCH_CB& search_cb = Loading
system/btif/src/btif_dm.cc +39 −10 Original line number Diff line number Diff line Loading @@ -1745,8 +1745,26 @@ static void btif_on_service_discovery_results( } Uuid existing_uuids[BT_MAX_NUM_UUIDS] = {}; btif_get_existing_uuids(&bd_addr, existing_uuids); bt_status_t existing_lookup_result = btif_get_existing_uuids(&pairing_cb.bd_addr, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; if (btif_should_ignore_uuid(uuid)) { continue; } if (btif_is_interesting_le_service(uuid)) { log::info("interesting le service {} insert", uuid.ToString()); uuids.insert(uuid); } } } existing_lookup_result = btif_get_existing_uuids(&pairing_cb.static_bdaddr, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; if (btif_should_ignore_uuid(uuid)) { Loading @@ -1757,6 +1775,8 @@ static void btif_on_service_discovery_results( uuids.insert(uuid); } } } for (auto& uuid : uuids) { auto uuid_128bit = uuid.To128BitBE(); property_value.insert(property_value.end(), uuid_128bit.begin(), Loading Loading @@ -2005,10 +2025,19 @@ void btif_on_gatt_results(RawAddress bd_addr, BD_NAME bd_name, num_properties++; } if (!transport_le) { /* If services were returned as part of SDP discovery, we will immediately * send them with rest of SDP results in on_service_discovery_results */ if (!transport_le) { return; } else { if (pairing_cb.sdp_over_classic == btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED && com::android::bluetooth::flags::bta_dm_discover_both()) { /* Don't report services yet, they will be reported together once SDP * finishes. */ log::info("will report services later, with SDP results {}", bd_addr); return; } } /* Send the event to the BTIF */ Loading