Buttons, touch gestures, and key combinations
Input discovery
Decompiled: voice-agent:0x24fd60 scans /dev/input for character devices. InputEventManager and TouchEventListener consume both physical key events and touch/gesture events. The early reset utility separately opens /dev/input/event0 directly.
The normal agent's internal event types are numeric. The table below maps observed dispatch behavior; it does not assume that internal type numbers equal Linux key codes.
Physical controls
Decompiled: the 32-byte key-combo records at 0xa12c90 map Linux input codes to internal event types. This resolves the physical controls without guessing from behavior:
| Linux code(s) | Internal type | Action in voice-agent |
|---|---|---|
| 115, 114, 164 | 0 | Three-key chord; reserved path |
| 115, 114 | 1 | Volume Up + Down long-chord behavior |
| 164, 115 | 2 | Next track (mediaNext) |
| 164, 114 | 3 | Previous track (mediaPrevious) |
| 115 | 4 | Volume up / continuous adjustment |
| 114 | 5 | Volume down / continuous adjustment |
| 164 | 6 | Play/pause and multi-count actions |
| 704 | 7 | Hidden doFun Easter eggs |
| 248 | 8 | Microphone mute toggle |
Codes 114/115 are Volume Down/Up, 164 is play/pause, and 248 is microphone mute. Type 6 dispatch is: one press play/pause or accept, two hang up/reject, three Bluetooth, four clock, six diagnostic telemetry. The type 0 and type 1 records have distinct flags from ordinary buttons; the early S60 reset checker independently handles the two-volume-key reset chord.
Play/pause behavior is state-dependent: ongoing calls, onboarding, Bluetooth, media, and setup can change the result. Dispatch is in voice-agent:0x25ed80; mediaNext/mediaPrevious are 0x142b00/0x142c30, and doFun is 0x1442e0.
Touch surface
| Gesture | Action | Evidence |
|---|---|---|
| Single tap, one contact | mediaPause / context-dependent stop |
voice-agent:0x262aa0 |
| Double tap, up to two contacts | mediaPlay / context-dependent start |
0x263090 |
| Triple tap | Toggle Bluetooth | 0x261f70 → 0x145eb0 |
| Six-tap “super tap” | Send diagnostic telemetry | 0x2620d0 → 0x16f8b0 |
| Swipe left | Next track | 0x262260 → mediaNext |
| Swipe right | Previous track | 0x262370 → mediaPrevious |
| Swipe up/down | Log only in the examined build | 0x261ca0, 0x261d90 |
| Long tap, one contact | Context-dependent accept/setup action | 0x263b30 |
| Long tap, two contacts | Toggle/setup mode behavior | same |
The touch listener consumes the same evdev stream, tracks contact points and a bounded histogram, and dispatches Point arrays. Swipe up/down only log in this build; left/right map to next/previous. The input reader logs type/code/value at verbose level, so coordinate and gesture timing can be captured without changing device state.
Early five-second factory-reset chord
S60 runs:
check-factory-reset \
--input=/dev/input/event0 \
--keys=114,115 \
--playback=pulse:alsa_playback
Linux codes 114 and 115 are Volume Down and Volume Up. check-factory-reset:main performs an EVIOCGKEY ioctl (0x80604518) and monitors input for five seconds. sub_B840 requires both requested keys; subsequent samples also reject additional pressed keys. A successful hold returns status 1.
If /data/DEVICE_TEST_REQUIRED exists, the utility exits without arming reset. This protects manufacturing/device-test mode.
On success S60 creates /data/do_factory_reset, stops LED and PulseAudio services, and forces a reboot. S03 performs the actual deletion on the next boot. See reset animation and factory reset.
Onboarding feedback
onboarding_playpause.json plays Onboarding_knopka_play_pause.opus. onboarding_micmute.json plays Onboarding_knopka_microfona.opus. onboarding_voice_assistant.json plays the play/pause instructions with blocking: true and then issues a listen command.
/data/voice-agent/button_onboarding.txt stores a decimal bitmask: bit 0 is play/pause onboarding and bit 1 is microphone-mute onboarding. The captured provisioned unit contains 3, meaning both prompts are complete.