diff options
Diffstat (limited to 'includes/external/matrix/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js')
-rw-r--r-- | includes/external/matrix/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/includes/external/matrix/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js b/includes/external/matrix/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js deleted file mode 100644 index 5e3c242..0000000 --- a/includes/external/matrix/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js +++ /dev/null @@ -1,347 +0,0 @@ -"use strict"; - -var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CallEventHandlerEvent = exports.CallEventHandler = void 0; -var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); -var _logger = require("../logger"); -var _call = require("./call"); -var _event = require("../@types/event"); -var _client = require("../client"); -var _groupCall3 = require("./groupCall"); -var _room = require("../models/room"); -/* -Copyright 2020 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Don't ring unless we'd be ringing for at least 3 seconds: the user needs some -// time to press the 'accept' button -const RING_GRACE_PERIOD = 3000; -let CallEventHandlerEvent; -exports.CallEventHandlerEvent = CallEventHandlerEvent; -(function (CallEventHandlerEvent) { - CallEventHandlerEvent["Incoming"] = "Call.incoming"; -})(CallEventHandlerEvent || (exports.CallEventHandlerEvent = CallEventHandlerEvent = {})); -class CallEventHandler { - // XXX: Most of these are only public because of the tests - - constructor(client) { - (0, _defineProperty2.default)(this, "calls", void 0); - (0, _defineProperty2.default)(this, "callEventBuffer", void 0); - (0, _defineProperty2.default)(this, "nextSeqByCall", new Map()); - (0, _defineProperty2.default)(this, "toDeviceEventBuffers", new Map()); - (0, _defineProperty2.default)(this, "client", void 0); - (0, _defineProperty2.default)(this, "candidateEventsByCall", void 0); - (0, _defineProperty2.default)(this, "eventBufferPromiseChain", void 0); - (0, _defineProperty2.default)(this, "onSync", () => { - // Process the current event buffer and start queuing into a new one. - const currentEventBuffer = this.callEventBuffer; - this.callEventBuffer = []; - - // Ensure correct ordering by only processing this queue after the previous one has finished processing - if (this.eventBufferPromiseChain) { - this.eventBufferPromiseChain = this.eventBufferPromiseChain.then(() => this.evaluateEventBuffer(currentEventBuffer)); - } else { - this.eventBufferPromiseChain = this.evaluateEventBuffer(currentEventBuffer); - } - }); - (0, _defineProperty2.default)(this, "onRoomTimeline", event => { - this.callEventBuffer.push(event); - }); - (0, _defineProperty2.default)(this, "onToDeviceEvent", event => { - const content = event.getContent(); - if (!content.call_id) { - this.callEventBuffer.push(event); - return; - } - if (!this.nextSeqByCall.has(content.call_id)) { - this.nextSeqByCall.set(content.call_id, 0); - } - if (content.seq === undefined) { - this.callEventBuffer.push(event); - return; - } - const nextSeq = this.nextSeqByCall.get(content.call_id) || 0; - if (content.seq !== nextSeq) { - if (!this.toDeviceEventBuffers.has(content.call_id)) { - this.toDeviceEventBuffers.set(content.call_id, []); - } - const buffer = this.toDeviceEventBuffers.get(content.call_id); - const index = buffer.findIndex(e => e.getContent().seq > content.seq); - if (index === -1) { - buffer.push(event); - } else { - buffer.splice(index, 0, event); - } - } else { - const callId = content.call_id; - this.callEventBuffer.push(event); - this.nextSeqByCall.set(callId, content.seq + 1); - const buffer = this.toDeviceEventBuffers.get(callId); - let nextEvent = buffer && buffer.shift(); - while (nextEvent && nextEvent.getContent().seq === this.nextSeqByCall.get(callId)) { - this.callEventBuffer.push(nextEvent); - this.nextSeqByCall.set(callId, nextEvent.getContent().seq + 1); - nextEvent = buffer.shift(); - } - } - }); - this.client = client; - this.calls = new Map(); - // The sync code always emits one event at a time, so it will patiently - // wait for us to finish processing a call invite before delivering the - // next event, even if that next event is a hangup. We therefore accumulate - // all our call events and then process them on the 'sync' event, ie. - // each time a sync has completed. This way, we can avoid emitting incoming - // call events if we get both the invite and answer/hangup in the same sync. - // This happens quite often, eg. replaying sync from storage, catchup sync - // after loading and after we've been offline for a bit. - this.callEventBuffer = []; - this.candidateEventsByCall = new Map(); - } - start() { - this.client.on(_client.ClientEvent.Sync, this.onSync); - this.client.on(_room.RoomEvent.Timeline, this.onRoomTimeline); - this.client.on(_client.ClientEvent.ToDeviceEvent, this.onToDeviceEvent); - } - stop() { - this.client.removeListener(_client.ClientEvent.Sync, this.onSync); - this.client.removeListener(_room.RoomEvent.Timeline, this.onRoomTimeline); - this.client.removeListener(_client.ClientEvent.ToDeviceEvent, this.onToDeviceEvent); - } - async evaluateEventBuffer(eventBuffer) { - await Promise.all(eventBuffer.map(event => this.client.decryptEventIfNeeded(event))); - const callEvents = eventBuffer.filter(event => { - const eventType = event.getType(); - return eventType.startsWith("m.call.") || eventType.startsWith("org.matrix.call."); - }); - const ignoreCallIds = new Set(); - - // inspect the buffer and mark all calls which have been answered - // or hung up before passing them to the call event handler. - for (const event of callEvents) { - const eventType = event.getType(); - if (eventType === _event.EventType.CallAnswer || eventType === _event.EventType.CallHangup) { - ignoreCallIds.add(event.getContent().call_id); - } - } - - // Process call events in the order that they were received - for (const event of callEvents) { - const eventType = event.getType(); - const callId = event.getContent().call_id; - if (eventType === _event.EventType.CallInvite && ignoreCallIds.has(callId)) { - // This call has previously been answered or hung up: ignore it - continue; - } - try { - await this.handleCallEvent(event); - } catch (e) { - _logger.logger.error("CallEventHandler evaluateEventBuffer() caught exception handling call event", e); - } - } - } - async handleCallEvent(event) { - var _getGroupCallById, _getGroupCallById$roo; - this.client.emit(_client.ClientEvent.ReceivedVoipEvent, event); - const content = event.getContent(); - const callRoomId = event.getRoomId() || ((_getGroupCallById = this.client.groupCallEventHandler.getGroupCallById(content.conf_id)) === null || _getGroupCallById === void 0 ? void 0 : (_getGroupCallById$roo = _getGroupCallById.room) === null || _getGroupCallById$roo === void 0 ? void 0 : _getGroupCallById$roo.roomId); - const groupCallId = content.conf_id; - const type = event.getType(); - const senderId = event.getSender(); - let call = content.call_id ? this.calls.get(content.call_id) : undefined; - let opponentDeviceId; - let groupCall; - if (groupCallId) { - groupCall = this.client.groupCallEventHandler.getGroupCallById(groupCallId); - if (!groupCall) { - _logger.logger.warn(`CallEventHandler handleCallEvent() could not find a group call - ignoring event (groupCallId=${groupCallId}, type=${type})`); - return; - } - opponentDeviceId = content.device_id; - if (!opponentDeviceId) { - _logger.logger.warn(`CallEventHandler handleCallEvent() could not find a device id - ignoring event (senderId=${senderId})`); - groupCall.emit(_groupCall3.GroupCallEvent.Error, new _groupCall3.GroupCallUnknownDeviceError(senderId)); - return; - } - if (content.dest_session_id !== this.client.getSessionId()) { - _logger.logger.warn("CallEventHandler handleCallEvent() call event does not match current session id - ignoring"); - return; - } - } - const weSentTheEvent = senderId === this.client.credentials.userId && (opponentDeviceId === undefined || opponentDeviceId === this.client.getDeviceId()); - if (!callRoomId) return; - if (type === _event.EventType.CallInvite) { - var _this$client$getTurnS, _createNewMatrixCall, _groupCall; - // ignore invites you send - if (weSentTheEvent) return; - // expired call - if (event.getLocalAge() > content.lifetime - RING_GRACE_PERIOD) return; - // stale/old invite event - if (call && call.state === _call.CallState.Ended) return; - if (call) { - _logger.logger.warn(`CallEventHandler handleCallEvent() already has a call but got an invite - clobbering (callId=${content.call_id})`); - } - if (content.invitee && content.invitee !== this.client.getUserId()) { - return; // This invite was meant for another user in the room - } - - const timeUntilTurnCresExpire = ((_this$client$getTurnS = this.client.getTurnServersExpiry()) !== null && _this$client$getTurnS !== void 0 ? _this$client$getTurnS : 0) - Date.now(); - _logger.logger.info("CallEventHandler handleCallEvent() current turn creds expire in " + timeUntilTurnCresExpire + " ms"); - call = (_createNewMatrixCall = (0, _call.createNewMatrixCall)(this.client, callRoomId, { - forceTURN: this.client.forceTURN, - opponentDeviceId, - groupCallId, - opponentSessionId: content.sender_session_id - })) !== null && _createNewMatrixCall !== void 0 ? _createNewMatrixCall : undefined; - if (!call) { - _logger.logger.log(`CallEventHandler handleCallEvent() this client does not support WebRTC (callId=${content.call_id})`); - // don't hang up the call: there could be other clients - // connected that do support WebRTC and declining the - // the call on their behalf would be really annoying. - return; - } - call.callId = content.call_id; - const stats = (_groupCall = groupCall) === null || _groupCall === void 0 ? void 0 : _groupCall.getGroupCallStats(); - if (stats) { - call.initStats(stats); - } - try { - await call.initWithInvite(event); - } catch (e) { - if (e instanceof _call.CallError) { - if (e.code === _groupCall3.GroupCallErrorCode.UnknownDevice) { - var _groupCall2; - (_groupCall2 = groupCall) === null || _groupCall2 === void 0 ? void 0 : _groupCall2.emit(_groupCall3.GroupCallEvent.Error, e); - } else { - _logger.logger.error(e); - } - } - } - this.calls.set(call.callId, call); - - // if we stashed candidate events for that call ID, play them back now - if (this.candidateEventsByCall.get(call.callId)) { - for (const ev of this.candidateEventsByCall.get(call.callId)) { - call.onRemoteIceCandidatesReceived(ev); - } - } - - // Were we trying to call that user (room)? - let existingCall; - for (const thisCall of this.calls.values()) { - var _call$getOpponentMemb; - const isCalling = [_call.CallState.WaitLocalMedia, _call.CallState.CreateOffer, _call.CallState.InviteSent].includes(thisCall.state); - if (call.roomId === thisCall.roomId && thisCall.direction === _call.CallDirection.Outbound && ((_call$getOpponentMemb = call.getOpponentMember()) === null || _call$getOpponentMemb === void 0 ? void 0 : _call$getOpponentMemb.userId) === thisCall.invitee && isCalling) { - existingCall = thisCall; - break; - } - } - if (existingCall) { - if (existingCall.callId > call.callId) { - _logger.logger.log(`CallEventHandler handleCallEvent() detected glare - answering incoming call and canceling outgoing call (incomingId=${call.callId}, outgoingId=${existingCall.callId})`); - existingCall.replacedBy(call); - } else { - _logger.logger.log(`CallEventHandler handleCallEvent() detected glare - hanging up incoming call (incomingId=${call.callId}, outgoingId=${existingCall.callId})`); - call.hangup(_call.CallErrorCode.Replaced, true); - } - } else { - this.client.emit(CallEventHandlerEvent.Incoming, call); - } - return; - } else if (type === _event.EventType.CallCandidates) { - if (weSentTheEvent) return; - if (!call) { - // store the candidates; we may get a call eventually. - if (!this.candidateEventsByCall.has(content.call_id)) { - this.candidateEventsByCall.set(content.call_id, []); - } - this.candidateEventsByCall.get(content.call_id).push(event); - } else { - call.onRemoteIceCandidatesReceived(event); - } - return; - } else if ([_event.EventType.CallHangup, _event.EventType.CallReject].includes(type)) { - // Note that we also observe our own hangups here so we can see - // if we've already rejected a call that would otherwise be valid - if (!call) { - var _createNewMatrixCall2; - // if not live, store the fact that the call has ended because - // we're probably getting events backwards so - // the hangup will come before the invite - call = (_createNewMatrixCall2 = (0, _call.createNewMatrixCall)(this.client, callRoomId, { - opponentDeviceId, - opponentSessionId: content.sender_session_id - })) !== null && _createNewMatrixCall2 !== void 0 ? _createNewMatrixCall2 : undefined; - if (call) { - call.callId = content.call_id; - call.initWithHangup(event); - this.calls.set(content.call_id, call); - } - } else { - if (call.state !== _call.CallState.Ended) { - if (type === _event.EventType.CallHangup) { - call.onHangupReceived(content); - } else { - call.onRejectReceived(content); - } - - // @ts-expect-error typescript thinks the state can't be 'ended' because we're - // inside the if block where it wasn't, but it could have changed because - // on[Hangup|Reject]Received are side-effecty. - if (call.state === _call.CallState.Ended) this.calls.delete(content.call_id); - } - } - return; - } - - // The following events need a call and a peer connection - if (!call || !call.hasPeerConnection) { - _logger.logger.info(`CallEventHandler handleCallEvent() discarding possible call event as we don't have a call (type=${type})`); - return; - } - // Ignore remote echo - if (event.getContent().party_id === call.ourPartyId) return; - switch (type) { - case _event.EventType.CallAnswer: - if (weSentTheEvent) { - if (call.state === _call.CallState.Ringing) { - call.onAnsweredElsewhere(content); - } - } else { - call.onAnswerReceived(event); - } - break; - case _event.EventType.CallSelectAnswer: - call.onSelectAnswerReceived(event); - break; - case _event.EventType.CallNegotiate: - call.onNegotiateReceived(event); - break; - case _event.EventType.CallAssertedIdentity: - case _event.EventType.CallAssertedIdentityPrefix: - call.onAssertedIdentityReceived(event); - break; - case _event.EventType.CallSDPStreamMetadataChanged: - case _event.EventType.CallSDPStreamMetadataChangedPrefix: - call.onSDPStreamMetadataChangedReceived(event); - break; - } - } -} -exports.CallEventHandler = CallEventHandler; -//# sourceMappingURL=callEventHandler.js.map
\ No newline at end of file |