fix(call): restore call audio mode after audio focus interruptions - #6546
Conversation
The audio focus change listener in WebRtcAudioManager only logged changes. A transient focus holder such as the telephony stack switches the global audio mode and restores its own saved mode on release, clobbering MODE_IN_COMMUNICATION. After an incoming GSM call the Talk call therefore continued without hardware echo cancellation and proper VoIP routing: remote parties heard echo, quiet audio, or nothing until the call was restarted. - Re-assert MODE_IN_COMMUNICATION and the selected audio route when focus returns after a transient loss (new AudioFocusState tracks this) - Request focus with AUDIOFOCUS_GAIN via AudioFocusRequest (voice communication attributes, delayed gain accepted) instead of the deprecated AUDIOFOCUS_GAIN_TRANSIENT hint meant for short use - Abandon focus via abandonAudioFocusRequest on stop Fixes #6541 Assisted-by: opencode:ox-alpha Signed-off-by: Tarek Loubani <tarek@tarek.org>
|
APK file: https://github.com/nextcloud/talk-android/actions/runs/32604199571/artifacts/9483779211 |
There was a problem hiding this comment.
Pull request overview
This PR fixes an audio-routing regression during Talk calls after audio focus interruptions (e.g., answering/hanging up a GSM call) by re-asserting AudioManager.MODE_IN_COMMUNICATION and the selected audio route when focus is regained, ensuring proper VoIP routing and hardware AEC behavior.
Changes:
- Implement audio focus change handling in
WebRtcAudioManagerto restore call audio mode/route after transient focus loss. - Switch audio focus acquisition to
AudioFocusRequestwithAUDIOFOCUS_GAINand voice-communicationAudioAttributes, and abandon focus viaabandonAudioFocusRequest. - Add Robolectric unit tests covering the focus request configuration and the transient-loss restore state machine.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java | Adds focus request/state tracking and re-applies MODE_IN_COMMUNICATION + routing on focus regain. |
| app/src/test/java/com/nextcloud/talk/webrtc/WebRtcAudioManagerFocusTest.kt | Adds unit tests for the focus request config and restore-on-gain behavior after transient loss. |
Suppressed comments (1)
app/src/main/java/com/nextcloud/talk/webrtc/WebRtcAudioManager.java:173
requestAudioFocus()can returnAUDIOFOCUS_REQUEST_DELAYEDwhenacceptsDelayedFocusGainis enabled. The current code treats any non-GRANTED result as an error, which will log a false failure in the delayed-focus scenario described in the PR and issue.
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(TAG, "Audio focus request granted for VOICE_CALL streams");
} else {
Log.e(TAG, "Audio focus request failed");
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
/backport to stable-25.0.x |
fix(call): restore call audio mode after audio focus interruptions
Fixes #6541
Description
The audio focus change listener in
WebRtcAudioManageronly logged changes (the "possibly extend support of handling audio-focus changes" TODO from the WebRTC sample was never implemented). A transient focus holder such as the telephony stack switches the global audio mode toMODE_IN_CALLand restores its own saved mode (typicallyMODE_NORMAL) on release, clobbering Talk'sMODE_IN_COMMUNICATION. Since nothing re-asserted it, a Talk call interrupted by an incoming GSM call continued without hardware echo cancellation and proper VoIP routing — remote parties heard echo, very quiet audio, or nothing until the call was left and rejoined.Changes:
AudioFocusStatetracks transient focus losses; when focus returns,MODE_IN_COMMUNICATIONand the selected audio route are re-asserted (guarded by the RUNNING state so late callbacks afterstop()are ignored)AUDIOFOCUS_GAINviaAudioFocusRequest(voice-communication attributes, delayed gain accepted, no ducking) instead of the deprecatedAUDIOFOCUS_GAIN_TRANSIENThint meant for short-lived usestop()abandons focus viaabandonAudioFocusRequestSteps to reproduce / How to test
Without this PR: echo / very quiet audio / silence until the call is restarted.
With this PR: normal two-way audio resumes when the phone call ends.
Also test: music app playing before/after the call, headset unplug (
ACTION_AUDIO_BECOMING_NOISYpath), joining a call while a phone call is active (delayed focus gain).WebRtcAudioManagerFocusTest: focus request config + restore state machine)Note: This PR was developed with AI assistance (opencode / Kimi K3); see the
Assisted-bycommit trailer.