remember terminal RTP session state
if the activity is not connected during finish it won’t receive the last end user state. this code remembers it even if the actual session is already gone. so when activity reconnects and we can’t find the real rtp session we can look up the last state instead.
This commit is contained in:
parent
7e2d87f39c
commit
552e17e39a
|
@ -53,6 +53,7 @@ import eu.siacs.conversations.utils.PermissionUtils;
|
||||||
import eu.siacs.conversations.utils.TimeFrameUtils;
|
import eu.siacs.conversations.utils.TimeFrameUtils;
|
||||||
import eu.siacs.conversations.xml.Namespace;
|
import eu.siacs.conversations.xml.Namespace;
|
||||||
import eu.siacs.conversations.xmpp.jingle.AbstractJingleConnection;
|
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.JingleRtpConnection;
|
||||||
import eu.siacs.conversations.xmpp.jingle.Media;
|
import eu.siacs.conversations.xmpp.jingle.Media;
|
||||||
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
import eu.siacs.conversations.xmpp.jingle.RtpEndUserState;
|
||||||
|
@ -427,8 +428,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager()
|
final WeakReference<JingleRtpConnection> reference = xmppConnectionService.getJingleConnectionManager()
|
||||||
.findJingleRtpConnection(account, with, sessionId);
|
.findJingleRtpConnection(account, with, sessionId);
|
||||||
if (reference == null || reference.get() == null) {
|
if (reference == null || reference.get() == null) {
|
||||||
|
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");
|
throw new IllegalStateException("failed to initialize activity with running rtp session. session not found");
|
||||||
}
|
}
|
||||||
|
initializeWithTerminatedSessionState(account, with, terminatedRtpSession);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
this.rtpConnectionReference = reference;
|
this.rtpConnectionReference = reference;
|
||||||
final RtpEndUserState currentState = requireRtpConnection().getEndUserState();
|
final RtpEndUserState currentState = requireRtpConnection().getEndUserState();
|
||||||
if (currentState == RtpEndUserState.ENDED) {
|
if (currentState == RtpEndUserState.ENDED) {
|
||||||
|
@ -451,6 +458,20 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
|
||||||
return false;
|
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) {
|
private void reInitializeActivityWithRunningRtpSession(final Account account, Jid with, String sessionId) {
|
||||||
runOnUiThread(() -> initializeActivityWithRunningRtpSession(account, with, sessionId));
|
runOnUiThread(() -> initializeActivityWithRunningRtpSession(account, with, sessionId));
|
||||||
resetIntent(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.Collections2;
|
||||||
import com.google.common.collect.ComparisonChain;
|
import com.google.common.collect.ComparisonChain;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.j2objc.annotations.Weak;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -57,8 +56,8 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
private final HashMap<RtpSessionProposal, DeviceDiscoveryState> rtpSessionProposals = new HashMap<>();
|
private final HashMap<RtpSessionProposal, DeviceDiscoveryState> rtpSessionProposals = new HashMap<>();
|
||||||
private final ConcurrentHashMap<AbstractJingleConnection.Id, AbstractJingleConnection> connections = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<AbstractJingleConnection.Id, AbstractJingleConnection> connections = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final Cache<PersistableSessionId, JingleRtpConnection.State> endedSessions = CacheBuilder.newBuilder()
|
private final Cache<PersistableSessionId, TerminatedRtpSession> terminatedSessions = CacheBuilder.newBuilder()
|
||||||
.expireAfterWrite(30, TimeUnit.MINUTES)
|
.expireAfterWrite(24, TimeUnit.HOURS)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
|
private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
|
||||||
|
@ -92,7 +91,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) {
|
if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) {
|
||||||
connection = new JingleFileTransferConnection(this, id, from);
|
connection = new JingleFileTransferConnection(this, id, from);
|
||||||
} else if (Namespace.JINGLE_APPS_RTP.equals(descriptionNamespace) && !usesTor(account)) {
|
} 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);
|
final boolean stranger = isWithStrangerAndStrangerNotificationsAreOff(account, id.with);
|
||||||
if (isBusy() || sessionEnded || stranger) {
|
if (isBusy() || sessionEnded || stranger) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": rejected session with " + id.with + " because busy. sessionEnded=" + sessionEnded + ", stranger=" + 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;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void endSession(AbstractJingleConnection.Id id, final AbstractJingleConnection.State state) {
|
void setTerminalSessionState(AbstractJingleConnection.Id id, final RtpEndUserState state, final Set<Media> media) {
|
||||||
this.endedSessions.put(PersistableSessionId.of(id), state);
|
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 {
|
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 {
|
public enum DeviceDiscoveryState {
|
||||||
SEARCHING, DISCOVERED, FAILED;
|
SEARCHING, DISCOVERED, FAILED;
|
||||||
|
|
||||||
|
|
|
@ -912,7 +912,6 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
}
|
}
|
||||||
if (isInState(State.PROCEED)) {
|
if (isInState(State.PROCEED)) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ending call while in state PROCEED just means ending the connection");
|
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.webRTCWrapper.close();
|
||||||
transitionOrThrow(State.TERMINATED_SUCCESS); //arguably this wasn't success; but not a real failure either
|
transitionOrThrow(State.TERMINATED_SUCCESS); //arguably this wasn't success; but not a real failure either
|
||||||
this.finish();
|
this.finish();
|
||||||
|
@ -1189,6 +1188,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
|
||||||
if (isTerminated()) {
|
if (isTerminated()) {
|
||||||
this.cancelRingingTimeout();
|
this.cancelRingingTimeout();
|
||||||
this.webRTCWrapper.verifyClosed();
|
this.webRTCWrapper.verifyClosed();
|
||||||
|
this.jingleConnectionManager.setTerminalSessionState(id, getEndUserState(), getMedia());
|
||||||
this.jingleConnectionManager.finishConnectionOrThrow(this);
|
this.jingleConnectionManager.finishConnectionOrThrow(this);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(String.format("Unable to call finish from %s", this.state));
|
throw new IllegalStateException(String.format("Unable to call finish from %s", this.state));
|
||||||
|
|
Loading…
Reference in a new issue