diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index b7e018abf..9cfda2174 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -53,6 +53,7 @@ import eu.siacs.conversations.utils.PermissionUtils; import eu.siacs.conversations.utils.TimeFrameUtils; import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection; +import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager; import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection; import eu.siacs.conversations.xmpp.jingle.Media; import eu.siacs.conversations.xmpp.jingle.RtpEndUserState; @@ -427,7 +428,13 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe final WeakReference reference = xmppConnectionService.getJingleConnectionManager() .findJingleRtpConnection(account, with, sessionId); if (reference == null || reference.get() == null) { - throw new IllegalStateException("failed to initialize activity with running rtp session. session not found"); + final JingleConnectionManager.TerminatedRtpSession terminatedRtpSession = xmppConnectionService + .getJingleConnectionManager().getTerminalSessionState(with, sessionId); + if (terminatedRtpSession == null) { + throw new IllegalStateException("failed to initialize activity with running rtp session. session not found"); + } + initializeWithTerminatedSessionState(account, with, terminatedRtpSession); + return true; } this.rtpConnectionReference = reference; final RtpEndUserState currentState = requireRtpConnection().getEndUserState(); @@ -451,6 +458,20 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return false; } + private void initializeWithTerminatedSessionState(final Account account, final Jid with, final JingleConnectionManager.TerminatedRtpSession terminatedRtpSession) { + Log.d(Config.LOGTAG,"initializeWithTerminatedSessionState()"); + if (terminatedRtpSession.state == RtpEndUserState.ENDED) { + finish(); + return; + } + RtpEndUserState state = terminatedRtpSession.state; + resetIntent(account, with, terminatedRtpSession.state, terminatedRtpSession.media); + updateButtonConfiguration(state); + updateStateDisplay(state); + updateProfilePicture(state); + binding.with.setText(account.getRoster().getContact(with).getDisplayName()); + } + private void reInitializeActivityWithRunningRtpSession(final Account account, Jid with, String sessionId) { runOnUiThread(() -> initializeActivityWithRunningRtpSession(account, with, sessionId)); resetIntent(account, with, sessionId); 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 34b6ac9ab..03bafb275 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -11,7 +11,6 @@ import com.google.common.cache.CacheBuilder; import com.google.common.collect.Collections2; import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableSet; -import com.google.j2objc.annotations.Weak; import java.lang.ref.WeakReference; import java.security.SecureRandom; @@ -57,8 +56,8 @@ public class JingleConnectionManager extends AbstractConnectionManager { private final HashMap rtpSessionProposals = new HashMap<>(); private final ConcurrentHashMap connections = new ConcurrentHashMap<>(); - private final Cache endedSessions = CacheBuilder.newBuilder() - .expireAfterWrite(30, TimeUnit.MINUTES) + private final Cache terminatedSessions = CacheBuilder.newBuilder() + .expireAfterWrite(24, TimeUnit.HOURS) .build(); private HashMap primaryCandidates = new HashMap<>(); @@ -92,7 +91,7 @@ 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)) { - final boolean sessionEnded = this.endedSessions.asMap().containsKey(PersistableSessionId.of(id)); + final boolean sessionEnded = this.terminatedSessions.asMap().containsKey(PersistableSessionId.of(id)); final boolean stranger = isWithStrangerAndStrangerNotificationsAreOff(account, id.with); if (isBusy() || sessionEnded || stranger) { Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": rejected session with " + id.with + " because busy. sessionEnded=" + sessionEnded + ", stranger=" + stranger); @@ -684,8 +683,12 @@ public class JingleConnectionManager extends AbstractConnectionManager { throw e; } - void endSession(AbstractJingleConnection.Id id, final AbstractJingleConnection.State state) { - this.endedSessions.put(PersistableSessionId.of(id), state); + void setTerminalSessionState(AbstractJingleConnection.Id id, final RtpEndUserState state, final Set media) { + this.terminatedSessions.put(PersistableSessionId.of(id), new TerminatedRtpSession(state, media)); + } + + public TerminatedRtpSession getTerminalSessionState(final Jid with, final String sessionId) { + return this.terminatedSessions.getIfPresent(new PersistableSessionId(with, sessionId)); } private static class PersistableSessionId { @@ -716,6 +719,16 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } + public static class TerminatedRtpSession { + public final RtpEndUserState state; + public final Set media; + + TerminatedRtpSession(RtpEndUserState state, Set media) { + this.state = state; + this.media = media; + } + } + 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 835560aa1..2f8486faa 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -912,7 +912,6 @@ 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(); transitionOrThrow(State.TERMINATED_SUCCESS); //arguably this wasn't success; but not a real failure either this.finish(); @@ -1189,6 +1188,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web if (isTerminated()) { this.cancelRingingTimeout(); this.webRTCWrapper.verifyClosed(); + this.jingleConnectionManager.setTerminalSessionState(id, getEndUserState(), getMedia()); this.jingleConnectionManager.finishConnectionOrThrow(this); } else { throw new IllegalStateException(String.format("Unable to call finish from %s", this.state));