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) { if (action == JinglePacket.Action.SESSION_INITIATE) {
init(packet); init(packet);
} else if (action == JinglePacket.Action.SESSION_TERMINATE) { } else if (action == JinglePacket.Action.SESSION_TERMINATE) {
final Reason reason = packet.getReason(); final Reason reason = packet.getReason().reason;
switch (reason) { switch (reason) {
case CANCEL: case CANCEL:
this.cancelled = true; this.cancelled = true;

View file

@ -36,6 +36,14 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
State.SESSION_INITIALIZED_PRE_APPROVED, State.SESSION_INITIALIZED_PRE_APPROVED,
State.SESSION_ACCEPTED 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; private static final Map<State, Collection<State>> VALID_TRANSITIONS;
static { static {
@ -137,11 +145,15 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
private void receiveSessionTerminate(final JinglePacket jinglePacket) { private void receiveSessionTerminate(final JinglePacket jinglePacket) {
respondOk(jinglePacket); respondOk(jinglePacket);
final Reason reason = jinglePacket.getReason(); final JinglePacket.ReasonWrapper wrapper = jinglePacket.getReason();
final State previous = this.state; 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(); webRTCWrapper.close();
transitionOrThrow(reasonToState(reason)); transitionOrThrow(reasonToState(wrapper.reason));
if (previous == State.PROPOSED || previous == State.SESSION_INITIALIZED) { if (previous == State.PROPOSED || previous == State.SESSION_INITIALIZED) {
xmppConnectionService.getNotificationService().cancelIncomingCallNotification(); xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
} }
@ -761,7 +773,11 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
public void onConnectionChange(final PeerConnection.PeerConnectionState newState) { public void onConnectionChange(final PeerConnection.PeerConnectionState newState) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": PeerConnectionState changed to " + newState); Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": PeerConnectionState changed to " + newState);
updateEndUserState(); 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); sendSessionTerminate(Reason.CONNECTIVITY_ERROR);
} }
} }

View file

@ -69,17 +69,21 @@ public class JinglePacket extends IqPacket {
addJingleChild(content); addJingleChild(content);
} }
public Reason getReason() { public ReasonWrapper getReason() {
final Element reason = getJingleChild("reason"); final Element reasonElement = getJingleChild("reason");
if (reason == null) { if (reasonElement == null) {
return Reason.UNKNOWN; return new ReasonWrapper(Reason.UNKNOWN,null);
} }
for(Element child : reason.getChildren()) { String text = null;
if (!"text".equals(child.getName())) { Reason reason = Reason.UNKNOWN;
return Reason.of(child.getName()); 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) { 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()); 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;
}
}
} }