@@ -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<JingleRtpConnection> 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);
@@ -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<RtpSessionProposal, DeviceDiscoveryState> rtpSessionProposals = new HashMap<>();
private final ConcurrentHashMap<AbstractJingleConnection.Id, AbstractJingleConnection> connections = new ConcurrentHashMap<>();
- private final Cache<PersistableSessionId, JingleRtpConnection.State> endedSessions = CacheBuilder.newBuilder()
- .expireAfterWrite(30, TimeUnit.MINUTES)
+ private final Cache<PersistableSessionId, TerminatedRtpSession> terminatedSessions = CacheBuilder.newBuilder()
+ .expireAfterWrite(24, TimeUnit.HOURS)
.build();
private HashMap<Jid, JingleCandidate> 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> 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> media;
+
+ TerminatedRtpSession(RtpEndUserState state, Set<Media> media) {
+ this.state = state;
+ this.media = media;
+ }
+ }
+
public enum DeviceDiscoveryState {
SEARCHING, DISCOVERED, FAILED;
@@ -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));