Files

15 KiB
Raw Permalink Blame History

v0.9.0 connection and support work

Status: project owner accepted the revised normal-use UI/support baseline for immediate v0.9.0 release. Extended network/storage/lifecycle validation remains explicitly deferred below. GitHub publication is pending; the agent did not install this update on a device.

Implemented scope

  • Android v0.9.0, version code 6, signed with the existing release key. The approved screen-timeout fix remains included.
  • Capture activity and receiver status are separate. Local encoding cannot turn the status green. A valid, recent PONG is required for Connected · receiver responding; this does not prove decoded/visible picture delivery.
  • Connecting, awaiting confirmation, unreachable/address errors, reply timeout, disconnected/retry states have fixed actionable text and amber styling. Encoder counters no longer overwrite receiver status. RTT resets on each attempt/disconnect. A 10-second reply deadline closes stalled connections, including blocked initial writes through the reader deadline.
  • Pairing rejection is currently connection closure, not a distinct wire error. The phone suggests checking pairing/relaunching but does not falsely assert a confirmed wrong-code diagnosis. Protocol-version errors receive update guidance.
  • Phone Settings → About shows version, version code, build label and debug/release type. Headset Settings → About / Export logs shows receiver version and Git build identifier (including dirty/source fallback).
  • Both About surfaces explicitly export bounded diagnostics to Downloads and report success/failure. Headset export requires a second deliberate activation, displays the saved filename, and runs file I/O on a worker rather than the render loop.
  • Phone Find headset on LAN performs a bounded automatic network search rather than requiring the user to know an IP. Results show receiver name, IP and version; selection is explicit even for one result. The chosen address/name is remembered, but a name is not authenticated identity. Capture consent and pairing remain required.

Discovery decision and wire contract

Android NSD/DNS-SD was evaluated. It is a good standard option, but using it here would require a receiver-side mDNS implementation/library or additional Avahi service/runtime integration. This first bounded same-LAN implementation instead uses IPv4 UDP, without a new headset daemon or dependency. This is a PhoneCast-specific finder, not mDNS interoperability or cryptographic identity.

  • Receiver listens on UDP 49322 only while the VR stream receiver runs; failure is non-fatal and manual TCP still works. TCP streaming defaults to 49321.
  • Query: ASCII PCVR_DISCOVER 1 <32 lowercase hexadecimal nonce>.
  • Unicast reply: ASCII PCVR_RECEIVER 1 <same nonce> <TCP port> <version> <name>.
  • Reply version is digits/dots up to 16 characters; hostname-derived name is sanitized ASCII, at most 48 characters. No pairing code, user stream metadata or payload is advertised.
  • Receiver accepts private/link-local IPv4 sources (and loopback for tests), validates exact query size/content, and caps replies globally at 20/second. Responses are under 160 bytes.
  • Android broadcasts to discovered interface broadcast addresses and limited broadcast, sends at most once/second for four seconds, limits interfaces/results/received packets, validates nonce and fields, and cancels on activity stop. A temporary Wi-Fi multicast lock is released on every exit.
  • Android's existing TCP endpoint is fixed at 49321, so the finder deliberately ignores custom-port responders. Manual address UI likewise retains its existing default-port behavior.
  • Android adds normal ACCESS_WIFI_STATE and CHANGE_WIFI_MULTICAST_STATE permissions, not location, root or broad storage permission. INTERNET remains required. Future Android local-network permission changes need separate compatibility validation.
  • Windows private-network firewall rules must also allow UDP 49322 for discovery. Never recommend router port forwarding or disabling security.

Guest/client isolation, VPNs, broadcast-blocked networks, cross-subnet and IPv6-only networks can prevent discovery. Manual IP entry remains available; discovery failure is not proof that TCP is unreachable. Existing v0.8 receivers do not implement this finder.

Changed-IP recovery: stop casting, run Find headset again, explicitly select the receiver, and start a new consented cast. Silent identity-based rediscovery/retargeting during an active reconnect is not implemented; it remains follow-up work with the trusted-device identity model. There is no continuous background scan or automatic capture start.

Diagnostic export privacy and limits

Android records its own fixed safe connection events plus periodic capture/receiver/frame-drop/RTT counters. The persistent ring is capped at 64 KiB and exported through MediaStore Downloads, using pending-file cleanup on failure. It does not read unrestricted system logcat, touch/notification contents, addresses, pairing credentials, or screen/audio samples. Android shared-storage APIs keep this independent of broad storage permission on API 29+.

Native export reads at most the trailing 256 KiB of the standard receiver log ($XDG_STATE_HOME/phonecast-vr/receiver.log, default ~/.local/state/phonecast-vr/receiver.log). Only explicitly allowed numeric diagnostic counters and fixed connection/pairing-result messages are retained; arbitrary text, notification/input/audio payloads, addresses and credentials are excluded. Filtered events are capped at 64 KiB plus a short header. Downloads honors XDG user-dirs configuration, with ~/Downloads fallback; exported Linux files are owner-only. Custom launch/log locations may yield a clearly marked log-unavailable report. The Windows fallback uses its standard user paths; this work primarily targets the native headset launcher.

Export is a safe support summary, not a full raw log dump. Review files before sharing privately. Native About reports the timestamped filename and saved Downloads location; phone export reports its exact saved path. Failed exports must not disrupt streaming.

Test and release checklist

  • JVM tests for fixed safe errors and bounded/correlated discovery parsing.
  • Real loopback TCP tests for TCP-without-PONG, invalid PONG, responsive PONG, disconnect/reconnect RTT reset, unreachable receiver and no-reply timeout.
  • Native tests for discovery query validation, real UDP query/reply/start-stop, About navigation/confirmation, safe export filtering, bounds, localized Downloads and failed export.
  • Local server candidate route/isolation tests; v0.8 aliases remain separate.
  • Final Android debug/release JVM tests (49 per variant), both APK assemblies and both lint tasks pass after the timeout-reason race fix.
  • Windows build and all 11 CTest tests pass.
  • Final Linux ARM64 build and QEMU portable/audio/support/runtime tests pass after final UI/export changes.
  • APK signature/version, ARM64 package contents/modes, checksum and live-download verification pass.
  • Owner accepted the revised normal-use UI/support baseline for immediate release.
  • Extended individual network/storage/lifecycle cases in the matrix below remain separately unvalidated.

The initial timeout test exposed a secondary reader-close error hiding the writer's actual reply timeout; reason preservation was corrected before final packaging. No new headset audio backend or render-path change is included. Existing decoder/Vulkan reliability follow-ups are not claimed fixed.

Release artifacts and local publication

Artifacts are ignored build output under out/packages:

  • phonecast-vr-v0.9.0-android.apk, SHA-256 c16adb399f0c16c830873d65fa063a61161d342d4eee1cad4754bf7b1312382d.
  • phonecast-vr-v0.9.0-steam-frame-arm64.tar.gz, SHA-256 18b4a3643575920af86a0373877a2c60bfe73210fc1446a3fcc99a057e7ecc99.
  • SHA256SUMS-v0.9.0 contains both entries. The APK verifies with the same certificate as v0.8 and reports version 0.9.0/code 6. Receiver About uses build 5195329-dirty for this uncommitted candidate.

The archive was created in Linux with stripped AArch64 binaries, 755 directories/executables/install scripts, 644 data/templates, and installer syntax checks. Only the local Node download server was restarted to expose a clearly labelled v0.9.0 test-candidate section. Both live downloads and served checksums match local artifacts. The old v0.8 aliases/bootstrap remain unchanged; the stable APK still matches the earlier code-4 timeout-fix artifact.

No phone/headset app, SteamVR, game or audio service was restarted or installed by this task. No GitHub release, commit or push was made. The owner subsequently accepted the revised release baseline; public GitHub publication remains a separate step. These artifacts were built from the working tree before the v0.9 source commit. The full implementation/documentation must be committed before tagging so the release's source includes these features. The tested receiver currently identifies its build as 5195329-dirty; rebuilding after a clean commit would change build metadata and artifact checksums and requires fresh verification.

Release documentation closure

The README now targets v0.9.0 filenames/install steps and explicitly explains the headset's two-selection export confirmation (not a thumbstick double-click). Copy-ready GitHub release notes are in docs/releases/v0.9.0.md. The local server is labelled release-ready/GitHub-publication-pending, and its revised export instructions and both live artifact hashes were checked. Three server/bootstrap tests, all 11 Windows CTest tests, README local-link checks and artifact checksums pass for the documentation closure; no native/Android source or binary changed in this closure. The full Android/ARM64 validation above remains the evidence for these exact artifacts.

The owner will create the GitHub release. Upload both versioned artifacts and SHA256SUMS-v0.9.0, and commit/tag all implementation/documentation changes first. GitHub release publication and tagging remain the owner's separate steps. Source commit/push is handled separately on the owner's request; it does not rebuild or change these tested artifacts.

Owner feedback and revision 6

The owner reported that the initial candidate works, receiver shutdown produces useful connection feedback, wrong pairing/IP produce relevant messages, and native log export works. Wrong-pairing retries rapidly alternated Connecting/Disconnected and changed page height; wrong-IP retries produced a slower variant. This is evidence for those exercised cases, not separate approval of discovery/multiple receivers, all About controls or storage failure paths.

Revision 6 addresses the feedback:

  • Retain the actionable failure across retry attempts until a valid PONG arrives, rather than flashing through Connecting/Awaiting states on each retry. Duplicate connection notifications are suppressed. Exponential backoff resets after a receiver-confirmed attempt, not merely TCP establishment, avoiding rapid wrong-code retry loops.
  • Use a stable short heading and fixed-line details/metrics areas so retry text and counters do not grow/shrink the status card. Tap the details text for the full message if it is ellipsized at large font sizes.
  • Native export filename is now phonecast-headset-<timestamp>.txt. The original pc-vr was only an abbreviation for PhoneCast VR, not another application or format.
  • Dashboard shortcut instructions now explicitly say CLOSE DASHBOARD FOR HOTKEYS. Shortcut behavior/input priority is unchanged.
  • Loopback regression tests cover repeated rejected handshakes without renewed Connecting/Awaiting text; presentation tests cover stable headings. Export tests check the clearer filename prefix.

Android debug/release tests, APKs and lint pass; Windows all 11 CTest tests and native ARM64/QEMU portable/audio/support/runtime tests pass. Both revised live downloads and checksums were verified without restarting the Node server. No device app/runtime was restarted. The owner subsequently said the revised update looks good and requested immediate release documentation. This closes the normal-use presentation baseline, not every independently witnessed discovery, storage-failure or lifecycle test.

Dashboard Settings assessment — proposal, not implemented

Moving Settings into the existing PhoneCast dashboard is moderate work rather than a settings-model rewrite. Keep the portable controller, transactional Apply/Cancel and live previews; add dashboard page navigation (Home → Settings → category), a dashboard-sized layout and shared settings pointer/slider handling. The existing dashboard handles only quick-action mouse-downs, whereas the floating panel owns settings row/drag events, so this is not just replacing a texture. Navigation, dirty-draft cancellation, dashboard closing/recreation and preview cleanup need regression coverage. Phone/notification/start-location previews can remain independent scene surfaces even if the settings menu stops floating.

A preliminary estimate is 1–2 focused development days plus physical headset layout/input tuning; it is not a committed delivery date. The current candidate still uses the floating Settings surface. Do not implement this proposal without the owner's follow-up approval.

Extended physical validation matrix (remaining cases deferred by release acceptance)

  1. Install both test endpoints; check About version/build information and retain saved settings/pairing. Stop casting and quit the receiver before updating.
  2. Receiver absent/wrong IP: amber error, no misleading green capture text, local drops explained, retry visible.
  3. Wrong pairing code and incompatible receiver: useful guidance, no claim that capture means pairing success.
  4. Correct receiver: green only after response, regular video/audio/control behavior unchanged; loss/reconnect removes/restores green and resets RTT.
  5. Find one and multiple receivers; require selection, check remembered-name hint, changed-IP search, activity cancellation and repeated search. Test blocked/guest network and manual fallback.
  6. Phone/headset exports are readable in Downloads, show correct versions, have bounded size, contain useful connection diagnostics, and exclude pairing/private content. Exercise storage failure separately.
  7. Validate portrait/landscape, consent cancellation, activity resume, stop/restart, and standalone-game input coexistence. Retain screen-timeout restoration checks.

Do not mark these physical cases complete from compilation, loopback tests or simulated receivers.