use of org.signal.ringrtc.GroupCall in project Signal-Android by WhisperSystems.
the class GroupPreJoinActionProcessor method handlePreJoinCall.
@Override
@NonNull
protected WebRtcServiceState handlePreJoinCall(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeer) {
Log.i(TAG, "handlePreJoinCall():");
byte[] groupId = currentState.getCallInfoState().getCallRecipient().requireGroupId().getDecodedId();
GroupCall groupCall = webRtcInteractor.getCallManager().createGroupCall(groupId, SignalStore.internalValues().groupCallingServer(), new byte[0], null, AudioProcessingMethodSelector.get(), webRtcInteractor.getGroupCallObserver());
try {
groupCall.setOutgoingAudioMuted(true);
groupCall.setOutgoingVideoMuted(true);
groupCall.setBandwidthMode(NetworkUtil.getCallingBandwidthMode(context, groupCall.getLocalDeviceState().getNetworkRoute().getLocalAdapterType()));
Log.i(TAG, "Connecting to group call: " + currentState.getCallInfoState().getCallRecipient().getId());
groupCall.connect();
} catch (CallException e) {
return groupCallFailure(currentState, "Unable to connect to group call", e);
}
SignalStore.tooltips().markGroupCallingLobbyEntered();
return currentState.builder().changeCallInfoState().groupCall(groupCall).groupCallState(WebRtcViewModel.GroupCallState.DISCONNECTED).activePeer(new RemotePeer(currentState.getCallInfoState().getCallRecipient().getId(), RemotePeer.GROUP_CALL_ID)).build();
}
use of org.signal.ringrtc.GroupCall in project Signal-Android by WhisperSystems.
the class SignalCallManager method requestMembershipProof.
@Override
public void requestMembershipProof(@NonNull final GroupCall groupCall) {
Log.i(TAG, "requestMembershipProof():");
Recipient recipient = serviceState.getCallInfoState().getCallRecipient();
if (!recipient.isPushV2Group()) {
Log.i(TAG, "Request membership proof for non-group");
return;
}
GroupCall currentGroupCall = serviceState.getCallInfoState().getGroupCall();
if (currentGroupCall == null || currentGroupCall.hashCode() != groupCall.hashCode()) {
Log.i(TAG, "Skipping group membership proof request, requested group call does not match current group call");
return;
}
networkExecutor.execute(() -> {
try {
GroupExternalCredential credential = GroupManager.getGroupExternalCredential(context, recipient.getGroupId().get().requireV2());
process((s, p) -> p.handleGroupRequestMembershipProof(s, groupCall.hashCode(), credential.getTokenBytes().toByteArray()));
} catch (IOException e) {
Log.w(TAG, "Unable to get group membership proof from service", e);
onEnded(groupCall, GroupCall.GroupCallEndReason.SFU_CLIENT_FAILED_TO_JOIN);
} catch (VerificationFailedException e) {
Log.w(TAG, "Unable to verify group membership proof", e);
onEnded(groupCall, GroupCall.GroupCallEndReason.DEVICE_EXPLICITLY_DISCONNECTED);
}
});
}
use of org.signal.ringrtc.GroupCall in project Signal-Android by WhisperSystems.
the class GroupActionProcessor method handleGroupCallEnded.
@Override
@NonNull
protected WebRtcServiceState handleGroupCallEnded(@NonNull WebRtcServiceState currentState, int groupCallHash, @NonNull GroupCall.GroupCallEndReason groupCallEndReason) {
Log.i(tag, "handleGroupCallEnded(): reason: " + groupCallEndReason);
GroupCall groupCall = currentState.getCallInfoState().getGroupCall();
if (groupCall == null || groupCall.hashCode() != groupCallHash) {
return currentState;
}
try {
groupCall.disconnect();
} catch (CallException e) {
return groupCallFailure(currentState, "Unable to disconnect from group call", e);
}
if (groupCallEndReason != GroupCall.GroupCallEndReason.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();
currentState = terminateGroupCall(currentState, false).builder().actionProcessor(new GroupNetworkUnavailableActionProcessor(webRtcInteractor)).changeVideoState().eglBase(videoState.getLockableEglBase()).camera(videoState.getCamera()).localSink(videoState.getLocalSink()).commit().changeCallInfoState().callState(WebRtcViewModel.State.CALL_PRE_JOIN).callRecipient(currentRecipient).build();
currentState = WebRtcVideoUtil.initializeVanityCamera(WebRtcVideoUtil.reinitializeCamera(context, webRtcInteractor.getCameraEventListener(), currentState));
return currentState.getActionProcessor().handlePreJoinCall(currentState, new RemotePeer(currentRecipient.getId()));
}
currentState = currentState.builder().changeCallInfoState().callState(WebRtcViewModel.State.CALL_DISCONNECTED).groupCallState(WebRtcViewModel.GroupCallState.DISCONNECTED).build();
webRtcInteractor.postStateUpdate(currentState);
return terminateGroupCall(currentState);
}
use of org.signal.ringrtc.GroupCall in project Signal-Android by WhisperSystems.
the class GroupActionProcessor method handleGroupRemoteDeviceStateChanged.
@Override
@NonNull
protected WebRtcServiceState handleGroupRemoteDeviceStateChanged(@NonNull WebRtcServiceState currentState) {
Log.i(tag, "handleGroupRemoteDeviceStateChanged():");
GroupCall groupCall = currentState.getCallInfoState().requireGroupCall();
Map<CallParticipantId, CallParticipant> participants = currentState.getCallInfoState().getRemoteCallParticipantsMap();
LongSparseArray<GroupCall.RemoteDeviceState> remoteDevices = groupCall.getRemoteDeviceStates();
if (remoteDevices == null) {
Log.w(tag, "Unable to update remote devices with null list.");
return currentState;
}
WebRtcServiceStateBuilder.CallInfoStateBuilder builder = currentState.builder().changeCallInfoState().clearParticipantMap();
List<GroupCall.RemoteDeviceState> remoteDeviceStates = new ArrayList<>(remoteDevices.size());
for (int i = 0; i < remoteDevices.size(); i++) {
remoteDeviceStates.add(remoteDevices.get(remoteDevices.keyAt(i)));
}
Collections.sort(remoteDeviceStates, (a, b) -> Long.compare(a.getAddedTime(), b.getAddedTime()));
Set<Recipient> seen = new HashSet<>();
seen.add(Recipient.self());
for (GroupCall.RemoteDeviceState device : remoteDeviceStates) {
Recipient recipient = Recipient.externalPush(ACI.from(device.getUserId()), null, false);
CallParticipantId callParticipantId = new CallParticipantId(device.getDemuxId(), recipient.getId());
CallParticipant callParticipant = participants.get(callParticipantId);
BroadcastVideoSink videoSink;
VideoTrack videoTrack = device.getVideoTrack();
if (videoTrack != null) {
videoSink = (callParticipant != null && callParticipant.getVideoSink().getLockableEglBase().getEglBase() != null) ? callParticipant.getVideoSink() : new BroadcastVideoSink(currentState.getVideoState().getLockableEglBase(), true, true, currentState.getLocalDeviceState().getOrientation().getDegrees());
videoTrack.addSink(videoSink);
} else {
videoSink = new BroadcastVideoSink();
}
builder.putParticipant(callParticipantId, CallParticipant.createRemote(callParticipantId, recipient, null, videoSink, Boolean.FALSE.equals(device.getAudioMuted()), Boolean.FALSE.equals(device.getVideoMuted()), device.getSpeakerTime(), device.getMediaKeysReceived(), device.getAddedTime(), Boolean.TRUE.equals(device.getPresenting()), seen.contains(recipient) ? CallParticipant.DeviceOrdinal.SECONDARY : CallParticipant.DeviceOrdinal.PRIMARY));
seen.add(recipient);
}
builder.remoteDevicesCount(remoteDevices.size());
return builder.build();
}
use of org.signal.ringrtc.GroupCall in project Signal-Android by WhisperSystems.
the class GroupActionProcessor method handleGroupRequestUpdateMembers.
@Override
@NonNull
protected WebRtcServiceState handleGroupRequestUpdateMembers(@NonNull WebRtcServiceState currentState) {
Log.i(tag, "handleGroupRequestUpdateMembers():");
Recipient group = currentState.getCallInfoState().getCallRecipient();
GroupCall groupCall = currentState.getCallInfoState().requireGroupCall();
List<GroupCall.GroupMemberInfo> members = Stream.of(GroupManager.getUuidCipherTexts(context, group.requireGroupId().requireV2())).map(entry -> new GroupCall.GroupMemberInfo(entry.getKey(), entry.getValue().serialize())).toList();
try {
groupCall.setGroupMembers(new ArrayList<>(members));
} catch (CallException e) {
return groupCallFailure(currentState, "Unable set group members", e);
}
return currentState;
}
Aggregations