Skip to content

[stable-24.0] fix(call): fix native crashes, muted icons and state broadcast in calls#6265

Merged
mahibi merged 1 commit into
stable-24.0from
backport/6261/stable-24.0
May 29, 2026
Merged

[stable-24.0] fix(call): fix native crashes, muted icons and state broadcast in calls#6265
mahibi merged 1 commit into
stable-24.0from
backport/6261/stable-24.0

Conversation

@backportbot
Copy link
Copy Markdown

@backportbot backportbot Bot commented May 29, 2026

Backport of PR #6261

This commit contains the code from #6039 (thank you tareko!)
as it needed to be combined with more fixes during it's review.

  PeerConnectionWrapper — native crash fixes:
  - Call peerConnection.close() before dataChannel.dispose() so the WebRTC
    signaling thread stops dispatching callbacks before native objects are freed
  - Call peerConnection.close() outside the synchronized lock; holding the lock
    deadlocks because close() blocks waiting for the signaling thread, which
    itself needs the lock to run its callbacks
  - Null out peerConnection before calling close() so in-flight callbacks see
    null and return early instead of NPE-ing on peerConnection.hashCode() in
    onIceConnectionChange, onCreateFailure, and onSetFailure
  - Call dataChannel.unregisterObserver() before dispose() in both
    removePeerConnection() and onDataChannel() to prevent the native observer
    from calling back into a disposed Java DataChannel object

  LocalStateBroadcasterNoMcu — initial mute state not sent to peers:
  - IceConnectionStateObserver.job was never started, so local audio/video/
    speaking state was never sent to newly connected participants; only a
    manual mute+unmute triggered a broadcast
  - handleCallParticipantAdded now accepts the live StateFlow<ParticipantUiState>
    and uses first { it.isConnected } to send initial state exactly once when
    ICE connects; base class gets a concrete StateFlow overload that defaults
    to the existing snapshot path so MCU behaviour is unchanged
  - Fix ParticipantHandler initial isConnected = false (was true), which caused
    retrying when ICE actually connected

  ParticipantHandler — guest audio not detected (cherry-pick of PR #6039):
  - handleStreamChange() now sets isAudioEnabled from audio track presence,
    not only isStreamEnabled from video tracks; guests whose DataChannel never
    opens were permanently shown as muted despite having an active audio track
  - handleIceConnectionStateChange() preserves audio/video state during ICE
    NEW/CHECKING if tracks are still present, rather than resetting to false
    unconditionally and relying on a DataChannel message to restore it
  - Add GuestAudioDetectionTest and diagnostic logging

AI-assistant: Claude Code v2.1.142 (Claude Sonnet 4.6)
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@backportbot backportbot Bot requested a review from mahibi May 29, 2026 15:25
@backportbot backportbot Bot added the 3. to review Waiting for reviews label May 29, 2026
@backportbot backportbot Bot added this to the 24.0.0 milestone May 29, 2026
@mahibi mahibi merged commit 599c782 into stable-24.0 May 29, 2026
9 of 15 checks passed
@mahibi mahibi deleted the backport/6261/stable-24.0 branch May 29, 2026 15:27
@github-actions
Copy link
Copy Markdown
Contributor

APK file: https://github.com/nextcloud/talk-android/actions/runs/26646008071/artifacts/7294595409
To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.
qrcode (please click on link to get QR code displayed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant