avoid terminating twice

This commit is contained in:
Daniel Gultsch 2020-04-12 09:59:32 +02:00
parent 82f9a77777
commit 1dc88f38ca
3 changed files with 44 additions and 13 deletions

View file

@ -245,7 +245,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
if (action == JinglePacket.Action.SESSION_INITIATE) {
init(packet);
} else if (action == JinglePacket.Action.SESSION_TERMINATE) {
final Reason reason = packet.getReason();
final Reason reason = packet.getReason().reason;
switch (reason) {
case CANCEL:
this.cancelled = true;

View file

@ -36,6 +36,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
State.SESSION_INITIALIZED_PRE_APPROVED,
State.SESSION_ACCEPTED
);
private static final List<State> TERMINATED = Arrays.asList(
State.TERMINATED_DECLINED_OR_BUSY,
State.TERMINATED_CONNECTIVITY_ERROR,
State.TERMINATED_CANCEL_OR_TIMEOUT,
State.TERMINATED_APPLICATION_FAILURE
);
private static final Map<State, Collection<State>> VALID_TRANSITIONS;
static {
@ -137,11 +145,15 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
private void receiveSessionTerminate(final JinglePacket jinglePacket) {
respondOk(jinglePacket);
final Reason reason = jinglePacket.getReason();
final JinglePacket.ReasonWrapper wrapper = jinglePacket.getReason();
final State previous = this.state;
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received session terminate reason=" + reason + " while in state " + previous);
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received session terminate reason=" + wrapper.reason + "(" + Strings.nullToEmpty(wrapper.text) + ") while in state " + previous);
if (TERMINATED.contains(previous)) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": ignoring session terminate because already in " + previous);
return;
}
webRTCWrapper.close();
transitionOrThrow(reasonToState(reason));
transitionOrThrow(reasonToState(wrapper.reason));
if (previous == State.PROPOSED || previous == State.SESSION_INITIALIZED) {
xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
}
@ -761,7 +773,11 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
public void onConnectionChange(final PeerConnection.PeerConnectionState newState) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": PeerConnectionState changed to " + newState);
updateEndUserState();
if (newState == PeerConnection.PeerConnectionState.FAILED) { //TODO guard this in isState(initiated,initiated_approved,accepted) otherwise it might fire too late
if (newState == PeerConnection.PeerConnectionState.FAILED) {
if (TERMINATED.contains(this.state)) {
Log.d(Config.LOGTAG,id.account.getJid().asBareJid()+": not sending session-terminate after connectivity error because session is already in state "+this.state);
return;
}
sendSessionTerminate(Reason.CONNECTIVITY_ERROR);
}
}

View file

@ -69,17 +69,21 @@ public class JinglePacket extends IqPacket {
addJingleChild(content);
}
public Reason getReason() {
final Element reason = getJingleChild("reason");
if (reason == null) {
return Reason.UNKNOWN;
public ReasonWrapper getReason() {
final Element reasonElement = getJingleChild("reason");
if (reasonElement == null) {
return new ReasonWrapper(Reason.UNKNOWN,null);
}
for(Element child : reason.getChildren()) {
if (!"text".equals(child.getName())) {
return Reason.of(child.getName());
String text = null;
Reason reason = Reason.UNKNOWN;
for(Element child : reasonElement.getChildren()) {
if ("text".equals(child.getName())) {
text = child.getContent();
} else {
reason = Reason.of(child.getName());
}
}
return Reason.UNKNOWN;
return new ReasonWrapper(reason, text);
}
public void setReason(final Reason reason, final String text) {
@ -149,4 +153,15 @@ public class JinglePacket extends IqPacket {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, super.toString());
}
}
public static class ReasonWrapper {
public final Reason reason;
public final String text;
public ReasonWrapper(Reason reason, String text) {
this.reason = reason;
this.text = text;
}
}
}