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

Commit 49a2a25d authored by Himanshu Rawat's avatar Himanshu Rawat Committed by Automerger Merge Worker
Browse files

Merge changes from topic "allow_switching_hid_and_hogp" into main am: 0243fff2 am: 754833b1

parents f5579f16 754833b1
Loading
Loading
Loading
Loading
+701 −274

File changed.

Preview size limit exceeded, changes collapsed.

+52 −102
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#define LOG_TAG "bt_bta_hh"

#include <android_bluetooth_flags.h>
#include <bluetooth/log.h>

#include <cstdint>
@@ -496,74 +497,12 @@ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data)
 *
 ******************************************************************************/
void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  bool hid_available = false;
  bool hogp_available = false;
  bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {};
  bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids),
                                     &remote_uuids};
  const RawAddress& bd_addr = p_data->api_conn.link_spec.addrt.bda;
  p_cb->link_spec = p_data->api_conn.link_spec;
  // Find the device type
  tBT_DEVICE_TYPE dev_type;
  tBLE_ADDR_TYPE addr_type;
  BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);

  // Find which transports are already connected
  bool bredr = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR);
  bool le_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE);

  // Find which services known to be available
  if (btif_storage_get_remote_device_property(&bd_addr,
                                              &remote_properties) == BT_STATUS_SUCCESS) {
    int count = remote_properties.len / sizeof(remote_uuids[0]);
    for (int i = 0; i < count; i++) {
      if (remote_uuids[i].Is16Bit()) {
        if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_HUMAN_INTERFACE) {
          hid_available = true;
        } else if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_LE_HID) {
          hogp_available = true;
        }
      }

      if (hid_available && hogp_available) {
        break;
      }
    }
  }

  /* Decide whether to connect HID or HOGP */
  if (bredr && hid_available) {
    p_cb->is_le_device = false;
  } else if (le_acl && hogp_available) {
    p_cb->is_le_device = true;
  } else if (hid_available) {
    p_cb->is_le_device = false;
  } else if (hogp_available) {
    p_cb->is_le_device = true;
  } else if (bredr) {
    p_cb->is_le_device = false;
  } else if (le_acl || dev_type == BT_DEVICE_TYPE_BLE) {
    p_cb->is_le_device = true;
  } else {
    p_cb->is_le_device = false;
  }

  log::debug(
      "bd_addr:{}, bredr:{}, hid_available:{}, le_acl:{}, hogp_available:{}, "
      "dev_type:{}, is_le_device:{}",
      ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr, hid_available, le_acl,
      hogp_available, dev_type, p_cb->is_le_device);

  // TODO: Use requested address type and transport
  p_cb->link_spec.addrt.type = addr_type;
  p_cb->link_spec.transport =
      p_cb->is_le_device ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;

  p_cb->mode = p_data->api_conn.mode;
  bta_hh_cb.p_cur = p_cb;

  // Initiate HID host connection
  if (p_cb->is_le_device) {
  if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
    bta_hh_le_open_conn(p_cb, p_data->api_conn.link_spec);
  } else {
    bta_hh_bredr_conn(p_cb, p_data);
@@ -584,7 +523,7 @@ void btif_hh_remove_device(tAclLinkSpec link_spec);
void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  CHECK(p_cb != nullptr);

  if (p_cb->is_le_device) {
  if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
    log::debug("Host initiating close to le device:{}",
               ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec));

@@ -635,18 +574,18 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  bta_hh_cb.cnt_num++;

  conn.status = p_cb->status;
  conn.le_hid = p_cb->is_le_device;
  conn.scps_supported = p_cb->scps_supported;
  conn.sub_class = p_cb->sub_class;
  conn.attr_mask = p_cb->attr_mask;
  conn.app_id = p_cb->app_id;

  BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Opened",
                 base::StringPrintf(
                     "%s initiator:%s", (p_cb->is_le_device) ? "le" : "classic",
  BTM_LogHistory(
      kBtmLogTag, p_cb->link_spec.addrt.bda, "Opened",
      base::StringPrintf("%s initiator:%s",
                         bt_transport_text(p_cb->link_spec.transport).c_str(),
                         (p_cb->incoming_conn) ? "remote" : "local"));

  if (!p_cb->is_le_device) {
  if (p_cb->link_spec.transport != BT_TRANSPORT_LE) {
    /* inform role manager */
    bta_sys_conn_open(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);

@@ -928,11 +867,12 @@ void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
      base::StringPrintf("%s %s %s", (l2cap_conn_fail) ? "l2cap_conn_fail" : "",
                         (l2cap_req_fail) ? "l2cap_req_fail" : "",
                         (l2cap_cfg_fail) ? "l2cap_cfg_fail" : "");
  BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed",
                 base::StringPrintf("%s reason %s %s",
                                    (p_cb->is_le_device) ? "le" : "classic",
                                    hid_status_text(hid_status).c_str(),
                                    overlay_fail.c_str()));
  BTM_LogHistory(
      kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed",
      base::StringPrintf(
          "%s reason %s %s",
          (p_cb->link_spec.transport == BT_TRANSPORT_LE) ? "le" : "classic",
          hid_status_text(hid_status).c_str(), overlay_fail.c_str()));

  /* inform role manager */
  bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda);
@@ -975,7 +915,7 @@ void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
 ******************************************************************************/
void bta_hh_get_dscp_act(tBTA_HH_DEV_CB* p_cb,
                         UNUSED_ATTR const tBTA_HH_DATA* p_data) {
  if (p_cb->is_le_device) {
  if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
    if (p_cb->hid_srvc.state >= BTA_HH_SERVICE_DISCOVERED) {
      p_cb->dscp_info.hid_handle = p_cb->hid_handle;
    }
@@ -1009,19 +949,24 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
      dev_info.link_spec = p_dev_info->link_spec;
      /* initialize callback data */
      if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
        if (BTM_UseLeLink(p_data->api_maintdev.link_spec.addrt.bda)) {
        tBT_TRANSPORT transport = p_data->api_maintdev.link_spec.transport;
        if (!IS_FLAG_ENABLED(allow_switching_hid_and_hogp)) {
          transport = BTM_UseLeLink(p_data->api_maintdev.link_spec.addrt.bda)
                          ? BT_TRANSPORT_LE
                          : BT_TRANSPORT_BR_EDR;
        }
        if (transport == BT_TRANSPORT_LE) {
          p_cb->link_spec.transport = BT_TRANSPORT_LE;
          p_cb->is_le_device = true;
          dev_info.handle = bta_hh_le_add_device(p_cb, p_dev_info);
          if (dev_info.handle != BTA_HH_INVALID_HANDLE)
            dev_info.status = BTA_HH_OK;
        } else

        } else if (transport == BT_TRANSPORT_BR_EDR) {
          if (HID_HostAddDev(p_dev_info->link_spec.addrt.bda,
                             p_dev_info->attr_mask,
                             &dev_handle) == HID_SUCCESS) {
            dev_info.handle = dev_handle;
            dev_info.status = BTA_HH_OK;
            p_cb->link_spec.transport = BT_TRANSPORT_BR_EDR;

            /* update DI information */
            bta_hh_update_di_info(
@@ -1038,6 +983,11 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
            /* update cb_index[] map */
            bta_hh_cb.cb_index[dev_handle] = p_cb->index;
          }
        } else {
          log::error("unexpected BT transport: {}",
                     bt_transport_text(transport).c_str());
          break;
        }
      } else /* device already been added */
      {
        dev_info.handle = p_cb->hid_handle;
@@ -1050,7 +1000,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
      dev_info.handle = (uint8_t)p_dev_info->hdr.layer_specific;
      dev_info.link_spec = p_cb->link_spec;

      if (p_cb->is_le_device) {
      if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
        bta_hh_le_remove_dev_bg_conn(p_cb);
        bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
        bta_hh_clean_up_kdev(p_cb);
@@ -1094,7 +1044,7 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  uint16_t event =
      (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) + BTA_HH_GET_RPT_EVT;

  if (p_cb->is_le_device)
  if (p_cb->link_spec.transport == BT_TRANSPORT_LE)
    bta_hh_le_write_dev_act(p_cb, p_data);
  else {
    /* match up BTE/BTA report/boot mode def */
+0 −1
Original line number Diff line number Diff line
@@ -208,7 +208,6 @@ typedef struct {
  uint8_t disc_active;
  tBTA_HH_STATUS status;
  tBTM_STATUS btm_status;
  bool is_le_device;
  tBTA_HH_LE_HID_SRVC hid_srvc;
  uint16_t conn_id;
  bool in_bg_conn;
+13 −12
Original line number Diff line number Diff line
@@ -305,7 +305,8 @@ static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(

  for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
    if (p_dev_cb->in_use &&
        p_dev_cb->link_spec.addrt.bda == link_spec.addrt.bda)
        p_dev_cb->link_spec.addrt.bda == link_spec.addrt.bda &&
        p_dev_cb->link_spec.transport == BT_TRANSPORT_LE)
      return p_dev_cb;
  }
  return NULL;
@@ -1159,7 +1160,6 @@ void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) {
      bta_hh_le_api_disc_act(p_cb);
      return;
    }
    p_cb->is_le_device = true;
    p_cb->in_use = true;
    p_cb->conn_id = p_data->conn_id;

@@ -1667,9 +1667,10 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) {
void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close;

  BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Open failed",
  BTM_LogHistory(
      kBtmLogTag, p_cb->link_spec.addrt.bda, "Open failed",
      base::StringPrintf(
                     "%s reason %s", (p_cb->is_le_device) ? "le" : "classic",
          "%s reason %s", bt_transport_text(p_cb->link_spec.transport).c_str(),
          gatt_disconnection_reason_text(le_close->reason).c_str()));
  log::warn("Open failed for device:{}",
            ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda));
@@ -1679,7 +1680,7 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
    bta_hh_clear_service_cache(p_cb);
  }

  if (p_cb->is_le_device && p_cb->status != BTA_HH_ERR_SDP) {
  if (p_cb->status != BTA_HH_ERR_SDP) {
    log::debug("gd_acl: Re-adding HID device to acceptlist");
    // gd removes from bg list after failed connection
    // Correct the cached state to allow re-add to acceptlist.
@@ -1695,7 +1696,6 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
              .status = (le_close->reason != GATT_CONN_OK) ? BTA_HH_ERR
                                                           : p_cb->status,
              .handle = p_cb->hid_handle,
              .le_hid = true,
              .scps_supported = p_cb->scps_supported,
          },
  };
@@ -1717,9 +1717,10 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
  const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close;

  BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed",
  BTM_LogHistory(
      kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed",
      base::StringPrintf(
                     "%s reason %s", (p_cb->is_le_device) ? "le" : "classic",
          "%s reason %s", bt_transport_text(p_cb->link_spec.transport).c_str(),
          gatt_disconnection_reason_text(le_close->reason).c_str()));

  /* deregister all notification */
+2 −2
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec) {
  /* See how many active devices there are. */
  for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
    /* check if any active/known devices is a match */
    if ((link_spec.addrt.bda == bta_hh_cb.kdev[xx].link_spec.addrt.bda &&
    if ((link_spec == bta_hh_cb.kdev[xx].link_spec &&
         !link_spec.addrt.bda.IsEmpty())) {
#if (BTA_HH_DEBUG == TRUE)
      log::verbose("found kdev_cb[{}] hid_handle={}", xx,
@@ -120,7 +120,7 @@ tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) {
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb) {
  uint8_t index;

  if (p_cb->is_le_device) {
  if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
    uint8_t le_hid_handle = BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle);
    if (le_hid_handle >= BTA_HH_LE_MAX_KNOWN) {
      log::warn("Invalid LE hid_handle {}", p_cb->hid_handle);
Loading