HydraIssues

Pico 4 Ultra Enterprise: build hydraheadpico kiosk APK (Head contract + Business Streaming handoff)
open feature Priority: medium Project: hydraheadpico Reporter: 27 Jul 2026 12:08

Description

## Goal

Build a single Android APK ("hydraheadpico") for the Pico 4 Ultra Enterprise headset that acts as the fleet's kiosk/default-experience app, joining the existing Hydra Head fleet (hydraheadflatscreen, hydraheadipad).

## Key architecture decisions (from investigation, 2026-07)

**One APK, not separate programs.** Android's app-sandboxing model rules out a free-standing daemon process like hydranode/hydraheadflatscreen use on desktop. The existing precedent in this codebase for a sandboxed platform is hydraheadipad (single app process implementing everything). hydraheadpico follows the same pattern.

**Implements the Head contract, not the Body contract.** "Node behavior" here means hydracluster's Head API (`PUT /api/v1/heads/{id}` heartbeat/diagnostics, config fetch, experience catalog, remote-commands poll) — the same contract hydraheadipad/hydraheadflatscreen implement — NOT hydranode's Body contract (`/api/v1/body/*`), which is for render nodes. A Pico headset is a Head.

**Server-side change needed:** `headType()` in `hydracluster/pkg/api/handlers_api.go:443` is currently a hardcoded binary switch (hydraheadipad vs. default "flatscreen"). Needs a new `pico` case.

**Kiosk/home-app + streaming handoff, not embedding:** hydraheadpico is set as the device's home/launcher app via Pico's Enterprise SDK `PXR_Enterprise.SetAPPAsHome` (deployable via a Pico Business Manager configuration package — confirmed working by @cederik with the already-enrolled device). Streaming itself is NOT embedded in our app — Pico Business Streaming is installed by default on the headset and on render-node PCs. hydraheadpico hands off to it via `PXR_Enterprise.StartActivity`, the same pattern Pico's own reference launcher demonstrates (github.com/picoxr/Launcher-Demo-UnityXR, `LauncherUtils.cs`).

**Render-node (hydrabody) side:** Business Streaming's PC host needs installing on render nodes (separate from Sunshine). Pico ships a native Business Streaming 2.1 SDK (`BStreamingSDK.h`, C/C++/C# DLL, JSON message protocol over local IPC) that lets a control program query/control the host: `query_connection`, `stop_streaming`, `close_app`, HMD/controller battery, `get/set_game_settings`, `set_autostart`, performance telemetry. This should become a new hydrabody provisioned role/provider (parallel to the existing `sunshine` provider in `hydracluster/pkg/provider/`), giving fleet parity with what Sunshine already reports.

**Pico Business Device Manager has no confirmed third-party fleet API.** It's a closed dashboard (device enrollment, kiosk pinning, remote reboot/wipe, app push) plus the on-device Enterprise SDK. We should not rely on it for hydracluster-style fleet visibility — keep hydraheadpico's own Head-contract heartbeat as the source of truth in hydracluster, and use Business Manager only for what it's good at (OS-level fleet ops).

## Open risk: Sunshine + Business Streaming coexistence on shared render nodes

Both Sunshine and Business Streaming require GPU hardware encode (NVENC/AMD-VCE) and desktop/app capture. Installing both on one PC is probably fine (separate services/install dirs, no known conflict). Whether they can *stream concurrently* from the same GPU without capture/encoder contention is unverified — needs a real hardware test (stream to a Moonlight head and to the Pico from the same box simultaneously and watch for capture/encode errors).

Until tested, the safe path: treat `business-streaming` as a new provisionable role alongside `sunshine`, and let hydracluster's existing body-assignment/eligibility logic (which already prevents two Moonlight heads double-booking one body) also gate Pico sessions, so a node only ever has one of the two actually streaming at a time — even if both are installed. Alternatively, dedicate a subset of render nodes to Pico-only duty until concurrent capture is verified on real hardware.

## Still to verify

- Business Streaming PC host's actual port list (couldn't get it out of Pico's docs — needed for firewall config and to rule out port collision with Sunshine's `47990`+ range).
- Full content of Pico's "PICO Business Suite for Headset: SDK Usage Guide (V4.30.0.13)" doc — listed in their docs TOC but its content wasn't reachable during this investigation; may reveal more headset-side integration surface than `SetAPPAsHome`/`StartActivity`.
- Real hardware test: Sunshine + Business Streaming concurrent streaming from one render node.

## Next steps

1. Scaffold `hydraheadpico` repo (Kotlin), Head-contract client (port of `HydraClusterClient.swift`/`AppState.swift`).
2. Add `pico` case to `hydracluster`'s `headType()`.
3. Test `SetAPPAsHome` + `StartActivity` against the enrolled Pico device.
4. Add `business-streaming` provider to hydrabody/hydracluster, using `BStreamingSDK`.
5. Hardware-test Sunshine/Business-Streaming coexistence on one render node.