Why
Two pad collisions in three days, same shape both times: a session read /data/local/tmp/pad.lock, gated only the writing of its own lock (or a pad-lock.sh take whose exit status was not checked), and then ran its device commands anyway under another session's live measurement.
- 2026-09-10 08:52Z: a chained
prove-freeform run walked past a refused pad-lock.sh take (3 minutes of contamination, both runs discarded).
- 2026-09-12 08:37Z: an ad-hoc script installed an APK, set debug props, pinned rotation and launched an app during an activity-thaw measurement (one side claim on runtime#1454 withdrawn because the window could not be separated from the launch; logcat had rolled by the time it was checked).
A check inside prove-* would have caught neither: the offending scripts were ad hoc. The lock is advisory today; the enforcement has to be the thing that runs commands.
What
android-bundle/scripts/pad-run.sh <handle> "<purpose/duration>" -- <cmd …>
- Refuse under a foreign lock. If
pad.lock exists and its first token is not <handle>: print the holder line, exit 75, exec nothing. No --force.
- Take / release around the command. Write
<handle> <ISO-8601 UTC> <purpose> (never truncate an existing lock), run the command with the lock held, rm the lock on exit (trap on EXIT/INT/TERM). Re-entrant for the same handle so a driver script can wrap several steps.
- Restore rotation on exit via the shared
restore_rotation (auto-rotate 1 / user_rotation 1 / fixed-to-user-rotation disabled), regardless of what the command did.
- Snapshot for after-the-fact checks. At start and end:
dumpsys usagestats (recent app launches/foreground events), dumpsys activity recents, and logcat -d -t 2000 filtered to ActivityTaskManager|ActivityManager: Start|Force stopping|am_proc_start into the caller's scratch dir ($PAD_RUN_OUT, default ./pad-run-<handle>-<ts>/). Print the delta at exit: which packages started/stopped/foregrounded inside the window. This is what lets a reading that was already taken be judged contaminated or clean once logcat has rolled.
- Refuse to force-stop the runtime service (
org.freedesktop.monado.openxr_runtime.out_of_process) from inside the wrapper unless --allow-runtime-stop is passed; that is the other standing rule that gets broken by accident.
prove-3d.sh / prove-freeform.sh / the bundle install and gate scripts then call themselves through it, and the README's protocol section points at it as the only sanctioned way to touch the pad from a script.
Not in scope
Cross-machine locking (the lock file on the device already serialises every box), and any change to what the prove scripts measure.
Refs: runtime#1454 (the withdrawn claim), displayxr-demo-mediaplayer#71 (the second collision's run).
Why
Two pad collisions in three days, same shape both times: a session read
/data/local/tmp/pad.lock, gated only the writing of its own lock (or apad-lock.sh takewhose exit status was not checked), and then ran its device commands anyway under another session's live measurement.prove-freeformrun walked past a refusedpad-lock.sh take(3 minutes of contamination, both runs discarded).A check inside
prove-*would have caught neither: the offending scripts were ad hoc. The lock is advisory today; the enforcement has to be the thing that runs commands.What
android-bundle/scripts/pad-run.sh <handle> "<purpose/duration>" -- <cmd …>pad.lockexists and its first token is not<handle>: print the holder line, exit 75, exec nothing. No--force.<handle> <ISO-8601 UTC> <purpose>(never truncate an existing lock), run the command with the lock held,rmthe lock on exit (trap on EXIT/INT/TERM). Re-entrant for the same handle so a driver script can wrap several steps.restore_rotation(auto-rotate 1 / user_rotation 1 / fixed-to-user-rotation disabled), regardless of what the command did.dumpsys usagestats(recent app launches/foreground events),dumpsys activity recents, andlogcat -d -t 2000filtered toActivityTaskManager|ActivityManager: Start|Force stopping|am_proc_startinto the caller's scratch dir ($PAD_RUN_OUT, default./pad-run-<handle>-<ts>/). Print the delta at exit: which packages started/stopped/foregrounded inside the window. This is what lets a reading that was already taken be judged contaminated or clean once logcat has rolled.org.freedesktop.monado.openxr_runtime.out_of_process) from inside the wrapper unless--allow-runtime-stopis passed; that is the other standing rule that gets broken by accident.prove-3d.sh/prove-freeform.sh/ the bundle install and gate scripts then call themselves through it, and the README's protocol section points at it as the only sanctioned way to touch the pad from a script.Not in scope
Cross-machine locking (the lock file on the device already serialises every box), and any change to what the prove scripts measure.
Refs: runtime#1454 (the withdrawn claim), displayxr-demo-mediaplayer#71 (the second collision's run).