diff --git a/rpcs3/Input/ds3_pad_handler.cpp b/rpcs3/Input/ds3_pad_handler.cpp index c2cf89afec..9e12bbd472 100644 --- a/rpcs3/Input/ds3_pad_handler.cpp +++ b/rpcs3/Input/ds3_pad_handler.cpp @@ -218,7 +218,7 @@ void ds3_pad_handler::init_config(cfg_pad* cfg) cfg->from_default(); } -void ds3_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) +void ds3_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) { if (!hidDevice) { @@ -508,12 +508,16 @@ bool ds3_pad_handler::get_is_right_stick(const std::shared_ptr& /*dev PadHandlerBase::connection ds3_pad_handler::update_connection(const std::shared_ptr& device) { ds3_device* dev = static_cast(device.get()); - if (!dev || dev->path.empty()) + if (!dev || dev->path == hid_enumerated_device_default) return connection::disconnected; if (dev->hidDevice == nullptr) { +#ifdef ANDROID + if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) +#else if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) +#endif { if (hid_set_nonblocking(hid_dev, 1) == -1) { diff --git a/rpcs3/Input/ds3_pad_handler.h b/rpcs3/Input/ds3_pad_handler.h index b6b423eff3..47dfbf4587 100644 --- a/rpcs3/Input/ds3_pad_handler.h +++ b/rpcs3/Input/ds3_pad_handler.h @@ -145,7 +145,7 @@ public: private: ds3_pad_handler::DataStatus get_data(ds3_device* ds3dev) override; int send_output_report(ds3_device* ds3dev) override; - void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) override; + void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) override; bool get_is_left_trigger(const std::shared_ptr& device, u64 keyCode) override; bool get_is_right_trigger(const std::shared_ptr& device, u64 keyCode) override; diff --git a/rpcs3/Input/ds4_pad_handler.cpp b/rpcs3/Input/ds4_pad_handler.cpp index 497db72e5d..5ad4f8f3af 100644 --- a/rpcs3/Input/ds4_pad_handler.cpp +++ b/rpcs3/Input/ds4_pad_handler.cpp @@ -556,7 +556,7 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const return true; } -void ds4_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) +void ds4_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) { if (!hidDevice) { @@ -831,13 +831,17 @@ bool ds4_pad_handler::get_is_touch_pad_motion(const std::shared_ptr& PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ptr& device) { DS4Device* dev = static_cast(device.get()); - if (!dev || dev->path.empty()) + if (!dev || dev->path == hid_enumerated_device_default) return connection::disconnected; if (dev->hidDevice == nullptr) { // try to reconnect +#ifdef ANDROID + if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) +#else if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) +#endif { if (hid_set_nonblocking(hid_dev, 1) == -1) { diff --git a/rpcs3/Input/ds4_pad_handler.h b/rpcs3/Input/ds4_pad_handler.h index 37c51dcfe2..4fdb829d73 100644 --- a/rpcs3/Input/ds4_pad_handler.h +++ b/rpcs3/Input/ds4_pad_handler.h @@ -184,7 +184,7 @@ private: // Copies data into padData if status is NewData, otherwise buffer is untouched DataStatus get_data(DS4Device* ds4Device) override; int send_output_report(DS4Device* device) override; - void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) override; + void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) override; bool get_is_left_trigger(const std::shared_ptr& device, u64 keyCode) override; bool get_is_right_trigger(const std::shared_ptr& device, u64 keyCode) override; diff --git a/rpcs3/Input/dualsense_pad_handler.cpp b/rpcs3/Input/dualsense_pad_handler.cpp index 4c0253adba..794c0bf4e7 100644 --- a/rpcs3/Input/dualsense_pad_handler.cpp +++ b/rpcs3/Input/dualsense_pad_handler.cpp @@ -99,7 +99,7 @@ dualsense_pad_handler::dualsense_pad_handler() m_thumb_threshold = thumb_max / 2; } -void dualsense_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) +void dualsense_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) { if (!hidDevice) { @@ -562,13 +562,17 @@ bool dualsense_pad_handler::get_is_touch_pad_motion(const std::shared_ptr& device) { DualSenseDevice* dev = static_cast(device.get()); - if (!dev || dev->path.empty()) + if (!dev || dev->path == hid_enumerated_device_default) return connection::disconnected; if (dev->hidDevice == nullptr) { // try to reconnect +#ifdef ANDROID + if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) +#else if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) +#endif { if (hid_set_nonblocking(hid_dev, 1) == -1) { diff --git a/rpcs3/Input/dualsense_pad_handler.h b/rpcs3/Input/dualsense_pad_handler.h index 981b8a568d..77b85f320b 100644 --- a/rpcs3/Input/dualsense_pad_handler.h +++ b/rpcs3/Input/dualsense_pad_handler.h @@ -245,7 +245,7 @@ private: bool get_calibration_data(DualSenseDevice* dev) const; DataStatus get_data(DualSenseDevice* device) override; - void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override; + void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override; int send_output_report(DualSenseDevice* device) override; bool get_is_left_trigger(const std::shared_ptr& device, u64 keyCode) override; diff --git a/rpcs3/Input/hid_pad_handler.cpp b/rpcs3/Input/hid_pad_handler.cpp index 40dcbdef24..16602412bf 100644 --- a/rpcs3/Input/hid_pad_handler.cpp +++ b/rpcs3/Input/hid_pad_handler.cpp @@ -18,6 +18,11 @@ LOG_CHANNEL(hid_log, "HID"); +#ifdef ANDROID +std::vector g_android_usb_devices; +std::mutex g_android_usb_devices_mutex; +#endif + struct hid_instance { public: @@ -56,9 +61,9 @@ public: hid_log.notice("Initializing HIDAPI ..."); - if (hid_init() != 0) + if (int errorCode = hid_init(); errorCode != 0) { - hid_log.fatal("hid_init error"); + hid_log.fatal("hid_init error %d", errorCode); return false; } @@ -179,9 +184,18 @@ template void hid_pad_handler::enumerate_devices() { Timer timer; - std::set device_paths; - std::map serials; + std::set device_paths; + std::map serials; +#ifdef ANDROID + { + std::lock_guard lock(g_android_usb_devices_mutex); + for (auto device : g_android_usb_devices) + { + device_paths.insert(device); + } + } +#else for (const auto& [vid, pid] : m_ids) { hid_device_info* dev_info = hid_enumerate(vid, pid); @@ -209,6 +223,7 @@ void hid_pad_handler::enumerate_devices() } hid_free_enumeration(head); } +#endif hid_log.notice("%s enumeration found %d devices (%f ms)", m_type, device_paths.size(), timer.GetElapsedTimeInMilliSec()); std::lock_guard lock(m_enumeration_mutex); @@ -254,7 +269,7 @@ void hid_pad_handler::update_devices() // Scrap devices that are not in the new list for (auto& controller : m_controllers) { - if (controller.second && !controller.second->path.empty() && !m_new_enumerated_devices.contains(controller.second->path)) + if (controller.second && controller.second->path != hid_enumerated_device_default && !m_new_enumerated_devices.contains(controller.second->path)) { controller.second->close(); cfg_pad* config = controller.second->config; @@ -284,7 +299,11 @@ void hid_pad_handler::update_devices() } #endif - if (hid_device* dev = hid_open_path(path.c_str())) +#ifdef ANDROID + if (hid_device* dev = hid_libusb_wrap_sys_device(path, -1)) +#else + if (hid_device* dev = hid_open_path(path)) +#endif { if (const hid_device_info* info = hid_get_device_info(dev)) { diff --git a/rpcs3/Input/hid_pad_handler.h b/rpcs3/Input/hid_pad_handler.h index b6dc093983..11fa1dba41 100644 --- a/rpcs3/Input/hid_pad_handler.h +++ b/rpcs3/Input/hid_pad_handler.h @@ -6,8 +6,24 @@ #include "hidapi.h" +#ifdef ANDROID +#include "hidapi_libusb.h" +#endif + #include +#ifdef ANDROID +using hid_enumerated_device_type = int; +using hid_enumerated_device_view = int; +inline constexpr auto hid_enumerated_device_default = -1; +extern std::vector g_android_usb_devices; +extern std::mutex g_android_usb_devices_mutex; +#else +using hid_enumerated_device_type = std::string; +using hid_enumerated_device_view = std::string_view; +inline constexpr auto hid_enumerated_device_default = std::string(); +#endif + struct CalibData { s16 bias = 0; @@ -38,7 +54,7 @@ public: #ifdef _WIN32 hid_device* bt_device{nullptr}; // Used in ps move handler #endif - std::string path; + hid_enumerated_device_type path = hid_enumerated_device_default; u8 led_delay_on{0}; u8 led_delay_off{0}; u8 battery_level{0}; @@ -78,9 +94,9 @@ protected: // pseudo 'controller id' to keep track of unique controllers std::map> m_controllers; - std::set m_last_enumerated_devices; - std::set m_new_enumerated_devices; - std::map m_enumerated_serials; + std::set m_last_enumerated_devices; + std::set m_new_enumerated_devices; + std::map m_enumerated_serials; std::mutex m_enumeration_mutex; std::unique_ptr>> m_enumeration_thread; @@ -88,7 +104,7 @@ protected: void update_devices(); std::shared_ptr get_hid_device(const std::string& padId); - virtual void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) = 0; + virtual void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) = 0; virtual int send_output_report(Device* device) = 0; virtual DataStatus get_data(Device* device) = 0; diff --git a/rpcs3/Input/ps_move_handler.cpp b/rpcs3/Input/ps_move_handler.cpp index 3b5aaec2f7..7eb74d3e96 100644 --- a/rpcs3/Input/ps_move_handler.cpp +++ b/rpcs3/Input/ps_move_handler.cpp @@ -265,7 +265,7 @@ hid_device* ps_move_handler::connect_move_device(ps_move_device* device, std::st } #endif -void ps_move_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) +void ps_move_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) { #ifndef _WIN32 if (!hidDevice) @@ -422,7 +422,7 @@ ps_move_handler::DataStatus ps_move_handler::get_data(ps_move_device* device) PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_ptr& device) { ps_move_device* move_device = static_cast(device.get()); - if (!move_device || move_device->path.empty()) + if (!move_device || move_device->path == hid_enumerated_device_default) return connection::disconnected; if (move_device->hidDevice == nullptr) @@ -433,8 +433,12 @@ PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_ { move_device->hidDevice = dev; } +#else +#ifdef ANDROID + if (hid_device* dev = hid_libusb_wrap_sys_device(move_device->path, -1)) #else if (hid_device* dev = hid_open_path(move_device->path.c_str())) +#endif { if (hid_set_nonblocking(dev, 1) == -1) { diff --git a/rpcs3/Input/ps_move_handler.h b/rpcs3/Input/ps_move_handler.h index 9b1da1d58b..6584364556 100644 --- a/rpcs3/Input/ps_move_handler.h +++ b/rpcs3/Input/ps_move_handler.h @@ -189,7 +189,7 @@ private: #endif DataStatus get_data(ps_move_device* device) override; - void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override; + void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override; int send_output_report(ps_move_device* device) override; bool get_is_left_trigger(const std::shared_ptr& device, u64 keyCode) override; diff --git a/rpcs3/Input/skateboard_pad_handler.cpp b/rpcs3/Input/skateboard_pad_handler.cpp index 86996847d6..c9194adc24 100644 --- a/rpcs3/Input/skateboard_pad_handler.cpp +++ b/rpcs3/Input/skateboard_pad_handler.cpp @@ -149,7 +149,7 @@ void skateboard_pad_handler::init_config(cfg_pad* cfg) cfg->from_default(); } -void skateboard_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) +void skateboard_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) { if (!hidDevice) { @@ -233,13 +233,17 @@ skateboard_pad_handler::DataStatus skateboard_pad_handler::get_data(skateboard_d PadHandlerBase::connection skateboard_pad_handler::update_connection(const std::shared_ptr& device) { skateboard_device* dev = static_cast(device.get()); - if (!dev || dev->path.empty()) + if (!dev || dev->path == hid_enumerated_device_default) return connection::disconnected; if (dev->hidDevice == nullptr) { // try to reconnect +#ifdef ANDROID + if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1)) +#else if (hid_device* hid_dev = hid_open_path(dev->path.c_str())) +#endif { if (hid_set_nonblocking(hid_dev, 1) == -1) { diff --git a/rpcs3/Input/skateboard_pad_handler.h b/rpcs3/Input/skateboard_pad_handler.h index db1e3536d8..e7f15c494e 100644 --- a/rpcs3/Input/skateboard_pad_handler.h +++ b/rpcs3/Input/skateboard_pad_handler.h @@ -179,7 +179,7 @@ public: private: DataStatus get_data(skateboard_device* device) override; - void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override; + void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override; int send_output_report(skateboard_device* device) override; PadHandlerBase::connection update_connection(const std::shared_ptr& device) override;