From 33050fea3997c7d0c1cf709fa5a70f5462e35ad9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 7 Oct 2022 11:29:49 -0700
Subject: [PATCH] Only open HID devices that might have a HIDAPI driver
available
This prevents an OS prompt for every connected device when running on Android
---
src/joystick/hidapi/SDL_hidapi_ps4.c | 2 +-
src/joystick/hidapi/SDL_hidapi_ps5.c | 2 +-
src/joystick/hidapi/SDL_hidapi_switch.c | 2 +-
src/joystick/hidapi/SDL_hidapijoystick.c | 96 ++++++++++++------------
4 files changed, 52 insertions(+), 50 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index 40884dade0f9..7bccd5fa038d 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps4.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps4.c
@@ -194,7 +194,7 @@ HIDAPI_DriverPS4_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name,
}
if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
- if (device) {
+ if (device && device->dev) {
if ((size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
data[2] == 0x27) {
/* Supported third party controller */
diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c
index 0e41d2e5aa83..4b2255d17c01 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps5.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps5.c
@@ -277,7 +277,7 @@ HIDAPI_DriverPS5_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name,
}
if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
- if (device) {
+ if (device && device->dev) {
if ((size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
data[2] == 0x28) {
/* Supported third party controller */
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 8eaadb31e24a..0bf66d856f94 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -1106,7 +1106,7 @@ static SDL_bool
HIDAPI_DriverJoyCons_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
if (vendor_id == USB_VENDOR_NINTENDO) {
- if (product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO && device) {
+ if (product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO && device && device->dev) {
/* This might be a Kinvoca Joy-Con that reports VID/PID as a Switch Pro controller */
ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device);
if (eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index ee56e5669455..8cf9596bb045 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -359,59 +359,61 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
return; /* Already setup */
}
- /* Make sure we can open the device and leave it open for the driver */
- if (device->num_children == 0) {
- /* On Android we need to leave joysticks unlocked because it calls
- * out to the main thread for permissions and the main thread can
- * be in the process of handling controller input.
- *
- * See https://github.com/libsdl-org/SDL/issues/6347 for details
- */
- SDL_HIDAPI_Device *curr;
- SDL_hid_device *dev;
- char *path;
-
- SDL_AssertJoysticksLocked();
- path = SDL_strdup(device->path);
- SDL_UnlockJoysticks();
- dev = SDL_hid_open_path(path, 0);
- SDL_LockJoysticks();
- SDL_free(path);
-
- /* Make sure the device didn't get removed while opening the HID path */
- for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
- continue;
- }
- if (!curr) {
- *removed = SDL_TRUE;
- if (dev) {
- SDL_hid_close(dev);
+ if (HIDAPI_GetDeviceDriver(device)) {
+ /* We might have a device driver for this device, try opening it and see */
+ if (device->num_children == 0) {
+ /* On Android we need to leave joysticks unlocked because it calls
+ * out to the main thread for permissions and the main thread can
+ * be in the process of handling controller input.
+ *
+ * See https://github.com/libsdl-org/SDL/issues/6347 for details
+ */
+ SDL_HIDAPI_Device *curr;
+ SDL_hid_device *dev;
+ char *path;
+
+ SDL_AssertJoysticksLocked();
+ path = SDL_strdup(device->path);
+ SDL_UnlockJoysticks();
+ dev = SDL_hid_open_path(path, 0);
+ SDL_LockJoysticks();
+ SDL_free(path);
+
+ /* Make sure the device didn't get removed while opening the HID path */
+ for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
+ continue;
+ }
+ if (!curr) {
+ *removed = SDL_TRUE;
+ if (dev) {
+ SDL_hid_close(dev);
+ }
+ return;
}
- return;
- }
- if (!dev) {
- SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
- "HIDAPI_SetupDeviceDriver() couldn't open %s: %s\n",
- device->path, SDL_GetError());
- return;
- }
- SDL_hid_set_nonblocking(dev, 1);
+ if (!dev) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
+ "HIDAPI_SetupDeviceDriver() couldn't open %s: %s\n",
+ device->path, SDL_GetError());
+ return;
+ }
+ SDL_hid_set_nonblocking(dev, 1);
- device->dev = dev;
- }
+ device->dev = dev;
+ }
- device->driver = HIDAPI_GetDeviceDriver(device);
+ device->driver = HIDAPI_GetDeviceDriver(device);
- /* Initialize the device, which may cause a connected event */
- if (device->driver && !device->driver->InitDevice(device)) {
- HIDAPI_CleanupDeviceDriver(device);
- }
+ /* Initialize the device, which may cause a connected event */
+ if (device->driver && !device->driver->InitDevice(device)) {
+ HIDAPI_CleanupDeviceDriver(device);
+ }
- if (!device->driver && device->dev) {
- /* No driver claimed this device, go ahead and close it */
- SDL_hid_close(device->dev);
- device->dev = NULL;
+ if (!device->driver && device->dev) {
+ /* No driver claimed this device, go ahead and close it */
+ SDL_hid_close(device->dev);
+ device->dev = NULL;
+ }
}
}