fixed rare race condition when receiving transport info right after WebRTCWrapper closes

Daniel Gultsch created

fixes #3849

Change summary

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java |  8 
src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java       | 10 
2 files changed, 15 insertions(+), 3 deletions(-)

Detailed changes

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

@@ -239,7 +239,11 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
             }
             final Set<Map.Entry<String, RtpContentMap.DescriptionTransport>> candidates = contentMap.contents.entrySet();
             if (this.state == State.SESSION_ACCEPTED) {
-                processCandidates(candidates);
+                try {
+                    processCandidates(candidates);
+                } catch (final WebRTCWrapper.PeerConnectionNotInitialized e) {
+                    Log.w(Config.LOGTAG, id.account.getJid().asBareJid() + ": PeerConnection was not initialized when processing transport info. this usually indicates a race condition that can be ignored");
+                }
             } else {
                 pendingIceCandidates.push(candidates);
             }
@@ -810,7 +814,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
                 final PeerConnection.PeerConnectionState state;
                 try {
                     state = webRTCWrapper.getState();
-                } catch (final IllegalStateException e) {
+                } catch (final WebRTCWrapper.PeerConnectionNotInitialized e) {
                     //We usually close the WebRTCWrapper *before* transitioning so we might still
                     //be in SESSION_ACCEPTED even though the peerConnection has been torn down
                     return RtpEndUserState.ENDING_CALL;

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

@@ -552,7 +552,7 @@ public class WebRTCWrapper {
     private PeerConnection requirePeerConnection() {
         final PeerConnection peerConnection = this.peerConnection;
         if (peerConnection == null) {
-            throw new IllegalStateException("initialize PeerConnection first");
+            throw new PeerConnectionNotInitialized();
         }
         return peerConnection;
     }
@@ -617,6 +617,14 @@ public class WebRTCWrapper {
         }
     }
 
+    public static class PeerConnectionNotInitialized extends IllegalStateException {
+
+        private PeerConnectionNotInitialized() {
+            super("initialize PeerConnection first");
+        }
+
+    }
+
     private static class CapturerChoice {
         private final CameraVideoCapturer cameraVideoCapturer;
         private final CameraEnumerationAndroid.CaptureFormat captureFormat;