handle network switching with webrtc

dirty hack from
https://bugs.chromium.org/p/chromium/issues/detail?id=982793
pull/2027/head
Audric Ackermann 4 years ago
parent 1203f1dc48
commit 67665dde56
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -50,7 +50,7 @@ export async function handleCallMessage(
if (type === SignalService.CallMessage.Type.END_CALL) { if (type === SignalService.CallMessage.Type.END_CALL) {
await removeFromCache(envelope); await removeFromCache(envelope);
CallManager.handleCallTypeEndCall(sender); CallManager.handleCallTypeEndCall(sender, callMessage.uuid);
return; return;
} }

@ -469,12 +469,12 @@ const findLastMessageTypeFromSender = (sender: string, msgType: SignalService.Ca
// FIXME this does not sort by timestamp as we do not have a timestamp stored in the SignalService.CallMessage object... // FIXME this does not sort by timestamp as we do not have a timestamp stored in the SignalService.CallMessage object...
const allMsg = _.flattenDeep([...msgCacheFromSenderWithDevices.values()]); const allMsg = _.flattenDeep([...msgCacheFromSenderWithDevices.values()]);
const allMsgFromType = allMsg.filter(m => m.type === msgType); const allMsgFromType = allMsg.filter(m => m.type === msgType);
const lastOfferMessage = _.last(allMsgFromType); const lastMessageOfType = _.last(allMsgFromType);
if (!lastOfferMessage) { if (!lastMessageOfType) {
return undefined; return undefined;
} }
return lastOfferMessage; return lastMessageOfType;
}; };
function handleSignalingStateChangeEvent() { function handleSignalingStateChangeEvent() {
@ -486,7 +486,7 @@ function handleSignalingStateChangeEvent() {
function handleConnectionStateChanged(pubkey: string) { function handleConnectionStateChanged(pubkey: string) {
window.log.info('handleConnectionStateChanged :', peerConnection?.connectionState); window.log.info('handleConnectionStateChanged :', peerConnection?.connectionState);
if (peerConnection?.signalingState === 'closed') { if (peerConnection?.signalingState === 'closed' || peerConnection?.connectionState === 'failed') {
closeVideoCall(); closeVideoCall();
} else if (peerConnection?.connectionState === 'connected') { } else if (peerConnection?.connectionState === 'connected') {
setIsRinging(false); setIsRinging(false);
@ -496,6 +496,7 @@ function handleConnectionStateChanged(pubkey: string) {
function closeVideoCall() { function closeVideoCall() {
window.log.info('closingVideoCall '); window.log.info('closingVideoCall ');
setIsRinging(false);
if (peerConnection) { if (peerConnection) {
peerConnection.ontrack = null; peerConnection.ontrack = null;
peerConnection.onicecandidate = null; peerConnection.onicecandidate = null;
@ -530,8 +531,14 @@ function closeVideoCall() {
selectedCameraId = DEVICE_DISABLED_DEVICE_ID; selectedCameraId = DEVICE_DISABLED_DEVICE_ID;
selectedAudioInputId = DEVICE_DISABLED_DEVICE_ID; selectedAudioInputId = DEVICE_DISABLED_DEVICE_ID;
currentCallUUID = undefined; currentCallUUID = undefined;
window.inboxStore?.dispatch(setFullScreenCall(false)); window.inboxStore?.dispatch(setFullScreenCall(false));
remoteVideoStreamIsMuted = true;
makingOffer = false;
ignoreOffer = false;
isSettingRemoteAnswerPending = false;
lastOutgoingOfferTimestamp = -Infinity;
callVideoListeners(); callVideoListeners();
} }
@ -552,7 +559,7 @@ function onDataChannelReceivedMessage(ev: MessageEvent<string>) {
if (!foundEntry || !foundEntry.id) { if (!foundEntry || !foundEntry.id) {
return; return;
} }
handleCallTypeEndCall(foundEntry.id); handleCallTypeEndCall(foundEntry.id, currentCallUUID);
return; return;
} }
@ -612,6 +619,24 @@ function createOrGetPeerConnection(withPubkey: string, isAcceptingCall = false)
handleIceCandidates(event, withPubkey); handleIceCandidates(event, withPubkey);
}; };
peerConnection.oniceconnectionstatechange = () => {
window.log.info(
'oniceconnectionstatechange peerConnection.iceConnectionState: ',
peerConnection?.iceConnectionState
);
if (peerConnection && peerConnection?.iceConnectionState === 'disconnected') {
//this will trigger a negotation event with iceRestart set to true in the createOffer options set
global.setTimeout(() => {
window.log.info('onconnectionstatechange disconnected: restartIce()');
if (peerConnection?.iceConnectionState === 'disconnected') {
(peerConnection as any).restartIce();
}
}, 2000);
}
};
return peerConnection; return peerConnection;
} }
@ -689,22 +714,31 @@ export async function USER_acceptIncomingCallRequest(fromSender: string) {
// tslint:disable-next-line: function-name // tslint:disable-next-line: function-name
export async function USER_rejectIncomingCallRequest(fromSender: string) { export async function USER_rejectIncomingCallRequest(fromSender: string) {
setIsRinging(false); setIsRinging(false);
const endCallMessage = new CallMessage({
type: SignalService.CallMessage.Type.END_CALL, const lastOfferMessage = findLastMessageTypeFromSender(
timestamp: Date.now(), fromSender,
uuid: uuidv4(), // just send a random thing, we just want to reject the call SignalService.CallMessage.Type.OFFER
}); );
// delete all msg not from that uuid only but from that sender pubkey
const lastCallUUID = lastOfferMessage?.uuid;
window.log.info(`USER_rejectIncomingCallRequest ${ed25519Str(fromSender)}: ${lastCallUUID}`);
if (lastCallUUID) {
const endCallMessage = new CallMessage({
type: SignalService.CallMessage.Type.END_CALL,
timestamp: Date.now(),
uuid: lastCallUUID,
});
await getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(fromSender), endCallMessage);
// delete all msg not from that uuid only but from that sender pubkey
clearCallCacheFromPubkeyAndUUID(fromSender, lastCallUUID);
}
window.inboxStore?.dispatch( window.inboxStore?.dispatch(
endCall({ endCall({
pubkey: fromSender, pubkey: fromSender,
}) })
); );
window.log.info('USER_rejectIncomingCallRequest');
clearCallCacheFromPubkey(fromSender);
await getMessageQueue().sendToPubKeyNonDurably(PubKey.cast(fromSender), endCallMessage);
const convos = getConversationController().getConversations(); const convos = getConversationController().getConversations();
const callingConvos = convos.filter(convo => convo.callState !== undefined); const callingConvos = convos.filter(convo => convo.callState !== undefined);
@ -737,28 +771,18 @@ export async function USER_hangup(fromSender: string) {
sendHangupViaDataChannel(); sendHangupViaDataChannel();
clearCallCacheFromPubkey(fromSender); clearCallCacheFromPubkeyAndUUID(fromSender, currentCallUUID);
const convos = getConversationController().getConversations(); closeVideoCall();
const callingConvos = convos.filter(convo => convo.callState !== undefined);
if (callingConvos.length > 0) {
// we just got a new offer from someone we are already in a call with
if (callingConvos.length === 1 && callingConvos[0].id === fromSender) {
closeVideoCall();
}
}
} }
export function handleCallTypeEndCall(sender: string) { export function handleCallTypeEndCall(sender: string, aboutCallUUID?: string) {
clearCallCacheFromPubkey(sender); window.log.info('handling callMessage END_CALL:', aboutCallUUID);
window.log.info('handling callMessage END_CALL'); if (aboutCallUUID) {
clearCallCacheFromPubkeyAndUUID(sender, aboutCallUUID);
const convos = getConversationController().getConversations(); if (aboutCallUUID === currentCallUUID) {
const callingConvos = convos.filter(convo => convo.callState !== undefined);
if (callingConvos.length > 0) {
// we just got a end call event from whoever we are in a call with
if (callingConvos.length === 1 && callingConvos[0].id === sender) {
closeVideoCall(); closeVideoCall();
window.inboxStore?.dispatch(endCall({ pubkey: sender })); window.inboxStore?.dispatch(endCall({ pubkey: sender }));
@ -983,8 +1007,8 @@ export async function handleOtherCallTypes(sender: string, callMessage: SignalSe
pushCallMessageToCallCache(sender, remoteCallUUID, callMessage); pushCallMessageToCallCache(sender, remoteCallUUID, callMessage);
} }
function clearCallCacheFromPubkey(sender: string) { function clearCallCacheFromPubkeyAndUUID(sender: string, callUUID: string) {
callCache.delete(sender); callCache.get(sender)?.delete(callUUID);
} }
function createCallCacheForPubkeyAndUUID(sender: string, uuid: string) { function createCallCacheForPubkeyAndUUID(sender: string, uuid: string) {

@ -7,6 +7,7 @@ let ringingAudio: HTMLAudioElement | undefined;
function stopRinging() { function stopRinging() {
if (ringingAudio) { if (ringingAudio) {
ringingAudio.pause(); ringingAudio.pause();
ringingAudio.srcObject = null;
} }
} }
@ -14,6 +15,7 @@ function startRinging() {
if (!ringingAudio) { if (!ringingAudio) {
ringingAudio = new Audio(sound); ringingAudio = new Audio(sound);
ringingAudio.loop = true; ringingAudio.loop = true;
ringingAudio.volume = 0.6;
} }
void ringingAudio.play(); void ringingAudio.play();
} }

Loading…
Cancel
Save