Support level-coded SW input on hardware reporting KEY_1 (Stargate) - #107
Merged
RapierXbox merged 2 commits intoSep 22, 2026
Merged
Conversation
3d13d7f added a Build.VERSION.SDK_INT check to buildInterpreter() without importing android.os.Build, which breaks compileDebugJavaWithJavac on main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The SW terminal is reported in one of two schemes. The implemented one is edge coded: each contact transition is a short key pulse whose keycode carries the direction (141/KEY_F11 rising, 142/KEY_F12 falling), verified on the X1i. The Wall Display "Stargate" (SAWD-0A1XX10EU1) uses a second scheme. Its gpio_keys node declares a single code, KEY_1 (scan code 2, Android keycode 8), and the contact level is the key state itself: down while the line is active, up when it goes inactive, with Android auto-repeating the down while it is held. levelForAndroidKey() returned null for that keycode, so SwInputHandler declined it, MainActivity fell through to super.dispatchKeyEvent() and the input was silently dropped - no switch_state, no relay, no JS event. Decode both schemes in the keymap and handle them on both intake paths (activity KeyEvents and the native input monitor incl. the getevent fallback). No per-model flag: the code sets are disjoint, so a model reporting either one works without a DeviceModel entry. KEYCODE_1 is an ordinary digit on a real keyboard, so unlike the F11/F12 pulses it is only claimed when the model has an SW input and the reporting input device has no letter keys; anything that can type text keeps its digit and passes through to the webview. Verified on a Stargate: press toggles the relay on the rising edge, GET /device/input reports state true for the full hold and false on release, in the screensaver activity as well as MainActivity. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Problem
On a Wall Display Stargate (
SAWD-0A1XX10EU1) the SW terminal does nothing: noswitch_stateon MQTT, no relay toggle, no JS event. The key event is delivered to the app —dumpsys inputshows it reachingMainActivity— but it is dropped.The cause is that the terminal is reported in a second scheme that the keymap does not know.
The implemented scheme is edge coded: each contact transition is a short key pulse whose keycode carries the direction (141/
KEY_F11rising, 142/KEY_F12falling), verified on the X1i.The Stargate's
gpio_keysnode declares exactly one code and nothing else:Here the contact level is the key state — down while the line is active, up when it goes inactive, with Android auto-repeating the down while it is held:
levelForAndroidKey(8)returnsnull, soSwInputHandlerdeclines the key,MainActivityfalls through tosuper.dispatchKeyEvent()and the edge is lost.Change
Decode both schemes in the keymap and handle them on both intake paths — the activity
KeyEvents and the native input monitor including itsgeteventfallback. Everything downstream is unchanged:SwInputStateMachineapplies the configured mode,publishSwitch()sends PRESS/RELEASE, the relay and JS paths are untouched.No per-model flag. The two code sets are disjoint, so a model reporting either scheme works without a
DeviceModelentry — including Atlantis and Pegasus, which I cannot verify for lack of hardware.KEYCODE_1is an ordinary digit on a real keyboard, so unlike the F11/F12 pulses it is only claimed when the model has an SW input and the reporting input device has no letter keys (hasKeys(KEYCODE_Q)).gpio_keysdeclares the one SW code; a USB or Bluetooth keyboard keeps its digit and passes through to the webview. The verdict is memoized perdeviceId, so there is no lookup per auto-repeat.Verification
On a Stargate, with the real wired push-button,
swInputMode0=1(Button):GET /device/input?num=0reportsstate: truefor the full hold andfalseon release. Verified with the screensaver activity in front as well asMainActivity, since both route throughSwInputHandler. Unit tests cover the extended keymap.Note on the first commit
481a1f6is unrelated to the SW input:3d13d7fadded aBuild.VERSION.SDK_INTcheck toWakeWordDetector.buildInterpreter()without importingandroid.os.Build, which breakscompileDebugJavaWithJavaconmain. It is in here because the branch does not build without it — happy to split it into its own PR if you prefer.🤖 Generated with Claude Code