From 6b5fb6fee6d8105db246804fb504267c0290c72b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 25 Mar 2024 10:39:24 +0100 Subject: [PATCH] deliver session-initiate before integrating call otherwise there could potentially be race conditions with showIncomingCallUi being called before we have media information --- .../xmpp/jingle/JingleConnectionManager.java | 44 ++++++++----------- .../xmpp/jingle/JingleRtpConnection.java | 18 ++++++++ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index e0eaaa08f..9dc13e174 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -128,33 +128,31 @@ public class JingleConnectionManager extends AbstractConnectionManager { return; } connections.put(id, connection); - - if (connection instanceof JingleRtpConnection) { - if (!CallIntegrationConnectionService.addNewIncomingCall( - mXmppConnectionService, id)) { - connections.remove(id); - Log.e( - Config.LOGTAG, - account.getJid().asBareJid() + ": could not add incoming call"); - sendSessionTerminate(account, packet, id); - writeLogMissedIncoming( - account, - id.with, - id.sessionId, - null, - System.currentTimeMillis(), - false); - } - } - mXmppConnectionService.updateConversationUi(); connection.deliverPacket(packet); + if (connection instanceof JingleRtpConnection rtpConnection) { + addNewIncomingCall(rtpConnection); + } } else { Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet); respondWithJingleError(account, packet, "unknown-session", "item-not-found", "cancel"); } } + private void addNewIncomingCall(final JingleRtpConnection rtpConnection) { + if (rtpConnection.isTerminated()) { + Log.d( + Config.LOGTAG, + "skip call integration because something must have gone during initiate"); + return; + } + if (CallIntegrationConnectionService.addNewIncomingCall( + mXmppConnectionService, rtpConnection.getId())) { + return; + } + rtpConnection.integrationFailure(); + } + private void sendSessionTerminate(final Account account, final IqPacket request, final AbstractJingleConnection.Id id) { mXmppConnectionService.sendIqPacket( account, request.generateResponse(IqPacket.TYPE.RESULT), null); @@ -398,9 +396,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { this.connections.put(id, rtpConnection); rtpConnection.setProposedMedia(ImmutableSet.copyOf(media)); rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); - - CallIntegrationConnectionService.addNewIncomingCall( - getXmppConnectionService(), id); + addNewIncomingCall(rtpConnection); // TODO actually do the automatic accept?! } else { Log.d( @@ -450,9 +446,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { this.connections.put(id, rtpConnection); rtpConnection.setProposedMedia(ImmutableSet.copyOf(media)); rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); - - CallIntegrationConnectionService.addNewIncomingCall( - getXmppConnectionService(), id); + addNewIncomingCall(rtpConnection); } } else { Log.d( diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index c9a7c055c..ab9659185 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -2237,6 +2237,24 @@ public class JingleRtpConnection extends AbstractJingleConnection } } + public synchronized void integrationFailure() { + final var state = getState(); + if (state == State.PROPOSED) { + Log.e( + Config.LOGTAG, + id.account.getJid().asBareJid() + + ": failed call integration in state proposed"); + rejectCallFromProposed(); + } else if (state == State.SESSION_INITIALIZED) { + Log.e(Config.LOGTAG, id.account.getJid().asBareJid() + ": failed call integration"); + this.webRTCWrapper.close(); + sendSessionTerminate(Reason.FAILED_APPLICATION, "CallIntegration failed"); + } else { + throw new IllegalStateException( + String.format("Can not fail integration in state %s", state)); + } + } + public synchronized void endCall() { if (isTerminated()) { Log.w(