Only open HID devices that might have a HIDAPI driver available

This prevents an OS prompt for every connected device when running on Android
This commit is contained in:
Sam Lantinga 2022-10-07 11:29:49 -07:00
parent 31991ab851
commit 33050fea39
4 changed files with 51 additions and 49 deletions

View File

@ -194,7 +194,7 @@ HIDAPI_DriverPS4_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name,
} }
if (SONY_THIRDPARTY_VENDOR(vendor_id)) { if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
if (device) { if (device && device->dev) {
if ((size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data))) == 48 && if ((size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
data[2] == 0x27) { data[2] == 0x27) {
/* Supported third party controller */ /* Supported third party controller */

View File

@ -277,7 +277,7 @@ HIDAPI_DriverPS5_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name,
} }
if (SONY_THIRDPARTY_VENDOR(vendor_id)) { if (SONY_THIRDPARTY_VENDOR(vendor_id)) {
if (device) { if (device && device->dev) {
if ((size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data))) == 48 && if ((size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data))) == 48 &&
data[2] == 0x28) { data[2] == 0x28) {
/* Supported third party controller */ /* Supported third party controller */

View File

@ -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) 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 (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 */ /* This might be a Kinvoca Joy-Con that reports VID/PID as a Switch Pro controller */
ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device); ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device);
if (eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || if (eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||

View File

@ -359,59 +359,61 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
return; /* Already setup */ return; /* Already setup */
} }
/* Make sure we can open the device and leave it open for the driver */ if (HIDAPI_GetDeviceDriver(device)) {
if (device->num_children == 0) { /* We might have a device driver for this device, try opening it and see */
/* On Android we need to leave joysticks unlocked because it calls if (device->num_children == 0) {
* out to the main thread for permissions and the main thread can /* On Android we need to leave joysticks unlocked because it calls
* be in the process of handling controller input. * 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 *
*/ * See https://github.com/libsdl-org/SDL/issues/6347 for details
SDL_HIDAPI_Device *curr; */
SDL_hid_device *dev; SDL_HIDAPI_Device *curr;
char *path; SDL_hid_device *dev;
char *path;
SDL_AssertJoysticksLocked(); SDL_AssertJoysticksLocked();
path = SDL_strdup(device->path); path = SDL_strdup(device->path);
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
dev = SDL_hid_open_path(path, 0); dev = SDL_hid_open_path(path, 0);
SDL_LockJoysticks(); SDL_LockJoysticks();
SDL_free(path); SDL_free(path);
/* Make sure the device didn't get removed while opening the HID 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) { for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
continue; continue;
}
if (!curr) {
*removed = SDL_TRUE;
if (dev) {
SDL_hid_close(dev);
} }
return; if (!curr) {
*removed = SDL_TRUE;
if (dev) {
SDL_hid_close(dev);
}
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);
device->dev = dev;
} }
if (!dev) { device->driver = HIDAPI_GetDeviceDriver(device);
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"HIDAPI_SetupDeviceDriver() couldn't open %s: %s\n", /* Initialize the device, which may cause a connected event */
device->path, SDL_GetError()); if (device->driver && !device->driver->InitDevice(device)) {
return; HIDAPI_CleanupDeviceDriver(device);
} }
SDL_hid_set_nonblocking(dev, 1);
device->dev = dev; if (!device->driver && device->dev) {
} /* No driver claimed this device, go ahead and close it */
SDL_hid_close(device->dev);
device->driver = HIDAPI_GetDeviceDriver(device); device->dev = NULL;
}
/* 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;
} }
} }