Loading system/btif/src/btif_hh.cc +9 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,15 @@ bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) { (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) { btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED; btif_hh_cb.pending_conn_address = RawAddress::kEmpty; /* need to notify up-layer device is disconnected to avoid * state out of sync with up-layer */ do_in_jni_thread(base::Bind( [](RawAddress bd_addrcb) { HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addrcb, BTHH_CONN_STATE_DISCONNECTED); }, *bd_addr)); } return BT_STATUS_FAIL; } Loading system/btif/test/btif_hh_test.cc +57 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {}; extern void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data); extern const bthh_interface_t* btif_hh_get_interface(); extern bt_status_t btif_hh_connect(const RawAddress* bd_addr); extern bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr); namespace test { namespace mock { Loading Loading @@ -93,6 +95,7 @@ std::array<uint8_t, 32> data32 = { }; const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const RawAddress kDeviceAddressConnecting({0x66, 0x55, 0x44, 0x33, 0x22, 0x11}); const uint16_t kHhHandle = 123; // Callback parameters grouped into a structure Loading @@ -102,10 +105,16 @@ struct get_report_cb_t { std::vector<uint8_t> data; } get_report_cb_; struct connection_state_cb_t { RawAddress raw_address; bthh_connection_state_t state; }; // Globals allow usage within function pointers std::promise<bt_cb_thread_evt> g_thread_evt_promise; std::promise<bt_status_t> g_status_promise; std::promise<get_report_cb_t> g_bthh_callbacks_get_report_promise; std::promise<connection_state_cb_t> g_bthh_connection_state_promise; } // namespace Loading Loading @@ -281,3 +290,51 @@ TEST_F(BtifHhWithDevice, BTA_HH_GET_RPT_EVT) { ASSERT_EQ(data, report.data[i++]); } } class BtifHHVirtualUnplugTest : public BtifHhAdapterReady { protected: void SetUp() override { BtifHhAdapterReady::SetUp(); bthh_callbacks.connection_state_cb = [](RawAddress* bd_addr, bthh_connection_state_t state) { connection_state_cb_t connection_state = { .raw_address = *bd_addr, .state = state, }; g_bthh_connection_state_promise.set_value(connection_state); }; } void TearDown() override { bthh_callbacks.connection_state_cb = [](RawAddress* bd_addr, bthh_connection_state_t state) {}; BtifHhAdapterReady::TearDown(); } }; TEST_F(BtifHHVirtualUnplugTest, test_btif_hh_virtual_unplug_device_not_open) { g_bthh_connection_state_promise = std::promise<connection_state_cb_t>(); auto future = g_bthh_connection_state_promise.get_future(); /* Make device in connecting state */ ASSERT_EQ(btif_hh_connect(&kDeviceAddressConnecting), BT_STATUS_SUCCESS); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); auto res = future.get(); ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str()); ASSERT_EQ(BTHH_CONN_STATE_CONNECTING, res.state); g_bthh_connection_state_promise = std::promise<connection_state_cb_t>(); future = g_bthh_connection_state_promise.get_future(); btif_hh_virtual_unplug(&kDeviceAddressConnecting); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); // Verify data was delivered res = future.get(); ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str()); ASSERT_EQ(BTHH_CONN_STATE_DISCONNECTED, res.state); } Loading
system/btif/src/btif_hh.cc +9 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,15 @@ bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) { (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) { btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED; btif_hh_cb.pending_conn_address = RawAddress::kEmpty; /* need to notify up-layer device is disconnected to avoid * state out of sync with up-layer */ do_in_jni_thread(base::Bind( [](RawAddress bd_addrcb) { HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addrcb, BTHH_CONN_STATE_DISCONNECTED); }, *bd_addr)); } return BT_STATUS_FAIL; } Loading
system/btif/test/btif_hh_test.cc +57 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {}; extern void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data); extern const bthh_interface_t* btif_hh_get_interface(); extern bt_status_t btif_hh_connect(const RawAddress* bd_addr); extern bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr); namespace test { namespace mock { Loading Loading @@ -93,6 +95,7 @@ std::array<uint8_t, 32> data32 = { }; const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const RawAddress kDeviceAddressConnecting({0x66, 0x55, 0x44, 0x33, 0x22, 0x11}); const uint16_t kHhHandle = 123; // Callback parameters grouped into a structure Loading @@ -102,10 +105,16 @@ struct get_report_cb_t { std::vector<uint8_t> data; } get_report_cb_; struct connection_state_cb_t { RawAddress raw_address; bthh_connection_state_t state; }; // Globals allow usage within function pointers std::promise<bt_cb_thread_evt> g_thread_evt_promise; std::promise<bt_status_t> g_status_promise; std::promise<get_report_cb_t> g_bthh_callbacks_get_report_promise; std::promise<connection_state_cb_t> g_bthh_connection_state_promise; } // namespace Loading Loading @@ -281,3 +290,51 @@ TEST_F(BtifHhWithDevice, BTA_HH_GET_RPT_EVT) { ASSERT_EQ(data, report.data[i++]); } } class BtifHHVirtualUnplugTest : public BtifHhAdapterReady { protected: void SetUp() override { BtifHhAdapterReady::SetUp(); bthh_callbacks.connection_state_cb = [](RawAddress* bd_addr, bthh_connection_state_t state) { connection_state_cb_t connection_state = { .raw_address = *bd_addr, .state = state, }; g_bthh_connection_state_promise.set_value(connection_state); }; } void TearDown() override { bthh_callbacks.connection_state_cb = [](RawAddress* bd_addr, bthh_connection_state_t state) {}; BtifHhAdapterReady::TearDown(); } }; TEST_F(BtifHHVirtualUnplugTest, test_btif_hh_virtual_unplug_device_not_open) { g_bthh_connection_state_promise = std::promise<connection_state_cb_t>(); auto future = g_bthh_connection_state_promise.get_future(); /* Make device in connecting state */ ASSERT_EQ(btif_hh_connect(&kDeviceAddressConnecting), BT_STATUS_SUCCESS); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); auto res = future.get(); ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str()); ASSERT_EQ(BTHH_CONN_STATE_CONNECTING, res.state); g_bthh_connection_state_promise = std::promise<connection_state_cb_t>(); future = g_bthh_connection_state_promise.get_future(); btif_hh_virtual_unplug(&kDeviceAddressConnecting); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); // Verify data was delivered res = future.get(); ASSERT_STREQ(kDeviceAddressConnecting.ToString().c_str(), res.raw_address.ToString().c_str()); ASSERT_EQ(BTHH_CONN_STATE_DISCONNECTED, res.state); }