Эх сурвалжийг харах

Done

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 7 жил өмнө
parent
commit
26eb025c28

+ 53 - 36
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -50,6 +50,7 @@ import com.nextcloud.talk.api.models.json.signaling.Signaling;
 import com.nextcloud.talk.api.models.json.signaling.SignalingOverall;
 import com.nextcloud.talk.api.models.json.signaling.SignalingOverall;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.events.MediaStreamEvent;
 import com.nextcloud.talk.events.MediaStreamEvent;
+import com.nextcloud.talk.events.PeerConnectionEvent;
 import com.nextcloud.talk.events.SessionDescriptionSendEvent;
 import com.nextcloud.talk.events.SessionDescriptionSendEvent;
 import com.nextcloud.talk.persistence.entities.UserEntity;
 import com.nextcloud.talk.persistence.entities.UserEntity;
 import com.nextcloud.talk.webrtc.MagicAudioManager;
 import com.nextcloud.talk.webrtc.MagicAudioManager;
@@ -321,7 +322,7 @@ public class CallActivity extends AppCompatActivity {
                                     @Override
                                     @Override
                                     public void onNext(GenericOverall genericOverall) {
                                     public void onNext(GenericOverall genericOverall) {
                                         callSession = callOverall.getOcs().getData().getSessionId();
                                         callSession = callOverall.getOcs().getData().getSessionId();
-                                        localPeer = alwaysGetPeerConnectionWrapperForSessionId(callSession, true).
+                                        localPeer = alwaysGetPeerConnectionWrapperForSessionId(callSession).
                                                 getPeerConnection();
                                                 getPeerConnection();
 
 
                                         // start pinging the call
                                         // start pinging the call
@@ -433,14 +434,14 @@ public class CallActivity extends AppCompatActivity {
                     NCSignalingMessage.class);
                     NCSignalingMessage.class);
             if (ncSignalingMessage.getRoomType().equals("video")) {
             if (ncSignalingMessage.getRoomType().equals("video")) {
                 MagicPeerConnectionWrapper magicPeerConnectionWrapper = alwaysGetPeerConnectionWrapperForSessionId
                 MagicPeerConnectionWrapper magicPeerConnectionWrapper = alwaysGetPeerConnectionWrapperForSessionId
-                        (ncSignalingMessage.getFrom(), ncSignalingMessage.getFrom().equals(callSession));
+                        (ncSignalingMessage.getFrom());
 
 
                 String type = null;
                 String type = null;
-                if (ncSignalingMessage.getType() != null) {
-                    type = ncSignalingMessage.getType();
-                } else if (ncSignalingMessage.getPayload() != null && ncSignalingMessage.getPayload().getType() !=
+                if (ncSignalingMessage.getPayload() != null && ncSignalingMessage.getPayload().getType() !=
                         null) {
                         null) {
                     type = ncSignalingMessage.getPayload().getType();
                     type = ncSignalingMessage.getPayload().getType();
+                } else if (ncSignalingMessage.getType() != null) {
+                    type = ncSignalingMessage.getType();
                 }
                 }
 
 
                 if (type != null) {
                 if (type != null) {
@@ -448,14 +449,9 @@ public class CallActivity extends AppCompatActivity {
                         case "offer":
                         case "offer":
                         case "answer":
                         case "answer":
                             magicPeerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick());
                             magicPeerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick());
-                            if (!magicPeerConnectionWrapper.getPeerConnection().signalingState().equals
-                                    (PeerConnection.SignalingState.STABLE) &&
-                                    magicPeerConnectionWrapper.getPeerConnection().getRemoteDescription() == null ||
-                                    magicPeerConnectionWrapper.getPeerConnection().getLocalDescription() == null) {
                                 magicPeerConnectionWrapper.getPeerConnection().setRemoteDescription(magicPeerConnectionWrapper
                                 magicPeerConnectionWrapper.getPeerConnection().setRemoteDescription(magicPeerConnectionWrapper
                                         .getMagicSdpObserver(), new SessionDescription(SessionDescription.Type.fromCanonicalForm(type),
                                         .getMagicSdpObserver(), new SessionDescription(SessionDescription.Type.fromCanonicalForm(type),
                                         ncSignalingMessage.getPayload().getSdp()));
                                         ncSignalingMessage.getPayload().getSdp()));
-                            }
                             break;
                             break;
                         case "candidate":
                         case "candidate":
                             NCIceCandidate ncIceCandidate = ncSignalingMessage.getPayload().getIceCandidate();
                             NCIceCandidate ncIceCandidate = ncSignalingMessage.getPayload().getIceCandidate();
@@ -497,6 +493,8 @@ public class CallActivity extends AppCompatActivity {
             }
             }
         }
         }
 
 
+
+
         for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) {
         for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) {
             if (!magicPeerConnectionWrapper.getSessionId().equals(callSession)) {
             if (!magicPeerConnectionWrapper.getSessionId().equals(callSession)) {
                 oldSesssions.add(magicPeerConnectionWrapper.getSessionId());
                 oldSesssions.add(magicPeerConnectionWrapper.getSessionId());
@@ -514,39 +512,27 @@ public class CallActivity extends AppCompatActivity {
             return;
             return;
         }
         }
 
 
-        MagicPeerConnectionWrapper magicPeerConnectionWrapper;
-
         for (String sessionId : newSessions) {
         for (String sessionId : newSessions) {
-            if (getPeerConnectionWrapperForSessionId(sessionId) == null) {
-                if (sessionId.compareTo(callSession) < 0) {
-                    MagicPeerConnectionWrapper connectionWrapper = alwaysGetPeerConnectionWrapperForSessionId(sessionId,
-                            false);
-                    if (connectionWrapper.getPeerConnection() != null) {
-                        connectionWrapper.getPeerConnection().createOffer(connectionWrapper.getMagicSdpObserver(),
-                                sdpConstraints);
-                    }
-                } else {
-                    Log.d(TAG, "Waiting for offer");
-                }
-
-            }
+            alwaysGetPeerConnectionWrapperForSessionId(sessionId);
         }
         }
 
 
         for (String sessionId : leftSessions) {
         for (String sessionId : leftSessions) {
-            if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
-                if (magicPeerConnectionWrapper.getPeerConnection() != null) {
-                    magicPeerConnectionWrapper.getPeerConnection().close();
-                }
-                magicPeerConnectionWrapperList.remove(magicPeerConnectionWrapper);
-            }
+            endPeerConnection(sessionId);
         }
         }
     }
     }
 
 
 
 
-    private MagicPeerConnectionWrapper alwaysGetPeerConnectionWrapperForSessionId(String sessionId, boolean isLocalPeer) {
+    private void deleteMagicPeerConnection(MagicPeerConnectionWrapper magicPeerConnectionWrapper) {
+        if (magicPeerConnectionWrapper.getPeerConnection() != null) {
+            magicPeerConnectionWrapper.getPeerConnection().close();
+        }
+        magicPeerConnectionWrapperList.remove(magicPeerConnectionWrapper);
+    }
+
+    private MagicPeerConnectionWrapper alwaysGetPeerConnectionWrapperForSessionId(String sessionId) {
         MagicPeerConnectionWrapper magicPeerConnectionWrapper;
         MagicPeerConnectionWrapper magicPeerConnectionWrapper;
-        if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
-            return magicPeerConnectionWrapper;
+            if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
+                return magicPeerConnectionWrapper;
         } else {
         } else {
             magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory,
             magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory,
                     iceServers, sdpConstraints, sessionId, callSession);
                     iceServers, sdpConstraints, sessionId, callSession);
@@ -612,6 +598,7 @@ public class CallActivity extends AppCompatActivity {
 
 
     private void gotRemoteStream(MediaStream stream, String session) {
     private void gotRemoteStream(MediaStream stream, String session) {
         //we have remote video stream. add to the renderer.
         //we have remote video stream. add to the renderer.
+        removeMediaStream(session);
         if (stream.videoTracks.size() < 2 && stream.audioTracks.size() < 2) {
         if (stream.videoTracks.size() < 2 && stream.audioTracks.size() < 2) {
             if (stream.videoTracks.size() == 1) {
             if (stream.videoTracks.size() == 1) {
 
 
@@ -631,7 +618,7 @@ public class CallActivity extends AppCompatActivity {
                                 surfaceViewRenderer.init(rootEglBase.getEglBaseContext(), null);
                                 surfaceViewRenderer.init(rootEglBase.getEglBaseContext(), null);
                                 surfaceViewRenderer.setZOrderMediaOverlay(true);
                                 surfaceViewRenderer.setZOrderMediaOverlay(true);
                                 surfaceViewRenderer.setEnableHardwareScaler(true);
                                 surfaceViewRenderer.setEnableHardwareScaler(true);
-                                surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
+                                surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
                                 VideoRenderer remoteRenderer = new VideoRenderer(surfaceViewRenderer);
                                 VideoRenderer remoteRenderer = new VideoRenderer(surfaceViewRenderer);
                                 videoRendererHashMap.put(session, remoteRenderer);
                                 videoRendererHashMap.put(session, remoteRenderer);
                                 videoTrack.addRenderer(remoteRenderer);
                                 videoTrack.addRenderer(remoteRenderer);
@@ -688,9 +675,38 @@ public class CallActivity extends AppCompatActivity {
         eventBus.unregister(this);
         eventBus.unregister(this);
     }
     }
 
 
+    @Subscribe(threadMode = ThreadMode.BACKGROUND)
+    public void onMessageEvent(PeerConnectionEvent peerConnectionEvent) {
+        endPeerConnection(peerConnectionEvent.getSessionId());
+    }
+
+    private void endPeerConnection(String sessionId) {
+        MagicPeerConnectionWrapper magicPeerConnectionWrapper;
+        if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId)) != null) {
+            runOnUiThread(() -> removeMediaStream(sessionId));
+            deleteMagicPeerConnection(magicPeerConnectionWrapper);
+        }
+    }
+
+    private void removeMediaStream(String sessionId) {
+        if (remoteRenderersLayout.getChildCount() > 0) {
+            for (int i = 0; i < remoteRenderersLayout.getChildCount(); i++) {
+                if (remoteRenderersLayout.getChildAt(i).getTag().equals(sessionId)) {
+                    remoteRenderersLayout.removeViewAt(i);
+                    remoteRenderersLayout.invalidate();
+                    break;
+                }
+            }
+        }
+    }
+
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
     public void onMessageEvent(MediaStreamEvent mediaStreamEvent) {
-        gotRemoteStream(mediaStreamEvent.getMediaStream(), mediaStreamEvent.getSession());
+        if (mediaStreamEvent.getMediaStream() != null) {
+            gotRemoteStream(mediaStreamEvent.getMediaStream(), mediaStreamEvent.getSession());
+        } else {
+            removeMediaStream(mediaStreamEvent.getSession());
+        }
     }
     }
 
 
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
@@ -700,6 +716,7 @@ public class CallActivity extends AppCompatActivity {
         ncMessageWrapper.setEv("message");
         ncMessageWrapper.setEv("message");
         ncMessageWrapper.setSessionId(callSession);
         ncMessageWrapper.setSessionId(callSession);
         NCSignalingMessage ncSignalingMessage = new NCSignalingMessage();
         NCSignalingMessage ncSignalingMessage = new NCSignalingMessage();
+        ncSignalingMessage.setFrom(callSession);
         ncSignalingMessage.setTo(sessionDescriptionSend.getPeerId());
         ncSignalingMessage.setTo(sessionDescriptionSend.getPeerId());
         ncSignalingMessage.setRoomType("video");
         ncSignalingMessage.setRoomType("video");
         ncSignalingMessage.setType(sessionDescriptionSend.getType());
         ncSignalingMessage.setType(sessionDescriptionSend.getType());

+ 3 - 1
app/src/main/java/com/nextcloud/talk/events/MediaStreamEvent.java

@@ -20,6 +20,8 @@
 
 
 package com.nextcloud.talk.events;
 package com.nextcloud.talk.events;
 
 
+import android.support.annotation.Nullable;
+
 import org.webrtc.MediaStream;
 import org.webrtc.MediaStream;
 
 
 import lombok.Data;
 import lombok.Data;
@@ -29,7 +31,7 @@ public class MediaStreamEvent {
     private final MediaStream mediaStream;
     private final MediaStream mediaStream;
     private final String session;
     private final String session;
 
 
-    public MediaStreamEvent(MediaStream mediaStream, String session) {
+    public MediaStreamEvent(@Nullable  MediaStream mediaStream, String session) {
         this.mediaStream = mediaStream;
         this.mediaStream = mediaStream;
         this.session = session;
         this.session = session;
     }
     }

+ 32 - 0
app/src/main/java/com/nextcloud/talk/events/PeerConnectionEvent.java

@@ -0,0 +1,32 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.events;
+
+import lombok.Data;
+
+@Data
+public class PeerConnectionEvent {
+    private final String sessionId;
+
+    public PeerConnectionEvent(String sessionId) {
+        this.sessionId = sessionId;
+    }
+}

+ 29 - 1
app/src/main/java/com/nextcloud/talk/jobs/AccountRemovalJob.java

@@ -36,6 +36,7 @@ import com.nextcloud.talk.persistence.entities.UserEntity;
 import com.nextcloud.talk.utils.database.user.UserUtils;
 import com.nextcloud.talk.utils.database.user.UserUtils;
 
 
 import java.io.IOException;
 import java.io.IOException;
+import java.net.CookieManager;
 import java.util.HashMap;
 import java.util.HashMap;
 
 
 import javax.inject.Inject;
 import javax.inject.Inject;
@@ -44,6 +45,9 @@ import autodagger.AutoInjector;
 import io.reactivex.CompletableObserver;
 import io.reactivex.CompletableObserver;
 import io.reactivex.Observer;
 import io.reactivex.Observer;
 import io.reactivex.disposables.Disposable;
 import io.reactivex.disposables.Disposable;
+import okhttp3.JavaNetCookieJar;
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
 
 
 @AutoInjector(NextcloudTalkApplication.class)
 @AutoInjector(NextcloudTalkApplication.class)
 public class AccountRemovalJob extends Job {
 public class AccountRemovalJob extends Job {
@@ -53,6 +57,11 @@ public class AccountRemovalJob extends Job {
     UserUtils userUtils;
     UserUtils userUtils;
 
 
     @Inject
     @Inject
+    Retrofit retrofit;
+
+    @Inject
+    OkHttpClient okHttpClient;
+
     NcApi ncApi;
     NcApi ncApi;
 
 
     @NonNull
     @NonNull
@@ -68,6 +77,10 @@ public class AccountRemovalJob extends Job {
                     pushConfigurationState = LoganSquare.parse(userEntity.getPushConfigurationState(),
                     pushConfigurationState = LoganSquare.parse(userEntity.getPushConfigurationState(),
                             PushConfigurationState.class);
                             PushConfigurationState.class);
                     PushConfigurationState finalPushConfigurationState = pushConfigurationState;
                     PushConfigurationState finalPushConfigurationState = pushConfigurationState;
+
+                    ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
+                            JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
+
                     ncApi.unregisterDeviceForNotificationsWithNextcloud(ApiHelper.getCredentials(userEntity.getUsername(),
                     ncApi.unregisterDeviceForNotificationsWithNextcloud(ApiHelper.getCredentials(userEntity.getUsername(),
                             userEntity.getToken()), ApiHelper.getUrlNextcloudPush(userEntity.getBaseUrl()))
                             userEntity.getToken()), ApiHelper.getUrlNextcloudPush(userEntity.getBaseUrl()))
                             .subscribe(new Observer<GenericOverall>() {
                             .subscribe(new Observer<GenericOverall>() {
@@ -161,7 +174,22 @@ public class AccountRemovalJob extends Job {
             } catch (IOException e) {
             } catch (IOException e) {
                 Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState");
                 Log.d(TAG, "Something went wrong while removing job at parsing PushConfigurationState");
                 userUtils.deleteUser(userEntity.getUsername(),
                 userUtils.deleteUser(userEntity.getUsername(),
-                        userEntity.getBaseUrl());
+                        userEntity.getBaseUrl()).subscribe(new CompletableObserver() {
+                    @Override
+                    public void onSubscribe(Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+
+                    @Override
+                    public void onError(Throwable e) {
+
+                    }
+                });
             }
             }
         }
         }
         return Result.SUCCESS;
         return Result.SUCCESS;

+ 12 - 1
app/src/main/java/com/nextcloud/talk/utils/PushUtils.java

@@ -41,6 +41,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.IOException;
+import java.net.CookieManager;
 import java.security.InvalidKeyException;
 import java.security.InvalidKeyException;
 import java.security.Key;
 import java.security.Key;
 import java.security.KeyFactory;
 import java.security.KeyFactory;
@@ -63,6 +64,9 @@ import javax.inject.Inject;
 import autodagger.AutoInjector;
 import autodagger.AutoInjector;
 import io.reactivex.functions.Consumer;
 import io.reactivex.functions.Consumer;
 import io.reactivex.schedulers.Schedulers;
 import io.reactivex.schedulers.Schedulers;
+import okhttp3.JavaNetCookieJar;
+import okhttp3.OkHttpClient;
+import retrofit2.Retrofit;
 
 
 @AutoInjector(NextcloudTalkApplication.class)
 @AutoInjector(NextcloudTalkApplication.class)
 public class PushUtils {
 public class PushUtils {
@@ -75,6 +79,11 @@ public class PushUtils {
     AppPreferences appPreferences;
     AppPreferences appPreferences;
 
 
     @Inject
     @Inject
+    OkHttpClient okHttpClient;
+
+    @Inject
+    Retrofit retrofit;
+
     NcApi ncApi;
     NcApi ncApi;
 
 
     private File keysFile;
     private File keysFile;
@@ -93,7 +102,6 @@ public class PushUtils {
                 Context.MODE_PRIVATE), "push_key.priv");
                 Context.MODE_PRIVATE), "push_key.priv");
         proxyServer = NextcloudTalkApplication.getSharedApplication().getResources().
         proxyServer = NextcloudTalkApplication.getSharedApplication().getResources().
                 getString(R.string.nc_push_server_url);
                 getString(R.string.nc_push_server_url);
-
     }
     }
 
 
 
 
@@ -253,6 +261,9 @@ public class PushUtils {
                             queryMap.put("devicePublicKey", publicKey);
                             queryMap.put("devicePublicKey", publicKey);
                             queryMap.put("proxyServer", proxyServer);
                             queryMap.put("proxyServer", proxyServer);
 
 
+                            ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
+                                    JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
+
                             ncApi.registerDeviceForNotificationsWithNextcloud(
                             ncApi.registerDeviceForNotificationsWithNextcloud(
                                     ApiHelper.getCredentials(userEntity.getUsername(), userEntity.getToken()),
                                     ApiHelper.getCredentials(userEntity.getUsername(), userEntity.getToken()),
                                     ApiHelper.getUrlNextcloudPush(userEntity.getBaseUrl()), queryMap)
                                     ApiHelper.getUrlNextcloudPush(userEntity.getBaseUrl()), queryMap)

+ 27 - 20
app/src/main/java/com/nextcloud/talk/webrtc/MagicPeerConnectionWrapper.java

@@ -26,6 +26,7 @@ import com.bluelinelabs.logansquare.LoganSquare;
 import com.nextcloud.talk.api.models.json.signaling.DataChannelMessage;
 import com.nextcloud.talk.api.models.json.signaling.DataChannelMessage;
 import com.nextcloud.talk.api.models.json.signaling.NCIceCandidate;
 import com.nextcloud.talk.api.models.json.signaling.NCIceCandidate;
 import com.nextcloud.talk.events.MediaStreamEvent;
 import com.nextcloud.talk.events.MediaStreamEvent;
+import com.nextcloud.talk.events.PeerConnectionEvent;
 import com.nextcloud.talk.events.SessionDescriptionSendEvent;
 import com.nextcloud.talk.events.SessionDescriptionSendEvent;
 
 
 import org.greenrobot.eventbus.EventBus;
 import org.greenrobot.eventbus.EventBus;
@@ -50,6 +51,7 @@ public class MagicPeerConnectionWrapper {
     List<IceCandidate> iceCandidates = new ArrayList<>();
     List<IceCandidate> iceCandidates = new ArrayList<>();
     private List<PeerConnection.IceServer> iceServers;
     private List<PeerConnection.IceServer> iceServers;
     private String sessionId;
     private String sessionId;
+    private String localSession;
     private String nick;
     private String nick;
     private MediaConstraints mediaConstraints;
     private MediaConstraints mediaConstraints;
     private DataChannel magicDataChannel;
     private DataChannel magicDataChannel;
@@ -64,22 +66,24 @@ public class MagicPeerConnectionWrapper {
                                       String sessionId, String localSession) {
                                       String sessionId, String localSession) {
 
 
         this.iceServers = iceServerList;
         this.iceServers = iceServerList;
+        this.localSession = localSession;
 
 
         peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, mediaConstraints,
         peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, mediaConstraints,
                 new MagicPeerConnectionObserver());
                 new MagicPeerConnectionObserver());
 
 
+        this.sessionId = sessionId;
+        this.mediaConstraints = mediaConstraints;
+
+        magicSdpObserver = new MagicSdpObserver();
+
         if (sessionId.compareTo(localSession) < 0) {
         if (sessionId.compareTo(localSession) < 0) {
             DataChannel.Init init = new DataChannel.Init();
             DataChannel.Init init = new DataChannel.Init();
             init.negotiated = false;
             init.negotiated = false;
             magicDataChannel = peerConnection.createDataChannel("status", init);
             magicDataChannel = peerConnection.createDataChannel("status", init);
             magicDataChannel.registerObserver(new MagicDataChannelObserver());
             magicDataChannel.registerObserver(new MagicDataChannelObserver());
+            peerConnection.createOffer(magicSdpObserver, mediaConstraints);
         }
         }
 
 
-        this.sessionId = sessionId;
-        this.mediaConstraints = mediaConstraints;
-
-        magicSdpObserver = new MagicSdpObserver();
-
     }
     }
 
 
     public void drainIceCandidates() {
     public void drainIceCandidates() {
@@ -177,6 +181,9 @@ public class MagicPeerConnectionWrapper {
 
 
         @Override
         @Override
         public void onSignalingChange(PeerConnection.SignalingState signalingState) {
         public void onSignalingChange(PeerConnection.SignalingState signalingState) {
+            if (signalingState.equals(PeerConnection.SignalingState.CLOSED)) {
+                EventBus.getDefault().post(new PeerConnectionEvent(sessionId));
+            }
         }
         }
 
 
         @Override
         @Override
@@ -219,6 +226,7 @@ public class MagicPeerConnectionWrapper {
         public void onRemoveStream(MediaStream mediaStream) {
         public void onRemoveStream(MediaStream mediaStream) {
             videoOn = mediaStream.videoTracks != null && mediaStream.videoTracks.size() == 1;
             videoOn = mediaStream.videoTracks != null && mediaStream.videoTracks.size() == 1;
             audioOn = mediaStream.audioTracks != null && mediaStream.audioTracks.size() == 1;
             audioOn = mediaStream.audioTracks != null && mediaStream.audioTracks.size() == 1;
+            EventBus.getDefault().post(new MediaStreamEvent(null, sessionId));
         }
         }
 
 
         @Override
         @Override
@@ -260,21 +268,20 @@ public class MagicPeerConnectionWrapper {
 
 
         @Override
         @Override
         public void onSetSuccess() {
         public void onSetSuccess() {
-            if (peerConnection.getRemoteDescription() == null) {
-                EventBus.getDefault().post(new SessionDescriptionSendEvent(peerConnection.getLocalDescription(), sessionId,
-                        peerConnection.getLocalDescription().type.canonicalForm(), null));
-
-            } else if (peerConnection.getLocalDescription() == null && peerConnection.getRemoteDescription().type
-                    .canonicalForm().equals
-                            ("offer")) {
-                peerConnection.createAnswer(magicSdpObserver, mediaConstraints);
-            } else if ((peerConnection.getLocalDescription() != null && peerConnection.getRemoteDescription().type
-                    .canonicalForm().equals
-                            ("offer"))) {
-                EventBus.getDefault().post(new SessionDescriptionSendEvent(peerConnection.getLocalDescription(), sessionId,
-                        peerConnection.getLocalDescription().type.canonicalForm(), null));
-            } else if (peerConnection.getRemoteDescription() != null) {
-                drainIceCandidates();
+            if (peerConnection != null) {
+                if (peerConnection.getRemoteDescription() != null) {
+                    drainIceCandidates();
+                }
+
+                if (peerConnection.getRemoteDescription() == null) {
+                    EventBus.getDefault().post(new SessionDescriptionSendEvent(peerConnection.getLocalDescription(), sessionId,
+                            peerConnection.getLocalDescription().type.canonicalForm(), null));
+                } else if (peerConnection.getLocalDescription() == null && sessionId.compareTo(localSession) > 0) {
+                    peerConnection.createAnswer(magicSdpObserver, mediaConstraints);
+                } else if ((peerConnection.getLocalDescription() != null)) {
+                    EventBus.getDefault().post(new SessionDescriptionSendEvent(peerConnection.getLocalDescription(), sessionId,
+                            peerConnection.getLocalDescription().type.canonicalForm(), null));
+                }
             }
             }
         }
         }
     }
     }

+ 3 - 2
app/src/main/res/layout/activity_call.xml

@@ -21,16 +21,17 @@
 
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 xmlns:tools="http://schemas.android.com/tools"
                 xmlns:tools="http://schemas.android.com/tools"
+                android:id="@+id/relative_layout"
                 android:layout_width="match_parent"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_height="match_parent"
                 android:fitsSystemWindows="true"
                 android:fitsSystemWindows="true"
-                android:id="@+id/relative_layout"
                 tools:context=".activities.CallActivity">
                 tools:context=".activities.CallActivity">
 
 
     <LinearLayout
     <LinearLayout
+        android:id="@+id/remote_renderers_layout"
         android:layout_width="match_parent"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_height="match_parent"
-        android:id="@+id/remote_renderers_layout"
+        android:animateLayoutChanges="true"
         android:orientation="vertical">
         android:orientation="vertical">
     </LinearLayout>
     </LinearLayout>