Skip to content

[codex] Gate Android Talk capture starts in background#98055

Merged
steipete merged 2 commits into
openclaw:mainfrom
NianJiuZst:codex/android-talk-foreground-gate
Jul 2, 2026
Merged

[codex] Gate Android Talk capture starts in background#98055
steipete merged 2 commits into
openclaw:mainfrom
NianJiuZst:codex/android-talk-foreground-gate

Conversation

@NianJiuZst

Copy link
Copy Markdown
Contributor

What Problem This Solves

Android Talk push-to-talk capture can start microphone capture and move NodeForegroundService into the microphone foreground-service type. On modern Android, starting a microphone foreground service from the background is restricted, so remote talk.ptt.start / talk.ptt.once invocations should not start a new capture while the app is backgrounded.

Why This Change Was Made

This gates new Talk capture starts at the Android runtime boundary. talk.ptt.once remains a foreground-only dispatcher command, while talk.ptt.start is handled in NodeRuntime so idempotent retries for an already-active capture can still return the current capture id. TalkModeManager.beginPushToTalk(allowNewCapture = false) owns the final new-capture check to avoid a race between an external active-capture precheck and the actual begin operation.

User Impact

Background remote commands no longer try to create a new microphone capture path that Android can reject at foreground-service startup time. Existing active PTT sessions can still be stopped/cancelled, and ptt.start retries for an active session still reconcile to the same capture id.

Evidence

  • cd apps/android && ./gradlew :app:testThirdPartyDebugUnitTest --tests ai.openclaw.app.node.InvokeCommandRegistryTest --tests ai.openclaw.app.node.InvokeDispatcherTest --tests ai.openclaw.app.GatewayBootstrapAuthTest --tests ai.openclaw.app.voice.TalkModeManagerTest
  • git diff --check
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main

Known unrelated local check gap:

  • cd apps/android && ./gradlew :app:ktlintCheck currently fails on untouched upstream files: apps/android/app/src/main/java/ai/openclaw/app/GatewayExecApprovals.kt and apps/android/app/src/main/java/ai/openclaw/app/ui/design/ClawSurfaces.kt.

@NianJiuZst
NianJiuZst marked this pull request as ready for review June 30, 2026 06:54
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 2, 2026, 9:16 AM ET / 13:16 UTC.

Summary
The PR changes Android Talk push-to-talk handling so background starts cannot create a new microphone capture while preserving active-session retry, stop, and cancel behavior.

PR surface: Other +88. Total +88 across 9 files.

Reproducibility: yes. Current main routes background talk.ptt.start through prepareTalkCapture without a foreground gate before microphone foreground-service promotion, and the PR discussion includes before/after Android 16 emulator proof of that path.

Review metrics: 1 noteworthy metric.

  • Foreground command policy changed: 1 command metadata change, 1 runtime capture gate. This changes remote node.invoke behavior during upgrade, so maintainers should review the foreground-only policy intentionally.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit ✨ media proof bonus
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] The PR intentionally changes upgrade behavior for any workflow that relied on starting a new Android Talk PTT microphone capture while the app is backgrounded; green CI cannot decide whether maintainers accept that compatibility break.

Maintainer options:

  1. Accept foreground-only Talk starts (recommended)
    Merge once maintainers accept that new background Android PTT starts now fail fast instead of attempting microphone capture.
  2. Pause for a compatibility mode
    If background PTT starts are considered supported on any target Android path, pause and replace this with an explicit compatibility or API-level policy design.

Next step before merge

  • No automated repair is needed; the remaining action is maintainer acceptance and merge handling for the intentional compatibility change.

Security
Cleared: The diff changes Android runtime microphone gating, tests, and i18n line metadata only; it does not add dependencies, workflows, permissions, secret handling, or supply-chain execution paths.

Review details

Best possible solution:

Merge the exact-head foreground gate if maintainers accept foreground-only new Android Talk capture starts, keeping the active retry and stop/cancel paths routable as the patch does.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main routes background talk.ptt.start through prepareTalkCapture without a foreground gate before microphone foreground-service promotion, and the PR discussion includes before/after Android 16 emulator proof of that path.

Is this the best way to solve the issue?

Yes. Gating new capture at NodeRuntime plus a final TalkModeManager allowNewCapture check is the narrow owner-boundary fix; marking only talk.ptt.once foreground-only preserves active-session retry and stop/cancel control.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against b60e8c48382d.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
  • add proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This is a focused Android runtime bug fix with limited blast radius and no crash-loop, data-loss, or cross-channel emergency signal.
  • merge-risk: 🚨 compatibility: The PR deliberately makes new background Android PTT capture starts fail fast, which can change existing remote-control workflows after upgrade.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
  • proof: sufficient: Contributor real behavior proof is sufficient. A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. A maintainer comment provides exact-head Android 16 emulator before/after screenshots and runtime observations for blocked new background capture, active retry, and stop release.
Evidence reviewed

PR surface:

Other +88. Total +88 across 9 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 9 103 15 +88
Total 9 103 15 +88

What I checked:

Likely related people:

  • steipete: Peter Steinberger introduced Android Talk mode and the native node Talk handoff in the central runtime/dispatcher/manager paths, and also provided exact-head runtime proof on this PR. (role: feature introducer and recent PR verifier; confidence: high; commits: 86d897cfaa6a, 466f7183207d; files: apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt, apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt, apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt)
  • joshavant: Recent work on Android microphone foreground-service handling touched the service/runtime boundary that this PR hardens. (role: recent foreground-service contributor; confidence: high; commits: 8ab36e4308df; files: apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt, apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt)
  • Ayaan Zaidi: Recent Android Talk/realtime and foreground-service work touched TalkModeManager, NodeForegroundService, and adjacent voice tests used to validate this behavior. (role: recent Android Talk area contributor; confidence: medium; commits: 70614f88cc05, e52a3b31e47d, 6d7eb9bb8483; files: apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt, apps/android/app/src/test/java/ai/openclaw/app/voice/TalkModeManagerTest.kt, apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 30, 2026
@steipete steipete self-assigned this Jul 2, 2026
@steipete
steipete force-pushed the codex/android-talk-foreground-gate branch from 29ce660 to ae446c1 Compare July 2, 2026 13:02
@steipete

steipete commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Maintainer verification on exact head ae446c11c8e565d13188bd9770e8c8e2f1bd16a8:

  • Made Talk capture policy explicit: talk.ptt.once is foreground-only; talk.ptt.start may reconcile an already-active capture in background but cannot create a new one; stop/cancel remain routable.
  • Passed 76 focused registry/dispatcher/runtime/manager tests, Android ktlint, native i18n inventory, debug APK assembly, git diff --check, and fresh exact-tree autoreview (no actionable findings).
  • Exact-head hosted CI is green: 63 passed, 12 skipped.

Live Android 16 emulator proof:

  • Before (current main): background talk.ptt.start succeeded, promoted the existing service to microphone type, started recognition, and left RECORD_AUDIO running.
  • After: the same new background start returned NODE_BACKGROUND_UNAVAILABLE; no recognizer start, microphone service transition, running AppOps record, or privacy chip.
  • Active retry: a foreground-started capture remained addressable from background. Retry returned the existing capture without a second recognizer start, and background stop released the microphone.

This matches Android's current while-in-use foreground-service restriction while preserving lifecycle control for an already-running capture.

Before: background start records After: new background start blocked After: active capture retry still works
Before fix Android microphone privacy indicator active after background Talk start After fix no microphone privacy indicator after blocked background Talk start After fix microphone privacy indicator for foreground-started active capture

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 2, 2026
@steipete
steipete merged commit e3f46d0 into openclaw:main Jul 2, 2026
105 of 112 checks passed
@steipete

steipete commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

LeonidasLux pushed a commit to LeonidasLux/openclaw that referenced this pull request Jul 3, 2026
* fix: gate Android talk capture starts

* refactor(android): make Talk capture policy explicit

---------

Co-authored-by: NianJiuZst <180004567+users.noreply.github.com>
Co-authored-by: Peter Steinberger <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 3, 2026
* fix: gate Android talk capture starts

* refactor(android): make Talk capture policy explicit

---------

Co-authored-by: NianJiuZst <180004567+users.noreply.github.com>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: android App: android merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants