Skip to content

tools: phone-gesture-test, on-phone gesture tests of the quick-settings pages - #652

Open
den-kloot wants to merge 1 commit into
derekross:mainfrom
den-kloot:tools-phone-gesture-test
Open

den-kloot wants to merge 1 commit into
derekross:mainfrom
den-kloot:tools-phone-gesture-test

Conversation

@den-kloot

Copy link
Copy Markdown
Contributor

What and why

tools/phone-gesture-test runs swipe scenarios on the quick-settings pages (Wi-Fi, Bluetooth, the notification shade) on a real phone and checks each one through the shell's own state. It came out of #553: the hand checks there didn't show that over an app a swipe from the very bottom edge reached the home strip instead of the page; a scripted run did.

  • Same result on any device: pages open through the shell's IPC (openWifi, openBluetooth, summon), never by a tap on a tile; the package's default tile layout for the run; an empty workspace or one with a terminal; and only the gesture under test is a real touch, through a uinput touchscreen (tools/phone-gesture-touch) at points in logical pixels taken from hyprctl monitors and the page's own window (hyprctl layers).
  • Verdicts are computed, never judged: the shell's state after the gesture (shell call omamobile.quicksettings state) with Recents still shut (no scenario opens it, so Recents means the touch reached the home strip), and for a page that should stay open, arithmetic on the pixels: the list's row profile has to move up with the drag, since a touch that never arrived would also leave the page open. Where rows look alike (network names of one length) the list lines up at several shifts, a whole row apart, and then every one of them has to be a move. A screen that isn't the one a scenario needs is a SKIP, not a pass or a fail.
  • It puts everything back: fictional notifications within the history's room (the service deletes its oldest files beyond historyLimit), dismissed again the way a swipe does; do-not-disturb during the run; the bar's unread mark; the tile layout. It waits for the phone to cool below 75 °C, since a throttled phone delivered touches late in one of my runs.
  • tests/phone-gesture-test checks the arithmetic, the touch points and the preconditions in CI, without a phone. docs/GESTURE-TESTS.md describes the scenarios, the verdicts and the limits; AGENTS.md lists the tool, with "announce it" since it takes over the screen for a few minutes.

Device and build

  • Phone: Pixel 9a (tegu)
  • Kernel release (uname -r): 7.3.0-rc6-omamobile-push1-gcbb1a7eb0a78
  • Packages changed, with versions: none (tools, a test, docs)

Checks (no phone needed)

  • tools/pr-check origin/main passes
  • tests/all passes: on the phone, everything up to tests/kernel-pr-check passes; that test needs the kernel build environment and fails the same way here on main without this change, and tests/all stops there. The tests after it that this change touches pass on their own (tests/phone-smoke, tests/phone-gesture-test, tests/tools-help); CI runs the whole suite
  • tests/packages passes (or the packages I touched: none)
  • Each changed package has its version bumped, and the new version is in the commit subject (no package changed)
  • Commits have area prefixes and bodies that say why; any AI help is a Co-Authored-By: or Assisted-by: trailer, never a Signed-off-by:

On the phone

tools/phone-smoke report

phone-smoke: unknown

Kernel 7.3.0-rc6-omamobile-push1-gcbb1a7eb0a78, tools at unknown, 2026-11-11T02:30Z.

Check Result Detail
boot (required) ok kernel 7.3.0-rc6-omamobile-push1-gcbb1a7eb0a78, slot b, up 19014s
storage guard (required) ok 62 partitions; only userdata and slot B's boot images writable
root (required) ok ext4 on userdata, 83G free
kernel health (required) ok no oops or BUG; 0 WARN, 31 error lines in dmesg (0 known, 31 new)
new dmesg errors not ok cpif: rx_demux: PCIE: ERR! N is not opened x8; cpif: pass_skb_to_demux: PCIE: N<N: ERR! N>recv_skb fail (N) x8; cpif: io_dev_recv_skb_single_from_link_dev: N<-PCIE: ERR! rx_demux fail (err N) x8
systemd units not ok failed: omamobile-bt-addr@hci0.service
USB gadget (required) ok bound to 11210000.usb
display ok card1-DSI-1 connected, 1080x2424
GPU ok render node on panthor
session (required) ok Hyprland and the Omarchy shell running
lock ok PAM file present (the shell didn't answer lock status)
touch ok Synaptics TouchComm Touchscreen
buttons ok gpio-keys
Wi-Fi ok wlp1s0 on brcmfmac, link up
Bluetooth ok hci0, powered false
battery ok 88% Full, 37 °C
sound cards ok googleteguaocsn
sensors ok Accelerometer AmbientLight Proximity
cameras skip no libcamera tools
thermal ok hottest zone 56 °C

Packages: hyprland 0.57.0-3.1, libcamera 0.7.2-4.22, mesa 1:26.2.4-1.4, omacam 0.3.3-1, omamessages 0.2.2-1, omamobile-apps 0.2.2-1, omamobile-audio 0.5.15-1, omamobile-device-tegu 0.2.9-1, omamobile-firstboot 0.1.3-1, omamobile-gnss 0.2.7-1, omamobile-keyring 20261026-1, omamobile-mirror 0.1.1-1, omamobile-mmd 0.1.2-1, omamobile-modem 0.1.16-1, omamobile-modem-sit 0.3.31-1, omamobile-omarchy 0.1.32-1, omamobile-owl-widgets 0.1.2-1, omamobile-sensors 0.2.1-1, omamobile-shell 0.2.100-1, omamobile-voice 0.1.0-1, omaphone 0.2.3-1, omarchy 4.0.6-1, omatel-agent 0.2.4-2, quickshell 0.3.2.r7.g2b4501a-1

🤖 Generated with Claude Code

…gs pages

derekross#553's hand checks didn't see that over an app a swipe from the very
bottom edge reached the home strip instead of the page; a scripted run
did. This adds that run as a tool: a uinput touchscreen
(tools/phone-gesture-touch) swipes at points taken from hyprctl's output
and layer geometry, so it runs the same on any device, and the verdict
comes from the shell's own state over IPC, with Recents still shut, plus
arithmetic on the pixels where a page should stay open (the list's row
profile has to move up with the drag; where rows look alike and line up
at several shifts, every one of them must be a move), never from a model
or a video.

Each test sets up its screen itself: pages open over IPC, the package's
default tile layout, an empty workspace or one with a terminal, fictional
notifications within the history's room, do-not-disturb, a phone below
75 C; and everything is put back. Thirteen scenarios cover derekross#553's pages on
the home screen and over an app, including a swipe from inside the home
strip's 44 px zone. docs/GESTURE-TESTS.md describes it;
tests/phone-gesture-test checks its arithmetic and preconditions in CI,
without a phone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derekross

Copy link
Copy Markdown
Owner

Thank you for this. Turning "the hand checks missed it" into a tool is the right response, and the design choices are the ones I'd want: pages opened over IPC so only the gesture is a touch, verdicts from the shell's own state with "recent apps stayed shut", a SKIP when the screen isn't the one a scenario needs, and pixel evidence where a pass could also mean that nothing happened. The care around the owner's phone shows too: the history headroom so a real notification is never pushed out, the unread mark, the tile layout moved aside and back. I checked that last one against Quickshell's FileView at the commit the phones run: it watches the directory as well as the file, so the shell does pick the owner's layout up again when you move it back.

I ran tests/phone-gesture-test and broke six of the tool's rules one at a time (the edge swipe's start point, the history headroom, the recent-apps check, the keyboard precondition, the look-alike-rows rule, the 20 px minimum). Each one failed the test, so it really does guard the arithmetic.

Two things to change before I merge:

  1. A dropped SSH session leaves the phone changed. The cleanup runs from finally, and you handle SIGTERM, but not SIGHUP, and a hang-up is what the tool gets when the USB link or the SSH session drops mid-run. Python then exits without finally: do-not-disturb stays on, the tile layout stays at .gesture-test-aside, the terminal stays open (it's in its own session) and the fictional notifications stay. The next run notices the tile file, but nothing notices do-not-disturb, and that's the one that costs the owner real notifications. Please handle SIGHUP the same way as SIGTERM, and at start detect a previous run's leftovers for do-not-disturb as well, for example a small state file that records the setting from before and that restore() removes.

  2. The sudo password.

    • ENV is a copy of the whole environment, so GESTURE_TEST_SUDO_PW is handed to every child, including the foot window, which keeps it for its lifetime. Please read it once and remove it from ENV.
    • With the variable set, the helper runs under sudo -S and you write the password to its stdin. sudo only reads stdin when it needs a password; if it already has a ticket from a moment ago, the password line goes on to phone-gesture-touch, which tries to parse it as a swipe and exits. I read this from the code and haven't run it, so tell me if I've got it wrong. sudo -S -v first and then sudo -n for the helper, as your interactive path does, would cover both cases.

Smaller things, as you see fit:

  • The lock is checked once at the start. A run takes minutes; a re-check in precondition() (and a SKIP while a call's surface is up) would keep a swipe off those screens.
  • Finger.close() ends with self.p.kill(), which a normal user can't do to a sudo child; the exception would come out of finally and results.json wouldn't be written.
  • A check at start for foot, grim, magick and notify-send, with one clear line when one is missing.
  • The test's python3 -I ignores PYTHONDONTWRITEBYTECODE, so it leaves tools/__pycache__/ behind; sys.dont_write_bytecode = True in the heredoc avoids that.
  • The AGENTS row says "(any device)". So far it has run on one 9a and a VM with the 9a's screen. I'll run it on my 7 Pro when I test omamobile-shell 0.2.119: a swipe up closes the shade card and the Wi-Fi and Bluetooth panels #553, and I'd rather the row said so once that's done.

I'll merge this after #553, since five of the scenarios are about what #553 adds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants