Move HID ids to common HID code

The HID ids (accessory ids or UHID ids) were defined by the keyboard and
mouse implementations.

Instead, define them in the common HID part, and make that id part of
the sc_hid_event.

This prepares the introduction of gamepad support, which will handle
several gamepads (and ids) in the common HID gamepad code.

PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This commit is contained in:
Romain Vimont 2024-09-06 23:08:08 +02:00
parent dad04bf138
commit 2dd02ebb80
11 changed files with 30 additions and 42 deletions

View file

@ -8,6 +8,7 @@
#define SC_HID_MAX_SIZE 8
struct sc_hid_event {
uint16_t hid_id;
uint8_t data[SC_HID_MAX_SIZE];
uint8_t size;
};

View file

@ -200,6 +200,7 @@ const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN =
static void
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
hid_event->hid_id = SC_HID_ID_KEYBOARD;
hid_event->size = SC_HID_KEYBOARD_EVENT_SIZE;
uint8_t *data = hid_event->data;

View file

@ -14,6 +14,8 @@
// 0x65 is Application, typically AT-101 Keyboard ends here.
#define SC_HID_KEYBOARD_KEYS 0x66
#define SC_HID_ID_KEYBOARD 1
extern const uint8_t SC_HID_KEYBOARD_REPORT_DESC[];
extern const size_t SC_HID_KEYBOARD_REPORT_DESC_LEN;

View file

@ -126,6 +126,7 @@ const size_t SC_HID_MOUSE_REPORT_DESC_LEN =
static void
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
hid_event->hid_id = SC_HID_ID_MOUSE;
hid_event->size = SC_HID_MOUSE_EVENT_SIZE;
// Leave hid_event->data uninitialized, it will be fully initialized by
// callers

View file

@ -8,6 +8,8 @@
#include "hid/hid_event.h"
#include "input_events.h"
#define SC_HID_ID_MOUSE 2
extern const uint8_t SC_HID_MOUSE_REPORT_DESC[];
extern const size_t SC_HID_MOUSE_REPORT_DESC_LEN;

View file

@ -9,14 +9,12 @@
#define DOWNCAST_RECEIVER(UR) \
container_of(UR, struct sc_keyboard_uhid, uhid_receiver)
#define UHID_KEYBOARD_ID 1
static void
sc_keyboard_uhid_send_input(struct sc_keyboard_uhid *kb,
const struct sc_hid_event *event) {
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT;
msg.uhid_input.id = UHID_KEYBOARD_ID;
msg.uhid_input.id = event->hid_id;
assert(event->size <= SC_HID_MAX_SIZE);
memcpy(msg.uhid_input.data, event->data, event->size);
@ -143,13 +141,13 @@ sc_keyboard_uhid_init(struct sc_keyboard_uhid *kb,
.process_output = sc_uhid_receiver_process_output,
};
kb->uhid_receiver.id = UHID_KEYBOARD_ID;
kb->uhid_receiver.id = SC_HID_ID_KEYBOARD;
kb->uhid_receiver.ops = &uhid_receiver_ops;
sc_uhid_devices_add_receiver(uhid_devices, &kb->uhid_receiver);
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = UHID_KEYBOARD_ID;
msg.uhid_create.id = SC_HID_ID_KEYBOARD;
msg.uhid_create.report_desc = SC_HID_KEYBOARD_REPORT_DESC;
msg.uhid_create.report_desc_size = SC_HID_KEYBOARD_REPORT_DESC_LEN;
if (!sc_controller_push_msg(controller, &msg)) {

View file

@ -7,14 +7,12 @@
/** Downcast mouse processor to mouse_uhid */
#define DOWNCAST(MP) container_of(MP, struct sc_mouse_uhid, mouse_processor)
#define UHID_MOUSE_ID 2
static void
sc_mouse_uhid_send_input(struct sc_mouse_uhid *mouse,
const struct sc_hid_event *event, const char *name) {
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT;
msg.uhid_input.id = UHID_MOUSE_ID;
msg.uhid_input.id = event->hid_id;
assert(event->size <= SC_HID_MAX_SIZE);
memcpy(msg.uhid_input.data, event->data, event->size);
@ -77,7 +75,7 @@ sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
struct sc_control_msg msg;
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
msg.uhid_create.id = UHID_MOUSE_ID;
msg.uhid_create.id = SC_HID_ID_MOUSE;
msg.uhid_create.report_desc = SC_HID_MOUSE_REPORT_DESC;
msg.uhid_create.report_desc_size = SC_HID_MOUSE_REPORT_DESC_LEN;
if (!sc_controller_push_msg(controller, &msg)) {

View file

@ -1,6 +1,7 @@
#include "util/log.h"
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include "aoa_hid.h"
@ -18,14 +19,14 @@
#define SC_AOA_EVENT_QUEUE_MAX 64
static void
sc_hid_event_log(uint16_t accessory_id, const struct sc_hid_event *event) {
sc_hid_event_log(const struct sc_hid_event *event) {
// HID Event: [00] FF FF FF FF...
assert(event->size);
char *hex = sc_str_to_hex_string(event->data, event->size);
if (!hex) {
return;
}
LOGV("HID Event: [%d] %s", accessory_id, hex);
LOGV("HID Event: [%" PRIu16 "] %s", event->hid_id, hex);
free(hex);
}
@ -146,14 +147,13 @@ sc_aoa_setup_hid(struct sc_aoa *aoa, uint16_t accessory_id,
}
static bool
sc_aoa_send_hid_event(struct sc_aoa *aoa, uint16_t accessory_id,
const struct sc_hid_event *event) {
sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
uint8_t request = ACCESSORY_SEND_HID_EVENT;
// <https://source.android.com/devices/accessories/aoa2.html#hid-support>
// value (arg0): accessory assigned ID for the HID device
// index (arg1): 0 (unused)
uint16_t value = accessory_id;
uint16_t value = event->hid_id;
uint16_t index = 0;
unsigned char *data = (uint8_t *) event->data; // discard const
uint16_t length = event->size;
@ -194,11 +194,10 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id) {
bool
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
uint16_t accessory_id,
const struct sc_hid_event *event,
uint64_t ack_to_wait) {
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
sc_hid_event_log(accessory_id, event);
sc_hid_event_log(event);
}
sc_mutex_lock(&aoa->mutex);
@ -209,7 +208,6 @@ sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
struct sc_aoa_event *aoa_event =
sc_vecdeque_push_hole_noresize(&aoa->queue);
aoa_event->hid = *event;
aoa_event->accessory_id = accessory_id;
aoa_event->ack_to_wait = ack_to_wait;
if (was_empty) {
@ -265,7 +263,7 @@ run_aoa_thread(void *data) {
}
}
bool ok = sc_aoa_send_hid_event(aoa, event.accessory_id, &event.hid);
bool ok = sc_aoa_send_hid_event(aoa, &event.hid);
if (!ok) {
LOGW("Could not send HID event to USB device");
}

View file

@ -15,7 +15,6 @@
struct sc_aoa_event {
struct sc_hid_event hid;
uint16_t accessory_id;
uint64_t ack_to_wait;
};
@ -56,14 +55,12 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id);
bool
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
uint16_t accessory_id,
const struct sc_hid_event *event,
uint64_t ack_to_wait);
static inline bool
sc_aoa_push_hid_event(struct sc_aoa *aoa, uint16_t accessory_id,
const struct sc_hid_event *event) {
return sc_aoa_push_hid_event_with_ack_to_wait(aoa, accessory_id, event,
sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
return sc_aoa_push_hid_event_with_ack_to_wait(aoa, event,
SC_SEQUENCE_INVALID);
}

View file

@ -8,8 +8,6 @@
/** Downcast key processor to keyboard_aoa */
#define DOWNCAST(KP) container_of(KP, struct sc_keyboard_aoa, key_processor)
#define HID_KEYBOARD_ACCESSORY_ID 1
static bool
push_mod_lock_state(struct sc_keyboard_aoa *kb, uint16_t mods_state) {
struct sc_hid_event hid_event;
@ -18,8 +16,7 @@ push_mod_lock_state(struct sc_keyboard_aoa *kb, uint16_t mods_state) {
return true;
}
if (!sc_aoa_push_hid_event(kb->aoa, HID_KEYBOARD_ACCESSORY_ID,
&hid_event)) {
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
LOGW("Could not request HID event (mod lock state)");
return false;
}
@ -58,9 +55,7 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
// synchronization is acknowledged by the server, otherwise it could
// paste the old clipboard content.
if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa,
HID_KEYBOARD_ACCESSORY_ID,
&hid_event,
if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa, &hid_event,
ack_to_wait)) {
LOGW("Could not request HID event (key)");
}
@ -71,7 +66,7 @@ bool
sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) {
kb->aoa = aoa;
bool ok = sc_aoa_setup_hid(aoa, HID_KEYBOARD_ACCESSORY_ID,
bool ok = sc_aoa_setup_hid(aoa, SC_HID_ID_KEYBOARD,
SC_HID_KEYBOARD_REPORT_DESC,
SC_HID_KEYBOARD_REPORT_DESC_LEN);
if (!ok) {
@ -103,7 +98,7 @@ sc_keyboard_aoa_init(struct sc_keyboard_aoa *kb, struct sc_aoa *aoa) {
void
sc_keyboard_aoa_destroy(struct sc_keyboard_aoa *kb) {
// Unregister HID keyboard so the soft keyboard shows again on Android
bool ok = sc_aoa_unregister_hid(kb->aoa, HID_KEYBOARD_ACCESSORY_ID);
bool ok = sc_aoa_unregister_hid(kb->aoa, SC_HID_ID_KEYBOARD);
if (!ok) {
LOGW("Could not unregister HID keyboard");
}

View file

@ -9,8 +9,6 @@
/** Downcast mouse processor to mouse_aoa */
#define DOWNCAST(MP) container_of(MP, struct sc_mouse_aoa, mouse_processor)
#define HID_MOUSE_ACCESSORY_ID 2
static void
sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
const struct sc_mouse_motion_event *event) {
@ -19,8 +17,7 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event;
sc_hid_mouse_event_from_motion(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID,
&hid_event)) {
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
LOGW("Could not request HID event (mouse motion)");
}
}
@ -33,8 +30,7 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event;
sc_hid_mouse_event_from_click(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID,
&hid_event)) {
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
LOGW("Could not request HID event (mouse click)");
}
}
@ -47,8 +43,7 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
struct sc_hid_event hid_event;
sc_hid_mouse_event_from_scroll(&hid_event, event);
if (!sc_aoa_push_hid_event(mouse->aoa, HID_MOUSE_ACCESSORY_ID,
&hid_event)) {
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
LOGW("Could not request HID event (mouse scroll)");
}
}
@ -57,7 +52,7 @@ bool
sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
mouse->aoa = aoa;
bool ok = sc_aoa_setup_hid(aoa, HID_MOUSE_ACCESSORY_ID,
bool ok = sc_aoa_setup_hid(aoa, SC_HID_ID_MOUSE,
SC_HID_MOUSE_REPORT_DESC,
SC_HID_MOUSE_REPORT_DESC_LEN);
if (!ok) {
@ -82,7 +77,7 @@ sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
void
sc_mouse_aoa_destroy(struct sc_mouse_aoa *mouse) {
bool ok = sc_aoa_unregister_hid(mouse->aoa, HID_MOUSE_ACCESSORY_ID);
bool ok = sc_aoa_unregister_hid(mouse->aoa, SC_HID_ID_MOUSE);
if (!ok) {
LOGW("Could not unregister HID mouse");
}