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

Commit f2a2180e authored by Archie Pusaka's avatar Archie Pusaka Committed by Gerrit Code Review
Browse files

Merge changes I136c7800,I38073d4a into main

* changes:
  hh: Queue input data when before receiving UHID_OPEN
  hh: run all uhid exchanges in uhid thread
parents dd4b1f87 6784dd72
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@
#ifndef BTA_HH_CO_H
#ifndef BTA_HH_CO_H
#define BTA_HH_CO_H
#define BTA_HH_CO_H


#include <linux/uhid.h>

#include <cstdint>
#include <cstdint>


#include "bta/include/bta_hh_api.h"
#include "bta/include/bta_hh_api.h"
@@ -37,6 +39,21 @@ typedef struct {
  uint16_t char_inst_id;
  uint16_t char_inst_id;
} tBTA_HH_RPT_CACHE_ENTRY;
} tBTA_HH_RPT_CACHE_ENTRY;


typedef enum : uint8_t {
  BTA_HH_UHID_INBOUND_INPUT_EVT,
  BTA_HH_UHID_INBOUND_CLOSE_EVT,
  BTA_HH_UHID_INBOUND_DSCP_EVT,
  BTA_HH_UHID_INBOUND_GET_REPORT_EVT,
  BTA_HH_UHID_INBOUND_SET_REPORT_EVT,
} tBTA_HH_UHID_INBOUND_EVT_TYPE;

typedef struct {
  tBTA_HH_UHID_INBOUND_EVT_TYPE type;
  union {
    uhid_event uhid;
  };
} tBTA_HH_TO_UHID_EVT;

/*******************************************************************************
/*******************************************************************************
 *
 *
 * Function         bta_hh_co_data
 * Function         bta_hh_co_data
+397 −73

File changed.

Preview size limit exceeded, changes collapsed.

+9 −5
Original line number Original line Diff line number Diff line
@@ -84,18 +84,20 @@ inline std::string btif_hh_status_text(const BTIF_HH_STATUS& status) {
  }
  }
}
}


/* Supposedly is exclusive to uhid thread, but now is still accessed by btif. */
/* Uhid thread has exclusive access to this block. */
/* TODO: remove btif_hh_uhid_t from btif_hh_device_t. */
typedef struct {
typedef struct {
  int fd;
  int fd;                // for interfacing with uhid
  int internal_recv_fd;  // for receiving internal events in uhid thread
  uint8_t dev_handle;
  uint8_t dev_handle;
  tAclLinkSpec link_spec;
  tAclLinkSpec link_spec;
  uint8_t hh_keep_polling;
  uint8_t hh_keep_polling;  // Deprecated with the aflags hid_report_queuing.
                            // TODO: remove after launching the aflag.
  bool ready_for_data;
  bool ready_for_data;
  fixed_queue_t* get_rpt_id_queue;
  fixed_queue_t* get_rpt_id_queue;
#if ENABLE_UHID_SET_REPORT
#if ENABLE_UHID_SET_REPORT
  fixed_queue_t* set_rpt_id_queue;
  fixed_queue_t* set_rpt_id_queue;
#endif  // ENABLE_UHID_SET_REPORT
#endif  // ENABLE_UHID_SET_REPORT
  fixed_queue_t* input_queue;  // to store the inputs before uhid is ready.
} btif_hh_uhid_t;
} btif_hh_uhid_t;


/* Control block to maintain properties of devices */
/* Control block to maintain properties of devices */
@@ -106,10 +108,12 @@ typedef struct {
  tBTA_HH_ATTR_MASK attr_mask;
  tBTA_HH_ATTR_MASK attr_mask;
  uint8_t sub_class;
  uint8_t sub_class;
  uint8_t app_id;
  uint8_t app_id;
  int internal_send_fd;  // for sending internal events from btif
  pthread_t hh_poll_thread_id;
  pthread_t hh_poll_thread_id;
  alarm_t* vup_timer;
  alarm_t* vup_timer;
  bool local_vup;  // Indicated locally initiated VUP
  bool local_vup;  // Indicated locally initiated VUP
  btif_hh_uhid_t uhid;
  btif_hh_uhid_t uhid;  // Deprecated with the aflags hid_report_queuing.
                        // TODO: remove after launching the aflag.
} btif_hh_device_t;
} btif_hh_device_t;


/* Control block to maintain properties of devices */
/* Control block to maintain properties of devices */
+25 −11
Original line number Original line Diff line number Diff line
@@ -295,7 +295,9 @@ static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) {
  if (keylockstates) {
  if (keylockstates) {
    log::verbose("Sending hid report to kernel indicating lock key state 0x{:x}", keylockstates);
    log::verbose("Sending hid report to kernel indicating lock key state 0x{:x}", keylockstates);
    usleep(200000);
    usleep(200000);
    toggle_os_keylockstates(p_dev->uhid.fd, keylockstates);
    int fd = (com::android::bluetooth::flags::hid_report_queuing() ? p_dev->internal_send_fd
                                                                   : p_dev->uhid.fd);
    toggle_os_keylockstates(fd, keylockstates);
  } else {
  } else {
    log::verbose("NOT sending hid report to kernel indicating lock key state 0x{:x}",
    log::verbose("NOT sending hid report to kernel indicating lock key state 0x{:x}",
                 keylockstates);
                 keylockstates);
@@ -557,8 +559,11 @@ static void hh_open_handler(tBTA_HH_CONN& conn) {


  log::info("Found device, getting dscp info for handle {}", conn.handle);
  log::info("Found device, getting dscp info for handle {}", conn.handle);


  if (!com::android::bluetooth::flags::hid_report_queuing()) {
    // link_spec and status is to be set in bta_hh_co_open instead.
    p_dev->link_spec = conn.link_spec;
    p_dev->link_spec = conn.link_spec;
    p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
    p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
  }
  hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_CONNECTED);
  hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_CONNECTED);
  // Send set_idle if the peer_device is a keyboard
  // Send set_idle if the peer_device is a keyboard
  if (check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_KEYBOARD) ||
  if (check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_KEYBOARD) ||
@@ -686,9 +691,11 @@ void btif_hh_remove_device(const tAclLinkSpec& link_spec) {
    bta_hh_co_close(p_dev);
    bta_hh_co_close(p_dev);
    p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
    p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
    p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
    if (!com::android::bluetooth::flags::hid_report_queuing()) {
      p_dev->uhid.ready_for_data = false;
      p_dev->uhid.ready_for_data = false;
    }
    }
  }
  }
}


bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest, tBTA_HH_DEV_DSCP_INFO* src) {
bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest, tBTA_HH_DEV_DSCP_INFO* src) {
  memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
  memset(dest, 0, sizeof(tBTA_HH_DEV_DSCP_INFO));
@@ -1000,8 +1007,10 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
                   p_data->dev_status.handle);
                   p_data->dev_status.handle);
      p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
      p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
      if (p_dev != NULL) {
      if (p_dev != NULL) {
        int fd = (com::android::bluetooth::flags::hid_report_queuing() ? p_dev->internal_send_fd
                                                                       : p_dev->uhid.fd);
        BTHH_STATE_UPDATE(p_dev->link_spec, BTHH_CONN_STATE_DISCONNECTING);
        BTHH_STATE_UPDATE(p_dev->link_spec, BTHH_CONN_STATE_DISCONNECTING);
        log::verbose("uhid fd={} local_vup={}", p_dev->uhid.fd, p_dev->local_vup);
        log::verbose("uhid fd={} local_vup={}", fd, p_dev->local_vup);
        btif_hh_stop_vup_timer(p_dev->link_spec);
        btif_hh_stop_vup_timer(p_dev->link_spec);
        /* If this is a locally initiated VUP, remove the bond as ACL got
        /* If this is a locally initiated VUP, remove the bond as ACL got
         *  disconnected while VUP being processed.
         *  disconnected while VUP being processed.
@@ -1131,7 +1140,9 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
        return;
        return;
      }
      }


      if (p_dev->uhid.fd < 0) {
      int fd = (com::android::bluetooth::flags::hid_report_queuing() ? p_dev->internal_send_fd
                                                                     : p_dev->uhid.fd);
      if (fd < 0) {
        log::error("BTA_HH_GET_DSCP_EVT: failed to find the uhid driver...");
        log::error("BTA_HH_GET_DSCP_EVT: failed to find the uhid driver...");
        return;
        return;
      }
      }
@@ -2042,8 +2053,10 @@ static void cleanup(void) {
  }
  }
  for (i = 0; i < BTIF_HH_MAX_HID; i++) {
  for (i = 0; i < BTIF_HH_MAX_HID; i++) {
    p_dev = &btif_hh_cb.devices[i];
    p_dev = &btif_hh_cb.devices[i];
    if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->uhid.fd >= 0) {
    int fd = (com::android::bluetooth::flags::hid_report_queuing() ? p_dev->internal_send_fd
      log::verbose("Closing uhid fd = {}", p_dev->uhid.fd);
                                                                   : p_dev->uhid.fd);
    if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && fd >= 0) {
      log::verbose("Closing uhid fd = {}", fd);
      bta_hh_co_close(p_dev);
      bta_hh_co_close(p_dev);
    }
    }
  }
  }
@@ -2126,10 +2139,11 @@ void DumpsysHid(int fd) {
  for (unsigned i = 0; i < BTIF_HH_MAX_HID; i++) {
  for (unsigned i = 0; i < BTIF_HH_MAX_HID; i++) {
    const btif_hh_device_t* p_dev = &btif_hh_cb.devices[i];
    const btif_hh_device_t* p_dev = &btif_hh_cb.devices[i];
    if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) {
    if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) {
      LOG_DUMPSYS(fd, "  %u: addr:%s fd:%d state:%s ready:%s thread_id:%d handle:%d", i,
      int fd = (com::android::bluetooth::flags::hid_report_queuing() ? p_dev->internal_send_fd
                  p_dev->link_spec.ToRedactedStringForLogging().c_str(), p_dev->uhid.fd,
                                                                     : p_dev->uhid.fd);
      LOG_DUMPSYS(fd, "  %u: addr:%s fd:%d state:%s thread_id:%d handle:%d", i,
                  p_dev->link_spec.ToRedactedStringForLogging().c_str(), fd,
                  bthh_connection_state_text(p_dev->dev_status).c_str(),
                  bthh_connection_state_text(p_dev->dev_status).c_str(),
                  (p_dev->uhid.ready_for_data) ? ("T") : ("F"),
                  static_cast<int>(p_dev->hh_poll_thread_id), p_dev->dev_handle);
                  static_cast<int>(p_dev->hh_poll_thread_id), p_dev->dev_handle);
    }
    }
  }
  }