Add call summary support for all calls.

This commit is contained in:
Jim Gustafson
2025-11-25 08:29:49 -08:00
committed by jeffrey-signal
parent 44ec15c0e0
commit c9a0fb30b0
15 changed files with 146 additions and 88 deletions

View File

@@ -49,7 +49,7 @@ import org.signal.core.util.concurrent.LifecycleDisposable
import org.signal.core.util.concurrent.SignalDispatchers
import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.logging.Log
import org.signal.ringrtc.GroupCall
import org.signal.ringrtc.CallManager
import org.thoughtcrime.securesms.BaseActivity
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.sensors.Orientation
@@ -398,7 +398,7 @@ class WebRtcCallActivity : BaseActivity(), SafetyNumberChangeDialog.Callback, Re
WebRtcViewModel.State.CALL_RINGING -> handleCallRinging()
WebRtcViewModel.State.CALL_BUSY -> handleCallBusy()
WebRtcViewModel.State.CALL_DISCONNECTED -> {
if (event.groupCallEndReason == GroupCall.GroupCallEndReason.HAS_MAX_DEVICES) {
if (event.groupCallEndReason == CallManager.CallEndReason.HAS_MAX_DEVICES) {
handleGroupCallHasMaxDevices(event.recipient)
} else {
handleTerminate(event.recipient, HangupMessage.Type.NORMAL)

View File

@@ -1,7 +1,7 @@
package org.thoughtcrime.securesms.events
import com.annimon.stream.OptionalLong
import org.signal.ringrtc.GroupCall.GroupCallEndReason
import org.signal.ringrtc.CallManager.CallEndReason
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink
import org.thoughtcrime.securesms.events.CallParticipant.Companion.createLocal
import org.thoughtcrime.securesms.recipients.Recipient
@@ -105,7 +105,7 @@ class WebRtcViewModel(state: WebRtcServiceState) {
val pendingParticipants: PendingParticipantCollection = state.callInfoState.pendingParticipants
val isCallLink: Boolean = state.callInfoState.callRecipient.isCallLink
val callLinkDisconnectReason: CallLinkDisconnectReason? = state.callInfoState.callLinkDisconnectReason
val groupCallEndReason: GroupCallEndReason? = state.callInfoState.groupCallEndReason
val groupCallEndReason: CallEndReason? = state.callInfoState.groupCallEndReason
val groupCallSpeechEvent: GroupCallSpeechEvent? = state.callInfoState.groupCallSpeechEvent
@get:JvmName("hasAtLeastOneRemote")

View File

@@ -9,7 +9,7 @@ import org.signal.core.util.ThreadUtil;
import org.signal.core.util.logging.Log;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallManager.CallEvent;
import org.signal.ringrtc.CallManager.CallEndReason;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
@@ -34,14 +34,14 @@ import static org.thoughtcrime.securesms.webrtc.CallNotificationBuilder.TYPE_OUT
*/
public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
private static final Map<CallEvent, WebRtcViewModel.State> ENDED_REMOTE_EVENT_TO_STATE = new HashMap<CallEvent, WebRtcViewModel.State>() {{
put(CallEvent.ENDED_REMOTE_HANGUP_ACCEPTED, WebRtcViewModel.State.CALL_ACCEPTED_ELSEWHERE);
put(CallEvent.ENDED_REMOTE_HANGUP_BUSY, WebRtcViewModel.State.CALL_ONGOING_ELSEWHERE);
put(CallEvent.ENDED_REMOTE_HANGUP_DECLINED, WebRtcViewModel.State.CALL_DECLINED_ELSEWHERE);
put(CallEvent.ENDED_REMOTE_BUSY, WebRtcViewModel.State.CALL_BUSY);
put(CallEvent.ENDED_REMOTE_HANGUP_NEED_PERMISSION, WebRtcViewModel.State.CALL_NEEDS_PERMISSION);
put(CallEvent.ENDED_REMOTE_GLARE, WebRtcViewModel.State.CALL_DISCONNECTED_GLARE);
put(CallEvent.ENDED_REMOTE_RECALL, WebRtcViewModel.State.CALL_DISCONNECTED_GLARE);
private static final Map<CallEndReason, WebRtcViewModel.State> ENDED_REMOTE_END_REASON_TO_STATE = new HashMap<CallEndReason, WebRtcViewModel.State>() {{
put(CallEndReason.REMOTE_HANGUP_ACCEPTED, WebRtcViewModel.State.CALL_ACCEPTED_ELSEWHERE);
put(CallEndReason.REMOTE_HANGUP_BUSY, WebRtcViewModel.State.CALL_ONGOING_ELSEWHERE);
put(CallEndReason.REMOTE_HANGUP_DECLINED, WebRtcViewModel.State.CALL_DECLINED_ELSEWHERE);
put(CallEndReason.REMOTE_BUSY, WebRtcViewModel.State.CALL_BUSY);
put(CallEndReason.REMOTE_HANGUP_NEED_PERMISSION, WebRtcViewModel.State.CALL_NEEDS_PERMISSION);
put(CallEndReason.REMOTE_GLARE, WebRtcViewModel.State.CALL_DISCONNECTED_GLARE);
put(CallEndReason.REMOTE_RECALL, WebRtcViewModel.State.CALL_DISCONNECTED_GLARE);
}};
public ActiveCallActionProcessorDelegate(@NonNull WebRtcInteractor webRtcInteractor, @NonNull String tag) {
@@ -166,10 +166,10 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
@Override
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState,
@NonNull CallEvent endedRemoteEvent,
@NonNull CallEndReason callEndReason,
@NonNull RemotePeer remotePeer)
{
Log.i(tag, "handleEndedRemote(): call_id: " + remotePeer.getCallId() + " action: " + endedRemoteEvent);
Log.i(tag, "handleEndedRemote(): call_id: " + remotePeer.getCallId() + " action: " + callEndReason);
WebRtcViewModel.State state = currentState.getCallInfoState().getCallState();
RemotePeer activePeer = currentState.getCallInfoState().getActivePeer();
@@ -177,11 +177,11 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
boolean outgoingBeforeAccept = remotePeer.getState() == CallState.DIALING || remotePeer.getState() == CallState.REMOTE_RINGING;
boolean incomingBeforeAccept = remotePeer.getState() == CallState.ANSWERING || remotePeer.getState() == CallState.LOCAL_RINGING;
if (remotePeerIsActive && ENDED_REMOTE_EVENT_TO_STATE.containsKey(endedRemoteEvent)) {
state = Objects.requireNonNull(ENDED_REMOTE_EVENT_TO_STATE.get(endedRemoteEvent));
if (remotePeerIsActive && ENDED_REMOTE_END_REASON_TO_STATE.containsKey(callEndReason)) {
state = Objects.requireNonNull(ENDED_REMOTE_END_REASON_TO_STATE.get(callEndReason));
}
if (endedRemoteEvent == CallEvent.ENDED_REMOTE_HANGUP || endedRemoteEvent == CallEvent.ENDED_REMOTE_HANGUP_BUSY) {
if (callEndReason == CallEndReason.REMOTE_HANGUP || callEndReason == CallEndReason.REMOTE_HANGUP_BUSY) {
if (remotePeerIsActive) {
state = outgoingBeforeAccept ? WebRtcViewModel.State.RECIPIENT_UNAVAILABLE : WebRtcViewModel.State.CALL_DISCONNECTED;
}
@@ -189,15 +189,15 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
if (incomingBeforeAccept) {
webRtcInteractor.insertMissedCall(remotePeer, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState(remotePeer).isRemoteVideoOffer());
}
} else if (endedRemoteEvent == CallEvent.ENDED_REMOTE_BUSY && remotePeerIsActive) {
} else if (callEndReason == CallEndReason.REMOTE_BUSY && remotePeerIsActive) {
activePeer.receivedBusy();
OutgoingRinger ringer = new OutgoingRinger(context);
ringer.start(OutgoingRinger.Type.BUSY);
ThreadUtil.runOnMainDelayed(ringer::stop, SignalCallManager.BUSY_TONE_LENGTH);
} else if (endedRemoteEvent == CallEvent.ENDED_REMOTE_GLARE && incomingBeforeAccept) {
} else if (callEndReason == CallEndReason.REMOTE_GLARE && incomingBeforeAccept) {
webRtcInteractor.insertMissedCall(remotePeer, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState(remotePeer).isRemoteVideoOffer());
} else if (endedRemoteEvent == CallEvent.ENDED_REMOTE_RECALL && incomingBeforeAccept) {
} else if (callEndReason == CallEndReason.REMOTE_RECALL && incomingBeforeAccept) {
webRtcInteractor.insertMissedCall(remotePeer, remotePeer.getCallStartTimestamp(), currentState.getCallSetupState(remotePeer).isRemoteVideoOffer());
}
@@ -216,13 +216,13 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
}
@Override
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallEvent endedEvent, @NonNull RemotePeer remotePeer) {
Log.i(tag, "handleEnded(): call_id: " + remotePeer.getCallId() + " action: " + endedEvent);
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
Log.i(tag, "handleEnded(): call_id: " + remotePeer.getCallId() + " action: " + callEndReason);
if (remotePeer.callIdEquals(currentState.getCallInfoState().getActivePeer()) && !currentState.getCallInfoState().getCallState().isErrorState()) {
currentState = currentState.builder()
.changeCallInfoState()
.callState(endedEvent == CallEvent.ENDED_TIMEOUT ? WebRtcViewModel.State.RECIPIENT_UNAVAILABLE : WebRtcViewModel.State.NETWORK_FAILURE)
.callState(callEndReason == CallEndReason.TIMEOUT ? WebRtcViewModel.State.RECIPIENT_UNAVAILABLE : WebRtcViewModel.State.NETWORK_FAILURE)
.build();
webRtcInteractor.postStateUpdate(currentState);

View File

@@ -7,6 +7,7 @@ package org.thoughtcrime.securesms.service.webrtc
import org.signal.core.util.logging.Log
import org.signal.ringrtc.CallException
import org.signal.ringrtc.CallManager
import org.signal.ringrtc.GroupCall
import org.signal.ringrtc.PeekInfo
import org.thoughtcrime.securesms.components.webrtc.CallLinkProfileKeySender
@@ -68,12 +69,12 @@ class CallLinkConnectedActionProcessor(
.build()
}
override fun handleGroupCallEnded(currentState: WebRtcServiceState, groupCallHash: Int, groupCallEndReason: GroupCall.GroupCallEndReason): WebRtcServiceState {
override fun handleGroupCallEnded(currentState: WebRtcServiceState, groupCallHash: Int, groupCallEndReason: CallManager.CallEndReason): WebRtcServiceState {
val serviceState = super.handleGroupCallEnded(currentState, groupCallHash, groupCallEndReason)
val callLinkDisconnectReason = when (groupCallEndReason) {
GroupCall.GroupCallEndReason.DENIED_REQUEST_TO_JOIN_CALL -> CallLinkDisconnectReason.DeniedRequestToJoinCall()
GroupCall.GroupCallEndReason.REMOVED_FROM_CALL -> CallLinkDisconnectReason.RemovedFromCall()
CallManager.CallEndReason.DENIED_REQUEST_TO_JOIN_CALL -> CallLinkDisconnectReason.DeniedRequestToJoinCall()
CallManager.CallEndReason.REMOVED_FROM_CALL -> CallLinkDisconnectReason.RemovedFromCall()
else -> null
}

View File

@@ -6,7 +6,7 @@
package org.thoughtcrime.securesms.service.webrtc
import org.signal.core.util.logging.Log
import org.signal.ringrtc.GroupCall
import org.signal.ringrtc.CallManager
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState
/**
@@ -27,12 +27,12 @@ class CallLinkJoiningActionProcessor(
return currentState
}
override fun handleGroupCallEnded(currentState: WebRtcServiceState, groupCallHash: Int, groupCallEndReason: GroupCall.GroupCallEndReason): WebRtcServiceState {
override fun handleGroupCallEnded(currentState: WebRtcServiceState, groupCallHash: Int, groupCallEndReason: CallManager.CallEndReason): WebRtcServiceState {
val serviceState = super.handleGroupCallEnded(currentState, groupCallHash, groupCallEndReason)
val callLinkDisconnectReason = when (groupCallEndReason) {
GroupCall.GroupCallEndReason.DENIED_REQUEST_TO_JOIN_CALL -> CallLinkDisconnectReason.DeniedRequestToJoinCall()
GroupCall.GroupCallEndReason.REMOVED_FROM_CALL -> CallLinkDisconnectReason.RemovedFromCall()
CallManager.CallEndReason.DENIED_REQUEST_TO_JOIN_CALL -> CallLinkDisconnectReason.DeniedRequestToJoinCall()
CallManager.CallEndReason.REMOVED_FROM_CALL -> CallLinkDisconnectReason.RemovedFromCall()
else -> null
}

View File

@@ -131,13 +131,13 @@ public class ConnectedCallActionProcessor extends DeviceAwareActionProcessor {
}
@Override
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedRemoteEvent, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEndedRemote(currentState, endedRemoteEvent, remotePeer);
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEndedRemote(currentState, callEndReason, remotePeer);
}
@Override
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedEvent, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, endedEvent, remotePeer);
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, callEndReason, remotePeer);
}
@Override

View File

@@ -8,6 +8,7 @@ import com.annimon.stream.Stream;
import org.signal.core.util.logging.Log;
import org.signal.ringrtc.CallException;
import org.signal.ringrtc.CallManager;
import org.signal.ringrtc.GroupCall;
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
import org.thoughtcrime.securesms.events.CallParticipant;
@@ -284,7 +285,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
}
@Override
protected @NonNull WebRtcServiceState handleGroupCallEnded(@NonNull WebRtcServiceState currentState, int groupCallHash, @NonNull GroupCall.GroupCallEndReason groupCallEndReason) {
protected @NonNull WebRtcServiceState handleGroupCallEnded(@NonNull WebRtcServiceState currentState, int groupCallHash, @NonNull CallManager.CallEndReason groupCallEndReason) {
Log.i(tag, "handleGroupCallEnded(): reason: " + groupCallEndReason);
GroupCall groupCall = currentState.getCallInfoState().getGroupCall();
@@ -299,7 +300,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
return groupCallFailure(currentState, "Unable to disconnect from group call", e);
}
if (groupCallEndReason != GroupCall.GroupCallEndReason.DEVICE_EXPLICITLY_DISCONNECTED) {
if (groupCallEndReason != CallManager.CallEndReason.DEVICE_EXPLICITLY_DISCONNECTED) {
Log.i(tag, "Group call ended unexpectedly, reinitializing and dropping back to lobby");
Recipient currentRecipient = currentState.getCallInfoState().getCallRecipient();
VideoState videoState = currentState.getVideoState();

View File

@@ -252,13 +252,13 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
}
@Override
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedRemoteEvent, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEndedRemote(currentState, endedRemoteEvent, remotePeer);
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEndedRemote(currentState, callEndReason, remotePeer);
}
@Override
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedEvent, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, endedEvent, remotePeer);
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, callEndReason, remotePeer);
}
@Override

View File

@@ -265,26 +265,26 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
}
@Override
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedRemoteEvent, @NonNull RemotePeer remotePeer) {
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
RemotePeer activePeer = currentState.getCallInfoState().getActivePeer();
if (activePeer != null &&
(endedRemoteEvent == CallManager.CallEvent.ENDED_REMOTE_HANGUP ||
endedRemoteEvent == CallManager.CallEvent.ENDED_REMOTE_HANGUP_NEED_PERMISSION ||
endedRemoteEvent == CallManager.CallEvent.ENDED_REMOTE_BUSY ||
endedRemoteEvent == CallManager.CallEvent.ENDED_TIMEOUT ||
endedRemoteEvent == CallManager.CallEvent.ENDED_REMOTE_GLARE))
(callEndReason == CallManager.CallEndReason.REMOTE_HANGUP ||
callEndReason == CallManager.CallEndReason.REMOTE_HANGUP_NEED_PERMISSION ||
callEndReason == CallManager.CallEndReason.REMOTE_BUSY ||
callEndReason == CallManager.CallEndReason.TIMEOUT ||
callEndReason == CallManager.CallEndReason.REMOTE_GLARE))
{
webRtcInteractor.sendNotAcceptedCallEventSyncMessage(activePeer,
true,
currentState.getCallSetupState(activePeer).isAcceptWithVideo() || currentState.getLocalDeviceState().getCameraState().isEnabled());
}
return activeCallDelegate.handleEndedRemote(currentState, endedRemoteEvent, remotePeer);
return activeCallDelegate.handleEndedRemote(currentState, callEndReason, remotePeer);
}
@Override
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedEvent, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, endedEvent, remotePeer);
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason callEndReason, @NonNull RemotePeer remotePeer) {
return activeCallDelegate.handleEnded(currentState, callEndReason, remotePeer);
}
@Override

View File

@@ -27,6 +27,7 @@ import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallLinkEpoch;
import org.signal.ringrtc.CallLinkRootKey;
import org.signal.ringrtc.CallManager;
import org.signal.ringrtc.CallSummary;
import org.signal.ringrtc.GroupCall;
import org.signal.ringrtc.GroupCall.Reaction;
import org.signal.ringrtc.HttpHeader;
@@ -530,10 +531,10 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
process((s, p) -> p.handleGroupMembershipProofResponse(s, groupCallHashCode, credential.token.getBytes(Charsets.UTF_8)));
} catch (IOException e) {
Log.w(TAG, "Unable to get group membership proof from service", e);
process((s, p) -> p.handleGroupCallEnded(s, groupCallHashCode, GroupCall.GroupCallEndReason.SFU_CLIENT_FAILED_TO_JOIN));
process((s, p) -> p.handleGroupCallEnded(s, groupCallHashCode, CallManager.CallEndReason.SFU_CLIENT_FAILED_TO_JOIN));
} catch (VerificationFailedException e) {
Log.w(TAG, "Unable to verify group membership proof", e);
process((s, p) -> p.handleGroupCallEnded(s, groupCallHashCode, GroupCall.GroupCallEndReason.DEVICE_EXPLICITLY_DISCONNECTED));
process((s, p) -> p.handleGroupCallEnded(s, groupCallHashCode, CallManager.CallEndReason.DEVICE_EXPLICITLY_DISCONNECTED));
}
});
}
@@ -585,6 +586,78 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
});
}
@Override
public void onCallEnded(@Nullable Remote remote, @NonNull CallManager.CallEndReason reason, @NonNull CallSummary summary) {
if (callManager == null) {
Log.w(TAG, "Unable to process call end, call manager is not initialized");
return;
}
if (!(remote instanceof RemotePeer)) {
return;
}
process((s, p) -> {
RemotePeer remotePeer = (RemotePeer) remote;
if (s.getCallInfoState().getPeer(remotePeer.hashCode()) == null) {
Log.w(TAG, "remotePeer not found in map with key: " + remotePeer.hashCode() + "! Dropping.");
try {
callManager.drop(remotePeer.getCallId());
} catch (CallException e) {
return p.callFailure(s, "callManager.drop() failed: ", e);
}
return s;
}
Log.i(TAG, "onCallEnded(): call_id: " + remotePeer.getCallId() + ", state: " + remotePeer.getState() + ", reason: " + reason);
// TODO: Handle the call summary.
switch (reason) {
case LOCAL_HANGUP:
Log.i(TAG, "Ignoring end reason: " + reason);
break;
case REMOTE_HANGUP:
case REMOTE_HANGUP_NEED_PERMISSION:
case REMOTE_HANGUP_ACCEPTED:
case REMOTE_HANGUP_DECLINED:
case REMOTE_HANGUP_BUSY:
case REMOTE_BUSY:
case REMOTE_GLARE:
case REMOTE_RECALL:
return p.handleEndedRemote(s, reason, remotePeer);
case TIMEOUT:
case INTERNAL_FAILURE:
case SIGNALING_FAILURE:
case CONNECTION_FAILURE:
return p.handleEnded(s, reason, remotePeer);
case APP_DROPPED_CALL:
Log.i(TAG, "Ignoring end reason: " + reason);
break;
case DEVICE_EXPLICITLY_DISCONNECTED:
case SERVER_EXPLICITLY_DISCONNECTED:
case DENIED_REQUEST_TO_JOIN_CALL:
case REMOVED_FROM_CALL:
case CALL_MANAGER_IS_BUSY:
case SFU_CLIENT_FAILED_TO_JOIN:
case FAILED_TO_CREATE_PEER_CONNECTION_FACTORY:
case FAILED_TO_NEGOTIATE_SRTP_KEYS:
case FAILED_TO_CREATE_PEER_CONNECTION:
case FAILED_TO_START_PEER_CONNECTION:
case FAILED_TO_UPDATE_PEER_CONNECTION:
case FAILED_TO_SET_MAX_SEND_BITRATE:
case ICE_FAILED_WHILE_CONNECTING:
case ICE_FAILED_AFTER_CONNECTED:
case SERVER_CHANGED_DEMUXID:
case HAS_MAX_DEVICES:
default:
throw new AssertionError("Unexpected end reason: " + reason);
}
return s;
});
}
@Override
public void onCallEvent(@Nullable Remote remote, @NonNull CallManager.CallEvent event) {
if (callManager == null) {
@@ -633,35 +706,17 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
return p.handleScreenSharingEnable(s, true);
case REMOTE_SHARING_SCREEN_DISABLE:
return p.handleScreenSharingEnable(s, false);
case ENDED_REMOTE_HANGUP:
case ENDED_REMOTE_HANGUP_NEED_PERMISSION:
case ENDED_REMOTE_HANGUP_ACCEPTED:
case ENDED_REMOTE_HANGUP_BUSY:
case ENDED_REMOTE_HANGUP_DECLINED:
case ENDED_REMOTE_BUSY:
case ENDED_REMOTE_GLARE:
case ENDED_REMOTE_RECALL:
return p.handleEndedRemote(s, event, remotePeer);
case ENDED_TIMEOUT:
case ENDED_INTERNAL_FAILURE:
case ENDED_SIGNALING_FAILURE:
case ENDED_GLARE_HANDLING_FAILURE:
case ENDED_CONNECTION_FAILURE:
return p.handleEnded(s, event, remotePeer);
case GLARE_HANDLING_FAILURE:
// Something broke when handling glare, end as an internal failure.
return p.handleEnded(s, CallManager.CallEndReason.INTERNAL_FAILURE, remotePeer);
case RECEIVED_OFFER_EXPIRED:
return p.handleReceivedOfferExpired(s, remotePeer);
case RECEIVED_OFFER_WHILE_ACTIVE:
case RECEIVED_OFFER_WITH_GLARE:
return p.handleReceivedOfferWhileActive(s, remotePeer);
case ENDED_LOCAL_HANGUP:
case ENDED_APP_DROPPED_CALL:
Log.i(TAG, "Ignoring event: " + event);
break;
default:
throw new AssertionError("Unexpected event: " + event);
}
return s;
});
}
@@ -969,14 +1024,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
}
@Override
public void onEnded(@NonNull GroupCall groupCall, @NonNull GroupCall.GroupCallEndReason groupCallEndReason) {
process((s, p) -> p.handleGroupCallEnded(s, groupCall.hashCode(), groupCallEndReason));
public void onEnded(@NonNull GroupCall groupCall, @NonNull CallManager.CallEndReason reason, @NonNull CallSummary summary) {
// TODO: Handle the call summary.
process((s, p) -> p.handleGroupCallEnded(s, groupCall.hashCode(), reason));
}
@Override
public void onRemoteMuteRequest(@NonNull GroupCall groupCall, long sourceDemuxId) {
process((s, p) -> p.handleRemoteMuteRequest(s, sourceDemuxId));
}
@Override

View File

@@ -655,7 +655,7 @@ public abstract class WebRtcActionProcessor {
//region End call
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedRemoteEvent, @NonNull RemotePeer remotePeer) {
protected @NonNull WebRtcServiceState handleEndedRemote(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason endedReason, @NonNull RemotePeer remotePeer) {
Log.i(tag, "handleEndedRemote not processed");
return currentState;
}
@@ -664,7 +664,7 @@ public abstract class WebRtcActionProcessor {
//region End call failure
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEvent endedEvent, @NonNull RemotePeer remotePeer) {
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull CallManager.CallEndReason endedReason, @NonNull RemotePeer remotePeer) {
Log.i(tag, "handleEnded not processed");
return currentState;
}
@@ -802,7 +802,7 @@ public abstract class WebRtcActionProcessor {
return currentState;
}
protected @NonNull WebRtcServiceState handleGroupCallEnded(@NonNull WebRtcServiceState currentState, int groupCallHash, @NonNull GroupCall.GroupCallEndReason groupCallEndReason) {
protected @NonNull WebRtcServiceState handleGroupCallEnded(@NonNull WebRtcServiceState currentState, int groupCallHash, @NonNull CallManager.CallEndReason groupCallEndReason) {
Log.i(tag, "handleGroupCallEnded not processed");
return currentState;
}

View File

@@ -2,8 +2,8 @@ package org.thoughtcrime.securesms.service.webrtc.state
import com.annimon.stream.OptionalLong
import org.signal.ringrtc.CallId
import org.signal.ringrtc.CallManager.CallEndReason
import org.signal.ringrtc.GroupCall
import org.signal.ringrtc.GroupCall.GroupCallEndReason
import org.thoughtcrime.securesms.events.CallParticipant
import org.thoughtcrime.securesms.events.CallParticipantId
import org.thoughtcrime.securesms.events.GroupCallSpeechEvent
@@ -33,7 +33,7 @@ data class CallInfoState(
var participantLimit: Long? = null,
var pendingParticipants: PendingParticipantCollection = PendingParticipantCollection(),
var callLinkDisconnectReason: CallLinkDisconnectReason? = null,
var groupCallEndReason: GroupCallEndReason? = null,
var groupCallEndReason: CallEndReason? = null,
var groupCallSpeechEvent: GroupCallSpeechEvent? = null
) {

View File

@@ -7,6 +7,7 @@ import com.annimon.stream.OptionalLong;
import org.checkerframework.checker.units.qual.N;
import org.signal.ringrtc.CallId;
import org.signal.ringrtc.CallManager;
import org.signal.ringrtc.GroupCall;
import org.thoughtcrime.securesms.components.sensors.Orientation;
import org.thoughtcrime.securesms.components.webrtc.BroadcastVideoSink;
@@ -382,7 +383,7 @@ public class WebRtcServiceStateBuilder {
return this;
}
public @NonNull CallInfoStateBuilder setGroupCallEndReason(@Nullable GroupCall.GroupCallEndReason groupCallEndReason) {
public @NonNull CallInfoStateBuilder setGroupCallEndReason(@Nullable CallManager.CallEndReason groupCallEndReason) {
toBuild.setGroupCallEndReason(groupCallEndReason);
return this;
}

View File

@@ -148,7 +148,7 @@ libsignal-client = { module = "org.signal:libsignal-client", version.ref = "libs
libsignal-android = { module = "org.signal:libsignal-android", version.ref = "libsignal-client" }
protobuf-gradle-plugin = { module = "com.google.protobuf:protobuf-gradle-plugin", version.ref = "protobuf-gradle-plugin" }
signal-aesgcmprovider = "org.signal:aesgcmprovider:0.0.4"
signal-ringrtc = "org.signal:ringrtc-android:2.59.3"
signal-ringrtc = "org.signal:ringrtc-android:2.60.0"
signal-android-database-sqlcipher = "org.signal:sqlcipher-android:4.6.0-S1"
# Third Party

View File

@@ -12852,12 +12852,12 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
<sha256 value="1350bf553215b8d6275801ad2c507f8fd58b0ed17403eb190215e27008dfa1fa" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.signal" name="ringrtc-android" version="2.59.3">
<artifact name="ringrtc-android-2.59.3.aar">
<sha256 value="d876b8bc47ff53aa2da472932a6fa75a24ed058260bc8f42a04b720aaffe4023" origin="Generated by Gradle"/>
<component group="org.signal" name="ringrtc-android" version="2.60.0">
<artifact name="ringrtc-android-2.60.0.aar">
<sha256 value="e6f7c7e3703e138bfc97eb111331f49af85ed07007608c6afdf1f51978f81014" origin="Generated by Gradle"/>
</artifact>
<artifact name="ringrtc-android-2.59.3.module">
<sha256 value="7f6e94f38f0c7df938a48ace0200329214f34be8e08a336d10ee3a751f8a2f49" origin="Generated by Gradle"/>
<artifact name="ringrtc-android-2.60.0.module">
<sha256 value="9f89ddef082f2e616721cb4c5b1cca3b9f283e69b366f16f0c195e56baf1f40d" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="org.signal" name="sqlcipher-android" version="4.6.0-S1">