From 5a0979b41e3d929154ba550b28b1bf2d584c3c30 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 19 Apr 2020 14:23:52 +0200 Subject: [PATCH] store 'ended call' when ended from proceed --- .../xmpp/jingle/JingleConnectionManager.java | 43 ++++++++++++++++++- .../xmpp/jingle/JingleRtpConnection.java | 1 + 2 files changed, 43 insertions(+), 1 deletion(-) 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 0dfb65c97..468b8d8a2 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -7,6 +7,8 @@ import android.util.Log; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Preconditions; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableSet; @@ -21,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -49,6 +52,10 @@ public class JingleConnectionManager extends AbstractConnectionManager { private final HashMap rtpSessionProposals = new HashMap<>(); private final Map connections = new ConcurrentHashMap<>(); + private final Cache endedSessions = CacheBuilder.newBuilder() + .expireAfterWrite(30, TimeUnit.MINUTES) + .build(); + private HashMap primaryCandidates = new HashMap<>(); public JingleConnectionManager(XmppConnectionService service) { @@ -79,7 +86,9 @@ public class JingleConnectionManager extends AbstractConnectionManager { if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) { connection = new JingleFileTransferConnection(this, id, from); } else if (Namespace.JINGLE_APPS_RTP.equals(descriptionNamespace) && !usesTor(account)) { - if (isBusy()) { + final boolean sessionEnded = this.endedSessions.asMap().containsKey(PersistableSessionId.of(id)); + if (isBusy() || sessionEnded) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": rejected session with " + id.with + " because busy. sessionEnded=" + sessionEnded); mXmppConnectionService.sendIqPacket(account, packet.generateResponse(IqPacket.TYPE.RESULT), null); final JinglePacket sessionTermination = new JinglePacket(JinglePacket.Action.SESSION_TERMINATE, id.sessionId); sessionTermination.setTo(id.with); @@ -523,6 +532,38 @@ public class JingleConnectionManager extends AbstractConnectionManager { throw new IllegalStateException("JingleConnection has not been registered with connection manager"); } + public void endSession(AbstractJingleConnection.Id id, final AbstractJingleConnection.State state) { + this.endedSessions.put(PersistableSessionId.of(id), state); + } + + private static class PersistableSessionId { + private final Jid with; + private final String sessionId; + + private PersistableSessionId(Jid with, String sessionId) { + this.with = with; + this.sessionId = sessionId; + } + + public static PersistableSessionId of(AbstractJingleConnection.Id id) { + return new PersistableSessionId(id.with, id.sessionId); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PersistableSessionId that = (PersistableSessionId) o; + return Objects.equal(with, that.with) && + Objects.equal(sessionId, that.sessionId); + } + + @Override + public int hashCode() { + return Objects.hashCode(with, sessionId); + } + } + public enum DeviceDiscoveryState { SEARCHING, DISCOVERED, FAILED; 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 121f894f2..313549fb1 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -819,6 +819,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } if (isInState(State.PROCEED)) { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ending call while in state PROCEED just means ending the connection"); + this.jingleConnectionManager.endSession(id, State.TERMINATED_SUCCESS); this.webRTCWrapper.close(); this.finish(); transitionOrThrow(State.TERMINATED_SUCCESS); //arguably this wasn't success; but not a real failure either