diff --git a/src/main/java/eu/siacs/conversations/services/CallIntegration.java b/src/main/java/eu/siacs/conversations/services/CallIntegration.java index 796368096..1777e9fd0 100644 --- a/src/main/java/eu/siacs/conversations/services/CallIntegration.java +++ b/src/main/java/eu/siacs/conversations/services/CallIntegration.java @@ -43,6 +43,7 @@ public class CallIntegration extends Connection { private AudioDevice initialAudioDevice = null; private final AtomicBoolean initialAudioDeviceConfigured = new AtomicBoolean(false); private final AtomicBoolean delayedDestructionInitiated = new AtomicBoolean(false); + private final AtomicBoolean isDestroyed = new AtomicBoolean(false); private List availableEndpoints = Collections.emptyList(); @@ -363,7 +364,6 @@ public class CallIntegration extends Connection { final var toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, DEFAULT_VOLUME); toneGenerator.startTone(ToneGenerator.TONE_CDMA_CALLDROP_LITE, 375); this.destroyWithDelay(new DisconnectCause(DisconnectCause.ERROR, null), 375); - this.destroyWith(new DisconnectCause(DisconnectCause.ERROR, null)); } public void retracted() { @@ -389,7 +389,7 @@ public class CallIntegration extends Connection { JingleConnectionManager.SCHEDULED_EXECUTOR_SERVICE.schedule( () -> { this.setDisconnected(disconnectCause); - this.destroy(); + this.destroyCallIntegration(); }, delay, TimeUnit.MILLISECONDS); @@ -404,7 +404,7 @@ public class CallIntegration extends Connection { return; } this.setDisconnected(disconnectCause); - this.destroy(); + this.destroyCallIntegration(); Log.d(Config.LOGTAG, "destroyed!"); } @@ -472,6 +472,15 @@ public class CallIntegration extends Connection { audioManager.getAudioDevices())); } + private void destroyCallIntegration() { + super.destroy(); + this.isDestroyed.set(true); + } + + public boolean isDestroyed() { + return this.isDestroyed.get(); + } + /** AudioDevice is the names of possible audio devices that we currently support. */ public enum AudioDevice { NONE, diff --git a/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java b/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java index ce4f0eb85..d47a28a22 100644 --- a/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/CallIntegrationConnectionService.java @@ -347,14 +347,14 @@ public class CallIntegrationConnectionService extends ConnectionService { } } - public static void addNewIncomingCall( + public static boolean addNewIncomingCall( final Context context, final AbstractJingleConnection.Id id) { if (CallIntegration.notSelfManaged(context)) { Log.d( Config.LOGTAG, "not adding incoming call to TelecomManager on Android " + Build.VERSION.RELEASE); - return; + return true; } final var phoneAccountHandle = CallIntegrationConnectionService.getHandle(context, id.account); @@ -373,7 +373,9 @@ public class CallIntegrationConnectionService extends ConnectionService { Config.LOGTAG, id.account.getJid().asBareJid() + ": call integration not available", e); + return false; } + return true; } public static class ServiceConnectionService { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 8541f6a44..0232478f5 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -109,13 +109,7 @@ public class JingleConnectionManager extends AbstractConnectionManager { + sessionEnded + ", stranger=" + stranger); - mXmppConnectionService.sendIqPacket( - account, packet.generateResponse(IqPacket.TYPE.RESULT), null); - final JinglePacket sessionTermination = - new JinglePacket(JinglePacket.Action.SESSION_TERMINATE, id.sessionId); - sessionTermination.setTo(id.with); - sessionTermination.setReason(Reason.BUSY, null); - mXmppConnectionService.sendIqPacket(account, sessionTermination, null); + sendSessionTerminate(account, packet, id); if (busy || stranger) { writeLogMissedIncoming( account, @@ -136,7 +130,21 @@ public class JingleConnectionManager extends AbstractConnectionManager { connections.put(id, connection); if (connection instanceof JingleRtpConnection) { - CallIntegrationConnectionService.addNewIncomingCall(getXmppConnectionService(), id); + 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(); @@ -147,14 +155,24 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } + private void sendSessionTerminate(final Account account, final IqPacket request, final AbstractJingleConnection.Id id) { + mXmppConnectionService.sendIqPacket( + account, request.generateResponse(IqPacket.TYPE.RESULT), null); + final JinglePacket sessionTermination = + new JinglePacket(JinglePacket.Action.SESSION_TERMINATE, id.sessionId); + sessionTermination.setTo(id.with); + sessionTermination.setReason(Reason.BUSY, null); + mXmppConnectionService.sendIqPacket(account, sessionTermination, null); + } + private boolean isUsingClearNet(final Account account) { return !account.isOnion() && !mXmppConnectionService.useTorToConnect(); } public boolean isBusy() { - for (AbstractJingleConnection connection : this.connections.values()) { - if (connection instanceof JingleRtpConnection) { - if (connection.isTerminated()) { + for (final AbstractJingleConnection connection : this.connections.values()) { + if (connection instanceof JingleRtpConnection rtpConnection) { + if (connection.isTerminated() && rtpConnection.getCallIntegration().isDestroyed()) { continue; } return true;