From a481584c3aa2bb4eb1483f81c5983aade7c21e71 Mon Sep 17 00:00:00 2001 From: Shaheen Gandhi Date: Tue, 17 Mar 2026 16:27:24 -0700 Subject: [PATCH] Guard handleIncoming* methods against missing call event listeners Skip processing incoming call offers when no call event listeners are registered, since there is nobody to notify about the call. For hangup and busy, also guard when there are no listeners AND no active call (the tunnel may still need cleanup if already spawned). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../signal/manager/helper/CallManager.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/CallManager.java b/lib/src/main/java/org/asamk/signal/manager/helper/CallManager.java index a01bc6f8..7fd6b4ed 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/CallManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/CallManager.java @@ -204,6 +204,20 @@ public class CallManager implements AutoCloseable { final MessageEnvelope.Call.Offer.Type type, final byte[] opaque ) { + if (callEventListeners.isEmpty()) { + logger.debug("Ignoring incoming offer for call {}: no call event listeners registered", callId); + try { + var address = context.getRecipientHelper().resolveSignalServiceAddress(senderId); + var busyMessage = new org.whispersystems.signalservice.api.messages.calls.BusyMessage(callId); + var callMessage = org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage.forBusy( + busyMessage, null); + dependencies.getMessageSender().sendCallMessage(address, null, callMessage); + } catch (Exception e) { + logger.warn("Failed to send busy for unhandled call {}", callId, e); + } + return; + } + var senderAddress = account.getRecipientAddressResolver() .resolveRecipientAddress(senderId) .toApiRecipientAddress(); @@ -325,10 +339,16 @@ public class CallManager implements AutoCloseable { } public void handleIncomingHangup(final long callId) { + if (callEventListeners.isEmpty() && !activeCalls.containsKey(callId)) { + return; + } endCall(callId, "remote_hangup"); } public void handleIncomingBusy(final long callId) { + if (callEventListeners.isEmpty() && !activeCalls.containsKey(callId)) { + return; + } endCall(callId, "remote_busy"); }