Skip to content

fix(prod-reliability): wire ReservationState, restore camera controls, harden release paths - #41

Open
YashasVM wants to merge 6 commits into
mainfrom
fix/openstream-prod-reliability
Open

YashasVM wants to merge 6 commits into
mainfrom
fix/openstream-prod-reliability

Conversation

@YashasVM

@YashasVM YashasVM commented Sep 20, 2026

Copy link
Copy Markdown
Owner

Resolves code-review + grill findings on HEAD working-tree diff.

Standards:

  • Fixes MainActivity val-vs-assignment compile break by routing all mutation through ReservationState beginSelection/confirm/release/clear
  • Removes Speculative Generality (pendingReservation) and unifies shinEncoder log tags
  • Encoder AVC hardware-only selection now has behavioural contract (Rule 15)
  • Dock keeps UI-thread safety (bounded slots only) while restoring peer-bound lens/torch/identify

Spec (reliability-audit + AGENT_PROGRESS provisional):

  • Session-owner half-migration completed: pending advertised-not-busy, confirmed busy, 45s pending rollback vs confirmed release
  • Camera controls exercisable from dock again via bounded send()
  • Discovery peer-authoritative with manual override + blank rejection
  • Worker-exit release-before-clear with destroy-order guarantee documented
  • Decoder audio path preserved, HW fallback warning intact

Follow-up (prod-ready pass, 4 commits):

  • Ported Android no-crash hardening: appContext, nullable CameraManager, guarded SRT native load, control onError, onStop off-UI (shinActivityStop daemon), identify leak fix, permission-denied UI, bitrate lock, lens restart off-UI with single-flight lock, stopPhoneServer blockingWork off-UI with Reserved escape hatch — ReservationState model preserved.
  • Plugin: discovery bounded 64 evict-eldest with warning; Reserved names SRT target + control-OK log; properties minimal (Test/Disconnect/Zoom/Identify, torch/lens live only in dock via bounded send, dead command table removed).
  • Tests: new test_prod_hardening_contract (12 guards) + srt-contract update for guarded native wrappers. pytest -q 113 passed.
  • Hygiene: local .claude/ scaffolding gitignored, not shipped.

Queues (Rule 16): discovery 64 evict-eldest + warning; control/lifecycle bounded coalescing slots; release queue urgent cap 4 drop-newest.
Perf (Rule 14): UI teardown 0ms block (was 2s join); discovery O(1) bounded; lens restart + MediaCodecList off UI; OBS slot render diffed (no per-beacon inflation).
HW (Rule 18): single HW AVC encoder, explicit throw, no silent SW; decode HW probe with explicit logged fallback.
Merge note: unified design = dock FULL (8 peer-bound buttons) + properties MINIMAL (no duplication). Pairs with #40 (crash/connect scope); if #40 merges first, this branch rebases keeping this dock. Physical 2-phone Wi-Fi acceptance still outstanding per AGENT_PROGRESS.

…, harden release paths

Android reservation now fully delegates to ReservationState:
pending selection is advertised but not busy, only /reserve
confirms. busy/advertised providers use isBusy/advertisedId,
45s lease split into pending rollback vs confirmed release.
Fixes MainActivity val-vs-assignment compile break.

Discovery prefers UDP peer with explicit manual override and
blank-host rejection. Encoder log tags unified to shinEncoder
with AVC hardware-only selection contract. Dock restores
peer-bound lens/torch/identify via bounded slots (8 buttons).
Worker exit documents release-before-clear destroy ordering.

Tests: 101 passed.
@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 8d7db27e-611c-46e2-8703-d0f7c21517d9


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…tall destinations

- Android unit tests run on JVM against android.jar stubs where
  org.json.JSONObject throws 'not mocked'. Add test-only
  org.json:json so ObsDiscoveryProtocolTest exercises real parsing.
  On-device code still uses platform org.json.
- Windows CMake MODULE target needs LIBRARY (and ARCHIVE)
  destination; configure failed with 'install TARGETS given no
  LIBRARY DESTINATION'. RUNTIME-only was insufficient.

Tests: pytest -q 101 passed locally. Android unit-test + Windows
build verification via CI.

@YashasVM YashasVM left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yashas's code review bot: Reviewed the current reliability patch and its reservation-state migration. The pending-vs-confirmed ownership model is materially safer than the prior half-migrated state, the release paths preserve ownership checks, and all four current CI workflows (Android, Windows OBS, Linux OBS, Website) pass on this exact head. I found no remaining correctness, security, or merge-blocking issue in this PR. This head is safe to merge.

- Camera2Controller: appContext + nullable CameraManager, non-crashing
  select/open/switch with single-Back fallback and warnings.
- CameraControlServer: clientLock sync, bind errors surfaced via onError.
- SrtStreamClient: guarded native load (loadError/isAvailable), explicit
  unavailable error instead of UnsatisfiedLinkError crash.
- docs/architecture: canonical 51615/239.255.43.99/9100/9101.
- gitignore local .claude/ agent scaffolding.

Tests: pytest -q 113 passed.
Keep pending-advertised/confirmed-busy ReservationState model while
porting crash/ANR fixes: appContext, native-unavailable status, control
onError surface, onStop off-UI (shinActivityStop daemon), identify leak
fix, permission-denied UI, bitrate lock, lens restart off-UI with
single-flight lock, stopPhoneServer blockingWork off-UI with
Reserved escape hatch.

Tests: pytest -q 113 passed.
…rties

- Discovery registry bounded 64 evict-eldest with warning (AGENTS 3/16).
- Reserved names SRT target + control-OK log (TCP 9101 OK vs SRT 9100
  blocked diagnosable).
- Properties minimal: Test/Disconnect/Zoom/Identify only; torch/lens live
  in dock via bounded send (no duplication). Drop dead command table.

Tests: pytest -q 113 passed.
- New test_prod_hardening_contract: 12 guards covering crash-free
  Android, ReservationState preserved, bounded discovery, diagnosable
  Reserved, dock-full/properties-minimal split, canonical docs.
- test_srt_contract: accept guarded native wrappers (nativeSendVideo/
  nativeSendAudio) + require loadError/isAvailable.

Tests: pytest -q 113 passed.

@YashasVM YashasVM left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yashas's code review bot: IMPORTANT — the ported off-UI teardown has the same replacement-session race here. stopPhoneServer() returns immediately on the main thread while a background worker later disconnects the shared streamClient and stops camera/encoder/audio. The Stop button immediately calls startPreviewIfAllowed() / startPhoneServerIfAllowed() after that return, and a fast onStop()onStart() can also restart discovery/control/listening before shinActivityStop finishes. The stale teardown can then stop the newly created session. Please make teardown/restart ordering explicit (or generation-guard stale teardown against newer starts) and cover stop→immediate restart plus lifecycle stop→start with a regression/contract test before merging.

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.

1 participant