diff --git a/app/build.gradle b/app/build.gradle index 661bf3cce..6b894348c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,9 +4,11 @@ * @author Mario Danic * @author Andy Scherzinger * @author Marcel Hibbe + * @author Tim Krüger * Copyright (C) 2021 Andy Scherzinger * Copyright (C) 2017-2019 Mario Danic * Copyright (C) 2021 Marcel Hibbe + * Copyright (C) 2022 Tim Krüger * * 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 @@ -34,6 +36,20 @@ configurations { ktlint } +def urlFile = { url, fileName -> + File file = new File("$buildDir/download/${fileName}") + file.parentFile.mkdirs() + if (!file.exists()) { + new URL(url).withInputStream { downloadStream -> + file.withOutputStream { fileOut -> + fileOut << downloadStream + } + } + } + files(file.absolutePath) +} + + android { compileSdkVersion 30 buildToolsVersion '30.0.3' @@ -134,6 +150,7 @@ android { } check.dependsOn 'spotbugsGplayDebugReport', 'lint', 'ktlint', 'detekt' + lint.dependsOn 'preBuild' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -240,7 +257,8 @@ dependencies { kapt "com.jakewharton:butterknife-compiler:${butterknifeVersion}" implementation 'eu.davidea:flexible-adapter:5.1.0' implementation 'eu.davidea:flexible-adapter-ui:1.0.0' - implementation 'org.webrtc:google-webrtc:1.0.32006' + implementation urlFile('https://github.com/nextcloud-releases/talk-clients-webrtc/releases/download/96.4664.0-RC1/libwebrtc-96.4664.0.aar', + 'libwebrtc-96.4664.0.aar') implementation 'com.yarolegovich:lovely-dialog:1.1.1' implementation 'com.yarolegovich:mp:1.1.6' implementation 'me.zhanghai.android.effortlesspermissions:library:1.1.0' diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 2080ef4af..36f6b9c69 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -93,7 +93,7 @@ import com.nextcloud.talk.utils.power.PowerManagerUtils; import com.nextcloud.talk.utils.preferences.AppPreferences; import com.nextcloud.talk.utils.singletons.ApplicationWideCurrentRoomHolder; import com.nextcloud.talk.webrtc.MagicAudioManager; -import com.nextcloud.talk.webrtc.MagicPeerConnectionWrapper; +import com.nextcloud.talk.webrtc.PeerConnectionWrapper; import com.nextcloud.talk.webrtc.MagicWebRTCUtils; import com.nextcloud.talk.webrtc.MagicWebSocketInstance; import com.nextcloud.talk.webrtc.WebSocketConnectionHelper; @@ -213,9 +213,9 @@ public class CallActivity extends CallBaseActivity { private UserEntity conversationUser; private String conversationName; private String callSession; - private MediaStream localMediaStream; + private MediaStream localStream; private String credentials; - private List magicPeerConnectionWrapperList = new ArrayList<>(); + private List peerConnectionWrapperList = new ArrayList<>(); private Map participantMap = new HashMap<>(); private boolean videoOn = false; @@ -408,7 +408,7 @@ public class CallActivity extends CallBaseActivity { audioConstraints = new MediaConstraints(); videoConstraints = new MediaConstraints(); - localMediaStream = peerConnectionFactory.createLocalMediaStream("NCMS"); + localStream = peerConnectionFactory.createLocalMediaStream("NCMS"); // Create and audio manager that will take care of audio routing, // audio modes, audio device enumeration etc. @@ -781,7 +781,7 @@ public class CallActivity extends CallBaseActivity { videoCapturer.initialize(surfaceTextureHelper, getApplicationContext(), videoSource.getCapturerObserver()); } localVideoTrack = peerConnectionFactory.createVideoTrack("NCv0", videoSource); - localMediaStream.addTrack(localVideoTrack); + localStream.addTrack(localVideoTrack); localVideoTrack.setEnabled(false); localVideoTrack.addSink(binding.selfVideoRenderer); } @@ -791,7 +791,7 @@ public class CallActivity extends CallBaseActivity { audioSource = peerConnectionFactory.createAudioSource(audioConstraints); localAudioTrack = peerConnectionFactory.createAudioTrack("NCa0", audioSource); localAudioTrack.setEnabled(false); - localMediaStream.addTrack(localAudioTrack); + localStream.addTrack(localAudioTrack); } private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) { @@ -963,8 +963,8 @@ public class CallActivity extends CallBaseActivity { } } - if (localMediaStream != null && localMediaStream.videoTracks.size() > 0) { - localMediaStream.videoTracks.get(0).setEnabled(enable); + if (localStream != null && localStream.videoTracks.size() > 0) { + localStream.videoTracks.get(0).setEnabled(enable); } if (enable) { binding.selfVideoRenderer.setVisibility(View.VISIBLE); @@ -980,20 +980,20 @@ public class CallActivity extends CallBaseActivity { binding.microphoneButton.setAlpha(0.7f); } - if (localMediaStream != null && localMediaStream.audioTracks.size() > 0) { - localMediaStream.audioTracks.get(0).setEnabled(enable); + if (localStream != null && localStream.audioTracks.size() > 0) { + localStream.audioTracks.get(0).setEnabled(enable); } } - if (isConnectionEstablished() && magicPeerConnectionWrapperList != null) { + if (isConnectionEstablished() && peerConnectionWrapperList != null) { if (!hasMCU) { - for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { - magicPeerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); + for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) { + peerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); } } else { - for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { - if (magicPeerConnectionWrapper.getSessionId().equals(webSocketClient.getSessionId())) { - magicPeerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); + for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) { + if (peerConnectionWrapper.getSessionId().equals(webSocketClient.getSessionId())) { + peerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); break; } } @@ -1517,7 +1517,7 @@ public class CallActivity extends CallBaseActivity { private void processMessage(NCSignalingMessage ncSignalingMessage) { if (ncSignalingMessage.getRoomType().equals("video") || ncSignalingMessage.getRoomType().equals("screen")) { - MagicPeerConnectionWrapper magicPeerConnectionWrapper = + PeerConnectionWrapper peerConnectionWrapper = getPeerConnectionWrapperForSessionIdAndType(ncSignalingMessage.getFrom(), ncSignalingMessage.getRoomType(), false); @@ -1535,7 +1535,7 @@ public class CallActivity extends CallBaseActivity { break; case "offer": case "answer": - magicPeerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick()); + peerConnectionWrapper.setNick(ncSignalingMessage.getPayload().getNick()); SessionDescription sessionDescriptionWithPreferredCodec; String sessionDescriptionStringWithPreferredCodec = MagicWebRTCUtils.preferCodec @@ -1546,8 +1546,8 @@ public class CallActivity extends CallBaseActivity { SessionDescription.Type.fromCanonicalForm(type), sessionDescriptionStringWithPreferredCodec); - if (magicPeerConnectionWrapper.getPeerConnection() != null) { - magicPeerConnectionWrapper.getPeerConnection().setRemoteDescription(magicPeerConnectionWrapper + if (peerConnectionWrapper.getPeerConnection() != null) { + peerConnectionWrapper.getPeerConnection().setRemoteDescription(peerConnectionWrapper .getMagicSdpObserver(), sessionDescriptionWithPreferredCodec); } break; @@ -1555,10 +1555,10 @@ public class CallActivity extends CallBaseActivity { NCIceCandidate ncIceCandidate = ncSignalingMessage.getPayload().getIceCandidate(); IceCandidate iceCandidate = new IceCandidate(ncIceCandidate.getSdpMid(), ncIceCandidate.getSdpMLineIndex(), ncIceCandidate.getCandidate()); - magicPeerConnectionWrapper.addCandidate(iceCandidate); + peerConnectionWrapper.addCandidate(iceCandidate); break; case "endOfCandidates": - magicPeerConnectionWrapper.drainIceCandidates(); + peerConnectionWrapper.drainIceCandidates(); break; default: break; @@ -1608,7 +1608,7 @@ public class CallActivity extends CallBaseActivity { peerConnectionFactory = null; } - localMediaStream = null; + localAudioTrack = null; localVideoTrack = null; @@ -1618,8 +1618,16 @@ public class CallActivity extends CallBaseActivity { } } - for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { - endPeerConnection(magicPeerConnectionWrapperList.get(i).getSessionId(), false); + for (int i = 0; i < peerConnectionWrapperList.size(); i++) { + endPeerConnection(peerConnectionWrapperList.get(i).getSessionId(), false); + } + + if(localStream != null) { + localStream.dispose(); + localStream = null; + Log.d(TAG, "Disposed localStream"); + } else { + Log.d(TAG, "localStream is null"); } hangupNetworkCalls(shutDownView); @@ -1703,9 +1711,9 @@ public class CallActivity extends CallBaseActivity { } } - for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { - if (!magicPeerConnectionWrapper.isMCUPublisher()) { - oldSessions.add(magicPeerConnectionWrapper.getSessionId()); + for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) { + if (!peerConnectionWrapper.isMCUPublisher()) { + oldSessions.add(peerConnectionWrapper.getSessionId()); } } @@ -1775,86 +1783,86 @@ public class CallActivity extends CallBaseActivity { }); } - private void deleteMagicPeerConnection(MagicPeerConnectionWrapper magicPeerConnectionWrapper) { - magicPeerConnectionWrapper.removePeerConnection(); - magicPeerConnectionWrapperList.remove(magicPeerConnectionWrapper); + private void deletePeerConnection(PeerConnectionWrapper peerConnectionWrapper) { + peerConnectionWrapper.removePeerConnection(); + peerConnectionWrapperList.remove(peerConnectionWrapper); } - private MagicPeerConnectionWrapper getPeerConnectionWrapperForSessionId(String sessionId, String type) { - for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { - if (magicPeerConnectionWrapperList.get(i).getSessionId().equals(sessionId) && magicPeerConnectionWrapperList.get(i).getVideoStreamType().equals(type)) { - return magicPeerConnectionWrapperList.get(i); + private PeerConnectionWrapper getPeerConnectionWrapperForSessionId(String sessionId, String type) { + for (int i = 0; i < peerConnectionWrapperList.size(); i++) { + if (peerConnectionWrapperList.get(i).getSessionId().equals(sessionId) && peerConnectionWrapperList.get(i).getVideoStreamType().equals(type)) { + return peerConnectionWrapperList.get(i); } } return null; } - private MagicPeerConnectionWrapper getPeerConnectionWrapperForSessionIdAndType(String sessionId, String type, boolean publisher) { - MagicPeerConnectionWrapper magicPeerConnectionWrapper; - if ((magicPeerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId, type)) != null) { - return magicPeerConnectionWrapper; + private PeerConnectionWrapper getPeerConnectionWrapperForSessionIdAndType(String sessionId, String type, boolean publisher) { + PeerConnectionWrapper peerConnectionWrapper; + if ((peerConnectionWrapper = getPeerConnectionWrapperForSessionId(sessionId, type)) != null) { + return peerConnectionWrapper; } else { if (hasMCU && publisher) { - magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory, - iceServers, - sdpConstraintsForMCU, - sessionId, - callSession, - localMediaStream, - true, - true, - type); + peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory, + iceServers, + sdpConstraintsForMCU, + sessionId, + callSession, + localStream, + true, + true, + type); } else if (hasMCU) { - magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory, - iceServers, - sdpConstraints, - sessionId, - callSession, - null, - false, - true, - type); + peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory, + iceServers, + sdpConstraints, + sessionId, + callSession, + null, + false, + true, + type); } else { if (!"screen".equals(type)) { - magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory, - iceServers, - sdpConstraints, - sessionId, - callSession, - localMediaStream, - false, - false, - type); + peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory, + iceServers, + sdpConstraints, + sessionId, + callSession, + localStream, + false, + false, + type); } else { - magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory, - iceServers, - sdpConstraints, - sessionId, - callSession, - null, - false, - false, - type); + peerConnectionWrapper = new PeerConnectionWrapper(peerConnectionFactory, + iceServers, + sdpConstraints, + sessionId, + callSession, + null, + false, + false, + type); } } - magicPeerConnectionWrapperList.add(magicPeerConnectionWrapper); + peerConnectionWrapperList.add(peerConnectionWrapper); if (publisher) { startSendingNick(); } - return magicPeerConnectionWrapper; + return peerConnectionWrapper; } } - private List getPeerConnectionWrapperListForSessionId(String sessionId) { - List internalList = new ArrayList<>(); - for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { - if (magicPeerConnectionWrapper.getSessionId().equals(sessionId)) { - internalList.add(magicPeerConnectionWrapper); + private List getPeerConnectionWrapperListForSessionId(String sessionId) { + List internalList = new ArrayList<>(); + for (PeerConnectionWrapper peerConnectionWrapper : peerConnectionWrapperList) { + if (peerConnectionWrapper.getSessionId().equals(sessionId)) { + internalList.add(peerConnectionWrapper); } } @@ -1862,15 +1870,15 @@ public class CallActivity extends CallBaseActivity { } private void endPeerConnection(String sessionId, boolean justScreen) { - List magicPeerConnectionWrappers; - MagicPeerConnectionWrapper magicPeerConnectionWrapper; - if (!(magicPeerConnectionWrappers = getPeerConnectionWrapperListForSessionId(sessionId)).isEmpty()) { - for (int i = 0; i < magicPeerConnectionWrappers.size(); i++) { - magicPeerConnectionWrapper = magicPeerConnectionWrappers.get(i); - if (magicPeerConnectionWrapper.getSessionId().equals(sessionId)) { - if (magicPeerConnectionWrapper.getVideoStreamType().equals("screen") || !justScreen) { + List peerConnectionWrappers; + PeerConnectionWrapper peerConnectionWrapper; + if (!(peerConnectionWrappers = getPeerConnectionWrapperListForSessionId(sessionId)).isEmpty()) { + for (int i = 0; i < peerConnectionWrappers.size(); i++) { + peerConnectionWrapper = peerConnectionWrappers.get(i); + if (peerConnectionWrapper.getSessionId().equals(sessionId)) { + if (peerConnectionWrapper.getVideoStreamType().equals("screen") || !justScreen) { runOnUiThread(() -> removeMediaStream(sessionId)); - deleteMagicPeerConnection(magicPeerConnectionWrapper); + deletePeerConnection(peerConnectionWrapper); } } } @@ -1982,10 +1990,10 @@ public class CallActivity extends CallBaseActivity { nickChangedPayload.put("userid", conversationUser.getUserId()); nickChangedPayload.put("name", conversationUser.getDisplayName()); dataChannelMessage.setPayload(nickChangedPayload); - final MagicPeerConnectionWrapper magicPeerConnectionWrapper; - for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { - if (magicPeerConnectionWrapperList.get(i).isMCUPublisher()) { - magicPeerConnectionWrapper = magicPeerConnectionWrapperList.get(i); + final PeerConnectionWrapper peerConnectionWrapper; + for (int i = 0; i < peerConnectionWrapperList.size(); i++) { + if (peerConnectionWrapperList.get(i).isMCUPublisher()) { + peerConnectionWrapper = peerConnectionWrapperList.get(i); Observable .interval(1, TimeUnit.SECONDS) .repeatUntil(() -> (!isConnectionEstablished() || isDestroyed())) @@ -1998,7 +2006,7 @@ public class CallActivity extends CallBaseActivity { @Override public void onNext(@io.reactivex.annotations.NonNull Long aLong) { - magicPeerConnectionWrapper.sendNickChannelData(dataChannelMessage); + peerConnectionWrapper.sendNickChannelData(dataChannelMessage); } @Override diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicPeerConnectionWrapper.java b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java similarity index 74% rename from app/src/main/java/com/nextcloud/talk/webrtc/MagicPeerConnectionWrapper.java rename to app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java index 4d29af22b..1fd33cc1b 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicPeerConnectionWrapper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/PeerConnectionWrapper.java @@ -2,6 +2,8 @@ * Nextcloud Talk application * * @author Mario Danic + * @author Tim Krüger + * Copyright (C) 2022 Tim Krüger * Copyright (C) 2017 Mario Danic * * This program is free software: you can redistribute it and/or modify @@ -37,6 +39,7 @@ import com.nextcloud.talk.models.json.signaling.DataChannelMessageNick; import com.nextcloud.talk.models.json.signaling.NCIceCandidate; import org.greenrobot.eventbus.EventBus; +import org.webrtc.AudioTrack; import org.webrtc.DataChannel; import org.webrtc.IceCandidate; import org.webrtc.MediaConstraints; @@ -46,81 +49,87 @@ import org.webrtc.PeerConnectionFactory; import org.webrtc.RtpReceiver; import org.webrtc.SdpObserver; import org.webrtc.SessionDescription; +import org.webrtc.VideoTrack; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Objects; import javax.inject.Inject; import androidx.annotation.Nullable; import autodagger.AutoInjector; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + @AutoInjector(NextcloudTalkApplication.class) -public class MagicPeerConnectionWrapper { - private static final String TAG = "MagicPeerConWrapper"; +public class PeerConnectionWrapper { + + private static final String TAG = PeerConnectionWrapper.class.getCanonicalName(); private List iceCandidates = new ArrayList<>(); private PeerConnection peerConnection; private String sessionId; private String nick; - private MediaConstraints sdpConstraints; - private DataChannel magicDataChannel; - private MagicSdpObserver magicSdpObserver; - private MediaStream remoteMediaStream; + private final MediaConstraints mediaConstraints; + private DataChannel dataChannel; + private final MagicSdpObserver magicSdpObserver; + private MediaStream remoteStream; - private boolean remoteVideoOn; - private boolean remoteAudioOn; + private final boolean hasInitiated; - private boolean hasInitiated; - - private MediaStream localMediaStream; - private boolean isMCUPublisher; - private boolean hasMCU; - private String videoStreamType; - - private int connectionAttempts = 0; - private PeerConnection.IceConnectionState peerIceConnectionState; + private final MediaStream localStream; + private final boolean isMCUPublisher; + private final String videoStreamType; @Inject Context context; - public MagicPeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory, - List iceServerList, - MediaConstraints sdpConstraints, - String sessionId, String localSession, @Nullable MediaStream mediaStream, - boolean isMCUPublisher, boolean hasMCU, String videoStreamType) { + public PeerConnectionWrapper(PeerConnectionFactory peerConnectionFactory, + List iceServerList, + MediaConstraints mediaConstraints, + String sessionId, String localSession, @Nullable MediaStream localStream, + boolean isMCUPublisher, boolean hasMCU, String videoStreamType) { - NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this); + Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getComponentApplication().inject(this); - this.localMediaStream = mediaStream; + this.localStream = localStream; this.videoStreamType = videoStreamType; - this.hasMCU = hasMCU; this.sessionId = sessionId; - this.sdpConstraints = sdpConstraints; + this.mediaConstraints = mediaConstraints; magicSdpObserver = new MagicSdpObserver(); hasInitiated = sessionId.compareTo(localSession) < 0; this.isMCUPublisher = isMCUPublisher; - - peerConnection = peerConnectionFactory.createPeerConnection(iceServerList, sdpConstraints, - new MagicPeerConnectionObserver()); + + PeerConnection.RTCConfiguration configuration = new PeerConnection.RTCConfiguration(iceServerList); + configuration.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN; + peerConnection = peerConnectionFactory.createPeerConnection(configuration, new MagicPeerConnectionObserver()); if (peerConnection != null) { - if (localMediaStream != null) { - peerConnection.addStream(localMediaStream); + if (this.localStream != null) { + List localStreamIds = Collections.singletonList(this.localStream.getId()); + for(AudioTrack track : this.localStream.audioTracks) { + peerConnection.addTrack(track, localStreamIds); + } + for(VideoTrack track : this.localStream.videoTracks) { + peerConnection.addTrack(track, localStreamIds); + } } if (hasMCU || hasInitiated) { DataChannel.Init init = new DataChannel.Init(); init.negotiated = false; - magicDataChannel = peerConnection.createDataChannel("status", init); - magicDataChannel.registerObserver(new MagicDataChannelObserver()); + dataChannel = peerConnection.createDataChannel("status", init); + dataChannel.registerObserver(new MagicDataChannelObserver()); if (isMCUPublisher) { - peerConnection.createOffer(magicSdpObserver, sdpConstraints); + peerConnection.createOffer(magicSdpObserver, mediaConstraints); } else if (hasMCU && this.videoStreamType.equals("video")) { // If the connection type is "screen" the client sharing the screen will send an // offer; offers should be requested only for videos. @@ -128,7 +137,7 @@ public class MagicPeerConnectionWrapper { hashMap.put("sessionId", sessionId); EventBus.getDefault().post(new WebSocketCommunicationEvent("peerReadyForRequestingOffer", hashMap)); } else if (!hasMCU && hasInitiated) { - peerConnection.createOffer(magicSdpObserver, sdpConstraints); + peerConnection.createOffer(magicSdpObserver, mediaConstraints); } } } @@ -139,18 +148,20 @@ public class MagicPeerConnectionWrapper { } public void removePeerConnection() { - if (magicDataChannel != null) { - magicDataChannel.dispose(); - magicDataChannel = null; + if (dataChannel != null) { + dataChannel.dispose(); + dataChannel = null; + Log.d(TAG, "Disposed DataChannel"); + } else { + Log.d(TAG, "DataChannel is null."); } if (peerConnection != null) { - if (localMediaStream != null) { - peerConnection.removeStream(localMediaStream); - } - peerConnection.close(); peerConnection = null; + Log.d(TAG, "Disposed PeerConnection"); + } else { + Log.d(TAG, "PeerConnection is null."); } } @@ -179,10 +190,10 @@ public class MagicPeerConnectionWrapper { public void sendNickChannelData(DataChannelMessageNick dataChannelMessage) { ByteBuffer buffer; - if (magicDataChannel != null) { + if (dataChannel != null) { try { buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes()); - magicDataChannel.send(new DataChannel.Buffer(buffer, false)); + dataChannel.send(new DataChannel.Buffer(buffer, false)); } catch (IOException e) { Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage); } @@ -191,10 +202,10 @@ public class MagicPeerConnectionWrapper { public void sendChannelData(DataChannelMessage dataChannelMessage) { ByteBuffer buffer; - if (magicDataChannel != null) { + if (dataChannel != null) { try { buffer = ByteBuffer.wrap(LoganSquare.serialize(dataChannelMessage).getBytes()); - magicDataChannel.send(new DataChannel.Buffer(buffer, false)); + dataChannel.send(new DataChannel.Buffer(buffer, false)); } catch (IOException e) { Log.d(TAG, "Failed to send channel data, attempting regular " + dataChannelMessage); } @@ -217,7 +228,7 @@ public class MagicPeerConnectionWrapper { if (!TextUtils.isEmpty(nick)) { return nick; } else { - return NextcloudTalkApplication.Companion.getSharedApplication().getString(R.string.nc_nick_guest); + return Objects.requireNonNull(NextcloudTalkApplication.Companion.getSharedApplication()).getString(R.string.nc_nick_guest); } } @@ -226,14 +237,14 @@ public class MagicPeerConnectionWrapper { } private void sendInitialMediaStatus() { - if (localMediaStream != null) { - if (localMediaStream.videoTracks.size() == 1 && localMediaStream.videoTracks.get(0).enabled()) { + if (localStream != null) { + if (localStream.videoTracks.size() == 1 && localStream.videoTracks.get(0).enabled()) { sendChannelData(new DataChannelMessage("videoOn")); } else { sendChannelData(new DataChannelMessage("videoOff")); } - if (localMediaStream.audioTracks.size() == 1 && localMediaStream.audioTracks.get(0).enabled()) { + if (localStream.audioTracks.size() == 1 && localStream.audioTracks.get(0).enabled()) { sendChannelData(new DataChannelMessage("audioOn")); } else { sendChannelData(new DataChannelMessage("audioOff")); @@ -254,8 +265,8 @@ public class MagicPeerConnectionWrapper { @Override public void onStateChange() { - if (magicDataChannel != null && magicDataChannel.state().equals(DataChannel.State.OPEN) && - magicDataChannel.label().equals("status")) { + if (dataChannel != null && dataChannel.state().equals(DataChannel.State.OPEN) && + dataChannel.label().equals("status")) { sendInitialMediaStatus(); } } @@ -292,23 +303,18 @@ public class MagicPeerConnectionWrapper { .NICK_CHANGE, sessionId, payloadHashMap.get("name"), null, videoStreamType)); } } - } else if ("audioOn".equals(dataChannelMessage.getType())) { - remoteAudioOn = true; EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, remoteAudioOn, videoStreamType)); + .AUDIO_CHANGE, sessionId, null, TRUE, videoStreamType)); } else if ("audioOff".equals(dataChannelMessage.getType())) { - remoteAudioOn = false; EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .AUDIO_CHANGE, sessionId, null, remoteAudioOn, videoStreamType)); + .AUDIO_CHANGE, sessionId, null, FALSE, videoStreamType)); } else if ("videoOn".equals(dataChannelMessage.getType())) { - remoteVideoOn = true; EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, remoteVideoOn, videoStreamType)); + .VIDEO_CHANGE, sessionId, null, TRUE, videoStreamType)); } else if ("videoOff".equals(dataChannelMessage.getType())) { - remoteVideoOn = false; EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .VIDEO_CHANGE, sessionId, null, remoteVideoOn, videoStreamType)); + .VIDEO_CHANGE, sessionId, null, FALSE, videoStreamType)); } } catch (IOException e) { Log.d(TAG, "Failed to parse data channel message"); @@ -316,26 +322,6 @@ public class MagicPeerConnectionWrapper { } } - private void restartIce() { - if (connectionAttempts <= 5) { - if (!hasMCU || isMCUPublisher) { - MediaConstraints.KeyValuePair iceRestartConstraint = - new MediaConstraints.KeyValuePair("IceRestart", "true"); - - if (sdpConstraints.mandatory.contains(iceRestartConstraint)) { - sdpConstraints.mandatory.add(iceRestartConstraint); - } - - peerConnection.createOffer(magicSdpObserver, sdpConstraints); - } else { - // we have an MCU and this is not the publisher - // Do something if we have an MCU - } - - connectionAttempts++; - } - } - private class MagicPeerConnectionObserver implements PeerConnection.Observer { @Override @@ -344,16 +330,12 @@ public class MagicPeerConnectionWrapper { @Override public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) { - peerIceConnectionState = iceConnectionState; Log.d("iceConnectionChangeTo: ", iceConnectionState.name() + " over " + peerConnection.hashCode() + " " + sessionId); if (iceConnectionState.equals(PeerConnection.IceConnectionState.CONNECTED)) { - connectionAttempts = 0; - /*EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType - .PEER_CONNECTED, sessionId, null, null));*/ if (!isMCUPublisher) { - EventBus.getDefault().post(new MediaStreamEvent(remoteMediaStream, sessionId, videoStreamType)); + EventBus.getDefault().post(new MediaStreamEvent(remoteStream, sessionId, videoStreamType)); } if (hasInitiated) { @@ -363,11 +345,7 @@ public class MagicPeerConnectionWrapper { } else if (iceConnectionState.equals(PeerConnection.IceConnectionState.CLOSED)) { EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType .PEER_CLOSED, sessionId, null, null, videoStreamType)); - connectionAttempts = 0; } else if (iceConnectionState.equals(PeerConnection.IceConnectionState.FAILED)) { - /*if (MerlinTheWizard.isConnectedToInternet() && connectionAttempts < 5) { - restartIce(); - }*/ if (isMCUPublisher) { EventBus.getDefault().post(new PeerConnectionEvent(PeerConnectionEvent.PeerConnectionEventType.PUBLISHER_FAILED, sessionId, null, null, null)); } @@ -401,7 +379,7 @@ public class MagicPeerConnectionWrapper { @Override public void onAddStream(MediaStream mediaStream) { - remoteMediaStream = mediaStream; + remoteStream = mediaStream; } @Override @@ -414,8 +392,8 @@ public class MagicPeerConnectionWrapper { @Override public void onDataChannel(DataChannel dataChannel) { if (dataChannel.label().equals("status") || dataChannel.label().equals("JanusDataChannel")) { - magicDataChannel = dataChannel; - magicDataChannel.registerObserver(new MagicDataChannelObserver()); + PeerConnectionWrapper.this.dataChannel = dataChannel; + PeerConnectionWrapper.this.dataChannel.registerObserver(new MagicDataChannelObserver()); } } @@ -466,7 +444,7 @@ public class MagicPeerConnectionWrapper { public void onSetSuccess() { if (peerConnection != null) { if (peerConnection.getLocalDescription() == null) { - peerConnection.createAnswer(magicSdpObserver, sdpConstraints); + peerConnection.createAnswer(magicSdpObserver, mediaConstraints); } if (peerConnection.getRemoteDescription() != null) { @@ -475,8 +453,4 @@ public class MagicPeerConnectionWrapper { } } } - - public PeerConnection.IceConnectionState getPeerIceConnectionState() { - return peerIceConnectionState; - } } \ No newline at end of file diff --git a/scripts/analysis/lint-up.rb b/scripts/analysis/lint-up.rb index 245866521..44eb132d8 100644 --- a/scripts/analysis/lint-up.rb +++ b/scripts/analysis/lint-up.rb @@ -56,12 +56,12 @@ end # run Lint puts "running Lint..." -system './gradlew --console=plain clean lintGplayDebug' +system './gradlew --console=plain lintGplayDebug' # confirm that Lint ran w/out error result = $?.to_i if result != 0 - puts "FAIL: failed to run ./gradlew --console=plain clean lintGplayDebug" + puts "FAIL: failed to run ./gradlew --console=plain lintGplayDebug" exit 1 end