add safeguards to ringtone playing twice

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/NotificationService.java        | 10 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  2 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java     |  9 
3 files changed, 17 insertions(+), 4 deletions(-)

Detailed changes

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

@@ -502,11 +502,9 @@ public class NotificationService {
     public synchronized void startRinging(
             final AbstractJingleConnection.Id id, final Set<Media> media) {
         showIncomingCallNotification(id, media);
-        final NotificationManager notificationManager =
-                (NotificationManager)
-                        mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE);
+        final NotificationManager notificationManager = mXmppConnectionService.getSystemService(NotificationManager.class);
         final int currentInterruptionFilter;
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && notificationManager != null) {
+        if (notificationManager != null) {
             currentInterruptionFilter = notificationManager.getCurrentInterruptionFilter();
         } else {
             currentInterruptionFilter = 1; // INTERRUPTION_FILTER_ALL
@@ -525,6 +523,10 @@ public class NotificationService {
         if (currentVibrationFuture != null) {
             currentVibrationFuture.cancel(true);
         }
+        final var preexistingRingtone = this.currentlyPlayingRingtone;
+        if (preexistingRingtone != null) {
+            preexistingRingtone.stop();
+        }
         final SharedPreferences preferences =
                 PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
         final Resources resources = mXmppConnectionService.getResources();

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

@@ -504,6 +504,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
             final RtpSessionProposal proposal =
                     getRtpSessionProposal(account, from.asBareJid(), sessionId);
             synchronized (rtpSessionProposals) {
+                // TODO remove the remove()!= null check to ensure we always call busy()
                 if (proposal != null && rtpSessionProposals.remove(proposal) != null) {
                     proposal.callIntegration.busy();
                     writeLogMissedOutgoing(
@@ -763,6 +764,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
             final RtpSessionProposal proposal =
                     RtpSessionProposal.of(account, with.asBareJid(), media, callIntegration);
             callIntegration.setCallback(new ProposalStateCallback(proposal));
+            // TODO ensure that there is no previous proposal?!
             this.rtpSessionProposals.put(proposal, DeviceDiscoveryState.SEARCHING);
             mXmppConnectionService.notifyJingleRtpConnectionUpdate(
                     account, proposal.with, proposal.sessionId, RtpEndUserState.FINDING_DEVICE);

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

@@ -2691,6 +2691,15 @@ public class JingleRtpConnection extends AbstractJingleConnection
 
     @Override
     public void onCallIntegrationShowIncomingCallUi() {
+        if (isTerminated()) {
+            // there might be race conditions with the call integration service invoking this
+            // callback when the rtp session has already ended. It should be enough to just return
+            // instead of throwing an exception. however throwing an exception gives us a sense of
+            // if and how frequently this happens
+            throw new IllegalStateException(
+                    "CallIntegration requested incoming call UI but session was already terminated");
+        }
+        // TODO apparently this can be called too early as well?
         xmppConnectionService.getNotificationService().startRinging(id, getMedia());
     }