- The overport CLI now comes from Android-XR-Bridge/OVRPort (fallback ovrport/app); its four new patches are described and shown only where they apply; parity classifies the 1.2.5 differences (VR metadata, config version, CLI-added platform compat) as expected: 34/34 at parity. - README rewritten (purpose, getting started, what works, credits, legal), INSTALL tightened, screenshots in docs/images (scripts/scrub_library.py + ui_smoke --docs --fake-frame), Quest2Frame references removed. - Game page: store descriptions without Markdown/[media] markup; themed labels on all switches. - `frameport install --apk` installs a given build (headset A/B tests).
7.1 KiB
Architecture
┌──────── UI (Flet, ui/: app shell + views/) ─────┐ ┌── CLI (cli.py) ──┐
└───────────────────────┬─────────────────────────┘ └────────┬─────────┘
▼ ▼
pipeline.py (add → suggest → build → install → test)
┌──────────────┬──────────────┼───────────────┬───────────────┬──────────────┐
sources/ analysis/ recommend/ build.py targets/ validate/
quest_dump detect, elf catalog, engine overport → base.Target static, device,
rift_dump stubgen, rift (+ catalog/*.yaml) patches(apk) → frame_lepton triage (+triage.yaml)
apk/sign pc_revive
│ │ │
patches/ registry tools/ toolchain frame/ ssh, discovery, pairing
overport, frame/*, (JRE, overport, install/installer ──► agent (on Frame)
settings apksigner)
Data flow for one game
- Source (
sources/quest_dump.py): folder with an APK and optional<package>/orobb/data. - Analysis (
analysis/detect.py): package/label/version (pyaxmlparser), ABIs, engine, XR API, graphics API, direct-VrApi, GLAD/eglGetProcAddress, Unity MSAA levels, Meta permissions, telemetry references. - Recipe (
recommend/engine.py): every patch'sdetect()suggests itself with a reason; a catalog entry (exact known-good recipe) overrides heuristics. The UI shows toggles; the user confirms. - Build (
build.py): overport CLI (OVRPort; defaults + extras) → apk-stage patches inorderon anApkWorkspace→ apksigner (with the package's own keystore) → static validation. Optional alternate build (e.g. without Unreal ForceQuit). - Install (
install/installer.py+agent/frameport_agent.py):prepare(paths, what's already there) → SFTP uploads with resume →finalize(move into place, settings.conf/framebridge.conf, device files, launch.sh, deployment.json, artwork) →shortcuts(detached systemd unit stops Steam, writes shortcuts.vdf + grid art, restarts Steam). - Test (
validate/device.py): agentlaunch_test(systemd-run launch.sh, wait, stop) → fetch launch.log →triage.py(milestones + signatures → suggested patches) → UI offers "apply suggestions and rebuild".
Extending
- New fix:
patches/frame/<name>.pywith aPatchsubclass (detect,apply, optionalvalidate), plus a signature incatalog/triage.yamland a PLAYBOOK row. Stages:overport|apk|install. - New heuristic: put it in the patch's
detect()(andapplies()for visibility), with the evidence in the reason text; checkscripts/eval_heuristics.pystill reproduces the catalog and add a test intests/test_heuristics.py. - New game recipe:
catalog/games/<package>.yaml(or "Save as known-good" in the GUI, which writes to the user catalog). Publish recipes by serving a folder withindex.jsonand pointingFRAMEPORT_CATALOG_URLat it. - New target: implement
targets/base.Target; the pipeline and UI only use that interface.
Oculus Rift (PC VR) games
sources/rift_dump finds Windows game folders; analysis/rift (own PE reader) detects exe, bitness, engine, LibOVR vs
OpenXR, D3D version and Oculus Platform SDK use; ids are rift.<slug>. Their only patches are the pcvr category
(patches/pcvr.py: Revive, OpenVR backend, crash reporter, Oculus detection, OpenXR layer, Proton
log/version/env); base.for_game keeps Quest and PC VR patches
apart. "Build" = pipeline.prepare_rift (checks + Revive). Revive is a portable tool (tools/revive.py unpacks
ReviveInstaller.exe in pure Python: NSIS header + deflate blocks). Targets:
targets/pc_revive.PcReviveTarget: Windows/WSL (core/winhost.py), non-Steam shortcut runningReviveInjector.exe /openxr <exe>via the agent's VDF code, grid art, local records in<user data>/pc/.FrameLeptonTarget.install_pcvr→installer.install_pcvr→ agentprepare_pcvr/finalize_pcvr: uploadgame/+revive/(+xrlayer/forpcvr.xr_timefix,helpers/forpcvr.oculus_unreal; size-manifest dedupe, stale files removed),launch.shrunning the ARM64 Proton chain (built from toolmanifest.vdf; withpcvr.oculus_unrealthe injector runs throughhelpers/fp_oculushmd.exe, which provides Unreal'sOculusHMDConnectedevent);proton_status/install_protonmanage Proton from Valve's ARM64 compat list.- Native binaries (
artifacts/): editnative/…, runpython native/build.py, commit the new artifacts + SHA256SUMS, runframeport parityto see which games change.
Self-update (updates.py, ui/updater.py, cli.py update)
check() GitHub releases/latest (cached 6 h, drafts/prereleases skipped, "skipped" version remembered)
│ → Update(version, notes = release body incl. "What's new" from the annotated tag, asset for this OS, sums, wheel)
▼
install_kind() bundle (running exe inside FramePort.exe's folder / FramePort.app / FramePort/FramePort)
│ source (git checkout) → git pull --ff-only + uv sync wheel (uv tool / pipx / pip) → reinstall wheel
▼ bundle
prepare() <data>/updates/<ver>/: download → SHA256SUMS.txt check → extract to staged/ (ditto on macOS) → layout check
│ → Windows: same Authenticode signer as the running exe → ready.json
▼
apply() writes <data>/updates/apply.{ps1,sh}, starts it detached; FramePort quits. The script waits for the pid,
Windows: backs up the files it replaces (updates/<ver>/previous) and copies over the folder (the zip has
no folder of its own); macOS/Linux: mv target → .old, staged → target, rollback on failure, clears the
quarantine; then relaunches. Log: <data>/logs/update.log.
GUI: background check 10 s after start + every 6 h → sidebar card + Library bar → dialog with notes → job
app-update (waits for other jobs) → restart. "Install updates automatically": prepare in the background, apply in
main() before the window opens. CLI: once-a-day hint from the cached result (a daemon thread refreshes it), frameport update [--check] [--yes]. CI runs scripts/update_smoke.py on every OS with the archive it just built.
Dynamic data (fetched live, cached, bundled fallback)
overport CLI release (Android-XR-Bridge/OVRPort, fallback ovrport/app) + patch list + titles, Temurin JRE (Adoptium API), apksigner (Google repository index), store artwork/titles (overport image API), catalog (optional remote), Lepton location/appid (Frame appmanifests), Steam user (Frame userdata).