Преглед изворни кода

Merge pull request #1769 from nextcloud/feature/1660/endMeetingForAll

Feature/1660/end meeting for all
Marcel Hibbe пре 3 година
родитељ
комит
77b6e2d6ec

+ 37 - 21
app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

@@ -1277,11 +1277,11 @@ public class CallActivity extends CallBaseActivity {
     }
 
     private void performCall() {
-        Integer inCallFlag;
+        int inCallFlag;
         if (isVoiceOnlyCall) {
-            inCallFlag = (int) Participant.ParticipantFlags.IN_CALL_WITH_AUDIO.getValue();
+            inCallFlag = Participant.InCallFlags.IN_CALL + Participant.InCallFlags.WITH_AUDIO;
         } else {
-            inCallFlag = (int) Participant.ParticipantFlags.IN_CALL_WITH_AUDIO_AND_VIDEO.getValue();
+            inCallFlag = Participant.InCallFlags.IN_CALL + Participant.InCallFlags.WITH_VIDEO;
         }
 
         int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
@@ -1393,6 +1393,7 @@ public class CallActivity extends CallBaseActivity {
     public void onMessageEvent(WebSocketCommunicationEvent webSocketCommunicationEvent) {
         switch (webSocketCommunicationEvent.getType()) {
             case "hello":
+                Log.d(TAG, "onMessageEvent 'hello'");
                 if (!webSocketCommunicationEvent.getHashMap().containsKey("oldResumeId")) {
                     if (currentCallStatus.equals(CallStatus.RECONNECTING)) {
                         hangup(false);
@@ -1402,6 +1403,7 @@ public class CallActivity extends CallBaseActivity {
                 }
                 break;
             case "roomJoined":
+                Log.d(TAG, "onMessageEvent 'roomJoined'");
                 startSendingNick();
 
                 if (webSocketCommunicationEvent.getHashMap().get("roomToken").equals(roomToken)) {
@@ -1409,6 +1411,7 @@ public class CallActivity extends CallBaseActivity {
                 }
                 break;
             case "participantsUpdate":
+                Log.d(TAG, "onMessageEvent 'participantsUpdate'");
                 if (webSocketCommunicationEvent.getHashMap().get("roomToken").equals(roomToken)) {
                     processUsersInRoom(
                         (List<HashMap<String, Object>>) webSocketClient
@@ -1417,10 +1420,12 @@ public class CallActivity extends CallBaseActivity {
                 }
                 break;
             case "signalingMessage":
+                Log.d(TAG, "onMessageEvent 'signalingMessage'");
                 processMessage((NCSignalingMessage) webSocketClient.getJobWithId(
                     Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId"))));
                 break;
             case "peerReadyForRequestingOffer":
+                Log.d(TAG, "onMessageEvent 'peerReadyForRequestingOffer'");
                 webSocketClient.requestOfferForSessionIdWithType(
                     webSocketCommunicationEvent.getHashMap().get("sessionId"), "video");
                 break;
@@ -1523,6 +1528,7 @@ public class CallActivity extends CallBaseActivity {
     }
 
     private void hangup(boolean shutDownView) {
+        Log.d(TAG, "hangup! shutDownView=" + shutDownView);
         stopCallingSound();
         dispose(null);
 
@@ -1538,19 +1544,19 @@ public class CallActivity extends CallBaseActivity {
                 videoCapturer = null;
             }
 
-            if (binding.selfVideoRenderer != null) {
-                binding.selfVideoRenderer.release();
-            }
+            binding.selfVideoRenderer.release();
 
             if (audioSource != null) {
                 audioSource.dispose();
                 audioSource = null;
             }
 
-            if (audioManager != null) {
-                audioManager.stop();
-                audioManager = null;
-            }
+            runOnUiThread(() -> {
+                if (audioManager != null) {
+                    audioManager.stop();
+                    audioManager = null;
+                }
+            });
 
             if (videoSource != null) {
                 videoSource = null;
@@ -1579,6 +1585,7 @@ public class CallActivity extends CallBaseActivity {
     }
 
     private void hangupNetworkCalls(boolean shutDownView) {
+        Log.d(TAG, "hangupNetworkCalls. shutDownView=" + shutDownView);
         int apiVersion = ApiUtils.getCallApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1});
 
         ncApi.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken))
@@ -1618,33 +1625,39 @@ public class CallActivity extends CallBaseActivity {
     }
 
     private void processUsersInRoom(List<HashMap<String, Object>> users) {
+        Log.d(TAG, "processUsersInRoom");
         List<String> newSessions = new ArrayList<>();
         Set<String> oldSessions = new HashSet<>();
 
         hasMCU = hasExternalSignalingServer && webSocketClient != null && webSocketClient.hasMCU();
-
+        Log.d(TAG, "   hasMCU is " + hasMCU);
 
         // The signaling session is the same as the Nextcloud session only when the MCU is not used.
-        String currentSessiondId = callSession;
+        String currentSessionId = callSession;
         if (hasMCU) {
-            currentSessiondId = webSocketClient.getSessionId();
+            currentSessionId = webSocketClient.getSessionId();
         }
 
+        Log.d(TAG, "   currentSessionId is " + currentSessionId);
+
         for (HashMap<String, Object> participant : users) {
-            if (!participant.get("sessionId").equals(currentSessiondId)) {
-                Object inCallObject = participant.get("inCall");
+            long inCallFlag = (long)participant.get("inCall");
+            if (!participant.get("sessionId").equals(currentSessionId)) {
                 boolean isNewSession;
-                if (inCallObject instanceof Boolean) {
-                    isNewSession = (boolean) inCallObject;
-                } else {
-                    isNewSession = ((long) inCallObject) != 0;
-                }
+                Log.d(TAG, "   inCallFlag of participant " + participant.get("sessionId").toString().substring(0,4) + " : " + inCallFlag);
+                isNewSession = inCallFlag != 0;
 
                 if (isNewSession) {
                     newSessions.add(participant.get("sessionId").toString());
                 } else {
                     oldSessions.add(participant.get("sessionId").toString());
                 }
+            } else {
+                Log.d(TAG, "   inCallFlag of currentSessionId: " + inCallFlag);
+                if (inCallFlag == 0){
+                    Log.d(TAG, "Most probably a moderator ended the call for all.");
+                    hangup(true);
+                }
             }
         }
 
@@ -1674,6 +1687,7 @@ public class CallActivity extends CallBaseActivity {
         }
 
         for (String sessionId : newSessions) {
+            Log.d(TAG, "   newSession joined: " + sessionId);
             getPeerConnectionWrapperForSessionIdAndType(sessionId, "video", false);
         }
 
@@ -1682,6 +1696,7 @@ public class CallActivity extends CallBaseActivity {
         }
 
         for (String sessionId : oldSessions) {
+            Log.d(TAG, "   oldSession that will be removed is: " + sessionId);
             endPeerConnection(sessionId, false);
         }
     }
@@ -1742,7 +1757,8 @@ public class CallActivity extends CallBaseActivity {
                 magicPeerConnectionWrapper = new MagicPeerConnectionWrapper(peerConnectionFactory,
                                                                             iceServers,
                                                                             sdpConstraintsForMCU,
-                                                                            sessionId, callSession,
+                                                                            sessionId,
+                                                                            callSession,
                                                                             localMediaStream,
                                                                             true,
                                                                             true,

+ 1 - 2
app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java

@@ -311,8 +311,7 @@ public class CallNotificationActivity extends CallBaseActivity {
     }
 
     private boolean isInCallWithVideo(int callFlag) {
-        return (Participant.ParticipantFlags.IN_CALL_WITH_VIDEO.getValue() == callFlag
-            || Participant.ParticipantFlags.IN_CALL_WITH_AUDIO_AND_VIDEO.getValue() == callFlag);
+        return (callFlag >= Participant.InCallFlags.IN_CALL + Participant.InCallFlags.WITH_VIDEO);
     }
 
     private void setUpAfterConversationIsKnown() {

+ 8 - 4
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -2298,10 +2298,14 @@ class ChatController(args: Bundle) :
     }
 
     private fun startACall(isVoiceOnlyCall: Boolean) {
-        ApplicationWideCurrentRoomHolder.getInstance().isDialing = true
-        val callIntent = getIntentForCall(isVoiceOnlyCall)
-        if (callIntent != null) {
-            startActivity(callIntent)
+        if (currentConversation?.canStartCall == false && currentConversation?.hasCall == false) {
+            Toast.makeText(context, R.string.startCallForbidden, Toast.LENGTH_LONG).show()
+        } else {
+            ApplicationWideCurrentRoomHolder.getInstance().isDialing = true
+            val callIntent = getIntentForCall(isVoiceOnlyCall)
+            if (callIntent != null) {
+                startActivity(callIntent)
+            }
         }
     }
 

+ 1 - 0
app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.java

@@ -621,6 +621,7 @@ public class ChatMessage implements MessageContentType, MessageContentType.Image
         CALL_JOINED,
         CALL_LEFT,
         CALL_ENDED,
+        CALL_ENDED_EVERYONE,
         CALL_MISSED,
         CALL_TRIED,
         READ_ONLY_OFF,

+ 30 - 0
app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.java

@@ -92,8 +92,12 @@ public class Conversation {
     public Long lobbyTimer;
     @JsonField(name = "lastReadMessage")
     public int lastReadMessage;
+    @JsonField(name = "hasCall")
+    public boolean hasCall;
     @JsonField(name = "callFlag")
     public int callFlag;
+    @JsonField(name = "canStartCall")
+    public boolean canStartCall;
 
     @JsonField(name = "canLeaveConversation")
     public Boolean canLeaveConversation;
@@ -259,10 +263,18 @@ public class Conversation {
         return this.lastReadMessage;
     }
 
+    public boolean getHasCall() {
+        return hasCall;
+    }
+
     public int getCallFlag() {
         return this.callFlag;
     }
 
+    public boolean getCanStartCall() {
+        return canStartCall;
+    }
+
     public Boolean getUnreadMentionDirect() {
         return unreadMentionDirect;
     }
@@ -370,10 +382,18 @@ public class Conversation {
         this.lastReadMessage = lastReadMessage;
     }
 
+    public void setHasCall(boolean hasCall) {
+        this.hasCall = hasCall;
+    }
+
     public void setCallFlag(int callFlag) {
         this.callFlag = callFlag;
     }
 
+    public void setCanStartCall(boolean canStartCall) {
+        this.canStartCall = canStartCall;
+    }
+
     public void setUnreadMentionDirect(Boolean unreadMentionDirect) {
         this.unreadMentionDirect = unreadMentionDirect;
     }
@@ -411,9 +431,15 @@ public class Conversation {
         if (lastReadMessage != that.lastReadMessage) {
             return false;
         }
+        if (hasCall != that.hasCall) {
+            return false;
+        }
         if (callFlag != that.callFlag) {
             return false;
         }
+        if (canStartCall != that.canStartCall) {
+            return false;
+        }
         if (!Objects.equals(roomId, that.roomId)) {
             return false;
         }
@@ -508,7 +534,9 @@ public class Conversation {
         result = 31 * result + (lobbyState != null ? lobbyState.hashCode() : 0);
         result = 31 * result + (lobbyTimer != null ? lobbyTimer.hashCode() : 0);
         result = 31 * result + lastReadMessage;
+        result = 31 * result + (hasCall ? 1 : 0);
         result = 31 * result + callFlag;
+        result = 31 * result + (canStartCall ? 1 : 0);
         result = 31 * result + (canLeaveConversation != null ? canLeaveConversation.hashCode() : 0);
         result = 31 * result + (canDeleteConversation != null ? canDeleteConversation.hashCode() : 0);
         result = 31 * result + (notificationCalls != null ? notificationCalls.hashCode() : 0);
@@ -543,7 +571,9 @@ public class Conversation {
                 ", lobbyState=" + lobbyState +
                 ", lobbyTimer=" + lobbyTimer +
                 ", lastReadMessage=" + lastReadMessage +
+                ", hasCall=" + hasCall +
                 ", callFlag=" + callFlag +
+                ", canStartCall=" + canStartCall +
                 ", canLeaveConversation=" + canLeaveConversation +
                 ", canDeleteConversation=" + canDeleteConversation +
                 ", notificationCalls=" + notificationCalls +

+ 4 - 0
app/src/main/java/com/nextcloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt

@@ -27,6 +27,7 @@ package com.nextcloud.talk.models.json.converters
 import com.bluelinelabs.logansquare.typeconverters.StringBasedTypeConverter
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_ENDED
+import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_ENDED_EVERYONE
 import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_JOINED
 import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_LEFT
 import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.CALL_MISSED
@@ -74,6 +75,7 @@ import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.USER_RE
 * `call_joined` - {actor} joined the call
 * `call_left` - {actor} left the call
 * `call_ended` - Call with {user1}, {user2}, {user3}, {user4} and {user5} (Duration 30:23)
+* `call_ended_everyone` - {user1} ended the call with {user2}, {user3}, {user4} and {user5} (Duration 30:23)
 * `call_missed` - You missed a call from {user}
 * `call_tried` - You tried to call {user}
 * `read_only_off` - {actor} unlocked the conversation
@@ -115,6 +117,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
             "call_joined" -> return CALL_JOINED
             "call_left" -> return CALL_LEFT
             "call_ended" -> return CALL_ENDED
+            "call_ended_everyone" -> return CALL_ENDED_EVERYONE
             "call_missed" -> return CALL_MISSED
             "call_tried" -> return CALL_TRIED
             "read_only_off" -> return READ_ONLY_OFF
@@ -163,6 +166,7 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter<ChatMessage.Syst
             CALL_JOINED -> return "call_joined"
             CALL_LEFT -> return "call_left"
             CALL_ENDED -> return "call_ended"
+            CALL_ENDED_EVERYONE -> return "call_ended_everyone"
             CALL_MISSED -> return "call_missed"
             CALL_TRIED -> return "call_tried"
             READ_ONLY_OFF -> return "read_only_off"

+ 0 - 53
app/src/main/java/com/nextcloud/talk/models/json/participants/Participant.java

@@ -82,23 +82,6 @@ public class Participant {
 
     public boolean selected;
 
-    public ParticipantFlags getParticipantFlags() {
-        ParticipantFlags participantFlags = ParticipantFlags.NOT_IN_CALL;
-        if (inCall != null) {
-            if (inCall instanceof Long) {
-                participantFlags = ParticipantFlags.fromValue((Long) inCall);
-            } else if (inCall instanceof Boolean) {
-                if ((boolean) inCall) {
-                    participantFlags = ParticipantFlags.IN_CALL;
-                } else {
-                    participantFlags = ParticipantFlags.NOT_IN_CALL;
-                }
-            }
-        }
-
-        return participantFlags;
-    }
-
     public Long getAttendeeId() {
         return attendeeId;
     }
@@ -346,40 +329,4 @@ public class Participant {
         public static final int WITH_VIDEO = 4;
         public static final int WITH_PHONE = 8;
     }
-
-    @Deprecated
-    public enum ParticipantFlags {
-        NOT_IN_CALL(0),
-        IN_CALL(1),
-        IN_CALL_WITH_AUDIO(3),
-        IN_CALL_WITH_VIDEO(5),
-        IN_CALL_WITH_AUDIO_AND_VIDEO(7);
-
-        private long value;
-
-        ParticipantFlags(long value) {
-            this.value = value;
-        }
-
-        public static ParticipantFlags fromValue(long value) {
-            if (value == 0) {
-                return NOT_IN_CALL;
-            } else if (value == 1) {
-                return IN_CALL;
-            } else if (value == 3) {
-                return IN_CALL_WITH_AUDIO;
-            } else if (value == 5) {
-                return IN_CALL_WITH_VIDEO;
-            } else if (value == 7) {
-                return IN_CALL_WITH_AUDIO_AND_VIDEO;
-            } else {
-                return NOT_IN_CALL;
-            }
-        }
-
-        public long getValue() {
-            return value;
-        }
-
-    }
 }

+ 1 - 0
app/src/main/res/layout/controller_chat.xml

@@ -23,6 +23,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/chat_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:animateLayoutChanges="true"

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -383,6 +383,7 @@
     <string name="nc_reply_privately">Reply privately</string>
     <string name="nc_delete_message">Delete</string>
     <string name="nc_delete_message_leaked_to_matterbridge">Message deleted successfully, but it might have been leaked to other services</string>
+    <string name="startCallForbidden">You are not allowed to start a call</string>
 
     <string name="share">Share</string>
     <string name="send_to">Send to</string>