Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6548320 authored by Huirong Liao's avatar Huirong Liao Committed by huirong liao
Browse files

Fix rc connect fail after remove bond

[Description]
Fix sometimes not notify framework connection status issue

[Root Cause]
when DUT is direct connect to RC, user remove bond of the RC.
whatever the RC connected or disconnected, it will not notify
framework the connection status, because bta_hh device will
be clear when remove bond.

[Solution]
so when remove bond and pending device is the connecting device,
then notify the framework disconnected, and cancel direct connect.

Bug: 245424920
Test: connect successfully after remove bond.
net_test_btif_hh unit test pass
Change-Id: Ib1a23c5bcd076e2e0a395b6b9a10fca90355d0df
parent 48196184
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
  }
+57 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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
@@ -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

@@ -285,3 +294,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);
}