delay integrated audio routing on callee end until picked up

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/CallIntegration.java            | 41 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  4 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java     |  4 
3 files changed, 34 insertions(+), 15 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/CallIntegration.java 🔗

@@ -53,6 +53,8 @@ public class CallIntegration extends Connection {
 
     private final AppRTCAudioManager appRTCAudioManager;
     private AudioDevice initialAudioDevice = null;
+
+    private boolean isAudioRoutingRequested = false;
     private final AtomicBoolean initialAudioDeviceConfigured = new AtomicBoolean(false);
     private final AtomicBoolean delayedDestructionInitiated = new AtomicBoolean(false);
     private final AtomicBoolean isDestroyed = new AtomicBoolean(false);
@@ -446,12 +448,28 @@ public class CallIntegration extends Connection {
     private void onAudioDeviceChanged(
             final CallIntegration.AudioDevice selectedAudioDevice,
             final Set<CallIntegration.AudioDevice> availableAudioDevices) {
-        if (this.initialAudioDevice != null
-                && this.initialAudioDeviceConfigured.compareAndSet(false, true)) {
-            if (availableAudioDevices.contains(this.initialAudioDevice)
+        if (isAudioRoutingRequested) {
+            configureInitialAudioDevice(availableAudioDevices);
+        }
+        final var callback = this.callback;
+        if (callback == null) {
+            return;
+        }
+        callback.onAudioDeviceChanged(selectedAudioDevice, availableAudioDevices);
+    }
+
+    private void configureInitialAudioDevice(final Set<AudioDevice> availableAudioDevices) {
+        final var initialAudioDevice = this.initialAudioDevice;
+        if (initialAudioDevice == null) {
+            Log.d(Config.LOGTAG, "skipping configureInitialAudioDevice()");
+            return;
+        }
+        final var target = this.initialAudioDevice;
+        if (this.initialAudioDeviceConfigured.compareAndSet(false, true)) {
+            if (availableAudioDevices.contains(target)
                     && !availableAudioDevices.contains(AudioDevice.BLUETOOTH)) {
-                setAudioDevice(this.initialAudioDevice);
-                Log.d(Config.LOGTAG, "configured initial audio device");
+                setAudioDevice(target);
+                Log.d(Config.LOGTAG, "configured initial audio device: " + target);
             } else {
                 Log.d(
                         Config.LOGTAG,
@@ -459,11 +477,6 @@ public class CallIntegration extends Connection {
                                 + availableAudioDevices);
             }
         }
-        final var callback = this.callback;
-        if (callback == null) {
-            return;
-        }
-        callback.onAudioDeviceChanged(selectedAudioDevice, availableAudioDevices);
     }
 
     private boolean selfManaged() {
@@ -494,8 +507,14 @@ public class CallIntegration extends Connection {
         this.initialAudioDevice = audioDevice;
     }
 
-    public void startLegacyAudioRouting() {
+    public void startAudioRouting() {
+        this.isAudioRoutingRequested = true;
         if (selfManaged()) {
+            final var devices = getAudioDevices();
+            if (devices.isEmpty()) {
+                return;
+            }
+            configureInitialAudioDevice(devices);
             return;
         }
         final var audioManager = requireAppRtcAudioManager();

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -736,7 +736,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
         final JingleRtpConnection rtpConnection =
                 new JingleRtpConnection(this, id, account.getJid());
         rtpConnection.setProposedMedia(media);
-        rtpConnection.getCallIntegration().startLegacyAudioRouting();
+        rtpConnection.getCallIntegration().startAudioRouting();
         this.connections.put(id, rtpConnection);
         rtpConnection.sendSessionInitiate();
         return rtpConnection;
@@ -777,7 +777,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                             ? VideoProfile.STATE_AUDIO_ONLY
                             : VideoProfile.STATE_BIDIRECTIONAL);
             callIntegration.setInitialAudioDevice(CallIntegration.initialAudioDevice(media));
-            callIntegration.startLegacyAudioRouting();
+            callIntegration.startAudioRouting();
             final RtpSessionProposal proposal =
                     RtpSessionProposal.of(account, with.asBareJid(), media, callIntegration);
             callIntegration.setCallback(new ProposalStateCallback(proposal));

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java 🔗

@@ -2329,7 +2329,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
     private void acceptCallFromProposed() {
         transitionOrThrow(State.PROCEED);
         xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
-        this.callIntegration.startLegacyAudioRouting();
+        this.callIntegration.startAudioRouting();
         this.sendJingleMessage("accept", id.account.getJid().asBareJid());
         this.sendJingleMessage("proceed");
     }
@@ -2398,7 +2398,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
 
     private void acceptCallFromSessionInitialized() {
         xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
-        this.callIntegration.startLegacyAudioRouting();
+        this.callIntegration.startAudioRouting();
         sendSessionAccept();
     }