@@ -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<CallEndpoint> 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,
@@ -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 {
@@ -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;