Store actor data from signaling messages with participant updates

Starting with Talk 20 the signaling messages that provide updates to the
participants ("participants->update" in the external signaling server,
"usersInRoom" in the internal signaling server) now include "actorType"
and "actorId" properties for each participant.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2024-08-28 08:30:38 +02:00 committed by Marcel Hibbe
parent 86b06488c3
commit 3b7c5e1d27
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
10 changed files with 78 additions and 6 deletions

View File

@ -2160,6 +2160,10 @@ class CallActivity : CallBaseActivity() {
Log.d(TAG, " newSession joined: $sessionId")
addCallParticipant(sessionId)
if (participant.actorType != null && participant.actorId != null) {
callParticipants[sessionId]!!.setActor(participant.actorType, participant.actorId)
}
val userId = participant.userId
if (userId != null) {
callParticipants[sessionId]!!.setUserId(userId)

View File

@ -14,6 +14,7 @@ import android.text.TextUtils;
import com.nextcloud.talk.call.CallParticipantModel;
import com.nextcloud.talk.call.RaisedHand;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.utils.ApiUtils;
import org.webrtc.EglBase;
@ -38,6 +39,8 @@ public class ParticipantDisplayItem {
private final CallParticipantModel callParticipantModel;
private Participant.ActorType actorType;
private String actorId;
private String userId;
private PeerConnection.IceConnectionState iceConnectionState;
private String nick;
@ -82,6 +85,8 @@ public class ParticipantDisplayItem {
}
private void updateFromModel() {
actorType = callParticipantModel.getActorType();
actorId = callParticipantModel.getActorId();
userId = callParticipantModel.getUserId();
nick = callParticipantModel.getNick();
@ -166,6 +171,8 @@ public class ParticipantDisplayItem {
public String toString() {
return "ParticipantSession{" +
"userId='" + userId + '\'' +
", actorType='" + actorType + '\'' +
", actorId='" + actorId + '\'' +
", session='" + session + '\'' +
", nick='" + nick + '\'' +
", urlForAvatar='" + urlForAvatar + '\'' +

View File

@ -6,6 +6,7 @@
*/
package com.nextcloud.talk.call;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.signaling.SignalingMessageReceiver;
import com.nextcloud.talk.webrtc.PeerConnectionWrapper;
@ -132,6 +133,10 @@ public class CallParticipant {
return callParticipantModel;
}
public void setActor(Participant.ActorType actorType, String actorId) {
callParticipantModel.setActor(actorType, actorId);
}
public void setUserId(String userId) {
callParticipantModel.setUserId(userId);
}

View File

@ -122,6 +122,8 @@ public class CallParticipantList {
private Participant copyParticipant(Participant participant) {
Participant copiedParticipant = new Participant();
copiedParticipant.setActorId(participant.getActorId());
copiedParticipant.setActorType(participant.getActorType());
copiedParticipant.setInCall(participant.getInCall());
copiedParticipant.setInternal(participant.getInternal());
copiedParticipant.setLastPing(participant.getLastPing());

View File

@ -8,6 +8,8 @@ package com.nextcloud.talk.call;
import android.os.Handler;
import com.nextcloud.talk.models.json.participants.Participant;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
@ -25,6 +27,8 @@ import java.util.Objects;
*
* Audio and video in screen shares, on the other hand, are always seen as available.
*
* Actor type and actor id will be set only in Talk >= 20.
*
* Clients of the model can observe it with CallParticipantModel.Observer to be notified when any value changes.
* Getters called after receiving a notification are guaranteed to provide at least the value that triggered the
* notification, but it may return even a more up to date one (so getting the value again on the following
@ -39,6 +43,8 @@ public class CallParticipantModel {
protected final String sessionId;
protected Data<Participant.ActorType> actorType;
protected Data<String> actorId;
protected Data<String> userId;
protected Data<String> nick;
@ -81,6 +87,8 @@ public class CallParticipantModel {
public CallParticipantModel(String sessionId) {
this.sessionId = sessionId;
this.actorType = new Data<>();
this.actorId = new Data<>();
this.userId = new Data<>();
this.nick = new Data<>();
@ -101,6 +109,14 @@ public class CallParticipantModel {
return sessionId;
}
public Participant.ActorType getActorType() {
return actorType.getValue();
}
public String getActorId() {
return actorId.getValue();
}
public String getUserId() {
return userId.getValue();
}

View File

@ -6,6 +6,8 @@
*/
package com.nextcloud.talk.call;
import com.nextcloud.talk.models.json.participants.Participant;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
@ -20,6 +22,11 @@ public class MutableCallParticipantModel extends CallParticipantModel {
super(sessionId);
}
public void setActor(Participant.ActorType actorType, String actorId) {
this.actorType.setValue(actorType);
this.actorId.setValue(actorId);
}
public void setUserId(String userId) {
this.userId.setValue(userId);
}

View File

@ -6,6 +6,7 @@
*/
package com.nextcloud.talk.signaling;
import com.nextcloud.talk.models.json.converters.EnumActorTypeConverter;
import com.nextcloud.talk.models.json.converters.EnumParticipantTypeConverter;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.models.json.signaling.NCIceCandidate;
@ -38,6 +39,8 @@ import java.util.Map;
*/
public abstract class SignalingMessageReceiver {
private final EnumActorTypeConverter enumActorTypeConverter = new EnumActorTypeConverter();
private final ParticipantListMessageNotifier participantListMessageNotifier = new ParticipantListMessageNotifier();
private final LocalParticipantMessageNotifier localParticipantMessageNotifier = new LocalParticipantMessageNotifier();
@ -398,6 +401,8 @@ public abstract class SignalingMessageReceiver {
// "nextcloudSessionId": #STRING#, // Optional
// "internal": #BOOLEAN#, // Optional
// "participantPermissions": #INTEGER#, // Talk >= 13
// "actorType": #STRING#, // Talk >= 20
// "actorId": #STRING#, // Talk >= 20
// },
// ...
// ],
@ -447,6 +452,8 @@ public abstract class SignalingMessageReceiver {
// "sessionId": #STRING#,
// "userId": #STRING#, // Always included, although it can be empty
// "participantPermissions": #INTEGER#, // Talk >= 13
// "actorType": #STRING#, // Talk >= 20
// "actorId": #STRING#, // Talk >= 20
// },
// ...
// ],
@ -492,6 +499,14 @@ public abstract class SignalingMessageReceiver {
participant.setInternal(Boolean.TRUE);
}
if (participantMap.get("actorType") != null && !participantMap.get("actorType").toString().isEmpty()) {
participant.setActorType(enumActorTypeConverter.getFromString(participantMap.get("actorType").toString()));
}
if (participantMap.get("actorId") != null && !participantMap.get("actorId").toString().isEmpty()) {
participant.setActorId(participantMap.get("actorId").toString());
}
// Only in external signaling messages
if (participantMap.get("participantType") != null) {
int participantTypeInt = Integer.parseInt(participantMap.get("participantType").toString());

View File

@ -71,6 +71,8 @@ public class CallParticipantListExternalSignalingTest {
participant.setSessionId(sessionId);
participant.setType(type);
participant.setUserId(userId);
participant.setActorType(Participant.ActorType.USERS);
participant.setActorId(userId);
return participant;
}
@ -81,6 +83,8 @@ public class CallParticipantListExternalSignalingTest {
participant.setLastPing(lastPing);
participant.setSessionId(sessionId);
participant.setType(type);
participant.setActorType(Participant.ActorType.GUESTS);
participant.setActorId("sha1-" + sessionId);
return participant;
}

View File

@ -61,6 +61,8 @@ public class CallParticipantListInternalSignalingTest {
participant.setLastPing(lastPing);
participant.setSessionId(sessionId);
participant.setUserId(userId);
participant.setActorType(Participant.ActorType.USERS);
participant.setActorId(userId);
return participant;
}
@ -70,6 +72,8 @@ public class CallParticipantListInternalSignalingTest {
participant.setInCall(inCall);
participant.setLastPing(lastPing);
participant.setSessionId(sessionId);
participant.setActorType(Participant.ActorType.GUESTS);
participant.setActorId("sha1-" + sessionId);
return participant;
}

View File

@ -58,10 +58,12 @@ public class SignalingMessageReceiverParticipantListTest {
user1.put("roomId", 108);
user1.put("sessionId", "theSessionId1");
user1.put("userId", "theUserId");
// If "participantPermissions" is set in any of the participants all the other participants in the message
// would have it too. But for test simplicity, and as it is not relevant for the processing, in this test it
// is included only in one of the participants.
// If any of the following properties is set in any of the participants all the other participants in the
// message would have it too. But for test simplicity, and as it is not relevant for the processing, in this
// test they are included only in one of the participants.
user1.put("participantPermissions", 42);
user1.put("actorType", "federated_users");
user1.put("actorId", "theActorId");
users.add(user1);
Map<String, Object> user2 = new HashMap<>();
user2.put("inCall", 0);
@ -78,6 +80,8 @@ public class SignalingMessageReceiverParticipantListTest {
expectedParticipant1.setLastPing(4815);
expectedParticipant1.setSessionId("theSessionId1");
expectedParticipant1.setUserId("theUserId");
expectedParticipant1.setActorType(Participant.ActorType.FEDERATED);
expectedParticipant1.setActorId("theActorId");
expectedParticipantList.add(expectedParticipant1);
Participant expectedParticipant2 = new Participant();
@ -266,11 +270,13 @@ public class SignalingMessageReceiverParticipantListTest {
user1.put("sessionId", "theSessionId1");
user1.put("participantType", 3);
user1.put("userId", "theUserId");
// If "nextcloudSessionId" or "participantPermissions" is set in any of the participants all the other
// participants in the message would have them too. But for test simplicity, and as it is not relevant for
// the processing, in this test they are included only in one of the participants.
// If any of the following properties is set in any of the participants all the other participants in the
// message would have it too. But for test simplicity, and as it is not relevant for the processing, in this
// test they are included only in one of the participants.
user1.put("nextcloudSessionId", "theNextcloudSessionId");
user1.put("participantPermissions", 42);
user1.put("actorType", "federated_users");
user1.put("actorId", "theActorId");
users.add(user1);
Map<String, Object> user2 = new HashMap<>();
user2.put("inCall", 0);
@ -289,6 +295,8 @@ public class SignalingMessageReceiverParticipantListTest {
expectedParticipant1.setSessionId("theSessionId1");
expectedParticipant1.setType(Participant.ParticipantType.USER);
expectedParticipant1.setUserId("theUserId");
expectedParticipant1.setActorType(Participant.ActorType.FEDERATED);
expectedParticipant1.setActorId("theActorId");
expectedParticipantList.add(expectedParticipant1);
Participant expectedParticipant2 = new Participant();