Skip to content

tvOS device.io.focus: accessibility-identity focus via bounded Siri Remote traversal#3

Closed
setoelkahfi wants to merge 4 commits into
mainfrom
feature/tvos-real-device
Closed

tvOS device.io.focus: accessibility-identity focus via bounded Siri Remote traversal#3
setoelkahfi wants to merge 4 commits into
mainfrom
feature/tvos-real-device

Conversation

@setoelkahfi

@setoelkahfi setoelkahfi commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a tvOS device.io.focus JSON-RPC command to the DeviceKit XCTest runner so agents can deterministically move Siri Remote focus to an on-screen element selected by its accessibility identity (identifier/label), instead of guessing remote sequences or interpreting screenshots.

This is part of a three-repo change (initial PRs target the setoelkahfi forks; upstream mobile-next PRs are deferred until the three-repo E2E is green).

What's in this PR (Milestone 4)

  • New device.io.focus handler (#if os(tvOS)): selects an element by identifier/label, then drives focus with a bounded (≤50-move) Siri Remote traversal. The direction heuristic re-reads the target frame each move to handle tvOS focus scrolling, and exits early on no-progress (dead end / oscillation).
    • Success: returns the focused element as a SourceTreeElement.
    • Failure: throws a new focusNotFound error (JSON-RPC code -32002) whose error.data carries the last focused element, plus a message naming the requested selector and the move count.
  • tvOS DumpUI robustness: guards SpringBoard-specific normalisation behind #if os(iOS) so a tvOS accessibility dump uses the foreground app's own root hierarchy. iOS behaviour is unchanged.
  • Removes throwaway Viaplay exploration scaffolding and an unused import from the UITests entry point.

Validation

  • make tvos-ipa-unsigned builds the tvOS UITests target and produces build/export/devicekit-tvos-runner.ipa.
  • iOS UITests target still compiles (no behavioural change on the iOS path).
  • project.pbxproj validated with plutil -lint.

Guardrails

  • Server bind stays loopback by default (DEVICEKIT_LISTEN_HOST=127.0.0.1); never 0.0.0.0 / never LAN.
  • iOS and tvOS runner bundle ids remain distinct; no credential/profile logging; RPC/response changes are additive.

Implements: SPECS/quality/real-tvos-device-support/SPEC.md

Related PRs (three-repo change)

setoelkahfi and others added 4 commits June 30, 2026 13:45
The DeviceKit XCUITest runner now builds for tvOS, so the automation
stack can drive the tvOS Simulator.

- Add a `devicekit-tvos` scheme and tvOS target to the Xcode project,
  plus a `scripts/patch-tvos-runner.sh` helper and Makefile targets that
  build and patch the tvOS runner.
- On tvOS, register a `device.io.button` handler that maps button names
  to `XCUIRemote.Button` presses (up, down, left, right, select, menu,
  home, playPause). tvOS navigates by focus, not touch.
- Keep the touch, keyboard, and orientation handlers iOS-only in the
  JSON-RPC dispatcher, behind `#if os(iOS)`.
- Read the screen size from `UIScreen.main.bounds` on tvOS, since there
  is no SpringBoard to query.
- Guard the remaining iOS-only handlers and helpers with `#if os(iOS)`
  so the shared sources still compile for both platforms.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a compiled brandassets catalog (imagestack/imagestacklayer) for the
tvOS UI test runner, wire up ASSETCATALOG_COMPILER_APPICON_NAME and
CFBundleDisplayName on the devicekit-tvosUITests target, and extend
patch-tvos-runner.sh to copy the compiled Assets.car and set
CFBundleIcons/CFBundleDisplayName on the Runner.app so the tvOS test
runner now shows the same Device Kit icon as the iOS one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirror the iOS real-device flow for tvOS. patch-tvos-runner.sh now takes a
simulator|device argument so it can pull the Swift Testing support libraries
from AppleTVOS.platform for device builds; the new tvos-ipa-unsigned Makefile
target builds the devicekit-tvos runner for generic/platform=tvOS, patches in
the Device Kit display name and icon, and packages an unsigned
devicekit-tvos-runner.ipa for re-signing at install time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a tvOS-only device.io.focus JSON-RPC handler that selects an element
by accessibility identifier/label and drives Siri Remote focus with a
bounded (<=50-move) traversal, returning the focused element on success
or a focusNotFound (-32002) error carrying the last focused element.

- New IOFocusMethodHandler (#if os(tvOS)); registered in the dispatcher
- Re-reads the target frame each move to handle tvOS focus scrolling
- Early-exit on no-progress (dead end / oscillation)
- Guard SpringBoard-specific DumpUI normalisation behind #if os(iOS) so
  tvOS dumps the foreground app's own accessibility hierarchy
- Remove throwaway Viaplay exploration scaffolding + unused import

Implements: SPECS/quality/real-tvos-device-support/SPEC.md (Milestone 4)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@setoelkahfi

Copy link
Copy Markdown
Owner Author

Superseded by upstream PR mobile-next#54. Keeping the branch as the source branch for upstream review.

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.

1 participant