deliver session-initiate before integrating call

otherwise there could potentially be race conditions with
showIncomingCallUi being called before we have media information
This commit is contained in:
Daniel Gultsch 2024-03-25 10:39:24 +01:00
parent 21732237d4
commit 6b5fb6fee6
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
2 changed files with 37 additions and 25 deletions

View file

@ -128,33 +128,31 @@ public class JingleConnectionManager extends AbstractConnectionManager {
return; return;
} }
connections.put(id, connection); connections.put(id, connection);
if (connection instanceof JingleRtpConnection) {
if (!CallIntegrationConnectionService.addNewIncomingCall(
mXmppConnectionService, id)) {
connections.remove(id);
Log.e(
Config.LOGTAG,
account.getJid().asBareJid() + ": could not add incoming call");
sendSessionTerminate(account, packet, id);
writeLogMissedIncoming(
account,
id.with,
id.sessionId,
null,
System.currentTimeMillis(),
false);
}
}
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();
connection.deliverPacket(packet); connection.deliverPacket(packet);
if (connection instanceof JingleRtpConnection rtpConnection) {
addNewIncomingCall(rtpConnection);
}
} else { } else {
Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet); Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet);
respondWithJingleError(account, packet, "unknown-session", "item-not-found", "cancel"); respondWithJingleError(account, packet, "unknown-session", "item-not-found", "cancel");
} }
} }
private void addNewIncomingCall(final JingleRtpConnection rtpConnection) {
if (rtpConnection.isTerminated()) {
Log.d(
Config.LOGTAG,
"skip call integration because something must have gone during initiate");
return;
}
if (CallIntegrationConnectionService.addNewIncomingCall(
mXmppConnectionService, rtpConnection.getId())) {
return;
}
rtpConnection.integrationFailure();
}
private void sendSessionTerminate(final Account account, final IqPacket request, final AbstractJingleConnection.Id id) { private void sendSessionTerminate(final Account account, final IqPacket request, final AbstractJingleConnection.Id id) {
mXmppConnectionService.sendIqPacket( mXmppConnectionService.sendIqPacket(
account, request.generateResponse(IqPacket.TYPE.RESULT), null); account, request.generateResponse(IqPacket.TYPE.RESULT), null);
@ -398,9 +396,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
this.connections.put(id, rtpConnection); this.connections.put(id, rtpConnection);
rtpConnection.setProposedMedia(ImmutableSet.copyOf(media)); rtpConnection.setProposedMedia(ImmutableSet.copyOf(media));
rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
addNewIncomingCall(rtpConnection);
CallIntegrationConnectionService.addNewIncomingCall(
getXmppConnectionService(), id);
// TODO actually do the automatic accept?! // TODO actually do the automatic accept?!
} else { } else {
Log.d( Log.d(
@ -450,9 +446,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
this.connections.put(id, rtpConnection); this.connections.put(id, rtpConnection);
rtpConnection.setProposedMedia(ImmutableSet.copyOf(media)); rtpConnection.setProposedMedia(ImmutableSet.copyOf(media));
rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp); rtpConnection.deliveryMessage(from, message, serverMsgId, timestamp);
addNewIncomingCall(rtpConnection);
CallIntegrationConnectionService.addNewIncomingCall(
getXmppConnectionService(), id);
} }
} else { } else {
Log.d( Log.d(

View file

@ -2237,6 +2237,24 @@ public class JingleRtpConnection extends AbstractJingleConnection
} }
} }
public synchronized void integrationFailure() {
final var state = getState();
if (state == State.PROPOSED) {
Log.e(
Config.LOGTAG,
id.account.getJid().asBareJid()
+ ": failed call integration in state proposed");
rejectCallFromProposed();
} else if (state == State.SESSION_INITIALIZED) {
Log.e(Config.LOGTAG, id.account.getJid().asBareJid() + ": failed call integration");
this.webRTCWrapper.close();
sendSessionTerminate(Reason.FAILED_APPLICATION, "CallIntegration failed");
} else {
throw new IllegalStateException(
String.format("Can not fail integration in state %s", state));
}
}
public synchronized void endCall() { public synchronized void endCall() {
if (isTerminated()) { if (isTerminated()) {
Log.w( Log.w(