unity_oculus_check revision 3: Unity's built-in Oculus input creates Touch controllers only on device model 'Oculus Quest'; Lepton's Android is 'Valve Lepton', so the compared string is repointed in place (BattleSisters: hands tracked, buttons dead although OVRPlugin reported every press)

This commit is contained in:
spoopyghosty0 committed 2026-10-05 23:39:53 -04:00
1 parent 608fac9d68
commit bd2e1a8410
4 files changed
+28 -3

No files matched your search

+7
View File
@@ -547,6 +547,13 @@ wait now also applies to Unity 2019 without the Oculus XR Plugin (`UnityOculusCh
config `hijack_responses`), but OVRPort's `patch_clean_up_frida` removes its loadLibrary call, so it never runs on
the Frame; `frame.ovr_trace` (opt-in, `native/ovrtrace`: 1138 exported ovr_* stubs → real loader functions, logcat
tag `fp_ovrtrace`: calls, PopMessage answers, unanswered requests every 10 s) is the next diagnostic.
**Unity built-in VR input (2026-10-05):** probe builds (`FRAMEPORT_INPUT_PROBE=1 frameport build …`) showed
OVRPlugin returns the full Touch state for every controller mask (also Go masks) and the presses (A/B/stick clicks)
reach both BattleSisters and Accounting+ code. Unity 2019's libunity creates Touch devices only when
SystemInfo.deviceModel == "Oculus Quest"; Lepton's Android is "Valve" "Lepton" (liblepton/properties.sh) → Go-style
devices only (libunity polls masks 0x8000000/0x1000000/0x2000000) → `unity_oculus_check` revision 3 repoints that
string to "Valve Lepton" (same length). Unity 2017 (Accounting+) has no such string ("Oculus Pacific" only): still
open. The probe log caps at 120 changes.
**Lepton storage (2026-09-30):** each app's /sdcard (= /storage/emulated/0 → `<base>/lepton-data/external`) has `Movies`/`Download`/`Documents` symlinked to the Frame's `~/Videos`/`~/Downloads`/`~/Documents` (liblepton/mounting.sh, only if they exist at start); agent v24 `storage_targets` reads that mapping. Android's MediaProvider canonicalises paths to /home/steamos/... and rejects every file ("doesn't appear under [/system/media...]"), `sm list-volumes` is empty: the media index never works, apps must browse folders. Lepton installs with `adb install -g` (runtime permissions granted, MANAGE_EXTERNAL_STORAGE too). Files: `install/files.py`, `frameport frame send|storage`, GUI Files tab (formerly Frame → Send files).
**SteamVR per-app settings (2026-09-30):** editing steamvr.vrsettings while SteamVR runs is lost; the web API (127.0.0.1:27062 /app/setsettings) needs `x-steamvr-secret`. `native/vrsettings` = `fp_vrsettings.exe` (freestanding, OpenVR `FnTable:IVRSettings_003` as a Utility app, loads SteamVR's bin/win64/openvr_api.dll) sets them live and SteamVR persists them: section `steam.app.<shortcut appid>`, keys `preferredRefreshRate` (float) and `motionSmoothingOverride` (0 global, 1 on, 2 off, 3 always). Steam Link (vrlink) lists the Frame's rates 72/80/90/96/108/120/144 in vrserver.txt and follows the per-app preference ("host preferred N Hz"; whether the key is honoured is unverified in-headset yet). Judder metric: vrcompositor.txt session summary dropped + "Timed out. N total" (Stormland: 0 dropped but 313 timeouts in 2 min); fpsVR (`%LOCALAPPDATA%\fpsVR\*.json`, 0.1 ms histograms) gives p99 CPU/GPU ms. `pcvr.steamvr_tuning` (default on, PC only) applies on Play: highest rate whose budget ≥ p99×1.05, at least one step down, smoothing on.
+1 -1
View File
@@ -1093,7 +1093,7 @@
"Uninstall. ": "",
"Uninstalled {title}": "",
"Uninstalled {title} and deleted its files on this PC ({size})": "",
"Unity's built-in Oculus support (Unity 2017–2019) only starts VR when Android has Meta's com.oculus.systemactivities package; without it the game runs as a 2D app (the Android home screen or a black window, e.g. Accounting+, BattleSisters). Points that package name in libunity.so at \"android\", which always exists. Games on Unity's built-in VR (2017–2018, and 2019 without the Oculus XR Plugin) also get the frame wait their legacy frame loop never makes (libfp_ovrp.so calls ovrp_WaitToBeginFrame before ovrp_Update2; without it no frame starts, the dashboard freezes or the GPU hangs).": "",
"Unity's built-in Oculus support (Unity 2017–2019) only starts VR when Android has Meta's com.oculus.systemactivities package; without it the game runs as a 2D app (the Android home screen or a black window, e.g. Accounting+, BattleSisters). Points that package name in libunity.so at \"android\", which always exists. Games on Unity's built-in VR (2017–2018, and 2019 without the Oculus XR Plugin) also get the frame wait their legacy frame loop never makes (libfp_ovrp.so calls ovrp_WaitToBeginFrame before ovrp_Update2; without it no frame starts, the dashboard freezes or the GPU hangs), and Unity's Touch controllers, which it only creates on a device model \"Oculus Quest\" (Lepton's Android is \"Valve Lepton\"; else buttons do nothing).": "",
"Unity's TMP_InputField / InputField wait for Android's on-screen keyboard and close themselves a frame later when there is none (Lepton has no on-screen keyboard; Meta's system keyboard does this on a Quest), so a selected text field only flashes a caret. Rewrites TouchScreenKeyboardShouldBeUsed -> false and isKeyboardUsingEvents (TMP) / InPlaceEditing (uGUI) -> true in libil2cpp.so, found per game with Cpp2IL (downloaded on first use), so fields stay selected and take key presses: Steam's keyboard (with \"Show the app window\") or Type on Frame from the PC.": "",
"Unity: disable MSAA": "",
"Unity: keep MSAA off at runtime (OVRManager)": "",
@@ -16,6 +16,11 @@ ALWAYS_THERE = "android"
# Unity's legacy frame loop never calls ovrp_WaitToBeginFrame: its ovrp_Update2 lookup goes to native/ovrpshim
SHIM = "libfp_ovrp.so"
UPDATE, SHIM_UPDATE = "ovrp_Update2", "fpov_Update2"
# Unity's built-in Oculus input creates Touch controllers only when SystemInfo.deviceModel (Build.MANUFACTURER + " " +
# Build.MODEL) is "Oculus Quest"; anything else gets Go-style devices (touchpad, tracked remotes), so the game's Touch
# bindings never fire (BattleSisters, Accounting+: hands tracked, buttons dead, although OVRPlugin reports every press).
# Lepton's Android is "Valve" "Lepton": the same length, so the compared string is repointed in place.
QUEST_MODEL, LEPTON_MODEL = "Oculus Quest", "Valve Lepton"
# input diagnostics (off): the C# P/Invoke names in libil2cpp.so pointed at the shim's wrappers, which log what they
# return, report input focus as true and release buttons held > 2 s. Accounting+ still didn't pass "press any button"
# with them (input reached the game cleanly), so they stay off; switch on to investigate another game.
@@ -34,9 +39,10 @@ class UnityOculusCheck(Patch):
"libunity.so at \"android\", which always exists. Games on Unity's built-in VR (2017–2018, and 2019 "
"without the Oculus XR Plugin) also get the frame wait their legacy frame loop never makes "
"(libfp_ovrp.so calls ovrp_WaitToBeginFrame before ovrp_Update2; without it no frame starts, the "
"dashboard freezes or the GPU hangs).")
"dashboard freezes or the GPU hangs), and Unity's Touch controllers, which it only creates on a "
"device model \"Oculus Quest\" (Lepton's Android is \"Valve Lepton\"; else buttons do nothing).")
order = 45
revision = 2 # 2: frame wait also for Unity 2019 without the Oculus XR Plugin
revision = 3 # 2: frame wait also for Unity 2019 without the Oculus XR Plugin; 3: Touch input (device model)
@staticmethod
def _major(a) -> int:
@@ -71,6 +77,10 @@ class UnityOculusCheck(Patch):
return False
data, loops = elf.replace_rodata_string(data, UPDATE, SHIM_UPDATE) if self.legacy_loop(ctx.analysis) \
else (data, 0)
if loops:
data, models = elf.replace_rodata_string(data, QUEST_MODEL, LEPTON_MODEL)
if models:
ctx.notes.append(f"libunity.so: device model \"{QUEST_MODEL}\" -> \"{LEPTON_MODEL}\" (Touch input)")
plugin = ws.lib("libOVRPlugin.so")
if loops and ws.abi == "arm64-v8a" and ws.has(plugin):
ovrp = ws.read(plugin)
+8
View File
@@ -272,3 +272,11 @@ def test_user_recipes_get_a_catalog_update_offer(tmp_path, monkeypatch):
g = library.game("com.x.vr4")
assert "catalog_update" not in g and g["recipe"]["patches"]["adapter.scale"] == {"value": 0.9}
assert g["recipe"].get("source") != "user" and "adapter.vk_shader_fix" in g["recipe"]["patches"]
def test_unity_device_model_is_repointed_in_place():
from frameport.patches.frame import unity_oculus_check as C
# Unity compares SystemInfo.deviceModel with "Oculus Quest" before creating Touch controllers; Lepton's Android is
# Build.MANUFACTURER "Valve" + Build.MODEL "Lepton" (liblepton/properties.sh): an in-place edit needs equal length
assert len(C.LEPTON_MODEL) <= len(C.QUEST_MODEL) and C.LEPTON_MODEL == "Valve Lepton"