-
Notifications
You must be signed in to change notification settings - Fork 0
Dual AIDL Dispatch Thread
This page documents the dual-thread AIDL dispatch architecture introduced in v2, which fixed the combo delay bug where the player pauses briefly when any button is pressed while moving.
Before v2, NativeGamepadMapper used a single aidlThread for ALL touch calls (analog move + button down/up). Since Binder calls are 5-15ms each and the queue is strict FIFO, a burst of button events would pile up in front of pending touchMove calls. The stick appeared frozen for 50-100ms every time a button was tapped during movement.
- stickAidlHandler (Thread.MAX_PRIORITY) — analog stick touchDown/touchMove/touchUp
- buttonAidlHandler (Thread.NORM_PRIORITY) — button touchDown/touchUp/injectTap
Both threads can execute Binder calls in parallel — Android InputManager accepts concurrent injectInputEvent calls for different pointer IDs without serialization.
- Stick (MAX_PRIORITY): A 10-20ms delay on stick movement is VERY perceptible. Stick move events fire at 100-200Hz from getevent.
- Button (NORM_PRIORITY): A 10-20ms delay on a button press is imperceptible. Buttons fire at most a few times per second.
Even with a dedicated stick thread, rapid touchMove events (100-200Hz) can pile up. v2 adds coalescing: only the LATEST move per pointer ID is actually sent to the daemon.
If 10 touchMove events arrive in 5ms (while a previous move is still being processed), only the LAST one is actually sent. The 9 intermediate positions are dropped — which is fine, because a fast-moving stick only cares about the final position per frame.
This caps stick move latency at one Binder call (~10ms) regardless of input rate.
- processStick touchDown/touchUp: dispatchStickCall (analog, high priority)
- processStick touchMove: dispatchStickMove (analog, coalesced)
- handleHoldInteraction touchDown/touchUp: dispatchButtonCall (button, normal priority)
- handleTap/handleTurbo/handleToggle/handleCharge/handleMacro: dispatchButtonCall
The legacy dispatchTouchCall function still exists and routes to dispatchButtonCall by default (since most existing call sites are button touchDown/touchUp).
- Injection-Architecture — 3-path injection overview
- Multi-Pointer-MotionEvent — How v3 builds correct multi-touch MotionEvents