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

Feature/1660/end meeting for all
This commit is contained in:
Marcel Hibbe 2022-01-12 13:57:58 +01:00 committed by GitHub
commit 77b6e2d6ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 83 additions and 80 deletions

View File

@ -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,

View File

@ -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() {

View File

@ -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)
}
}
}

View File

@ -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,

View File

@ -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 +

View File

@ -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"

View File

@ -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;
}
}
}

View File

@ -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"

View File

@ -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>