use of org.signal.ringrtc.CallException in project Signal-Android by signalapp.
the class IncomingGroupCallActionProcessor method handleGroupCallRingUpdate.
@Override
@NonNull
protected WebRtcServiceState handleGroupCallRingUpdate(@NonNull WebRtcServiceState currentState, @NonNull RemotePeer remotePeerGroup, @NonNull GroupId.V2 groupId, long ringId, @NonNull UUID uuid, @NonNull CallManager.RingUpdate ringUpdate) {
Log.i(TAG, "handleGroupCallRingUpdate(): recipient: " + remotePeerGroup.getId() + " ring: " + ringId + " update: " + ringUpdate);
Recipient recipient = remotePeerGroup.getRecipient();
boolean updateForCurrentRingId = ringId == currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingId();
boolean isCurrentlyRinging = currentState.getCallInfoState().getGroupCallState().isRinging();
if (SignalDatabase.groupCallRings().isCancelled(ringId)) {
try {
Log.i(TAG, "Ignoring incoming ring request for already cancelled ring: " + ringId);
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, null);
} catch (CallException e) {
Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
}
return currentState;
}
if (ringUpdate != CallManager.RingUpdate.REQUESTED) {
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
if (updateForCurrentRingId && isCurrentlyRinging) {
Log.i(TAG, "Cancelling current ring: " + ringId);
currentState = currentState.builder().changeCallInfoState().callState(WebRtcViewModel.State.CALL_DISCONNECTED).build();
webRtcInteractor.postStateUpdate(currentState);
return terminateGroupCall(currentState);
} else {
return currentState;
}
}
if (!updateForCurrentRingId && isCurrentlyRinging) {
try {
Log.i(TAG, "Already ringing so reply busy for new ring: " + ringId);
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.Busy);
} catch (CallException e) {
Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
}
return currentState;
}
if (updateForCurrentRingId) {
Log.i(TAG, "Already ringing for ring: " + ringId);
return currentState;
}
Log.i(TAG, "Requesting new ring: " + ringId);
SignalDatabase.groupCallRings().insertGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, RemotePeer.GROUP_CALL_ID.longValue());
webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_RINGING, remotePeerGroup);
webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
webRtcInteractor.initializeAudioForCall();
boolean shouldDisturbUserWithCall = DoNotDisturbUtil.shouldDisturbUserWithCall(context.getApplicationContext());
if (shouldDisturbUserWithCall) {
boolean started = webRtcInteractor.startWebRtcCallActivityIfPossible();
if (!started) {
Log.i(TAG, "Unable to start call activity due to OS version or not being in the foreground");
ApplicationDependencies.getAppForegroundObserver().addListener(webRtcInteractor.getForegroundListener());
}
}
if (shouldDisturbUserWithCall && SignalStore.settings().isCallNotificationsEnabled()) {
Uri ringtone = recipient.resolve().getCallRingtone();
RecipientDatabase.VibrateState vibrateState = recipient.resolve().getCallVibrate();
if (ringtone == null) {
ringtone = SignalStore.settings().getCallRingtone();
}
webRtcInteractor.startIncomingRinger(ringtone, vibrateState == RecipientDatabase.VibrateState.ENABLED || (vibrateState == RecipientDatabase.VibrateState.DEFAULT && SignalStore.settings().isCallVibrateEnabled()));
}
webRtcInteractor.registerPowerButtonReceiver();
return currentState.builder().changeCallSetupState(RemotePeer.GROUP_CALL_ID).isRemoteVideoOffer(true).ringId(ringId).ringerRecipient(Recipient.externalPush(ACI.from(uuid), null, false)).commit().changeCallInfoState().activePeer(new RemotePeer(currentState.getCallInfoState().getCallRecipient().getId(), RemotePeer.GROUP_CALL_ID)).callRecipient(remotePeerGroup.getRecipient()).callState(WebRtcViewModel.State.CALL_INCOMING).groupCallState(WebRtcViewModel.GroupCallState.RINGING).putParticipant(remotePeerGroup.getRecipient(), CallParticipant.createRemote(new CallParticipantId(remotePeerGroup.getRecipient()), remotePeerGroup.getRecipient(), null, new BroadcastVideoSink(currentState.getVideoState().getLockableEglBase(), false, true, currentState.getLocalDeviceState().getOrientation().getDegrees()), true, false, 0, true, 0, false, CallParticipant.DeviceOrdinal.PRIMARY)).build();
}
use of org.signal.ringrtc.CallException in project Signal-Android by signalapp.
the class WebRtcActionProcessor method handleMessageSentError.
@NonNull
protected WebRtcServiceState handleMessageSentError(@NonNull WebRtcServiceState currentState, @NonNull CallId callId, @NonNull WebRtcViewModel.State errorCallState, @NonNull Optional<IdentityKey> identityKey) {
Log.w(tag, "handleMessageSentError():");
try {
webRtcInteractor.getCallManager().messageSendFailure(callId);
} catch (CallException e) {
currentState = callFailure(currentState, "callManager.messageSendFailure() failed: ", e);
}
RemotePeer activePeer = currentState.getCallInfoState().getActivePeer();
if (activePeer == null) {
return currentState;
}
WebRtcServiceStateBuilder builder = currentState.builder();
if (errorCallState == WebRtcViewModel.State.UNTRUSTED_IDENTITY) {
CallParticipant participant = Objects.requireNonNull(currentState.getCallInfoState().getRemoteCallParticipant(activePeer.getRecipient()));
CallParticipant untrusted = participant.withIdentityKey(identityKey.orNull());
builder.changeCallInfoState().callState(WebRtcViewModel.State.UNTRUSTED_IDENTITY).putParticipant(activePeer.getRecipient(), untrusted).commit();
} else {
builder.changeCallInfoState().callState(errorCallState).commit();
}
return builder.build();
}
use of org.signal.ringrtc.CallException in project Signal-Android by signalapp.
the class WebRtcActionProcessor method handleReceivedOffer.
// endregion Outgoing call
// region Incoming call
@NonNull
protected WebRtcServiceState handleReceivedOffer(@NonNull WebRtcServiceState currentState, @NonNull CallMetadata callMetadata, @NonNull OfferMetadata offerMetadata, @NonNull ReceivedOfferMetadata receivedOfferMetadata) {
Log.i(tag, "handleReceivedOffer(): id: " + callMetadata.getCallId().format(callMetadata.getRemoteDevice()) + " offer_type:" + offerMetadata.getOfferType());
if (TelephonyUtil.isAnyPstnLineBusy(context)) {
Log.i(tag, "PSTN line is busy.");
currentState = currentState.getActionProcessor().handleSendBusy(currentState, callMetadata, true);
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
return currentState;
}
if (!RecipientUtil.isCallRequestAccepted(context.getApplicationContext(), callMetadata.getRemotePeer().getRecipient())) {
Log.w(tag, "Caller is untrusted.");
currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NEED_PERMISSION), true);
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
return currentState;
}
if (offerMetadata.getOpaque() == null) {
Log.w(tag, "Opaque data is required.");
currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NORMAL), true);
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
return currentState;
}
NotificationProfile activeProfile = NotificationProfiles.getActiveProfile(SignalDatabase.notificationProfiles().getProfiles());
if (activeProfile != null && !(activeProfile.isRecipientAllowed(callMetadata.getRemotePeer().getId()) || activeProfile.getAllowAllCalls())) {
Log.w(tag, "Caller is excluded by notification profile.");
currentState = currentState.getActionProcessor().handleSendHangup(currentState, callMetadata, WebRtcData.HangupMetadata.fromType(HangupMessage.Type.NORMAL), true);
webRtcInteractor.insertMissedCall(callMetadata.getRemotePeer(), receivedOfferMetadata.getServerReceivedTimestamp(), offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL);
return currentState;
}
Log.i(tag, "add remotePeer callId: " + callMetadata.getRemotePeer().getCallId() + " key: " + callMetadata.getRemotePeer().hashCode());
callMetadata.getRemotePeer().setCallStartTimestamp(receivedOfferMetadata.getServerReceivedTimestamp());
currentState = currentState.builder().changeCallSetupState(callMetadata.getCallId()).isRemoteVideoOffer(offerMetadata.getOfferType() == OfferMessage.Type.VIDEO_CALL).commit().changeCallInfoState().putRemotePeer(callMetadata.getRemotePeer()).build();
long messageAgeSec = Math.max(receivedOfferMetadata.getServerDeliveredTimestamp() - receivedOfferMetadata.getServerReceivedTimestamp(), 0) / 1000;
Log.i(tag, "messageAgeSec: " + messageAgeSec + ", serverReceivedTimestamp: " + receivedOfferMetadata.getServerReceivedTimestamp() + ", serverDeliveredTimestamp: " + receivedOfferMetadata.getServerDeliveredTimestamp());
try {
byte[] remoteIdentityKey = WebRtcUtil.getPublicKeyBytes(receivedOfferMetadata.getRemoteIdentityKey());
byte[] localIdentityKey = WebRtcUtil.getPublicKeyBytes(SignalStore.account().getAciIdentityKey().getPublicKey().serialize());
webRtcInteractor.getCallManager().receivedOffer(callMetadata.getCallId(), callMetadata.getRemotePeer(), callMetadata.getRemoteDevice(), offerMetadata.getOpaque(), messageAgeSec, WebRtcUtil.getCallMediaTypeFromOfferType(offerMetadata.getOfferType()), SignalStore.account().getDeviceId(), SignalStore.account().isPrimaryDevice(), remoteIdentityKey, localIdentityKey);
} catch (CallException | InvalidKeyException e) {
return callFailure(currentState, "Unable to process received offer: ", e);
}
return currentState;
}
use of org.signal.ringrtc.CallException in project Signal-Android by signalapp.
the class ActiveCallActionProcessorDelegate method handleLocalHangup.
@Override
@NonNull
protected WebRtcServiceState handleLocalHangup(@NonNull WebRtcServiceState currentState) {
RemotePeer remotePeer = currentState.getCallInfoState().getActivePeer();
if (remotePeer == null) {
Log.i(tag, "handleLocalHangup(): no active peer");
} else {
Log.i(tag, "handleLocalHangup(): call_id: " + remotePeer.getCallId());
}
ApplicationDependencies.getSignalServiceAccountManager().cancelInFlightRequests();
ApplicationDependencies.getSignalServiceMessageSender().cancelInFlightRequests();
try {
webRtcInteractor.getCallManager().hangup();
currentState = currentState.builder().changeCallInfoState().callState(WebRtcViewModel.State.CALL_DISCONNECTED).build();
webRtcInteractor.postStateUpdate(currentState);
return terminate(currentState, remotePeer);
} catch (CallException e) {
return callFailure(currentState, "hangup() failed: ", e);
}
}
use of org.signal.ringrtc.CallException in project Signal-Android by signalapp.
the class ActiveCallActionProcessorDelegate method handleSetupFailure.
@Override
@NonNull
protected WebRtcServiceState handleSetupFailure(@NonNull WebRtcServiceState currentState, @NonNull CallId callId) {
Log.i(tag, "handleSetupFailure(): call_id: " + callId);
RemotePeer activePeer = currentState.getCallInfoState().getActivePeer();
if (activePeer != null && activePeer.getCallId().equals(callId)) {
try {
if (activePeer.getState() == CallState.DIALING || activePeer.getState() == CallState.REMOTE_RINGING) {
webRtcInteractor.getCallManager().hangup();
} else {
webRtcInteractor.getCallManager().drop(callId);
}
} catch (CallException e) {
return callFailure(currentState, "Unable to drop call due to setup failure", e);
}
currentState = currentState.builder().changeCallInfoState().callState(WebRtcViewModel.State.NETWORK_FAILURE).build();
webRtcInteractor.postStateUpdate(currentState);
if (activePeer.getState() == CallState.ANSWERING || activePeer.getState() == CallState.LOCAL_RINGING) {
webRtcInteractor.insertMissedCall(activePeer, activePeer.getCallStartTimestamp(), currentState.getCallSetupState(activePeer).isRemoteVideoOffer());
}
return terminate(currentState, activePeer);
}
return currentState;
}
Aggregations