Skip to content

Give QuantumCast a public link too; versionCode 16 - #6

Merged
guerman5 merged 2 commits into
mainfrom
tunnel-toggle
Aug 28, 2026
Merged

guerman5 merged 2 commits into
mainfrom
tunnel-toggle

Conversation

@guerman5

Copy link
Copy Markdown
Contributor

Depends on capullo-audio#5, and is pinned to that commit (ac21187) — already published on jitpack, so this builds and CI passes independently of when that PR merges.

QC drew the shared ListenQrDialog and always passed PublicLinkState.Off, because the tunnel lived in Telecloud's own folder. Now that it is a library module, QC gets the setting, the toggle and the wiring, and the dialog has something to show.

The pieces mirror Telecloud: a tunnelEnabled DataStore key, a Public link switch under Web player with the same copy (the bandwidth cost and the fact that the link is world-reachable both belong in front of the switch), TunnelManager provided @Singleton in AppModule, and PlaybackService starting the tunnel while the setting is on and the broadcast is up.

The one design decision

QC had no observable broadcast liveness. It knew only snapserverProcess != null && snapserverJob?.isActive, which a flow cannot watch, so PlaybackState gains isBroadcasting, set in startSnapcast and cleared in stopSnapcast — the only two places that own the snapserver's lifetime. The collector is distinctUntilChanged because _state churns on every ICY title and buffering tick.

onDestroy stops the tunnel explicitly rather than relying on the collector: cancelling the scope kills the collector, so an implicit stop would leave cloudflared running.

The second commit adds a dbg tunnel hook, since the switch is otherwise UI-only and the rig cannot reach it. Gated to debuggable builds like every other dbg hook.

Verification

Verified against the real pin (sibling aside, --refresh-dependencies --rerun-tasks); the APK carries lib/arm64-v8a/libcloudflared.so and tunnel_enabled is in the dex.

Device-proven end to end on the OPPO, and this is the first time the tunnel has ever run from a QC build: with the toggle on and a broadcast up, QC spawned libcloudflared.so and minted a trycloudflare.com hostname; fetching / over it returned the 112 KB Capullo web player (--http1.1, per the known HTTP/2 404 trap). Toggling back off killed cloudflared and left the snapserver running, so both directions of the wiring are proven.

QC drew the shared ListenQrDialog and always passed PublicLinkState.Off,
because the tunnel lived in Telecloud's own folder. Now that it is a library
module, QC gets the setting, the toggle and the wiring, and the dialog has
something to show.

The pieces mirror Telecloud: a tunnelEnabled DataStore key, a Public link switch
under Web player with the same copy (the bandwidth cost and the fact that the
link is world-reachable both belong in front of the switch), TunnelManager
provided @singleton in AppModule, and PlaybackService starting the tunnel while
the setting is on and the broadcast is up.

One thing QC lacked: any observable broadcast liveness. It knew only
`snapserverProcess != null && snapserverJob?.isActive`, which a flow cannot
watch, so PlaybackState gains isBroadcasting, set in startSnapcast and cleared
in stopSnapcast - the only two places that own the snapserver's lifetime. The
collector is distinctUntilChanged because _state churns on every ICY title and
buffering tick.

onDestroy stops the tunnel explicitly rather than relying on the collector:
cancelling the scope kills the collector, so an implicit stop would leave
cloudflared running.

Pinned to capullo-audio ac21187 like Telecloud - one pin, three modules.
The switch is otherwise UI-only, so the rig cannot exercise the tunnel without
tapping through Settings. Mirrors fixport, and is gated to debuggable builds
like every other dbg hook.

am start -n tech.capullo.quantumcast/.MainActivity --es dbg tunnel --ez on true
@guerman5
guerman5 requested a review from gsalinaslopez August 27, 2026 08:31
@guerman5
guerman5 merged commit 660a08f into main Aug 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants