Harden XR runtime override observation lane

This commit is contained in:
axiomlogicnexus 2026-07-02 08:21:24 +00:00
parent da911b07fb
commit 02399cf736
13 changed files with 530 additions and 14 deletions

View file

@ -0,0 +1,30 @@
{
"reportVersion": "ht-interactive-desktop-task/v1",
"generatedAtUtc": "2026-07-02T08:12:05.7777857Z",
"taskName": "HyperTwist-InteractiveDesktop-20260702-101205",
"taskRunnerPath": "C:\\Windows\\Temp\\HyperTwist-InteractiveDesktop-20260702-101205.runner.ps1",
"taskResultPath": "C:\\Windows\\Temp\\HyperTwist-InteractiveDesktop-20260702-101205.result.json",
"timeoutSeconds": 420,
"currentSessionId": 0,
"explorerSessionIds": [
1
],
"createExitCode": 0,
"runExitCode": 0,
"taskOutput": {
"succeeded": true,
"user": "DESKTOP-KS3VGHU\\Anthracite Ace",
"processId": 35204,
"sessionId": 1,
"explorerSessionIds": [
1
],
"generatedAtUtc": "2026-07-02T08:12:17.3348869Z",
"outputLines": [
],
"error": null
},
"result": "passed",
"error": null
}

View file

@ -0,0 +1,65 @@
{
"reportVersion": "ht-xr-package-smoke/v1",
"generatedAtUtc": "2026-07-02T08:12:17.7076451Z",
"packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild",
"executablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\Windows\\UnrealHyperTwist.exe",
"mapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"mapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"runtimeLaunchMode": "windowed",
"observationSeconds": 120,
"timeoutSeconds": 150,
"resolution": {
"width": 1600,
"height": 900
},
"keepRunning": false,
"runtimeReportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe-wmr-override-grace\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"preflight": {
"currentSessionId": 1,
"explorerSessionIds": [
1
],
"isInteractiveDesktopSession": true,
"openXrActiveRuntimePath": "C:\\Windows\\System32\\MixedRealityRuntime.json",
"openXrActiveRuntimePresent": true,
"openXrRuntimeSource": "environment-override",
"openXrRegistryRuntimePath": null,
"openXrEnvironmentOverridePath": "C:\\Windows\\System32\\MixedRealityRuntime.json"
},
"runtimeReportGraceApplied": true,
"runtimeReportGraceSeconds": 60,
"result": "passed",
"processId": 35224,
"processStopped": true,
"exitCode": null,
"runtimeReport": {
"reportVersion": "ht-xr-packaged-validation/v1",
"generatedAtUtc": "2026-07-02T08:15:13.664Z",
"launchSurfaceId": "xr/openxr-desktop-training-packaged-validation-launch-surface",
"gameModeClassPath": "/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"cookMapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"launchMapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"result": "passed",
"packagedProofStatus": "pending-hmd-session-observation",
"runtimeOwnerId": "xr/openxr-desktop-training-runtime-owner",
"preferenceProfileId": "xr-openxr-training-preferences/v1",
"controllerBindingProfileId": "xr-openxr-motion-controllers/v1",
"controllerSettingsOwnerId": "xr-openxr-controller-settings-owner/v1",
"runtimeStatusLine": "OpenXR runtime owner xr/openxr-desktop-training-runtime-owner | preferences xr-openxr-training-preferences/v1 | bindings xr-openxr-motion-controllers/v1 | HMD connected no | HMD enabled no | posture standing | dominant hand right | snap turn on | smooth locomotion on | vertical offset 0 | desktop pitch 0 | grip 0.00/0.00 | trigger 0.00/0.00",
"reportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe-wmr-override-grace\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"error": "",
"observationSeconds": 120,
"bRuntimeOwnerStructurallyValid": true,
"bControllerSettingsOwnerStructurallyValid": true,
"bHeadMountedDisplayConnected": false,
"bHeadMountedDisplayEnabled": false,
"bObservedHeadMountedDisplaySession": false,
"bObservedControllerInputActivity": false,
"observedControllerInputMagnitude": 0,
"remainingGateIds": [
"xr/windows-packaged-headset-session-observation",
"xr/windows-packaged-controller-input-observation"
]
},
"error": null
}

View file

@ -0,0 +1,29 @@
{
"reportVersion": "ht-xr-packaged-validation/v1",
"generatedAtUtc": "2026-07-02T08:15:13.664Z",
"launchSurfaceId": "xr/openxr-desktop-training-packaged-validation-launch-surface",
"gameModeClassPath": "/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"cookMapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"launchMapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"result": "passed",
"packagedProofStatus": "pending-hmd-session-observation",
"runtimeOwnerId": "xr/openxr-desktop-training-runtime-owner",
"preferenceProfileId": "xr-openxr-training-preferences/v1",
"controllerBindingProfileId": "xr-openxr-motion-controllers/v1",
"controllerSettingsOwnerId": "xr-openxr-controller-settings-owner/v1",
"runtimeStatusLine": "OpenXR runtime owner xr/openxr-desktop-training-runtime-owner | preferences xr-openxr-training-preferences/v1 | bindings xr-openxr-motion-controllers/v1 | HMD connected no | HMD enabled no | posture standing | dominant hand right | snap turn on | smooth locomotion on | vertical offset 0 | desktop pitch 0 | grip 0.00/0.00 | trigger 0.00/0.00",
"reportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe-wmr-override-grace\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"error": "",
"observationSeconds": 120,
"bRuntimeOwnerStructurallyValid": true,
"bControllerSettingsOwnerStructurallyValid": true,
"bHeadMountedDisplayConnected": false,
"bHeadMountedDisplayEnabled": false,
"bObservedHeadMountedDisplaySession": false,
"bObservedControllerInputActivity": false,
"observedControllerInputMagnitude": 0,
"remainingGateIds": [
"xr/windows-packaged-headset-session-observation",
"xr/windows-packaged-controller-input-observation"
]
}

View file

@ -0,0 +1,103 @@
{
"reportVersion": "ht-xr-windowed-live-observation/v1",
"generatedAtUtc": "2026-07-02T08:12:17.5483208Z",
"packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild",
"smokeMaps": [
"/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining"
],
"observationSeconds": 120,
"timeoutSeconds": 150,
"runtimeLaunchMode": "windowed",
"resolution": {
"width": 1600,
"height": 900
},
"openXrRuntimePathOverride": "C:\\Windows\\System32\\MixedRealityRuntime.json",
"smokeReports": [
{
"reportVersion": "ht-xr-package-smoke/v1",
"generatedAtUtc": "2026-07-02T08:12:17.7076451Z",
"packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild",
"executablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\Windows\\UnrealHyperTwist.exe",
"mapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"mapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"runtimeLaunchMode": "windowed",
"observationSeconds": 120,
"timeoutSeconds": 150,
"resolution": {
"width": 1600,
"height": 900
},
"keepRunning": false,
"runtimeReportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe-wmr-override-grace\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"preflight": {
"currentSessionId": 1,
"explorerSessionIds": [
1
],
"isInteractiveDesktopSession": true,
"openXrActiveRuntimePath": "C:\\Windows\\System32\\MixedRealityRuntime.json",
"openXrActiveRuntimePresent": true,
"openXrRuntimeSource": "environment-override",
"openXrRegistryRuntimePath": null,
"openXrEnvironmentOverridePath": "C:\\Windows\\System32\\MixedRealityRuntime.json"
},
"runtimeReportGraceApplied": true,
"runtimeReportGraceSeconds": 60,
"result": "passed",
"processId": 35224,
"processStopped": true,
"exitCode": null,
"runtimeReport": {
"reportVersion": "ht-xr-packaged-validation/v1",
"generatedAtUtc": "2026-07-02T08:15:13.664Z",
"launchSurfaceId": "xr/openxr-desktop-training-packaged-validation-launch-surface",
"gameModeClassPath": "/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"cookMapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"launchMapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"result": "passed",
"packagedProofStatus": "pending-hmd-session-observation",
"runtimeOwnerId": "xr/openxr-desktop-training-runtime-owner",
"preferenceProfileId": "xr-openxr-training-preferences/v1",
"controllerBindingProfileId": "xr-openxr-motion-controllers/v1",
"controllerSettingsOwnerId": "xr-openxr-controller-settings-owner/v1",
"runtimeStatusLine": "OpenXR runtime owner xr/openxr-desktop-training-runtime-owner | preferences xr-openxr-training-preferences/v1 | bindings xr-openxr-motion-controllers/v1 | HMD connected no | HMD enabled no | posture standing | dominant hand right | snap turn on | smooth locomotion on | vertical offset 0 | desktop pitch 0 | grip 0.00/0.00 | trigger 0.00/0.00",
"reportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe-wmr-override-grace\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"error": "",
"observationSeconds": 120,
"bRuntimeOwnerStructurallyValid": true,
"bControllerSettingsOwnerStructurallyValid": true,
"bHeadMountedDisplayConnected": false,
"bHeadMountedDisplayEnabled": false,
"bObservedHeadMountedDisplaySession": false,
"bObservedControllerInputActivity": false,
"observedControllerInputMagnitude": 0,
"remainingGateIds": [
"xr/windows-packaged-headset-session-observation",
"xr/windows-packaged-controller-input-observation"
]
},
"error": null
}
],
"preflight": {
"currentSessionId": 1,
"explorerSessionIds": [
1
],
"isInteractiveDesktopSession": true,
"openXrActiveRuntimePath": "C:\\Windows\\System32\\MixedRealityRuntime.json",
"openXrActiveRuntimePresent": true,
"openXrRuntimeSource": "environment-override",
"openXrRegistryRuntimePath": null,
"openXrEnvironmentOverridePath": "C:\\Windows\\System32\\MixedRealityRuntime.json"
},
"packagedHeadMountedDisplaySessionObserved": false,
"packagedControllerInputObserved": false,
"remainingGateIds": [
"xr/windows-packaged-headset-session-observation",
"xr/windows-packaged-controller-input-observation"
],
"result": "pending-live-observation",
"error": null
}

View file

@ -255,3 +255,21 @@ widening.
- that rerun shows the interactive-desktop requirement is now satisfied and
the remaining blocker has narrowed further to one host fact only:
`OpenXR` still has no active runtime registered on the desktop
- the latest same-day continuation then closed even that runtime-resolution
blocker without mutating the machine-wide registry:
- `scripts\Launch-HyperTwistXrPackage.ps1` and
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1` now also accept a
bounded per-process `OpenXrRuntimePathOverride`
- the maintained lane used that override to point at existing host manifest
`C:\Windows\System32\MixedRealityRuntime.json`
- checked-in corrected proof now lives at:
`docs/generated/xr/xr_interactive_desktop_task_probe_wmr_override_grace_2026-07-02.json`
and
`docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
- that corrected rerun proves the packaged follow-along map now reaches
runtime report result `passed` with packaged proof status
`pending-hmd-session-observation`
- the remaining live blockers are therefore no longer runtime resolution but
the actual physical observation facts:
`bHeadMountedDisplayConnected: false`,
`bHeadMountedDisplayEnabled: false`, and no controller-input activity yet

View file

@ -776,6 +776,37 @@ Operational rules reinforced by this proof:
- the remaining blocker is no longer the desktop-session bridge
- the remaining blocker is the absent active `OpenXR` runtime on the logged-
in Windows desktop
- the next same-day continuation then removed the runtime-resolution blocker
too without changing the machine-wide registry:
- `scripts\Launch-HyperTwistXrPackage.ps1` and
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1` now also accept
`-OpenXrRuntimePathOverride`
- the maintained lane used override path
`C:\Windows\System32\MixedRealityRuntime.json`
- the first override-backed rerun exposed a real wrapper defect rather than a
host/runtime defect: the packaged runtime report arrived after the original
timeout window, which falsely marked the pass failed
- the wrapper was then hardened with a bounded windowed-only runtime-report
grace window, and the maintained bridge-assisted rerun checked in:
`docs/generated/xr/xr_interactive_desktop_task_probe_wmr_override_grace_2026-07-02.json`
and
`docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
- that corrected rerun now proves:
- Session `1`: reached
- `openXrRuntimeSource`: `environment-override`
- `openXrActiveRuntimePresent`: `true`
- packaged runtime report result: `passed`
- packaged proof status: `pending-hmd-session-observation`
- `bHeadMountedDisplayConnected`: `false`
- `bHeadMountedDisplayEnabled`: `false`
- observed controller input: none
- operational reading after the override plus grace continuation:
- the reverse-SSH lane plus first-party desktop bridge is now sufficient to
launch a real Session `1` windowed XR proof without relying on a machine-
wide `ActiveRuntime` registry entry
- the remaining live blockers are now the actual physical headset-session
and controller-input observations, not the launcher bridge and not runtime
manifest resolution
- canonical local Windows desktop command for that remaining gate is still:
```powershell
@ -783,11 +814,19 @@ powershell -NoProfile -ExecutionPolicy Bypass -File C:\HyperTwist_worktrees\phas
```
- canonical Session `0` bridge-assisted command shape is now:
without override:
```powershell
& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1' -InlineCommand "& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1' -PackageRoot 'C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild'"
```
- canonical Session `0` bridge-assisted command shape with bounded runtime
override is now:
```powershell
& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1' -InlineCommand "& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1' -PackageRoot 'C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild' -OpenXrRuntimePathOverride 'C:\Windows\System32\MixedRealityRuntime.json'"
```
- that local desktop run writes the aggregate live-observation report beneath:
`C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild\validation\windowed-live\`

View file

@ -645,3 +645,8 @@ But the mature path is:
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- the wrapper therefore belongs to the bounded workflow/review or provider/ops
command-surface family, not to the shippable gameplay feature layer
- the later same-day `OpenXrRuntimePathOverride` continuation on
`scripts\Launch-HyperTwistXrPackage.ps1` and
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1` follows the same rule:
it is a bounded validation/ops command seam for runtime selection and proof,
not a new player-facing product feature

View file

@ -422,6 +422,24 @@ scripts/run-hypertwist-remote-unreal-automation-sequence.sh \
proves the session-context requirement is satisfied and that the only
remaining blocker is an absent active `OpenXR` runtime on the Windows
desktop
- a later same-day continuation then added bounded per-process
`OpenXrRuntimePathOverride` support to
`scripts\Launch-HyperTwistXrPackage.ps1` and
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1`, which let the
maintained bridge-assisted lane use existing host manifest
`C:\Windows\System32\MixedRealityRuntime.json` without mutating the machine-
wide registry
- that same override-backed rerun also exposed a real wrapper defect: the
packaged runtime report could arrive after the original timeout budget even
when the packaged runtime itself later reported `result: passed`
- `scripts\Launch-HyperTwistXrPackage.ps1` therefore now carries a bounded
windowed-only runtime-report grace window, and corrected proof now lives at
`docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
- operational reading after that correction:
- runtime manifest resolution is no longer the remaining live blocker when
the bounded override seam is used
- the remaining live blockers are now actual physical headset-session and
controller-input observation on the Windows desktop
- for reverse-SSH/headless classic-cube replay-export validation, use
`-NullRHI` only for the asset-authoring leg and `-RenderOffScreen` for the
actual `MovieRenderQueue` render leg; they solve different failure modes

View file

@ -430,6 +430,22 @@ truthfully claim:
Session `1` with `isInteractiveDesktopSession: true`
- the remaining blocker is therefore narrowed to absent active `OpenXR`
runtime, not to the Windows desktop-session bridge anymore
- a later same-day override plus grace continuation then removed the runtime-
resolution blocker too without changing the global host registry:
- `scripts\Launch-HyperTwistXrPackage.ps1` and
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1` now also own bounded
per-process `OpenXrRuntimePathOverride`
- checked-in corrected rerun:
`docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
- that corrected rerun proves:
- `isInteractiveDesktopSession: true`
- `openXrRuntimeSource: environment-override`
- `openXrActiveRuntimePresent: true`
- packaged runtime report result: `passed`
- packaged proof status: `pending-hmd-session-observation`
- `bHeadMountedDisplayConnected: false`
- `bHeadMountedDisplayEnabled: false`
- no controller-input activity observed yet
- the current remaining unproven pieces therefore are:
- live packaged headset-session observation on the Windows lane
- live packaged controller-input observation on the Windows lane
@ -511,8 +527,9 @@ first clean remaining implementation packet should be:
Windows Unreal lane, kept explicit above the now-landed bounded runtime-
owner plus controller settings/rebinding substrate and above the already-
shipped headless `nullrhi` packaged structural proof, and run from the
interactive logged-in Windows desktop session with an active local `OpenXR`
runtime; that session may now be reached either directly on the desktop or
through the new first-party interactive-desktop task bridge above the
reverse-SSH Session `0` lane
interactive logged-in Windows desktop session; that session may now be
reached either directly on the desktop or through the new first-party
interactive-desktop task bridge above the reverse-SSH Session `0` lane, and
runtime resolution may now be provided either by a real machine-wide active
runtime or by the bounded first-party per-process override seam
2. public/product copy update only after that live packaged proof exists

View file

@ -2540,6 +2540,42 @@ powershell -NoProfile -ExecutionPolicy Bypass -File C:\HyperTwist_worktrees\phas
& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1' -InlineCommand "& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1' -PackageRoot 'C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild'"
```
## XR runtime-override plus grace hardening continuation (`2026-07-02`)
- the next same-family continuation then removed the remaining runtime-
resolution blocker without mutating the host-wide `OpenXR` registry state
- current exact-source truth is now also source-backed through:
- `scripts/Launch-HyperTwistXrPackage.ps1`
- `scripts/Invoke-HyperTwistXrWindowedObservation.ps1`
- checked-in corrected proof:
`docs/generated/xr/xr_interactive_desktop_task_probe_wmr_override_grace_2026-07-02.json`
- checked-in aggregate rerun:
`docs/generated/xr/xr_windowed_interactive_desktop_probe_wmr_override_grace_2026-07-02.json`
- the wrappers now accept bounded per-process
`OpenXrRuntimePathOverride`, and the maintained reverse-SSH bridge used
existing host manifest `C:\Windows\System32\MixedRealityRuntime.json`
- the first override-backed rerun exposed a truthful wrapper defect: the
packaged runtime report arrived after the original timeout budget even though
the packaged runtime itself later reported `result: passed`
- `scripts/Launch-HyperTwistXrPackage.ps1` now therefore carries a bounded
windowed-only runtime-report grace window instead of calling that late report
a hard failure
- the corrected rerun now proves:
- Session `1`: reached
- `openXrRuntimeSource: environment-override`
- `openXrActiveRuntimePresent: true`
- packaged runtime report result: `passed`
- packaged proof status: `pending-hmd-session-observation`
- `bHeadMountedDisplayConnected: false`
- `bHeadMountedDisplayEnabled: false`
- no controller-input activity observed yet
- current truthful reading after this continuation:
- HyperTwist now owns first-party desktop bridge plus per-process runtime
override plus late-report grace hardening for the remaining live XR lane
- the remaining live blockers are the actual physical headset-session and
controller-input observations, not launcher reachability and not runtime
manifest resolution
## Latest protected launch-status responsive recovery plus tooling rerun (`2026-06-29`)
- the next same-family browser pass fixed a real small-screen regression on the

File diff suppressed because one or more lines are too long

View file

@ -8,6 +8,7 @@ param(
[double]$TimeoutSeconds = 150.0,
[int]$ResX = 1600,
[int]$ResY = 900,
[string]$OpenXrRuntimePathOverride = '',
[string]$ValidationDirectory = '',
[string]$AggregateReportPath = '',
[switch]$KeepRunning
@ -120,6 +121,7 @@ $AggregateReport = [ordered]@{
width = $ResX
height = $ResY
}
openXrRuntimePathOverride = $OpenXrRuntimePathOverride
smokeReports = @()
preflight = $null
packagedHeadMountedDisplaySessionObserved = $false
@ -145,6 +147,7 @@ try
-RuntimeLaunchMode 'windowed' `
-ResX $ResX `
-ResY $ResY `
-OpenXrRuntimePathOverride $OpenXrRuntimePathOverride `
-ReportPath $SmokeReportPath `
-KeepRunning:$KeepRunning

View file

@ -7,6 +7,7 @@ param(
[string]$RuntimeLaunchMode = 'nullrhi',
[int]$ResX = 1600,
[int]$ResY = 900,
[string]$OpenXrRuntimePathOverride = '',
[string]$ReportPath = '',
[switch]$KeepRunning
)
@ -104,20 +105,61 @@ function Get-OpenXrActiveRuntimePath {
return $null
}
function Get-ResolvedOpenXrRuntime {
param(
[string]$RuntimePathOverride = ''
)
$RegistryRuntimePath = Get-OpenXrActiveRuntimePath
$ResolvedOverridePath = if ([string]::IsNullOrWhiteSpace($RuntimePathOverride))
{
$null
}
else
{
[string]$RuntimePathOverride
}
if (-not [string]::IsNullOrWhiteSpace($ResolvedOverridePath))
{
return [ordered]@{
activeRuntimePath = $ResolvedOverridePath
runtimeSource = 'environment-override'
runtimePresent = [bool](Test-Path -LiteralPath $ResolvedOverridePath)
registryRuntimePath = $RegistryRuntimePath
environmentOverridePath = $ResolvedOverridePath
}
}
return [ordered]@{
activeRuntimePath = $RegistryRuntimePath
runtimeSource = 'registry'
runtimePresent =
-not [string]::IsNullOrWhiteSpace($RegistryRuntimePath) `
-and [bool](Test-Path -LiteralPath $RegistryRuntimePath)
registryRuntimePath = $RegistryRuntimePath
environmentOverridePath = $null
}
}
function Get-XrWindowedPreflight {
param(
[string]$RuntimePathOverride = ''
)
$CurrentSessionId = Get-CurrentSessionId
$ExplorerSessionIds = @(Get-ExplorerSessionIds)
$OpenXrActiveRuntimePath = Get-OpenXrActiveRuntimePath
$OpenXrActiveRuntimePresent =
-not [string]::IsNullOrWhiteSpace($OpenXrActiveRuntimePath) `
-and (Test-Path -LiteralPath $OpenXrActiveRuntimePath)
$ResolvedOpenXrRuntime = Get-ResolvedOpenXrRuntime -RuntimePathOverride $RuntimePathOverride
return [ordered]@{
currentSessionId = $CurrentSessionId
explorerSessionIds = @($ExplorerSessionIds)
isInteractiveDesktopSession = [bool]($ExplorerSessionIds -contains $CurrentSessionId)
openXrActiveRuntimePath = $OpenXrActiveRuntimePath
openXrActiveRuntimePresent = [bool]$OpenXrActiveRuntimePresent
openXrActiveRuntimePath = $ResolvedOpenXrRuntime.activeRuntimePath
openXrActiveRuntimePresent = [bool]$ResolvedOpenXrRuntime.runtimePresent
openXrRuntimeSource = $ResolvedOpenXrRuntime.runtimeSource
openXrRegistryRuntimePath = $ResolvedOpenXrRuntime.registryRuntimePath
openXrEnvironmentOverridePath = $ResolvedOpenXrRuntime.environmentOverridePath
}
}
@ -148,14 +190,35 @@ function Assert-XrWindowedPreflight {
if (-not [bool]$Preflight.openXrActiveRuntimePresent)
{
$RuntimeSource = [string](Get-JsonPropertyValue `
-Object $Preflight `
-Names @('openXrRuntimeSource', 'OpenXrRuntimeSource') `
-Default 'registry')
if ([string]::IsNullOrWhiteSpace([string]$Preflight.openXrActiveRuntimePath))
{
if ($RuntimeSource -eq 'environment-override')
{
throw (
"Windowed XR validation received an OpenXR runtime override request, but the override path was empty. " +
"Provide a full runtime manifest path or remove the override and activate a local OpenXR runtime."
)
}
throw (
"Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. " +
"Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun."
)
}
if ($RuntimeSource -eq 'environment-override')
{
throw (
"Windowed XR validation received OpenXR runtime override path '{0}', but that manifest was not present on disk. " +
"Repair the override path or remove it and reactivate a local OpenXR runtime."
) -f $Preflight.openXrActiveRuntimePath
}
throw (
"Windowed XR validation requires an installed active OpenXR runtime, but the configured ActiveRuntime path '{0}' was not present on disk. " +
"Repair or reactivate the local OpenXR runtime on the interactive desktop and rerun."
@ -163,6 +226,60 @@ function Assert-XrWindowedPreflight {
}
}
function Format-ProcessArgument {
param(
[AllowNull()]
[string]$Value
)
if ($null -eq $Value)
{
return '""'
}
if ($Value -notmatch '[\s"]')
{
return $Value
}
$EscapedValue = $Value -replace '(\\*)"', '$1$1\"'
$EscapedValue = $EscapedValue -replace '(\\+)$', '$1$1'
return '"' + $EscapedValue + '"'
}
function Start-ObservedProcess {
param(
[Parameter(Mandatory = $true)]
[string]$FilePath,
[Parameter(Mandatory = $true)]
[string[]]$ArgumentList,
[Parameter(Mandatory = $true)]
[string]$WorkingDirectory,
[string]$OpenXrRuntimePathOverride = ''
)
if ([string]::IsNullOrWhiteSpace($OpenXrRuntimePathOverride))
{
return Start-Process `
-FilePath $FilePath `
-ArgumentList $ArgumentList `
-WorkingDirectory $WorkingDirectory `
-PassThru
}
$ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessStartInfo.FileName = $FilePath
$ProcessStartInfo.Arguments = (
@($ArgumentList) |
ForEach-Object { Format-ProcessArgument -Value ([string]$_) }
) -join ' '
$ProcessStartInfo.WorkingDirectory = $WorkingDirectory
$ProcessStartInfo.UseShellExecute = $false
$ProcessStartInfo.EnvironmentVariables['XR_RUNTIME_JSON'] = $OpenXrRuntimePathOverride
return [System.Diagnostics.Process]::Start($ProcessStartInfo)
}
function Convert-PathToken {
param(
[string]$Value
@ -218,7 +335,7 @@ if (Test-Path -LiteralPath $RuntimeReportPath)
$WindowedPreflight = if ($ResolvedRuntimeLaunchMode -eq 'windowed')
{
Get-XrWindowedPreflight
Get-XrWindowedPreflight -RuntimePathOverride $OpenXrRuntimePathOverride
}
else
{
@ -279,6 +396,15 @@ $Report = [ordered]@{
keepRunning = [bool]$KeepRunning
runtimeReportPath = $RuntimeReportPath
preflight = $WindowedPreflight
runtimeReportGraceApplied = $false
runtimeReportGraceSeconds = if ($ResolvedRuntimeLaunchMode -eq 'windowed')
{
[double][Math]::Max(60.0, [Math]::Ceiling($ObservationSeconds * 0.5))
}
else
{
0.0
}
result = 'failed'
processId = $null
processStopped = $false
@ -295,11 +421,11 @@ try
}
Write-Host "Launching packaged XR validation lane from '$ExecutablePath'..."
$Process = Start-Process `
$Process = Start-ObservedProcess `
-FilePath $ExecutablePath `
-ArgumentList $ArgumentList `
-WorkingDirectory (Split-Path -Parent $ExecutablePath) `
-PassThru
-OpenXrRuntimePathOverride $OpenXrRuntimePathOverride
$Report.processId = $Process.Id
$Deadline = [DateTime]::UtcNow.AddSeconds([Math]::Max($TimeoutSeconds, $ObservationSeconds + 5.0))
@ -318,6 +444,33 @@ try
}
}
if (-not (Test-Path -LiteralPath $RuntimeReportPath) `
-and $ResolvedRuntimeLaunchMode -eq 'windowed' `
-and $null -ne $Process)
{
$Process.Refresh()
if (-not $Process.HasExited -and $Report.runtimeReportGraceSeconds -gt 0.0)
{
$Report.runtimeReportGraceApplied = $true
$GraceDeadline = [DateTime]::UtcNow.AddSeconds($Report.runtimeReportGraceSeconds)
while ([DateTime]::UtcNow -lt $GraceDeadline)
{
if (Test-Path -LiteralPath $RuntimeReportPath)
{
break
}
Start-Sleep -Milliseconds 500
$Process.Refresh()
if ($Process.HasExited)
{
$Report.exitCode = $Process.ExitCode
break
}
}
}
}
if (-not (Test-Path -LiteralPath $RuntimeReportPath))
{
throw "The packaged XR runtime report was not written to '$RuntimeReportPath' before timeout."