Split call participants and peer connections

Instead of trying to create a video peer connection for any joined
participant now only a call participant is created for any joined
participant, and a video peer connection is created only for those
participants that are publishing audio or video.

If a call participants does not have a video peer connection the call
participant is now seen as "connected" from the UI, as there is no need
to show a progress bar for that participant.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2022-11-29 20:34:32 +01:00 committed by Marcel Hibbe (Rebase PR Action)
parent 2cb7572dbc
commit 9ae969b0f8
2 changed files with 42 additions and 9 deletions

View File

@ -1721,14 +1721,22 @@ public class CallActivity extends CallBaseActivity {
}
}
List<String> sessionIdsToEnd = new ArrayList<String>(peerConnectionWrapperList.size());
List<String> peerConnectionIdsToEnd = new ArrayList<String>(peerConnectionWrapperList.size());
for (PeerConnectionWrapper wrapper : peerConnectionWrapperList) {
sessionIdsToEnd.add(wrapper.getSessionId());
peerConnectionIdsToEnd.add(wrapper.getSessionId());
}
for (String sessionId : sessionIdsToEnd) {
for (String sessionId : peerConnectionIdsToEnd) {
endPeerConnection(sessionId, false);
}
List<String> callParticipantIdsToEnd = new ArrayList<String>(peerConnectionWrapperList.size());
for (CallParticipant callParticipant : callParticipants.values()) {
callParticipantIdsToEnd.add(callParticipant.getCallParticipantModel().getSessionId());
}
for (String sessionId : callParticipantIdsToEnd) {
removeCallParticipant(sessionId);
}
hangupNetworkCalls(shutDownView);
ApplicationWideCurrentRoomHolder.getInstance().setInCall(false);
}
@ -1798,6 +1806,7 @@ public class CallActivity extends CallBaseActivity {
participantsInCall.addAll(unchanged);
boolean isSelfInCall = false;
Participant selfParticipant = null;
for (Participant participant : participantsInCall) {
long inCallFlag = participant.getInCall();
@ -1809,6 +1818,7 @@ public class CallActivity extends CallBaseActivity {
} else {
Log.d(TAG, " inCallFlag of currentSessionId: " + inCallFlag);
isSelfInCall = inCallFlag != 0;
selfParticipant = participant;
}
}
@ -1826,6 +1836,7 @@ public class CallActivity extends CallBaseActivity {
String sessionId = participant.getSessionId();
Log.d(TAG, " session that will be removed is: " + sessionId);
endPeerConnection(sessionId, false);
removeCallParticipant(sessionId);
}
return;
@ -1841,6 +1852,7 @@ public class CallActivity extends CallBaseActivity {
}
boolean selfJoined = false;
boolean selfParticipantHasAudioOrVideo = participantInCallFlagsHaveAudioOrVideo(selfParticipant);
for (Participant participant : joined) {
String sessionId = participant.getSessionId();
@ -1856,7 +1868,8 @@ public class CallActivity extends CallBaseActivity {
}
Log.d(TAG, " newSession joined: " + sessionId);
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false);
CallParticipant callParticipant = addCallParticipant(sessionId);
String userId = participant.getUserId();
if (userId != null) {
@ -1870,6 +1883,17 @@ public class CallActivity extends CallBaseActivity {
nick = offerAnswerNickProviders.get(sessionId) != null ? offerAnswerNickProviders.get(sessionId).getNick() : "";
}
callParticipants.get(sessionId).setNick(nick);
boolean participantHasAudioOrVideo = participantInCallFlagsHaveAudioOrVideo(participant);
// FIXME Without MCU, PeerConnectionWrapper only sends an offer if the local session ID is higher than the
// remote session ID. However, if the other participant does not have audio nor video that participant
// will not send an offer, so no connection is actually established when the remote participant has a
// higher session ID but is not publishing media.
if ((hasMCU && participantHasAudioOrVideo) ||
(!hasMCU && selfParticipantHasAudioOrVideo && (!participantHasAudioOrVideo || sessionId.compareTo(currentSessionId) < 0))) {
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false);
}
}
boolean othersInCall = selfJoined ? joined.size() > 1 : joined.size() > 0;
@ -1881,9 +1905,19 @@ public class CallActivity extends CallBaseActivity {
String sessionId = participant.getSessionId();
Log.d(TAG, " oldSession that will be removed is: " + sessionId);
endPeerConnection(sessionId, false);
removeCallParticipant(sessionId);
}
}
private boolean participantInCallFlagsHaveAudioOrVideo(Participant participant) {
if (participant == null) {
return false;
}
return (participant.getInCall() & Participant.InCallFlags.WITH_AUDIO) > 0 ||
(!isVoiceOnlyCall && (participant.getInCall() & Participant.InCallFlags.WITH_VIDEO) > 0);
}
private void deletePeerConnection(PeerConnectionWrapper peerConnectionWrapper) {
peerConnectionWrapper.removePeerConnection();
peerConnectionWrapperList.remove(peerConnectionWrapper);
@ -2059,10 +2093,6 @@ public class CallActivity extends CallBaseActivity {
}
}
}
if (!justScreen) {
removeCallParticipant(sessionId);
}
}
private void removeCallParticipant(String sessionId) {

View File

@ -95,7 +95,10 @@ public class ParticipantDisplayItem {
public boolean isConnected() {
return iceConnectionState == PeerConnection.IceConnectionState.CONNECTED ||
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED;
iceConnectionState == PeerConnection.IceConnectionState.COMPLETED ||
// If there is no connection state that means that no connection is needed, so it is a special case that is
// also seen as "connected".
iceConnectionState == null;
}
public String getNick() {