Repository navigation
feat(hardware-button): add Android mute, sleep, wake and media keys - #3866
Conversation
Follow-up to #3859: hardware-button now names eight more phone keys — mute, sleep, wake, media-play-pause, media-next, media-previous, media-rewind, media-fast-forward — each a single dispatch-only press on Android phones and tablets across the local adb/helper leg, the Limrun Android leg, and Appium's mobile: pressKey route. sleep and wake are the explicit Android events; power stays the toggle. Every other owner keeps the family denial: Apple volume is unchanged and refuses the rest at typed fact admission, TV targets still use tv-remote. The mute/sleep/wake/media cells join SYSTEM_BUTTONS, so admission, the catalog binder, the daemon row table, and the CLI/SDK/MCP/journal vocabulary extend as pure table rows; the two Android owners state the phone/TV rule once through the shared facts builder. Follow-up to #3848 and #3859.
- The daemon conformance table derives one refusal row per hardware-button name from the command vocabulary instead of three hand-written rows, so every extended key proves its own refusal before binding. - The WebDriver leg sends every hardware key through one keycode table and one pressAndroidKeycode helper; the eight extended legs share one keyed press. - The daemon route test is one test.each over all eleven names on an Android fixture, pinned against the vocabulary; the contracts family equality is restored to toEqual over every cell. - Fact-builder and label types and comments tightened; dangling follow-up references and duplicate magic counts removed.
- Key every derived hardware-button conformance row as `hardware-button <name>`; the bare route key carried no extra rule. - Fix the inverted sentinel texts in the iOS refusal tests and the Android-only comment on the extended-key cell type. - Drop the remaining dangling follow-up references.
|
Size Report
Startup median (7 runs, lower is better):
|
|
Final validation and review evidence for
{
"status": "passed",
"exitCode": 0,
"exactCommit": true,
"checkoutChanged": false,
"startedAt": "2026-10-21T14:45:54.061Z",
"finishedAt": "2026-10-21T14:57:57.820Z",
"head": "1a1adcd9536f81f45e06d2675ae9609eb118e586",
"mergeBase": "7922864e7beabd57ef563081ab6d78a69e95172b",
"checks": {
"passed": 12,
"failed": 0,
"skipped": 8,
"not-run": 0
}
}Independent review: two fresh rounds. The first round's conformance, WebDriver dispatch, and test findings were fixed; the second found no blockers, majors, or minors. Its nits were applied, then final-head validation passed. The code uses the existing system-button family and small keycode tables; Android and Limrun share their fact-row construction, and Appium key presses share one helper. No parallel dispatcher or generic framework was added. Live checks were performed on Android emulator
Appium was verified by exact CI coverage and device lanes remain separate obligations; locally skipped checks are not claimed as passes. |
|
The Android keycodes need one owner before this can merge. I reviewed 1a1adcd. All checks pass, and there are no conflicts. The new ANDROID_HARDWARE_BUTTON_KEYCODES table in webdriver-interactor.ts is a verbatim copy of the 11-entry table in input-actions.ts, which this PR grows from 3 entries to 11. Both copy Could the change be smaller still? Not blocking, and you can take or leave these: the help text, I did not reproduce your live Android run (mute logcat, sleep and wake through dumpsys power, media-fast-forward replay). I only checked that the Android and Limrun execution code did not change since c7f9ad9. There was no live Appium session, so the WebDriver presses are proven only by recording-client transcripts. I also did not check that keycodes 223 and 224 work on every supported API level, or run the registry and conformance gates. |
|
Addressed in
I made this fixup myself and re-read its full diff cold. No independent reviewer was used for this fixup, per the request to handle it myself. The focused run passed 929 tests, including exact Android/Appium payload tests, iOS refusal tests, contract coverage, the TV regression, and eager-loading budgets. Typecheck, lint, layering and Fallow passed. Live verification used a new isolated Android 15 emulator ( Final-head {
"status": "passed",
"exitCode": 0,
"exactCommit": true,
"checkoutChanged": false,
"startedAt": "2026-10-21T15:53:58.424Z",
"finishedAt": "2026-10-21T15:59:24.624Z",
"head": "f3263517019688f5bdc580361b9836a680832ad3",
"mergeBase": "7922864e7beabd57ef563081ab6d78a69e95172b",
"checks": {
"passed": 12,
"deduplicated": 2,
"skipped": 8
},
"passedChecks": [
"format",
"lint",
"typecheck",
"layering",
"fallow",
"build",
"integration-node",
"macos-coverage",
"vitest-related",
"command-docs",
"docs-links",
"docs-prose"
],
"deduplicatedChecks": [
"unit",
"provider-integration"
]
} |
|
This PR is ready. The keycode duplication from the earlier review at 1a1adcd is fixed at f326351, and nothing from that review remains open. All 19 checks pass at this commit, and I know of no conflicts. Nothing else blocks maintainer review. Not blocking: For evidence, I took the live Android 15 emulator run from your comment and did not reproduce it. There was no live Appium session, so the WebDriver |
Summary
Extend
hardware-buttonwith eight Android keys:mute,sleep,wake,media-play-pause,media-next,media-previous,media-rewind, andmedia-fast-forward. ADB/helper, Limrun Android, and Appium use the existing button family. Sleep/wake are idempotent; power toggles.Android phone and TV presses now share the contracts keycode table. Deleted both consumer tables and numeric capability notes; simplified capability descriptions and derived the Android cell list. Scope: 33 files; follow-up to #3859 and #3848. Existing iOS volume routes remain. WebDriver already rejects TV targets; added regression coverage and corrected the earlier admission claim.
Validation
Head:
f3263517019688f5bdc580361b9836a680832ad3.pnpm check:affected --run --head <sha>passed on reviewed base1a1adcd953and this head, bothexactCommit:true: receipts, review dispositions, live evidence.