delay legacy audio routing until after call has been accepted

Daniel Gultsch created

fixes #249

Change summary

src/main/java/eu/siacs/conversations/services/AppRTCAudioManager.java         |  7 
src/main/java/eu/siacs/conversations/services/CallIntegration.java            | 18 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  2 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java     |  2 
4 files changed, 18 insertions(+), 11 deletions(-)

Detailed changes

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

@@ -88,15 +88,18 @@ public class AppRTCAudioManager {
         AppRTCUtils.logDeviceInfo(Config.LOGTAG);
     }
 
+    public void setAudioManagerEvents(final AudioManagerEvents audioManagerEvents) {
+        this.audioManagerEvents = audioManagerEvents;
+    }
+
     @SuppressWarnings("deprecation")
-    public void start(final AudioManagerEvents audioManagerEvents) {
+    public void start() {
         Log.d(Config.LOGTAG, AppRTCAudioManager.class.getName() + ".start()");
         ThreadUtils.checkIsOnMainThread();
         if (amState == AudioManagerState.RUNNING) {
             Log.e(Config.LOGTAG, "AudioManager is already active");
             return;
         }
-        this.audioManagerEvents = audioManagerEvents;
         amState = AudioManagerState.RUNNING;
         // Store current audio state so we can restore it when stop() is called.
         savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn();

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

@@ -15,7 +15,6 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
-import androidx.core.content.ContextCompat;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -70,8 +69,7 @@ public class CallIntegration extends Connection {
             this.appRTCAudioManager = null;
         } else {
             this.appRTCAudioManager = new AppRTCAudioManager(context);
-            ContextCompat.getMainExecutor(context)
-                    .execute(() -> this.appRTCAudioManager.start(this::onAudioDeviceChanged));
+            this.appRTCAudioManager.setAudioManagerEvents(this::onAudioDeviceChanged);
         }
         setRingbackRequested(true);
     }
@@ -490,17 +488,19 @@ public class CallIntegration extends Connection {
     public void setInitialAudioDevice(final AudioDevice audioDevice) {
         Log.d(Config.LOGTAG, "setInitialAudioDevice(" + audioDevice + ")");
         this.initialAudioDevice = audioDevice;
+    }
+
+    public void startLegacyAudioRouting() {
         if (selfManaged()) {
-            // once the 'CallIntegration' gets added to the system we receive calls to update audio
-            // state
             return;
         }
         final var audioManager = requireAppRtcAudioManager();
         audioManager.executeOnMain(
-                () ->
-                        this.onAudioDeviceChanged(
-                                audioManager.getSelectedAudioDevice(),
-                                audioManager.getAudioDevices()));
+                () -> {
+                    audioManager.start();
+                    this.onAudioDeviceChanged(
+                            audioManager.getSelectedAudioDevice(), audioManager.getAudioDevices());
+                });
     }
 
     private void destroyCallIntegration() {

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

@@ -736,6 +736,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
         final JingleRtpConnection rtpConnection =
                 new JingleRtpConnection(this, id, account.getJid());
         rtpConnection.setProposedMedia(media);
+        rtpConnection.getCallIntegration().startLegacyAudioRouting();
         this.connections.put(id, rtpConnection);
         rtpConnection.sendSessionInitiate();
         return rtpConnection;
@@ -776,6 +777,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                             ? VideoProfile.STATE_AUDIO_ONLY
                             : VideoProfile.STATE_BIDIRECTIONAL);
             callIntegration.setInitialAudioDevice(CallIntegration.initialAudioDevice(media));
+            callIntegration.startLegacyAudioRouting();
             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,6 +2329,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
     private void acceptCallFromProposed() {
         transitionOrThrow(State.PROCEED);
         xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
+        this.callIntegration.startLegacyAudioRouting();
         this.sendJingleMessage("accept", id.account.getJid().asBareJid());
         this.sendJingleMessage("proceed");
     }
@@ -2397,6 +2398,7 @@ public class JingleRtpConnection extends AbstractJingleConnection
 
     private void acceptCallFromSessionInitialized() {
         xmppConnectionService.getNotificationService().cancelIncomingCallNotification();
+        this.callIntegration.startLegacyAudioRouting();
         sendSessionAccept();
     }