Skip to content

Config-on-connect app_config silently ignored when LocalProxy is OFF (drop the localProxy guard) #843

Description

@jonathaneoliver

Problem

The client-side config-on-connect read-back (#800 app_config: segment / protocol / live_offset_s / peak_bitrate_mbps, and now muted from #838) is gated on the localProxy flag, so it silently does not apply on any LocalProxy-OFF run.

  • iOS: applyServerAppConfig() opens with guard localProxy else { return }apple/InfiniteStreamPlayer/InfiniteStreamPlayer/PlayerViewModel.swift:1087
  • Android: applyServerAppConfig() opens with if (!_state.value.localProxy) returnandroid/InfiniteStreamPlayer/app/src/main/java/com/infinitestream/player/state/PlayerViewModel.kt:879

Why the guard is wrong

localProxy (is.flag.local_proxy) toggles the on-device LocalHTTPProxy (rewrite-through-127.0.0.1 vs direct) — it does not control whether playback routes through go-proxy. Per the code's own comment in composeURLAndLoad, session playback always routes through the go-proxy port regardless of localProxy, and app_config is read from /api/sessions on the API port (reachable regardless). So the session and its app_config exist whether or not LocalProxy is on; tying the overlay to localProxy couples it to an unrelated flag.

Net effect: any harness/characterization run with -is.flag.local_proxy false (the characterization default — see the feedback_char_localproxy_autorecovery_off convention) never applies server-pushed app_config.

Verification caveat from #838 (launch-arg confound)

The #838 config-on-connect mute verification ran with CHAR_LOCAL_PROXY=true, so LocalProxy was ON and the overlay did run (the applied server overlay … muted= log — which is emitted after the guard — fired). But that verification did not isolate config-on-connect as the cause of the client's mute state, because the char probe also sets mute via the -is.flag.muted launch arg (ProbeConfig.Mutedrunner/probe.go), which is not guarded by localProxy. Both sinks carried the same value, so "audio was muted" could be attributed to the launch arg alone.

Concretely, this is exactly why "mute worked even though the char default is LocalProxy OFF" is unsurprising: the launch arg mutes regardless; it's the config-on-connect overlay that's gated. The only unconfounded config-on-connect evidence from #838 is server-side (GET /api/sessions showing app_config.muted per player), which owes nothing to localProxy.

Proposed change

Drop the localProxy guard in applyServerAppConfig() on both platforms (or replace it with a check that actually reflects "playback routes through go-proxy", which is always true today). The fetch is already best-effort — a miss / non-proxied target is a no-op — so removing the guard is low-risk.

This touches all #800 app_config fields, not just mute, so it warrants its own PR (not a quiet change) and a fleet re-verify.

Acceptance criteria

The re-verify must isolate config-on-connect from the launch arg, and use a value opposite the app default so the overlay is the only thing that could produce it:

  • Deliver mute via config-on-connect onlyapp_config.muted: false (audible) on the session, with no -is.flag.muted launch arg. false is opposite the app's default-muted (Mute audio across all client apps — default muted, settable from every config path #838), so muting/unmuting is attributable solely to the overlay.
  • 2×2 (or at least the two diagonal cells) on a Device Farm fleet:
    • LocalProxy OFF → overlay does not run → app stays at its default (muted=true); no applied server overlay log. (Pre-fix baseline; post-fix this must change to apply.)
    • LocalProxy ON → overlay runs → muted=false (audible); applied server overlay … muted=false log present.
  • Confirm from data both server- and client-side: GET /api/sessions app_config.muted=false per player (identical in both cells — proves the value is stored regardless of LocalProxy), plus the per-sim overlay-log presence/absence (proves the guard's effect).
  • After the fix: the OFF cell now applies the overlay (audible) — i.e. config-on-connect no longer depends on localProxy.
  • Drop the CHAR_LOCAL_PROXY=true note from the Mute audio across all client apps — default muted, settable from every config path #838 mute matrix specs once it's no longer required.
  • Confirm /api/sessions lookup (metricsBaseURL) resolves correctly with LocalProxy off (it should — API port, not the on-device proxy).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions