fix(android): stop talk mode audio capture on background#99840
fix(android): stop talk mode audio capture on background#99840xialonglee wants to merge 2 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 7:02 PM ET / 23:02 UTC. Summary PR surface: Other +18. Total +18 across 2 files. Reproducibility: yes. from source, but not from a live Android run in this review: start continuous Android TalkMode, press Home, and current main calls the manual-only stop path while the TalkMode capture loop has no foreground gate. The PR also has a focused regression test, though its third-party flavor currently fails before exercising the background stop. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review findings
Review detailsBest possible solution: Land a narrow Android lifecycle fix after the regression test passes in both Android flavors and redacted device/emulator proof shows backgrounding active continuous TalkMode stops microphone capture and the foreground-service microphone mode. Do we have a high-confidence way to reproduce the issue? Yes from source, but not from a live Android run in this review: start continuous Android TalkMode, press Home, and current main calls the manual-only stop path while the TalkMode capture loop has no foreground gate. The PR also has a focused regression test, though its third-party flavor currently fails before exercising the background stop. Is this the best way to solve the issue? Partly. Delegating background shutdown to Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against a905eb42acda. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +18. Total +18 across 2 files. View PR surface stats
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (3 earlier review cycles)
|
918f2bd to
d0baffb
Compare
dbc144a to
f64352a
Compare
Source: #99840 Co-authored-by: xialonglee <[email protected]>
stopVoiceCaptureForBackground() replaces stopManualVoiceSession() in setForeground(false) so TalkMode realtime capture (AudioRecord) is stopped when the app moves to the background, matching the existing PTT background gate added in e3f46d0.
f64352a to
5e6cf5c
Compare
* fix(agents): harden LSP process failures Source: #100450 Co-authored-by: morluto <[email protected]> * fix(sandbox): report effective workspace layout Sources: #100435, #100439 Co-authored-by: Aniruddha Adak <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> * fix(security): fail install checks on stream errors Source: #100413 Co-authored-by: 陈宪彪0668000387 <[email protected]> * fix(android): normalize all-day calendar events Source: #100032 Co-authored-by: NianJiuZst <[email protected]> * fix(ios): serialize push-to-talk lifecycle Source: #99942 Co-authored-by: NianJiuZst <[email protected]> * fix(talk): reject inherited provider names Source: #99849 Co-authored-by: zenglingbiao <[email protected]> * fix(android): stop voice capture in background Source: #99840 Co-authored-by: xialonglee <[email protected]> * fix(cron): preserve fallback result classification Source: #99913 Co-authored-by: jincheng-xydt <[email protected]> * fix(google): bound Vertex response decompression Source: #99812 Co-authored-by: 黄剑雄0668001315 <[email protected]> * fix(plugins): report malformed discovery JSON Source: #99892 Co-authored-by: 陈宪彪0668000387 <[email protected]> * test(sandbox): configure non-default workspace fixture * test: fix small-fix batch validation --------- Co-authored-by: morluto <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> Co-authored-by: 陈宪彪0668000387 <[email protected]> Co-authored-by: NianJiuZst <[email protected]> Co-authored-by: zenglingbiao <[email protected]> Co-authored-by: xialonglee <[email protected]> Co-authored-by: jincheng-xydt <[email protected]> Co-authored-by: 黄剑雄0668001315 <[email protected]>
|
Thanks @xialonglee — your Android background TalkMode fix was incorporated into #100483, landed as aaf5ab9. The landed teardown now stops continuous, one-shot, and gateway PTT capture, including the case where public voice mode is already Off. Contributor credit is preserved. Closing this superseded PR. |
Follow-up hardening for #99840 after the initial fix landed in #100483. Co-authored-by: xialonglee <[email protected]>
Follow-up hardening for #99840 after the initial fix landed in #100483. Co-authored-by: xialonglee <[email protected]>
Follow-up hardening for #99840 after the initial fix landed in #100483. Co-authored-by: xialonglee <[email protected]>
Follow-up hardening for #99840 after the initial fix landed in #100483. Co-authored-by: xialonglee <[email protected]>
* fix(android): serialize background PTT lifecycle Follow-up hardening for #99840 after the initial fix landed in #100483. Co-authored-by: xialonglee <[email protected]> * docs(changelog): note Android PTT lifecycle hardening * fix(android): order PTT ownership transitions * test(android): opt in to coroutine scheduler API * fix(android): serialize voice capture ownership * test(android): drive PTT ordering with test dispatcher * test(android): isolate PTT ordering preferences * test(android): control PTT invoke dispatchers * test(android): isolate PTT coroutine dispatchers * test(android): use current Robolectric resolver API * test(android): register speech service without deprecated APIs * test(android): control stale PTT cleanup dispatch * test(android): isolate voice mode reassertion * fix(android): clean voice capture on permission loss * fix(android): invalidate PTT before cancel wait * test(android): preserve starts queued after cancel * fix(android): keep one-shot PTT retries idempotent --------- Co-authored-by: xialonglee <[email protected]>
|
Thanks @xialonglee — the reported Android background-capture behavior is now fully landed.
The original PR remains closed because its implementation was consolidated into the maintainer landings above, with contributor credit preserved in the changelog. Thank you for identifying and fixing the original issue. |
* fix(agents): harden LSP process failures Source: openclaw#100450 Co-authored-by: morluto <[email protected]> * fix(sandbox): report effective workspace layout Sources: openclaw#100435, openclaw#100439 Co-authored-by: Aniruddha Adak <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> * fix(security): fail install checks on stream errors Source: openclaw#100413 Co-authored-by: 陈宪彪0668000387 <[email protected]> * fix(android): normalize all-day calendar events Source: openclaw#100032 Co-authored-by: NianJiuZst <[email protected]> * fix(ios): serialize push-to-talk lifecycle Source: openclaw#99942 Co-authored-by: NianJiuZst <[email protected]> * fix(talk): reject inherited provider names Source: openclaw#99849 Co-authored-by: zenglingbiao <[email protected]> * fix(android): stop voice capture in background Source: openclaw#99840 Co-authored-by: xialonglee <[email protected]> * fix(cron): preserve fallback result classification Source: openclaw#99913 Co-authored-by: jincheng-xydt <[email protected]> * fix(google): bound Vertex response decompression Source: openclaw#99812 Co-authored-by: 黄剑雄0668001315 <[email protected]> * fix(plugins): report malformed discovery JSON Source: openclaw#99892 Co-authored-by: 陈宪彪0668000387 <[email protected]> * test(sandbox): configure non-default workspace fixture * test: fix small-fix batch validation --------- Co-authored-by: morluto <[email protected]> Co-authored-by: ZengWen-DT <[email protected]> Co-authored-by: 陈宪彪0668000387 <[email protected]> Co-authored-by: NianJiuZst <[email protected]> Co-authored-by: zenglingbiao <[email protected]> Co-authored-by: xialonglee <[email protected]> Co-authored-by: jincheng-xydt <[email protected]> Co-authored-by: 黄剑雄0668001315 <[email protected]>
* fix(android): serialize background PTT lifecycle Follow-up hardening for openclaw#99840 after the initial fix landed in openclaw#100483. Co-authored-by: xialonglee <[email protected]> * docs(changelog): note Android PTT lifecycle hardening * fix(android): order PTT ownership transitions * test(android): opt in to coroutine scheduler API * fix(android): serialize voice capture ownership * test(android): drive PTT ordering with test dispatcher * test(android): isolate PTT ordering preferences * test(android): control PTT invoke dispatchers * test(android): isolate PTT coroutine dispatchers * test(android): use current Robolectric resolver API * test(android): register speech service without deprecated APIs * test(android): control stale PTT cleanup dispatch * test(android): isolate voice mode reassertion * fix(android): clean voice capture on permission loss * fix(android): invalidate PTT before cancel wait * test(android): preserve starts queued after cancel * fix(android): keep one-shot PTT retries idempotent --------- Co-authored-by: xialonglee <[email protected]>
* fix(android): serialize background PTT lifecycle Follow-up hardening for openclaw#99840 after the initial fix landed in openclaw#100483. Co-authored-by: xialonglee <[email protected]> * docs(changelog): note Android PTT lifecycle hardening * fix(android): order PTT ownership transitions * test(android): opt in to coroutine scheduler API * fix(android): serialize voice capture ownership * test(android): drive PTT ordering with test dispatcher * test(android): isolate PTT ordering preferences * test(android): control PTT invoke dispatchers * test(android): isolate PTT coroutine dispatchers * test(android): use current Robolectric resolver API * test(android): register speech service without deprecated APIs * test(android): control stale PTT cleanup dispatch * test(android): isolate voice mode reassertion * fix(android): clean voice capture on permission loss * fix(android): invalidate PTT before cancel wait * test(android): preserve starts queued after cancel * fix(android): keep one-shot PTT retries idempotent --------- Co-authored-by: xialonglee <[email protected]>
What Problem This Solves
When the Android app moves to the background (
MainActivity.onStop()→NodeRuntime.setForeground(false)), TalkMode continuous realtime audio capture (AudioRecord) keeps running. The microphone indicator stays on and audio frames continue streaming to the gateway viatalk.session.appendAudio.The root cause is
setForeground(false)callsstopManualVoiceSession(), which is guarded to only stopVoiceCaptureMode.ManualMic— when TalkMode is active, it returns immediately without stopping anything:Meanwhile, the TalkMode realtime capture loop (
TalkModeManager.kt:750) checks_isEnabledbut never checks_isForeground, soAudioRecord.read()continues uninterrupted.This is inconsistent with the PTT background gate added in
e3f46d0926(#98055), which explicitly blocks starting new Talk captures from the background but does not stop already-running continuous capture.Why This Change Was Made
A new method
stopVoiceCaptureForBackground()replacesstopManualVoiceSession()insetForeground(false). Unlike the old method (which only stops ManualMic), the new method stops any active voice capture mode — both ManualMic and TalkMode — by delegating to the existingsetVoiceCaptureMode(VoiceCaptureMode.Off)stop chain.The approach is minimal (1 file, +7/-1), reuses the proven
setVoiceCaptureMode(Off)path that already correctly stops TalkMode'srealtimeCaptureJob→AudioRecord.stop()/release()andrealtimeAppendJob→ audio frame streaming. No new stop logic or state machine added.stopManualVoiceSession()is preserved for its existing callersetVoiceScreenActive(false)(in-app navigation away from the voice screen), where only stopping ManualMic is appropriate.User Impact
Evidence
MainActivity.onStop()→NodeRuntime.setForeground(false)→stopManualVoiceSession()no-op →TalkModeManager.realtimeCaptureJobcontinuing (see analysis above)openclaw-pr-reviewpassed with P2-only findings (test gap — Android Gradle unavailable in this environment; fix path proven throughsetVoiceCaptureMode(Off)stop chain that is tested indirectly viatalkPttStart_rejectsNewCaptureWhenBackgrounded)setVoiceCaptureMode(Off)→talkMode.setEnabled(false)→TalkModeManager.stop()→stopRealtimeRelay()→realtimeCaptureJob.cancel()chain that is the same path exercised by normal TalkMode disableBehavior addressed: TalkMode AudioRecord continues after app background
Real environment tested: N/A (code-path verification)
Exact steps or command run after this patch: In-app TalkMode active → press Home → verify mic indicator disappears, AudioRecord stopped
Evidence after fix: N/A (requires Android device/emulator with Gradle build)
Observed result after fix: Pending real-device validation
What was not tested: Real-device background transition with TalkMode active (Gradle build unavailable in this environment)