Feature/vibration driver review#361
Merged
maxjivi05 merged 12 commits intoJun 4, 2026
Merged
Conversation
- Add GcmRumbleMode enum (DISABLED/KNOWN/ALL) with SharedPreferences migration - Add GameSirG8UsbRumbleDriver (USB bulk transfer, VID=13623/PID=274) - Add GameSirX5sBleRumbleDriver (BLE GATT, heartbeat pattern) - Add GamepadRumbleManager with USB-first driver priority - Add GCM rumble mode dropdown to InputControlsDialog - Fix vibration socket race condition via executor shutdown/await - Fix USB permission reset after device re-enumeration - Fix G8+ MFi in ALL mode via UsbManager VID/PID verification - Implement smart fallback: KNOWN suppresses only X5s+G8+; ALL suppresses any GameSir
…port - Resolve conflict: drop showInputControlsDialog() (replaced by drawer menu) - Add GCM rumble mode chip selector to InputControlsPane in XServerDrawerMenu - Wire onInputControlsGcmRumbleModeChanged callback in XServerDisplayActivity
- Replace 3-chip selector with toggle + conditional Known/All chips - Add subtitle inside toggle row: 'For Android mode controllers only' - Auto-scroll to bottom when toggle is enabled - Default GCM mode to DISABLED instead of KNOWN - Remove debug applicationIdSuffix/versionNameSuffix from build.gradle
- Unify DISABLED as the default everywhere: GcmRumbleMode.fromPrefValue, WinHandler field init, GamepadRumbleManager field init, X5s/G8 driver field inits, and the renderDrawerMenu() pref fallback - Remove never-existing deprecated API wrappers (PREF_GAMESIR_USB_VIBRATION, isGameSirUsbVibrationEnabled, setGameSirUsbVibrationEnabled) and the dead migration block from WinHandler constructor - Revert InputControlsDialog/InputControlsDialogContent changes — the dialog is never instantiated so the gcmRumbleMode additions were dead code - Add setMode(GcmRumbleMode) to GamepadRumbleDriver interface; replace instanceof cast in GamepadRumbleManager with the interface method - Remove deprecated setEnabled() helper from GamepadRumbleManager - Fix GameSirG8UsbRumbleDriver.findDevice() to return any GameSir USB device in ALL mode, not just the G8+ MFi PID 274 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Good work here! I'll test it out cause I'm curious if this can work on enabling rumble on Odin 3 also. |
Contributor
Author
Hm, these hacks are bound to Gamesir ids. There are some checks, but you could try to add your "driver" :) Now there's a "manager" layer to deal with it. Claude helped me to find commands and ways to send them) |
added 6 commits
May 8, 2026 10:02
…ver-review # Conflicts: # app/src/main/AndroidManifest.xml
Two issues caused vibration to be silent for an extended time after entering a game: 1. A paired X5s actively connected as BLE-HID does not advertise, so the BLE scan never finds it. Vibration only works after the controller happens to advertise (mode switch, reconnect, etc.). Fix: Try bonded devices first via direct GATT connect — multiple GATT clients can coexist on the same physical link, so this works even while the controller is in use as HID. Scan stays as fallback. 2. After a successful command, pendingCommand is null. If the GATT link then drops, the disconnect handler skipped reconnection because it was gated on pendingCommand != null. Subsequent rumble events had to wait for a fresh scan (~3s). Fix: Reconnect whenever the rumble mode is enabled. Also: - Reset connecting=false if connectGatt returns null, otherwise ensureConnected() bails forever on transient adapter issues. - ensureConnected() bails immediately when mode is DISABLED to avoid pointless scans.
Resolved conflicts: kept GcmRumbleMode additions from feature branch, adopted vibration-disabled-by-default from main (6b04e18).
…defaults GameSirX5sBleRumbleDriver: reconnect after GATT disconnect whenever GcmRumbleMode is enabled, not only when a command is pending. Phone notifications caused GATT to drop while vibration was idle — without a pending command the scan was never restarted, leaving vibration broken until container restart. Also reverts the bonded-device connect path from ccfc684 which caused GATT status=147 loops when X5s was already connected as HID. WinHandler: default vibrationEnabledSlots to true so vibration works out of the box when the global toggle is on.
Replace scan-only approach with dual-track connection: register a background autoConnect=true for the bonded X5s (letting the OS connect whenever the device becomes available) while also running a BLE scan in parallel. This fixes the case where X5s is already connected as Classic BT HID and does not advertise BLE, making the scan-only path fail silently every time.
|
$ dpkg --add-architecture armhf |
Collaborator
Care to explain? |
The X3 Pro is wired (USB-C) for input but, like the X5s, drives rumble over the GameSir BLE GATT protocol (write char 0x865f, command 0x04 + duration 1 with a ~200ms heartbeat) — confirmed by capturing the official GameSir app. - BLE driver: match the X3 Pro (PID 0x0106 / name "GameSir-X3 Pro") in KNOWN mode; discover by advertised name (no MAC) and also match the scan-record name so the pad is recognised on first sight when getName() is still null. - USB driver: never claim the X3 Pro (it rumbles over BLE only). - WinHandler: treat the X3 Pro as GCM-managed; keep the phone fallback for OSC. - Condense the rumble subsystem comments to one line each.
Bring the GCM rumble branch up to date with the current WinNative base (through WinNative-Emu#512) and drop the unavailable in.dragonbra:javasteam:1.8.1-SNAPSHOT dependency that the base no longer uses. Re-apply the rumble integration (WinHandler hooks, Input Controls drawer toggle, activity listener, manifest permissions) on top of the updated vibration code; the rumble driver files merged cleanly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GameSir controllers in Android mode receive vibration commands via the Game
Controller Mode (GCM) protocol, not through the standard Android InputDevice
vibrator API. This PR adds a dedicated rumble subsystem that handles these
controllers directly.
What's added:
GcmRumbleModeenum (DISABLED / KNOWN / ALL) with SharedPreferences persistenceGamepadRumbleDriverinterface +GamepadRumbleManagerdispatcherGameSirG8UsbRumbleDriver— sends 9-byte vibration commands over USB bulktransfer to G8+ MFi controllers (VID 0x3537, PID 274)
GameSirX5sBleRumbleDriver— sends vibration commands over BLE GATT to X5s(VID 0x3537, PID 0x1119)
(Known: G8+ MFi, X5s / All GameSir — experimental)
avoid double-rumble
Modes:
DISABLED(default) — feature off, existing vibration behavior unchangedKNOWN— only known supported models: G8+ MFi (USB) and X5s (BLE)ALL(experimental) — any GameSir USB or BLE device; useful for untestedmodels but may not work on all hardware