From 4f5a344a20a99b165845ec995397c47642ba418c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Kr=C3=BCger?= Date: Wed, 4 May 2022 12:32:35 +0200 Subject: [PATCH 1/2] Add handling for "event.participants.update.all" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case a moderator of a restricted room ends the call for all participants a update participants event with the field 'all=true' will be thrown by the HPB. { "type": "event" "event": { "target": "participants", "type": "update", "update": [ "roomid": "the-room-id", "incall": new-incall-state, "all": true ] } } In that case the call can be ended directly without handling every single participant. Resolves: #1881 Signed-off-by: Tim Krüger --- .../talk/activities/CallActivity.java | 25 ++++++++++++++----- .../talk/webrtc/MagicWebSocketInstance.java | 15 ++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) 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 3cd82bc42..a459ee93f 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -93,9 +93,9 @@ 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.PeerConnectionWrapper; import com.nextcloud.talk.webrtc.MagicWebRTCUtils; import com.nextcloud.talk.webrtc.MagicWebSocketInstance; +import com.nextcloud.talk.webrtc.PeerConnectionWrapper; import com.nextcloud.talk.webrtc.WebSocketConnectionHelper; import com.wooplr.spotlight.SpotlightView; @@ -1481,11 +1481,24 @@ public class CallActivity extends CallBaseActivity { break; case "participantsUpdate": Log.d(TAG, "onMessageEvent 'participantsUpdate'"); - if (webSocketCommunicationEvent.getHashMap().get("roomToken").equals(roomToken)) { - processUsersInRoom( - (List>) webSocketClient - .getJobWithId( - Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId")))); + + // See MagicWebSocketInstance#onMessage in case "participants" how the 'updateParameters' are created + Map updateParameters = webSocketCommunicationEvent.getHashMap(); + + if (roomToken.equals(updateParameters.get("roomToken"))) { + if (updateParameters.containsKey("all") && Boolean.parseBoolean(updateParameters.get("all"))) { + if (updateParameters.containsKey("incall") && "0".equals(updateParameters.get("incall"))) { + Log.d(TAG, "Most probably a moderator ended the call for all."); + hangup(true); + } + } else if (updateParameters.containsKey("jobId")) { + // In that case a list of users for the room is passed. + processUsersInRoom( + (List>) webSocketClient + .getJobWithId( + Integer.valueOf(updateParameters.get("jobId")))); + } + } break; case "signalingMessage": diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java index 4cc2667ce..417918524 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java @@ -269,7 +269,20 @@ public class MagicWebSocketInstance extends WebSocketListener { HashMap refreshChatHashMap = new HashMap<>(); HashMap updateEventMap = (HashMap) eventOverallWebSocketMessage.getEventMap().get("update"); refreshChatHashMap.put("roomToken", (String) updateEventMap.get("roomid")); - refreshChatHashMap.put("jobId", Integer.toString(magicMap.add(updateEventMap.get("users")))); + + if (updateEventMap.containsKey("users")) { + refreshChatHashMap.put("jobId", Integer.toString(magicMap.add(updateEventMap.get("users")))); + } + + if (updateEventMap.containsKey("incall")) { + refreshChatHashMap.put("incall", + Long.toString((Long)updateEventMap.get("incall"))); + } + + if (updateEventMap.containsKey("all")) { + refreshChatHashMap.put("all", Boolean.toString((Boolean) updateEventMap.get("all"))); + } + eventBus.post(new WebSocketCommunicationEvent("participantsUpdate", refreshChatHashMap)); } break; From e52b2d8b7ffbad4e4343bb6b97d40663ddc58149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Kr=C3=BCger?= Date: Thu, 5 May 2022 13:06:15 +0200 Subject: [PATCH 2/2] Add null checks and extract constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tim Krüger --- .../talk/activities/CallActivity.java | 27 ++++-- .../com/nextcloud/talk/webrtc/Globals.java | 18 ++++ .../talk/webrtc/MagicWebSocketInstance.java | 92 ++++++++++++------- 3 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/webrtc/Globals.java 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 a459ee93f..093dd9134 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -157,6 +157,12 @@ import me.zhanghai.android.effortlesspermissions.OpenAppDetailsDialogFragment; import okhttp3.Cache; import pub.devrel.easypermissions.AfterPermissionGranted; +import static com.nextcloud.talk.webrtc.Globals.JOB_ID; +import static com.nextcloud.talk.webrtc.Globals.PARTICIPANTS_UPDATE; +import static com.nextcloud.talk.webrtc.Globals.ROOM_TOKEN; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_ALL; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_IN_CALL; + @AutoInjector(NextcloudTalkApplication.class) public class CallActivity extends CallBaseActivity { @@ -1479,24 +1485,33 @@ public class CallActivity extends CallBaseActivity { performCall(); } break; - case "participantsUpdate": + case PARTICIPANTS_UPDATE: Log.d(TAG, "onMessageEvent 'participantsUpdate'"); // See MagicWebSocketInstance#onMessage in case "participants" how the 'updateParameters' are created Map updateParameters = webSocketCommunicationEvent.getHashMap(); - if (roomToken.equals(updateParameters.get("roomToken"))) { - if (updateParameters.containsKey("all") && Boolean.parseBoolean(updateParameters.get("all"))) { - if (updateParameters.containsKey("incall") && "0".equals(updateParameters.get("incall"))) { + if (updateParameters == null) { + break; + } + + String updateRoomToken = updateParameters.get(ROOM_TOKEN); + String updateAll = updateParameters.get(UPDATE_ALL); + String updateInCall = updateParameters.get(UPDATE_IN_CALL); + String jobId = updateParameters.get(JOB_ID); + + if (roomToken.equals(updateRoomToken)) { + if (updateAll != null && Boolean.parseBoolean(updateAll)) { + if ("0".equals(updateInCall)) { Log.d(TAG, "Most probably a moderator ended the call for all."); hangup(true); } - } else if (updateParameters.containsKey("jobId")) { + } else if (jobId != null) { // In that case a list of users for the room is passed. processUsersInRoom( (List>) webSocketClient .getJobWithId( - Integer.valueOf(updateParameters.get("jobId")))); + Integer.valueOf(jobId))); } } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java b/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java new file mode 100644 index 000000000..8d74fb920 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/webrtc/Globals.java @@ -0,0 +1,18 @@ +package com.nextcloud.talk.webrtc; + +public class Globals { + public static final String ROOM_TOKEN = "roomToken"; + public static final String JOB_ID = "jobId"; + + public static final String PARTICIPANTS_UPDATE = "participantsUpdate"; + + public static final String TARGET_PARTICIPANTS = "participants"; + + public static final String EVENT_TYPE = "type"; + public static final String EVENT_TYPE_UPDATE = "update"; + + public static final String UPDATE_ALL = "all"; + public static final String UPDATE_IN_CALL = "incall"; + public static final String UPDATE_ROOM_ID = "roomid"; + public static final String UPDATE_USERS = "users"; +} diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java index 417918524..84a3d76e7 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/MagicWebSocketInstance.java @@ -65,11 +65,22 @@ import okio.ByteString; import static com.nextcloud.talk.models.json.participants.Participant.ActorType.GUESTS; import static com.nextcloud.talk.models.json.participants.Participant.ActorType.USERS; +import static com.nextcloud.talk.webrtc.Globals.EVENT_TYPE; +import static com.nextcloud.talk.webrtc.Globals.EVENT_TYPE_UPDATE; +import static com.nextcloud.talk.webrtc.Globals.JOB_ID; +import static com.nextcloud.talk.webrtc.Globals.PARTICIPANTS_UPDATE; +import static com.nextcloud.talk.webrtc.Globals.ROOM_TOKEN; +import static com.nextcloud.talk.webrtc.Globals.TARGET_PARTICIPANTS; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_ALL; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_IN_CALL; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_ROOM_ID; +import static com.nextcloud.talk.webrtc.Globals.UPDATE_USERS; @AutoInjector(NextcloudTalkApplication.class) public class MagicWebSocketInstance extends WebSocketListener { private static final String TAG = "MagicWebSocketInstance"; + @Inject OkHttpClient okHttpClient; @@ -190,7 +201,7 @@ public class MagicWebSocketInstance extends WebSocketListener { } if (!TextUtils.isEmpty(currentRoomToken)) { - helloHasHap.put("roomToken", currentRoomToken); + helloHasHap.put(ROOM_TOKEN, currentRoomToken); } eventBus.post(new WebSocketCommunicationEvent("hello", helloHasHap)); break; @@ -221,23 +232,23 @@ public class MagicWebSocketInstance extends WebSocketListener { switch (target) { case "room": if (eventOverallWebSocketMessage.getEventMap().get("type").equals("message")) { - Map messageHashMap = - (Map) eventOverallWebSocketMessage.getEventMap().get("message"); - if (messageHashMap.containsKey("data")) { - Map dataHashMap = (Map) messageHashMap.get( - "data"); - if (dataHashMap.containsKey("chat")) { - boolean shouldRefreshChat; - Map chatMap = (Map) dataHashMap.get("chat"); - if (chatMap.containsKey("refresh")) { - shouldRefreshChat = (boolean) chatMap.get("refresh"); - if (shouldRefreshChat) { - HashMap refreshChatHashMap = new HashMap<>(); - refreshChatHashMap.put(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), (String) messageHashMap.get("roomid")); - refreshChatHashMap.put(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), Long.toString(conversationUser.getId())); - eventBus.post(new WebSocketCommunicationEvent("refreshChat", refreshChatHashMap)); - } + Map messageHashMap = + (Map) eventOverallWebSocketMessage.getEventMap().get("message"); + if (messageHashMap.containsKey("data")) { + Map dataHashMap = (Map) messageHashMap.get( + "data"); + if (dataHashMap.containsKey("chat")) { + boolean shouldRefreshChat; + Map chatMap = (Map) dataHashMap.get("chat"); + if (chatMap.containsKey("refresh")) { + shouldRefreshChat = (boolean) chatMap.get("refresh"); + if (shouldRefreshChat) { + HashMap refreshChatHashMap = new HashMap<>(); + refreshChatHashMap.put(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN(), (String) messageHashMap.get("roomid")); + refreshChatHashMap.put(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), Long.toString(conversationUser.getId())); + eventBus.post(new WebSocketCommunicationEvent("refreshChat", refreshChatHashMap)); } + } } } } else if (eventOverallWebSocketMessage.getEventMap().get("type").equals("join")) { @@ -264,26 +275,45 @@ public class MagicWebSocketInstance extends WebSocketListener { } } break; - case "participants": - if (eventOverallWebSocketMessage.getEventMap().get("type").equals("update")) { + case TARGET_PARTICIPANTS: + if (EVENT_TYPE_UPDATE.equals(eventOverallWebSocketMessage.getEventMap().get(EVENT_TYPE))) { HashMap refreshChatHashMap = new HashMap<>(); - HashMap updateEventMap = (HashMap) eventOverallWebSocketMessage.getEventMap().get("update"); - refreshChatHashMap.put("roomToken", (String) updateEventMap.get("roomid")); + HashMap updateEventMap = (HashMap) eventOverallWebSocketMessage.getEventMap().get(EVENT_TYPE_UPDATE); - if (updateEventMap.containsKey("users")) { - refreshChatHashMap.put("jobId", Integer.toString(magicMap.add(updateEventMap.get("users")))); + if (updateEventMap == null) { + break; } - if (updateEventMap.containsKey("incall")) { - refreshChatHashMap.put("incall", - Long.toString((Long)updateEventMap.get("incall"))); + if (updateEventMap.containsKey(UPDATE_ROOM_ID)) { + Object updateRoomId = updateEventMap.get(UPDATE_ROOM_ID); + if (updateRoomId != null) { + refreshChatHashMap.put(ROOM_TOKEN, + (String) updateEventMap.get(UPDATE_ROOM_ID)); + } } - if (updateEventMap.containsKey("all")) { - refreshChatHashMap.put("all", Boolean.toString((Boolean) updateEventMap.get("all"))); + if (updateEventMap.containsKey(UPDATE_USERS)) { + Object updateUsers = updateEventMap.get(UPDATE_USERS); + if (updateUsers != null) { + refreshChatHashMap.put(JOB_ID, Integer.toString(magicMap.add(updateUsers))); + } } - eventBus.post(new WebSocketCommunicationEvent("participantsUpdate", refreshChatHashMap)); + if (updateEventMap.containsKey(UPDATE_IN_CALL)) { + Object inCall = updateEventMap.get(UPDATE_IN_CALL); + if (inCall != null) { + refreshChatHashMap.put(UPDATE_IN_CALL, Long.toString((Long) inCall)); + } + } + + if (updateEventMap.containsKey(UPDATE_ALL)) { + Object updateAll = updateEventMap.get(UPDATE_ALL); + if (updateAll != null) { + refreshChatHashMap.put(UPDATE_ALL, Boolean.toString((Boolean) updateAll)); + } + } + + eventBus.post(new WebSocketCommunicationEvent(PARTICIPANTS_UPDATE, refreshChatHashMap)); } break; } @@ -298,7 +328,7 @@ public class MagicWebSocketInstance extends WebSocketListener { if (!TextUtils.isEmpty(ncSignalingMessage.getFrom())) { HashMap messageHashMap = new HashMap<>(); - messageHashMap.put("jobId", Integer.toString(magicMap.add(ncSignalingMessage))); + messageHashMap.put(JOB_ID, Integer.toString(magicMap.add(ncSignalingMessage))); eventBus.post(new WebSocketCommunicationEvent("signalingMessage", messageHashMap)); } break; @@ -316,7 +346,7 @@ public class MagicWebSocketInstance extends WebSocketListener { private void sendRoomJoinedEvent() { HashMap joinRoomHashMap = new HashMap<>(); - joinRoomHashMap.put("roomToken", currentRoomToken); + joinRoomHashMap.put(ROOM_TOKEN, currentRoomToken); eventBus.post(new WebSocketCommunicationEvent("roomJoined", joinRoomHashMap)); }