@webex/plugin-meetings 2.29.3 → 2.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","isBrowser","pc","insertBandwidthLimit","sdpLines","index","limit","periodicKeyFrame","search","AUDIO","StaticConfig","meetings","bandwidth","audio","video","SDP","PERIODIC_KEYFRAME","splice","B_LINE","setMaxFs","sdp","level","QUALITY_LEVELS","HIGH","MAX_FRAMESIZES","ParameterError","replaceSdp","maxFsLine","MAX_FS","replace","setStartBitrateOnRemoteSdp","startBitrate","checkH264Support","videoPresent","match","h264Present","isSdpInvalid","parsedSdp","sdpTransform","parse","media","mediaLine","candidates","length","LoggerProxy","logger","error","BAD_MEDIA_PORTS","includes","port","icePwd","iceUfrag","limitBandwidth","offerSdp","split","CARRIAGE_RETURN","i","M_LINE","join","setContentSlides","screenPc","A_CONTENT_SLIDES","iceCandidate","peerConnection","remoteQualityLevel","resolve","reject","now","doneGatheringIceCandidate","miliseconds","Math","abs","localDescription","PeerConnectionUtils","convertCLineToIpv4","invalidSdpPresent","InvalidSdpError","log","iceGatheringState","COMPLETE","onIceGatheringStateChange","GATHERING","onicecandidate","evt","candidate","type","protocol","address","onicecandidateerror","event","replaceTrack","track","senders","getSenders","forEach","sender","kind","err","addStream","stream","tracksPresent","find","getTracks","addTrack","setRemoteSessionDetails","typeStr","remoteSdp","meetingId","signalingState","Metrics","postEvent","eventType","REMOTE_SDP_RECEIVED","data","canProceed","errors","generateErrorPayload","name","MEDIA_ENGINE","HAVE_LOCAL_OFFER","STABLE","OFFER","enableExtmap","setRemoteDescription","window","RTCSessionDescription","then","catch","metricName","BEHAVIORAL_METRICS","PEERCONNECTION_FAILURE","correlation_id","reason","message","stack","metadata","sendBehavioralMetric","MediaError","createOffer","enableRtx","description","setLocalDescription","LOCAL_SDP_GENERATED","INVALID_ICE_CANDIDATE","code","close","rollBackLocalDescription","ROLLBACK","updatePeerConnection","params","createAnswer","peerconnection","HAVE_REMOTE_OFFER","sdpConstraints","answer","connectionState","PEER_CONNECTION_STATE","CLOSED","setPeerConnectionEvents","meeting","mediaProperties","connectionFailed","reconnectionManager","iceState","reconnect","networkDisconnect","ICE_END","uploadLogs","file","function","CONNECTION_FAILURE","correlationId","locus_id","locusId","oniceconnectionstatechange","info","iceConnectionState","ICE_STATE","CHECKING","ICE_START","COMPLETED","CONNECTED","CONNECTION_SUCCESS","setNetworkStatus","NETWORK_STATUS","iceReconnected","DISCONNECTED","waitForIceReconnect","FAILED","onconnectionstatechange","CONNECTION_STATE","NEW","CONNECTING"],"sources":["index.js"],"sourcesContent":["\n// We need to figure out how to pass a webex logger instance to these util files\n\n/* globals RTCSessionDescription */\n\nimport window from 'global/window';\nimport sdpTransform from 'sdp-transform'; // https://github.com/clux/sdp-transform\n\nimport Metrics from '../metrics';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport StaticConfig from '../common/config';\nimport {\n COMPLETE,\n GATHERING,\n AUDIO,\n SDP,\n ICE_STATE,\n CONNECTION_STATE,\n NETWORK_STATUS,\n PEER_CONNECTION_STATE,\n OFFER,\n QUALITY_LEVELS,\n MAX_FRAMESIZES\n} from '../constants';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport {error, eventType} from '../metrics/config';\nimport MediaError from '../common/errors/media';\nimport ParameterError from '../common/errors/parameter';\nimport {InvalidSdpError} from '../common/errors/webex-errors';\nimport BrowserDetection from '../common/browser-detection';\n\nimport PeerConnectionUtils from './util';\n\nconst {isBrowser} = BrowserDetection();\n\n/**\n * @export\n * @public\n */\nconst pc = {};\n\n/**\n * munges the bandwidth limit into the sdp\n * @param {String} sdpLines\n * @param {Number} index\n * @returns {String}\n */\nconst insertBandwidthLimit = (sdpLines, index) => {\n // eslint-disable-next-line no-warning-comments\n // TODO convert to sdp parser\n let limit;\n let periodicKeyFrame = '';\n\n if (sdpLines[index].search(AUDIO) !== -1) {\n limit = StaticConfig.meetings.bandwidth.audio;\n }\n else {\n limit = StaticConfig.meetings.bandwidth.video;\n periodicKeyFrame = SDP.PERIODIC_KEYFRAME;\n sdpLines.splice(index + 2, 0, periodicKeyFrame);\n }\n sdpLines.splice(index + 1, 0, `${SDP.B_LINE}:${limit}`);\n\n return sdpLines;\n};\n\n/**\n * needed for calliope max-fs\n * @param {String} sdp\n * @param {String} [level=QUALITY_LEVELS.HIGH] quality level for max-fs\n * @returns {String}\n */\nconst setMaxFs = (sdp, level = QUALITY_LEVELS.HIGH) => {\n if (!MAX_FRAMESIZES[level]) {\n throw new ParameterError(`setMaxFs: unable to set max framesize, value for level \"${level}\" is not defined`);\n }\n // eslint-disable-next-line no-warning-comments\n // TODO convert with sdp parser, no munging\n let replaceSdp = sdp;\n const maxFsLine = `${SDP.MAX_FS}${MAX_FRAMESIZES[level]}`;\n\n replaceSdp = replaceSdp.replace(/(\\na=fmtp:(\\d+).*profile-level-id=.*)/gi, `$1;${maxFsLine}`);\n\n return replaceSdp;\n};\n\n\nconst setStartBitrateOnRemoteSdp = (sdp) => {\n if (StaticConfig.meetings.bandwidth.startBitrate) {\n sdp = sdp.replace(/(\\na=fmtp:(\\d+).*profile-level-id=.*)/gi, `$1;x-google-start-bitrate=${StaticConfig.meetings.bandwidth.startBitrate}`);\n }\n\n return sdp;\n};\n\n/**\n * checks that sdp has h264 codec in it\n * @param {String} sdp\n * @returns {boolean}\n */\nconst checkH264Support = (sdp) => {\n // eslint-disable-next-line no-warning-comments\n // TODO convert to sdp parser to read rtp.codec\n const videoPresent = sdp.match(/\\nm=video.*/g);\n const h264Present = sdp.match(/\\na=rtpmap:\\d+\\sH264.*/g);\n\n if (videoPresent) {\n return !!h264Present;\n }\n\n return true;\n};\n\n/**\n * validates the sdp, checks port, candidates, and ice info\n * @param {String} sdp\n * @returns {String}\n */\nconst isSdpInvalid = (sdp) => {\n const parsedSdp = sdpTransform.parse(sdp);\n\n for (const mediaLine of parsedSdp.media) {\n if (!mediaLine.candidates || mediaLine.candidates?.length === 0) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Ice candadate never completed');\n\n return 'iceCandidate: Ice gathering never completed';\n }\n\n if (SDP.BAD_MEDIA_PORTS.includes(mediaLine.port)) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Found invalid port number for the ice candidate');\n\n return 'iceCandidate: Found invalid port number for the ice candidate';\n }\n if (!mediaLine.icePwd || !mediaLine.iceUfrag) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: ice ufrag and password not found');\n\n return 'iceCandidate: ice ufrag and password not found';\n }\n }\n\n return '';\n};\n\n/**\n * munges the bandwidth into the sdp\n * @param {String} sdp\n * @returns {String}\n */\nconst limitBandwidth = (sdp) => {\n // TODO convert to sdp parser\n let offerSdp = sdp;\n let sdpLines = offerSdp.split(SDP.CARRIAGE_RETURN);\n\n for (let i = 0; i < sdpLines.length; i += 1) {\n if (sdpLines[i].search(SDP.M_LINE) !== -1) {\n sdpLines = insertBandwidthLimit(sdpLines, i);\n }\n }\n offerSdp = sdpLines.join(SDP.CARRIAGE_RETURN);\n\n return offerSdp;\n};\n\n/**\n * makes sure the screen pc sdp has content:slides for server\n * @param {RTCPeerConnection} screenPc\n * @returns {RTCPeerConnection}\n */\npc.setContentSlides = (screenPc) => {\n if (screenPc && screenPc.sdp) {\n screenPc.sdp += `${SDP.A_CONTENT_SLIDES}${SDP.CARRIAGE_RETURN}`;\n }\n\n return screenPc;\n};\n\n/**\n * handles ice trickling and establishes ICE connection onto peer connection object\n * @param {Object} peerConnection\n * @param {Object} options\n * @param {String} options.remoteQualityLevel\n * @returns {Promise.RTCPeerConnection}\n */\npc.iceCandidate = (peerConnection, {remoteQualityLevel}) =>\n new Promise((resolve, reject) => {\n const now = Date.now();\n const doneGatheringIceCandidate = () => {\n const miliseconds = parseInt(Math.abs(Date.now() - now), 4);\n\n peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);\n peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);\n peerConnection.sdp = PeerConnectionUtils.convertCLineToIpv4(peerConnection.sdp);\n\n const invalidSdpPresent = isSdpInvalid(peerConnection.sdp);\n\n if (invalidSdpPresent) {\n LoggerProxy.logger.error('PeerConnectionManager:index#iceCandidate --> SDP not valid after waiting.');\n reject(new InvalidSdpError(invalidSdpPresent));\n }\n LoggerProxy.logger.log(`PeerConnectionManager:index#iceCandidate --> Time to gather ice candidate ${miliseconds} miliseconds`);\n\n\n resolve();\n };\n\n // If ice has already been gathered\n if (peerConnection.iceGatheringState === COMPLETE) {\n doneGatheringIceCandidate();\n }\n\n peerConnection.onIceGatheringStateChange = () => {\n if (peerConnection.iceGatheringState === COMPLETE) {\n doneGatheringIceCandidate(peerConnection);\n }\n if (peerConnection.iceGatheringState === GATHERING) {\n LoggerProxy.logger.log('PeerConnectionManager:index#onIceGatheringStateChange --> Ice state changed to gathering');\n }\n };\n\n peerConnection.onicecandidate = (evt) => {\n if (evt.candidate === null) {\n doneGatheringIceCandidate(peerConnection);\n }\n else {\n LoggerProxy.logger.log(`PeerConnectionManager:index#onicecandidate --> Candidate ${evt.candidate?.type} ${evt.candidate?.protocol} ${evt.candidate?.address}:${evt.candidate?.port}`);\n }\n };\n\n peerConnection.onicecandidateerror = (event) => {\n // we can often get ICE candidate errors (for example when failing to communicate with a TURN server)\n // they don't mean that the whole ICE connection will fail, so it's OK to ignore them\n LoggerProxy.logger.error('PeerConnectionManager:index#onicecandidateerror --> ignoring ice error:', event);\n };\n });\n\n/**\n * swapping tracks\n * @param {Object} peerConnection\n * @param {Object} track\n * @returns {undefined}\n */\npc.replaceTrack = (peerConnection, track) => {\n try {\n const senders = peerConnection.getSenders();\n\n if (senders.length > 0) {\n senders.forEach((sender) => {\n if (sender.track && sender.track.kind === track.kind) {\n sender.replaceTrack(track);\n }\n });\n }\n }\n catch (err) {\n LoggerProxy.logger.error(`PeerConnectionManager:index#replaceTrack --> Error replacing track, ${err}`);\n }\n};\n\n/**\n * adding streams to peerConnection\n * @param {Object} peerConnection\n * @param {Object} stream\n * @returns {undefined}\n */\npc.addStream = (peerConnection, stream) => {\n try {\n if (stream && !isBrowser('edge')) {\n const tracksPresent = peerConnection.getSenders && peerConnection.getSenders().find((sender) => sender.track != null);\n\n if (tracksPresent) {\n stream.getTracks().forEach((track) => {\n pc.replaceTrack(peerConnection, track);\n });\n\n return;\n }\n stream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, stream);\n });\n // // TODO : may come back disable addTracks for chrome they are moving back to addStream\n // // https://bugs.chromium.org/p/chromium/issues/detail?id=764414\n // // https://bugs.chromium.org/p/chromium/issues/detail?id=738918#c7\n // peerConnection.addStream(stream);\n }\n else if (isBrowser('edge')) {\n peerConnection.addStream(stream);\n }\n }\n catch (err) {\n LoggerProxy.logger.error(`PeerConnectionManager:index#addStream --> Error adding stream, error: ${error}`);\n }\n};\n\n/**\n * setting the remote description\n * @param {Object} peerConnection\n * @param {String} typeStr\n * @param {String} remoteSdp\n * @param {String} meetingId\n * @returns {undefined}\n */\npc.setRemoteSessionDetails = (\n peerConnection,\n typeStr,\n remoteSdp,\n meetingId,\n) => {\n LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);\n let sdp = remoteSdp;\n\n // making sure that the remoteDescription is only set when there is a answer for offer\n // or there is a offer from the server\n\n if (!sdp) {\n Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId,\n data: {\n canProceed: false,\n errors: [Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE, 'missing remoteSdp')]\n }\n });\n }\n if (peerConnection.signalingState === SDP.HAVE_LOCAL_OFFER || (peerConnection.signalingState === SDP.STABLE && typeStr === SDP.OFFER)) {\n sdp = setStartBitrateOnRemoteSdp(sdp);\n\n if (!peerConnection.enableExtmap) {\n sdp = sdp.replace(/\\na=extmap.*/g, '');\n }\n\n // remove any xtls candidates\n sdp = sdp.replace(/^a=candidate:.*xTLS.*\\r\\n/gim, '');\n\n return peerConnection.setRemoteDescription(\n new window.RTCSessionDescription({\n type: typeStr,\n sdp\n })\n )\n .then(() => {\n if (peerConnection.signalingState === SDP.STABLE) {\n Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId\n });\n }\n })\n .catch((error) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#setRemoteDescription --> ${error} missing remotesdp`);\n\n\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n\n return Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId,\n data: {\n canProceed: false,\n errors: [Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE, 'missing remoteSdp')]\n }\n });\n });\n }\n\n return Promise.reject(new MediaError('PeerConnection in wrong state'));\n};\n\n/**\n * create offer with a valid paramater\n * @param {Object} peerConnection\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @param {string} meetingProperties.enableRtx\n * @param {string} meetingProperties.enableExtmap\n * @returns {RTCPeerConnection}\n */\npc.createOffer = (peerConnection, {\n meetingId,\n remoteQualityLevel,\n enableRtx,\n enableExtmap\n}) => {\n LoggerProxy.logger.log('PeerConnectionManager:index#createOffer --> creating a new offer');\n\n // saving the extMap State to use in setRemoteDescription\n\n peerConnection.enableExtmap = enableExtmap;\n\n return peerConnection\n .createOffer()\n .then((description) => {\n // bug https://bugs.chromium.org/p/chromium/issues/detail?id=1020642\n // chrome currently generates RTX line irrespective of weither the server side supports it\n // we are removing apt as well because its associated with rtx line\n\n if (!enableRtx) {\n description.sdp = description.sdp.replace(/\\r\\na=rtpmap:\\d+ rtx\\/\\d+/g, '');\n description.sdp = description.sdp.replace(/\\r\\na=fmtp:\\d+ apt=\\d+/g, '');\n }\n\n return peerConnection.setLocalDescription(description);\n })\n .then(() => pc.iceCandidate(peerConnection, {remoteQualityLevel}))\n .then(() => {\n if (!checkH264Support(peerConnection.sdp)) {\n throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');\n }\n\n if (!enableExtmap) {\n peerConnection.sdp = peerConnection.sdp.replace(/\\na=extmap.*/g, '');\n }\n\n pc.setContentSlides(peerConnection);\n\n Metrics.postEvent({\n event: eventType.LOCAL_SDP_GENERATED,\n meetingId\n });\n\n return peerConnection;\n })\n .catch((error) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#createOffer --> ${error}`);\n if (error instanceof InvalidSdpError) {\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE,\n {\n correlation_id: meetingId,\n code: error.code,\n reason: error.message\n }\n );\n }\n else {\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n }\n\n Metrics.postEvent({\n event: eventType.LOCAL_SDP_GENERATED,\n meetingId,\n data: {\n canProceed: false,\n errors: [\n Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE)]\n }\n });\n pc.close(peerConnection);\n throw error;\n });\n};\n\n/**\n * rollBack local description in peerconnection\n * @param {Object} peerConnection\n * @returns {Promise.RTCPeerConnection}\n */\npc.rollBackLocalDescription = (peerConnection) => peerConnection\n .setLocalDescription(new RTCSessionDescription({type: SDP.ROLLBACK}))\n .then(() => peerConnection)\n .catch((err) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#setLocalDescription --> ${err} `);\n\n return Promise.error(err);\n });\n\n/**\n * @param {Object} params {\n * @param {Boolean} params.offerToReceiveAudio\n * @param {Boolean} params.offerToReceiveVideo\n * @param {string} params.offerSdp\n * @param {MediaStream} params.stream\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @returns {Promise.<Array>} [MediaSDP, ScreenSDP]\n */\npc.updatePeerConnection = (params, {meetingId, remoteQualityLevel}) => {\n LoggerProxy.logger.log(`PeerConnectionManager:index#updatePeerConnection --> updating the peerConnection with params: ${params}`);\n\n const {peerConnection, offerSdp} = params;\n\n return pc.createAnswer({\n peerConnection,\n offerSdp: offerSdp[0]\n }, {meetingId, remoteQualityLevel}).then((peerconnection) => {\n // The content slides should also be set when we are sending inactive\n pc.setContentSlides(peerconnection);\n\n return Promise.resolve([peerconnection.sdp]);\n });\n};\n\n/**\n * @param {Object} params\n * @param {Object} params.peerConnection\n * @param {Object} params.sdpConstraints\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @returns {RTCPeerConnection} peerConnection\n */\npc.createAnswer = (params, {meetingId, remoteQualityLevel}) => {\n const {peerConnection} = params;\n\n // TODO: Some times to many mercury event comes at the same time\n // Need to maintain state of peerconnection\n if (peerConnection.signalingState === SDP.HAVE_REMOTE_OFFER) {\n return Promise.resolve(peerConnection);\n }\n\n return pc.setRemoteSessionDetails(peerConnection, OFFER, params.offerSdp, meetingId)\n .then(() => peerConnection.createAnswer(params.sdpConstraints))\n .then((answer) =>\n\n peerConnection.setLocalDescription(answer))\n .then(() => pc.iceCandidate(peerConnection, {remoteQualityLevel}))\n .then(() => {\n peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);\n peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);\n peerConnection.sdp = PeerConnectionUtils.convertCLineToIpv4(peerConnection.sdp);\n if (!checkH264Support(peerConnection.sdp)) {\n throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');\n }\n\n return peerConnection;\n })\n .catch((error) => {\n if (error instanceof InvalidSdpError) {\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE,\n {\n correlation_id: meetingId\n }\n );\n }\n else {\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n }\n\n LoggerProxy.logger.error(`PeerConnectionManager:index#setRemoteSessionDetails --> Error creating remote session, error: ${error}`);\n });\n};\n\n/**\n * shut down the peer connection\n * @param {Object} peerConnection\n * @returns {undefined}\n */\npc.close = (peerConnection) => {\n // peerConnection.close() fails on firefox on network changes and gives a Dom exception\n // To avoid this we have added a try catch block.\n // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=1274407 for more information\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> attempting to close the peer connection');\n\n if (peerConnection && peerConnection.connectionState === PEER_CONNECTION_STATE.CLOSED) {\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> connection already closed');\n\n return Promise.resolve();\n }\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> closing the mediaPeerConnection');\n\n return Promise.resolve()\n .then(() => {\n if (peerConnection && peerConnection.close) {\n peerConnection.close();\n }\n });\n};\n\n\npc.setPeerConnectionEvents = (meeting) => {\n // In case ICE fail\n const {peerConnection} = meeting.mediaProperties;\n\n const connectionFailed = () => {\n if (meeting.reconnectionManager.iceState.resolve) {\n // DISCONNECTED state triggers first then it goes to FAILED STATE\n // sometimes the failed state can happen before 10 seconds (Which is the timer for the reconnect for ice disconnect)\n meeting.reconnectionManager.iceState.resolve();\n }\n\n meeting.reconnect({networkDisconnect: true});\n Metrics.postEvent({\n event: eventType.ICE_END,\n meeting,\n data: {\n canProceed: false,\n errors: [\n Metrics.generateErrorPayload(\n 2004, false, error.name.MEDIA_ENGINE\n )]\n }\n });\n\n meeting.uploadLogs({\n file: 'peer-connection-manager/index',\n function: 'connectionFailed'\n });\n\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.CONNECTION_FAILURE,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusId\n }\n );\n };\n\n peerConnection.oniceconnectionstatechange = () => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CHANGE.');\n switch (peerConnection.iceConnectionState) {\n case ICE_STATE.CHECKING:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CHECKING.');\n Metrics.postEvent({event: eventType.ICE_START, meeting});\n break;\n case ICE_STATE.COMPLETED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE COMPLETED.');\n break;\n case ICE_STATE.CONNECTED:\n // Ice connection state goes to connected when both client and server sends STUN packets and\n // Established connected between them. Firefox does not trigger COMPLETED and only trigger CONNECTED\n Metrics.postEvent({event: eventType.ICE_END, meeting});\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.CONNECTION_SUCCESS,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusId\n }\n );\n meeting.setNetworkStatus(NETWORK_STATUS.CONNECTED);\n meeting.reconnectionManager.iceReconnected();\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CONNECTED.');\n break;\n case ICE_STATE.CLOSED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CLOSED.');\n break;\n case ICE_STATE.DISCONNECTED:\n meeting.setNetworkStatus(NETWORK_STATUS.DISCONNECTED);\n meeting.reconnectionManager.waitForIceReconnect()\n .catch(() => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE DISCONNECTED. Automatic Reconnection Timed Out.');\n\n connectionFailed();\n });\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE DISCONNECTED.');\n break;\n case ICE_STATE.FAILED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE FAILED.');\n // notify of ice failure\n // Ice failure is the only indicator currently for identifying the actual connection drop\n // Firefox takes sometime 10-15 seconds to go to failed state\n connectionFailed();\n break;\n default:\n break;\n }\n };\n\n peerConnection.onconnectionstatechange = () => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CHANGE.');\n switch (peerConnection.connectionState) {\n case CONNECTION_STATE.NEW:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE NEW.');\n break;\n case CONNECTION_STATE.CONNECTING:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CONNECTING.');\n break;\n case CONNECTION_STATE.CONNECTED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CONNECTED.');\n break;\n case CONNECTION_STATE.CLOSED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CLOSED.');\n break;\n case CONNECTION_STATE.DISCONNECTED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE DISCONNECTED.');\n break;\n case CONNECTION_STATE.FAILED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE FAILED.');\n // Special case happens only on chrome where there is no ICE FAILED event\n // only CONNECTION FAILED event gets triggered\n\n connectionFailed();\n break;\n default:\n break;\n }\n };\n};\n\nexport default pc;\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","isBrowser","pc","insertBandwidthLimit","sdpLines","index","limit","periodicKeyFrame","search","AUDIO","StaticConfig","meetings","bandwidth","audio","video","SDP","PERIODIC_KEYFRAME","splice","B_LINE","setMaxFs","sdp","level","QUALITY_LEVELS","HIGH","MAX_FRAMESIZES","ParameterError","replaceSdp","maxFsLine","MAX_FS","replace","setStartBitrateOnRemoteSdp","startBitrate","checkH264Support","videoPresent","match","h264Present","isSdpInvalid","parsedSdp","sdpTransform","parse","media","mediaLine","candidates","length","LoggerProxy","logger","error","BAD_MEDIA_PORTS","includes","port","icePwd","iceUfrag","limitBandwidth","offerSdp","split","CARRIAGE_RETURN","i","M_LINE","join","setContentSlides","screenPc","A_CONTENT_SLIDES","iceCandidate","peerConnection","remoteQualityLevel","resolve","reject","now","doneGatheringIceCandidate","miliseconds","Math","abs","localDescription","PeerConnectionUtils","convertCLineToIpv4","invalidSdpPresent","InvalidSdpError","log","iceGatheringState","COMPLETE","onIceGatheringStateChange","GATHERING","onicecandidate","evt","candidate","type","protocol","address","onicecandidateerror","event","replaceTrack","track","senders","getSenders","forEach","sender","kind","err","addStream","stream","tracksPresent","find","getTracks","addTrack","setRemoteSessionDetails","typeStr","remoteSdp","meetingId","signalingState","Metrics","postEvent","eventType","REMOTE_SDP_RECEIVED","data","canProceed","errors","generateErrorPayload","name","MEDIA_ENGINE","HAVE_LOCAL_OFFER","STABLE","OFFER","enableExtmap","setRemoteDescription","window","RTCSessionDescription","then","catch","metricName","BEHAVIORAL_METRICS","PEERCONNECTION_FAILURE","correlation_id","reason","message","stack","metadata","sendBehavioralMetric","MediaError","createOffer","enableRtx","description","setLocalDescription","LOCAL_SDP_GENERATED","INVALID_ICE_CANDIDATE","code","close","rollBackLocalDescription","ROLLBACK","updatePeerConnection","params","createAnswer","peerconnection","HAVE_REMOTE_OFFER","sdpConstraints","answer","connectionState","PEER_CONNECTION_STATE","CLOSED","setPeerConnectionEvents","meeting","mediaProperties","connectionFailed","reconnectionManager","iceState","reconnect","networkDisconnect","ICE_END","uploadLogs","file","function","CONNECTION_FAILURE","correlationId","locus_id","locusId","oniceconnectionstatechange","info","iceConnectionState","ICE_STATE","CHECKING","ICE_START","COMPLETED","CONNECTED","CONNECTION_SUCCESS","setNetworkStatus","NETWORK_STATUS","iceReconnected","DISCONNECTED","waitForIceReconnect","FAILED","onconnectionstatechange","CONNECTION_STATE","NEW","CONNECTING"],"sources":["index.js"],"sourcesContent":["\n// We need to figure out how to pass a webex logger instance to these util files\n\n/* globals RTCSessionDescription */\n\nimport window from 'global/window';\nimport sdpTransform from 'sdp-transform'; // https://github.com/clux/sdp-transform\n\nimport Metrics from '../metrics';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport StaticConfig from '../common/config';\nimport {\n COMPLETE,\n GATHERING,\n AUDIO,\n SDP,\n ICE_STATE,\n CONNECTION_STATE,\n NETWORK_STATUS,\n PEER_CONNECTION_STATE,\n OFFER,\n QUALITY_LEVELS,\n MAX_FRAMESIZES\n} from '../constants';\nimport BEHAVIORAL_METRICS from '../metrics/constants';\nimport {error, eventType} from '../metrics/config';\nimport MediaError from '../common/errors/media';\nimport ParameterError from '../common/errors/parameter';\nimport {InvalidSdpError} from '../common/errors/webex-errors';\nimport BrowserDetection from '../common/browser-detection';\n\nimport PeerConnectionUtils from './util';\n\nconst {isBrowser} = BrowserDetection();\n\n/**\n * @export\n * @public\n */\nconst pc = {};\n\n/**\n * munges the bandwidth limit into the sdp\n * @param {String} sdpLines\n * @param {Number} index\n * @returns {String}\n */\nconst insertBandwidthLimit = (sdpLines, index) => {\n // eslint-disable-next-line no-warning-comments\n // TODO convert to sdp parser\n let limit;\n let periodicKeyFrame = '';\n\n if (sdpLines[index].search(AUDIO) !== -1) {\n limit = StaticConfig.meetings.bandwidth.audio;\n }\n else {\n limit = StaticConfig.meetings.bandwidth.video;\n periodicKeyFrame = SDP.PERIODIC_KEYFRAME;\n sdpLines.splice(index + 2, 0, periodicKeyFrame);\n }\n sdpLines.splice(index + 1, 0, `${SDP.B_LINE}:${limit}`);\n\n return sdpLines;\n};\n\n/**\n * needed for calliope max-fs\n * @param {String} sdp\n * @param {String} [level=QUALITY_LEVELS.HIGH] quality level for max-fs\n * @returns {String}\n */\nconst setMaxFs = (sdp, level = QUALITY_LEVELS.HIGH) => {\n if (!MAX_FRAMESIZES[level]) {\n throw new ParameterError(`setMaxFs: unable to set max framesize, value for level \"${level}\" is not defined`);\n }\n // eslint-disable-next-line no-warning-comments\n // TODO convert with sdp parser, no munging\n let replaceSdp = sdp;\n const maxFsLine = `${SDP.MAX_FS}${MAX_FRAMESIZES[level]}`;\n\n replaceSdp = replaceSdp.replace(/(\\na=fmtp:(\\d+).*profile-level-id=.*)/gi, `$1;${maxFsLine}`);\n\n return replaceSdp;\n};\n\n\nconst setStartBitrateOnRemoteSdp = (sdp) => {\n if (StaticConfig.meetings.bandwidth.startBitrate) {\n sdp = sdp.replace(/(\\na=fmtp:(\\d+).*profile-level-id=.*)/gi, `$1;x-google-start-bitrate=${StaticConfig.meetings.bandwidth.startBitrate}`);\n }\n\n return sdp;\n};\n\n/**\n * checks that sdp has h264 codec in it\n * @param {String} sdp\n * @returns {boolean}\n */\nconst checkH264Support = (sdp) => {\n // eslint-disable-next-line no-warning-comments\n // TODO convert to sdp parser to read rtp.codec\n const videoPresent = sdp.match(/\\nm=video.*/g);\n const h264Present = sdp.match(/\\na=rtpmap:\\d+\\sH264.*/g);\n\n if (videoPresent) {\n return !!h264Present;\n }\n\n return true;\n};\n\n/**\n * validates the sdp, checks port, candidates, and ice info\n * @param {String} sdp\n * @returns {String}\n */\nconst isSdpInvalid = (sdp) => {\n const parsedSdp = sdpTransform.parse(sdp);\n\n for (const mediaLine of parsedSdp.media) {\n if (!mediaLine.candidates || mediaLine.candidates?.length === 0) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Ice candidate never completed');\n\n return 'iceCandidate: Ice gathering never completed';\n }\n\n if (SDP.BAD_MEDIA_PORTS.includes(mediaLine.port)) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Found invalid port number for the ice candidate');\n\n return 'iceCandidate: Found invalid port number for the ice candidate';\n }\n if (!mediaLine.icePwd || !mediaLine.iceUfrag) {\n LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: ice ufrag and password not found');\n\n return 'iceCandidate: ice ufrag and password not found';\n }\n }\n\n return '';\n};\n\n/**\n * munges the bandwidth into the sdp\n * @param {String} sdp\n * @returns {String}\n */\nconst limitBandwidth = (sdp) => {\n // TODO convert to sdp parser\n let offerSdp = sdp;\n let sdpLines = offerSdp.split(SDP.CARRIAGE_RETURN);\n\n for (let i = 0; i < sdpLines.length; i += 1) {\n if (sdpLines[i].search(SDP.M_LINE) !== -1) {\n sdpLines = insertBandwidthLimit(sdpLines, i);\n }\n }\n offerSdp = sdpLines.join(SDP.CARRIAGE_RETURN);\n\n return offerSdp;\n};\n\n/**\n * makes sure the screen pc sdp has content:slides for server\n * @param {RTCPeerConnection} screenPc\n * @returns {RTCPeerConnection}\n */\npc.setContentSlides = (screenPc) => {\n if (screenPc && screenPc.sdp) {\n screenPc.sdp += `${SDP.A_CONTENT_SLIDES}${SDP.CARRIAGE_RETURN}`;\n }\n\n return screenPc;\n};\n\n/**\n * handles ice trickling and establishes ICE connection onto peer connection object\n * @param {Object} peerConnection\n * @param {Object} options\n * @param {String} options.remoteQualityLevel\n * @returns {Promise.RTCPeerConnection}\n */\npc.iceCandidate = (peerConnection, {remoteQualityLevel}) =>\n new Promise((resolve, reject) => {\n const now = Date.now();\n const doneGatheringIceCandidate = () => {\n const miliseconds = parseInt(Math.abs(Date.now() - now), 4);\n\n peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);\n peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);\n peerConnection.sdp = PeerConnectionUtils.convertCLineToIpv4(peerConnection.sdp);\n\n const invalidSdpPresent = isSdpInvalid(peerConnection.sdp);\n\n if (invalidSdpPresent) {\n LoggerProxy.logger.error('PeerConnectionManager:index#iceCandidate --> SDP not valid after waiting.');\n reject(new InvalidSdpError(invalidSdpPresent));\n }\n LoggerProxy.logger.log(`PeerConnectionManager:index#iceCandidate --> Time to gather ice candidate ${miliseconds} miliseconds`);\n\n\n resolve();\n };\n\n // If ice has already been gathered\n if (peerConnection.iceGatheringState === COMPLETE) {\n doneGatheringIceCandidate();\n }\n\n peerConnection.onIceGatheringStateChange = () => {\n if (peerConnection.iceGatheringState === COMPLETE) {\n doneGatheringIceCandidate(peerConnection);\n }\n if (peerConnection.iceGatheringState === GATHERING) {\n LoggerProxy.logger.log('PeerConnectionManager:index#onIceGatheringStateChange --> Ice state changed to gathering');\n }\n };\n\n peerConnection.onicecandidate = (evt) => {\n if (evt.candidate === null) {\n doneGatheringIceCandidate(peerConnection);\n }\n else {\n LoggerProxy.logger.log(`PeerConnectionManager:index#onicecandidate --> Candidate ${evt.candidate?.type} ${evt.candidate?.protocol} ${evt.candidate?.address}:${evt.candidate?.port}`);\n }\n };\n\n peerConnection.onicecandidateerror = (event) => {\n // we can often get ICE candidate errors (for example when failing to communicate with a TURN server)\n // they don't mean that the whole ICE connection will fail, so it's OK to ignore them\n LoggerProxy.logger.error('PeerConnectionManager:index#onicecandidateerror --> ignoring ice error:', event);\n };\n });\n\n/**\n * swapping tracks\n * @param {Object} peerConnection\n * @param {Object} track\n * @returns {undefined}\n */\npc.replaceTrack = (peerConnection, track) => {\n try {\n const senders = peerConnection.getSenders();\n\n if (senders.length > 0) {\n senders.forEach((sender) => {\n if (sender.track && sender.track.kind === track.kind) {\n sender.replaceTrack(track);\n }\n });\n }\n }\n catch (err) {\n LoggerProxy.logger.error(`PeerConnectionManager:index#replaceTrack --> Error replacing track, ${err}`);\n }\n};\n\n/**\n * adding streams to peerConnection\n * @param {Object} peerConnection\n * @param {Object} stream\n * @returns {undefined}\n */\npc.addStream = (peerConnection, stream) => {\n try {\n if (stream && !isBrowser('edge')) {\n const tracksPresent = peerConnection.getSenders && peerConnection.getSenders().find((sender) => sender.track != null);\n\n if (tracksPresent) {\n stream.getTracks().forEach((track) => {\n pc.replaceTrack(peerConnection, track);\n });\n\n return;\n }\n stream.getTracks().forEach((track) => {\n peerConnection.addTrack(track, stream);\n });\n // // TODO : may come back disable addTracks for chrome they are moving back to addStream\n // // https://bugs.chromium.org/p/chromium/issues/detail?id=764414\n // // https://bugs.chromium.org/p/chromium/issues/detail?id=738918#c7\n // peerConnection.addStream(stream);\n }\n else if (isBrowser('edge')) {\n peerConnection.addStream(stream);\n }\n }\n catch (err) {\n LoggerProxy.logger.error(`PeerConnectionManager:index#addStream --> Error adding stream, error: ${error}`);\n }\n};\n\n/**\n * setting the remote description\n * @param {Object} peerConnection\n * @param {String} typeStr\n * @param {String} remoteSdp\n * @param {String} meetingId\n * @returns {undefined}\n */\npc.setRemoteSessionDetails = (\n peerConnection,\n typeStr,\n remoteSdp,\n meetingId,\n) => {\n LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);\n let sdp = remoteSdp;\n\n // making sure that the remoteDescription is only set when there is a answer for offer\n // or there is a offer from the server\n\n if (!sdp) {\n Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId,\n data: {\n canProceed: false,\n errors: [Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE, 'missing remoteSdp')]\n }\n });\n }\n if (peerConnection.signalingState === SDP.HAVE_LOCAL_OFFER || (peerConnection.signalingState === SDP.STABLE && typeStr === SDP.OFFER)) {\n sdp = setStartBitrateOnRemoteSdp(sdp);\n\n if (!peerConnection.enableExtmap) {\n sdp = sdp.replace(/\\na=extmap.*/g, '');\n }\n\n // remove any xtls candidates\n sdp = sdp.replace(/^a=candidate:.*xTLS.*\\r\\n/gim, '');\n\n return peerConnection.setRemoteDescription(\n new window.RTCSessionDescription({\n type: typeStr,\n sdp\n })\n )\n .then(() => {\n if (peerConnection.signalingState === SDP.STABLE) {\n Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId\n });\n }\n })\n .catch((error) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#setRemoteDescription --> ${error} missing remotesdp`);\n\n\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n\n return Metrics.postEvent({\n event: eventType.REMOTE_SDP_RECEIVED,\n meetingId,\n data: {\n canProceed: false,\n errors: [Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE, 'missing remoteSdp')]\n }\n });\n });\n }\n\n return Promise.reject(new MediaError('PeerConnection in wrong state'));\n};\n\n/**\n * Create offer with a valid parameter\n * @param {Object} peerConnection\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @param {string} meetingProperties.enableRtx\n * @param {string} meetingProperties.enableExtmap\n * @returns {RTCPeerConnection}\n */\npc.createOffer = (peerConnection, {\n meetingId,\n remoteQualityLevel,\n enableRtx,\n enableExtmap\n}) => {\n LoggerProxy.logger.log('PeerConnectionManager:index#createOffer --> creating a new offer');\n\n // saving the extMap State to use in setRemoteDescription\n\n peerConnection.enableExtmap = enableExtmap;\n\n return peerConnection\n .createOffer()\n .then((description) => {\n // bug https://bugs.chromium.org/p/chromium/issues/detail?id=1020642\n // chrome currently generates RTX line irrespective of whether the server side supports it\n // we are removing apt as well because its associated with rtx line\n\n if (!enableRtx) {\n description.sdp = description.sdp.replace(/\\r\\na=rtpmap:\\d+ rtx\\/\\d+/g, '');\n description.sdp = description.sdp.replace(/\\r\\na=fmtp:\\d+ apt=\\d+/g, '');\n }\n\n return peerConnection.setLocalDescription(description);\n })\n .then(() => pc.iceCandidate(peerConnection, {remoteQualityLevel}))\n .then(() => {\n if (!checkH264Support(peerConnection.sdp)) {\n throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');\n }\n\n if (!enableExtmap) {\n peerConnection.sdp = peerConnection.sdp.replace(/\\na=extmap.*/g, '');\n }\n\n pc.setContentSlides(peerConnection);\n\n Metrics.postEvent({\n event: eventType.LOCAL_SDP_GENERATED,\n meetingId\n });\n\n return peerConnection;\n })\n .catch((error) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#createOffer --> ${error}`);\n if (error instanceof InvalidSdpError) {\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE,\n {\n correlation_id: meetingId,\n code: error.code,\n reason: error.message\n }\n );\n }\n else {\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n }\n\n Metrics.postEvent({\n event: eventType.LOCAL_SDP_GENERATED,\n meetingId,\n data: {\n canProceed: false,\n errors: [\n Metrics.generateErrorPayload(2001, true,\n error.name.MEDIA_ENGINE)]\n }\n });\n pc.close(peerConnection);\n throw error;\n });\n};\n\n/**\n * rollBack local description in peerconnection\n * @param {Object} peerConnection\n * @returns {Promise.RTCPeerConnection}\n */\npc.rollBackLocalDescription = (peerConnection) => peerConnection\n .setLocalDescription(new RTCSessionDescription({type: SDP.ROLLBACK}))\n .then(() => peerConnection)\n .catch((err) => {\n LoggerProxy.logger.error(`Peer-connection-manager:index#setLocalDescription --> ${err} `);\n\n return Promise.error(err);\n });\n\n/**\n * @param {Object} params {\n * @param {Boolean} params.offerToReceiveAudio\n * @param {Boolean} params.offerToReceiveVideo\n * @param {string} params.offerSdp\n * @param {MediaStream} params.stream\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @returns {Promise.<Array>} [MediaSDP, ScreenSDP]\n */\npc.updatePeerConnection = (params, {meetingId, remoteQualityLevel}) => {\n LoggerProxy.logger.log(`PeerConnectionManager:index#updatePeerConnection --> updating the peerConnection with params: ${params}`);\n\n const {peerConnection, offerSdp} = params;\n\n return pc.createAnswer({\n peerConnection,\n offerSdp: offerSdp[0]\n }, {meetingId, remoteQualityLevel}).then((peerconnection) => {\n // The content slides should also be set when we are sending inactive\n pc.setContentSlides(peerconnection);\n\n return Promise.resolve([peerconnection.sdp]);\n });\n};\n\n/**\n * @param {Object} params\n * @param {Object} params.peerConnection\n * @param {Object} params.sdpConstraints\n * @param {Object} meetingProperties\n * @param {string} meetingProperties.meetingId\n * @param {string} meetingProperties.remoteQualityLevel LOW|MEDIUM|HIGH\n * @returns {RTCPeerConnection} peerConnection\n */\npc.createAnswer = (params, {meetingId, remoteQualityLevel}) => {\n const {peerConnection} = params;\n\n // TODO: Some times to many mercury event comes at the same time\n // Need to maintain state of peerconnection\n if (peerConnection.signalingState === SDP.HAVE_REMOTE_OFFER) {\n return Promise.resolve(peerConnection);\n }\n\n return pc.setRemoteSessionDetails(peerConnection, OFFER, params.offerSdp, meetingId)\n .then(() => peerConnection.createAnswer(params.sdpConstraints))\n .then((answer) =>\n\n peerConnection.setLocalDescription(answer))\n .then(() => pc.iceCandidate(peerConnection, {remoteQualityLevel}))\n .then(() => {\n peerConnection.sdp = limitBandwidth(peerConnection.localDescription.sdp);\n peerConnection.sdp = setMaxFs(peerConnection.sdp, remoteQualityLevel);\n peerConnection.sdp = PeerConnectionUtils.convertCLineToIpv4(peerConnection.sdp);\n if (!checkH264Support(peerConnection.sdp)) {\n throw new MediaError('openH264 is downloading please Wait. Upload logs if not working on second try');\n }\n\n return peerConnection;\n })\n .catch((error) => {\n if (error instanceof InvalidSdpError) {\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE,\n {\n correlation_id: meetingId\n }\n );\n }\n else {\n const metricName = BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE;\n const data = {\n correlation_id: meetingId,\n reason: error.message,\n stack: error.stack\n };\n const metadata = {\n type: error.name\n };\n\n Metrics.sendBehavioralMetric(metricName, data, metadata);\n }\n\n LoggerProxy.logger.error(`PeerConnectionManager:index#setRemoteSessionDetails --> Error creating remote session, error: ${error}`);\n });\n};\n\n/**\n * shut down the peer connection\n * @param {Object} peerConnection\n * @returns {undefined}\n */\npc.close = (peerConnection) => {\n // peerConnection.close() fails on firefox on network changes and gives a Dom exception\n // To avoid this we have added a try catch block.\n // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=1274407 for more information\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> attempting to close the peer connection');\n\n if (peerConnection && peerConnection.connectionState === PEER_CONNECTION_STATE.CLOSED) {\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> connection already closed');\n\n return Promise.resolve();\n }\n LoggerProxy.logger.log('PeerConnectionManager:index#close --> pc: close() -> closing the mediaPeerConnection');\n\n return Promise.resolve()\n .then(() => {\n if (peerConnection && peerConnection.close) {\n peerConnection.close();\n }\n });\n};\n\n\npc.setPeerConnectionEvents = (meeting) => {\n // In case ICE fail\n const {peerConnection} = meeting.mediaProperties;\n\n const connectionFailed = () => {\n if (meeting.reconnectionManager.iceState.resolve) {\n // DISCONNECTED state triggers first then it goes to FAILED STATE\n // sometimes the failed state can happen before 10 seconds (Which is the timer for the reconnect for ice disconnect)\n meeting.reconnectionManager.iceState.resolve();\n }\n\n meeting.reconnect({networkDisconnect: true});\n Metrics.postEvent({\n event: eventType.ICE_END,\n meeting,\n data: {\n canProceed: false,\n errors: [\n Metrics.generateErrorPayload(\n 2004, false, error.name.MEDIA_ENGINE\n )]\n }\n });\n\n meeting.uploadLogs({\n file: 'peer-connection-manager/index',\n function: 'connectionFailed'\n });\n\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.CONNECTION_FAILURE,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusId\n }\n );\n };\n\n peerConnection.oniceconnectionstatechange = () => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CHANGE.');\n switch (peerConnection.iceConnectionState) {\n case ICE_STATE.CHECKING:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CHECKING.');\n Metrics.postEvent({event: eventType.ICE_START, meeting});\n break;\n case ICE_STATE.COMPLETED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE COMPLETED.');\n break;\n case ICE_STATE.CONNECTED:\n // Ice connection state goes to connected when both client and server sends STUN packets and\n // Established connected between them. Firefox does not trigger COMPLETED and only trigger CONNECTED\n Metrics.postEvent({event: eventType.ICE_END, meeting});\n Metrics.sendBehavioralMetric(\n BEHAVIORAL_METRICS.CONNECTION_SUCCESS,\n {\n correlation_id: meeting.correlationId,\n locus_id: meeting.locusId\n }\n );\n meeting.setNetworkStatus(NETWORK_STATUS.CONNECTED);\n meeting.reconnectionManager.iceReconnected();\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CONNECTED.');\n break;\n case ICE_STATE.CLOSED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE CLOSED.');\n break;\n case ICE_STATE.DISCONNECTED:\n meeting.setNetworkStatus(NETWORK_STATUS.DISCONNECTED);\n meeting.reconnectionManager.waitForIceReconnect()\n .catch(() => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE DISCONNECTED. Automatic Reconnection Timed Out.');\n\n connectionFailed();\n });\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE DISCONNECTED.');\n break;\n case ICE_STATE.FAILED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> ICE STATE FAILED.');\n // notify of ice failure\n // Ice failure is the only indicator currently for identifying the actual connection drop\n // Firefox takes sometime 10-15 seconds to go to failed state\n connectionFailed();\n break;\n default:\n break;\n }\n };\n\n peerConnection.onconnectionstatechange = () => {\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CHANGE.');\n switch (peerConnection.connectionState) {\n case CONNECTION_STATE.NEW:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE NEW.');\n break;\n case CONNECTION_STATE.CONNECTING:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CONNECTING.');\n break;\n case CONNECTION_STATE.CONNECTED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CONNECTED.');\n break;\n case CONNECTION_STATE.CLOSED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE CLOSED.');\n break;\n case CONNECTION_STATE.DISCONNECTED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE DISCONNECTED.');\n break;\n case CONNECTION_STATE.FAILED:\n LoggerProxy.logger.info('PeerConnectionManager:index#setPeerConnectionEvents --> CONNECTION STATE FAILED.');\n // Special case happens only on chrome where there is no ICE FAILED event\n // only CONNECTION FAILED event gets triggered\n\n connectionFailed();\n break;\n default:\n break;\n }\n };\n};\n\nexport default pc;\n"],"mappings":"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"}
@@ -80,26 +80,30 @@ git checkout -b 39555-new-feature plugin-meetings
80
80
 
81
81
  ```bash
82
82
  # Point all package.json files to the src directory instead of the dist directory.
83
- npm run distsrc
83
+ yarn run distsrc
84
+
84
85
  ```
85
86
 
86
87
  #### Testers
87
88
 
88
89
  ```bash
89
90
  # Transpile the code into the dist directory.
90
- npm run build
91
+ yarn run build
92
+
91
93
  ```
92
94
 
93
95
  > Individual packages containing samples can usually be run this way:
94
96
  > ```
95
- > npm run serve:package -- --env.package @webex/plugin-meetings
97
+ > yarn run serve:package --env.package @webex/plugin-meetings
98
+
96
99
  > ```
97
100
  > However, `webex` does not get compiled properly for `plugin-meetings` using this method, so do the following instead.
98
101
 
99
102
 
100
103
  ```bash
101
104
  # Run the "sample app" sample.
102
- npm run samples:meetings
105
+ yarn run samples:meetings
106
+
103
107
  ```
104
108
 
105
109
  - Visit https://localhost:8000/
@@ -118,13 +122,16 @@ npm run samples:meetings
118
122
 
119
123
  ### Run tests
120
124
 
121
- Use `npm run distsrc` to point each package's `main` entry at the raw src and let `babel` compile on the fly.
125
+ Use `yarn run distsrc` to point each package's `main` entry at the raw src and let `babel` compile on the fly.
126
+
122
127
 
123
128
  ```bash
124
129
  # Point all package.json files to the src directory instead of the dist directory.
125
- npm run distsrc
130
+ yarn run distsrc
131
+
126
132
  # Run the package tests.
127
- npm test -- --packages @webex/plugin-meetings
133
+ yarn run test --packages @webex/plugin-meetings
134
+
128
135
  ```
129
136
 
130
137
  You can use the `--unit`, `--integration`, `--automation`, and `--documentation` switches to control what types of tests you run and `--node` and `--browser` to control which environments your tests run in.
@@ -133,14 +140,16 @@ You can use the `--unit`, `--integration`, `--automation`, and `--documentation`
133
140
 
134
141
  ```bash
135
142
  # Example running browser tests in debug mode.
136
- npm test -- --packages @webex/plugin-teams --browser --karma-debug
143
+ yarn run test --packages @webex/plugin-teams --browser --karma-debug
144
+
137
145
  ```
138
146
 
139
147
  > See [SCRIPTS.md](https://github.com/webex/webex-js-sdk/blob/master/SCRIPTS.md) to learn how to run tests on [SauceLabs](https://saucelabs.com/) and more.
140
148
 
141
149
  ```bash
142
150
  # Point all package.json files back to the dist directory.
143
- npm run srcdist
151
+ yarn run srcdist
152
+
144
153
  ```
145
154
 
146
155
  ### Commit changes
package/package.json CHANGED
@@ -1,43 +1,61 @@
1
1
  {
2
- "name": "@webex/plugin-meetings",
3
- "version": "2.29.3",
4
- "description": "",
5
- "license": "MIT",
6
- "contributors": [
7
- "Adam Weeks <adweeks@cisco.com> (https://adamweeks.com/)",
8
- "Arun Ganeshan <arungane@cisco.com>",
9
- "Christopher DuBois <chdubois@cisco.com> (https://chrisadubois.github.io/)",
10
- "Matt Norris <matnorri@cisco.com> (http://mattnorris.me)",
11
- "Moriah Maney <momaney@cisco.com>",
12
- "Taymoor Khan <taykhan@cisco.com>"
13
- ],
14
- "main": "dist/index.js",
15
- "devMain": "src/index.js",
16
- "repository": "https://github.com/webex/webex-js-sdk/tree/master/packages/node_modules/@webex/plugin-meetings",
17
- "engines": {
18
- "node": ">=8"
19
- },
20
- "browserify": {
21
- "transform": [
22
- "envify"
23
- ]
24
- },
25
- "dependencies": {
26
- "@babel/runtime-corejs2": "^7.14.8",
27
- "@webex/webex-core": "2.29.3",
28
- "@webex/internal-plugin-mercury": "2.29.3",
29
- "@webex/internal-plugin-conversation": "2.29.3",
30
- "webrtc-adapter": "^7.7.0",
31
- "lodash": "^4.17.21",
32
- "uuid": "^3.3.2",
33
- "global": "^4.4.0",
34
- "ip-anonymize": "^0.1.0",
35
- "@webex/common": "2.29.3",
36
- "bowser": "^2.11.0",
37
- "sdp-transform": "^2.12.0",
38
- "btoa": "^1.2.1",
39
- "@webex/internal-media-core": "^0.0.7-beta",
40
- "javascript-state-machine": "^3.1.0",
41
- "envify": "^4.1.0"
42
- }
2
+ "name": "@webex/plugin-meetings",
3
+ "version": "2.30.0",
4
+ "description": "",
5
+ "license": "MIT",
6
+ "contributors": [
7
+ "Adam Weeks <adweeks@cisco.com> (https://adamweeks.com/)",
8
+ "Arun Ganeshan <arungane@cisco.com>",
9
+ "Christopher DuBois <chdubois@cisco.com> (https://chrisadubois.github.io/)",
10
+ "Matt Norris <matnorri@cisco.com> (http://mattnorris.me)",
11
+ "Moriah Maney <momaney@cisco.com>",
12
+ "Taymoor Khan <taykhan@cisco.com>"
13
+ ],
14
+ "main": "dist/index.js",
15
+ "devMain": "src/index.js",
16
+ "repository": "https://github.com/webex/webex-js-sdk/tree/master/packages/@webex/plugin-meetings",
17
+ "engines": {
18
+ "node": ">=14"
19
+ },
20
+ "browserify": {
21
+ "transform": [
22
+ "babelify",
23
+ "envify"
24
+ ]
25
+ },
26
+ "devDependencies": {
27
+ "@webex/plugin-meetings": "workspace:^",
28
+ "@webex/test-helper-chai": "workspace:^",
29
+ "@webex/test-helper-mocha": "workspace:^",
30
+ "@webex/test-helper-mock-webex": "workspace:^",
31
+ "@webex/test-helper-retry": "workspace:^",
32
+ "@webex/test-helper-test-users": "workspace:^",
33
+ "chai": "^4.3.4",
34
+ "chai-as-promised": "^7.1.1",
35
+ "jsdom-global": "3.0.2",
36
+ "sinon": "^9.2.4"
37
+ },
38
+ "dependencies": {
39
+ "@webex/common": "workspace:^",
40
+ "@webex/internal-media-core": "^0.0.7-beta",
41
+ "@webex/internal-plugin-conversation": "workspace:^",
42
+ "@webex/internal-plugin-device": "workspace:^",
43
+ "@webex/internal-plugin-mercury": "workspace:^",
44
+ "@webex/internal-plugin-metrics": "workspace:^",
45
+ "@webex/internal-plugin-support": "workspace:^",
46
+ "@webex/internal-plugin-user": "workspace:^",
47
+ "@webex/plugin-people": "workspace:^",
48
+ "@webex/plugin-rooms": "workspace:^",
49
+ "@webex/webex-core": "workspace:^",
50
+ "bowser": "^2.11.0",
51
+ "btoa": "^1.2.1",
52
+ "dotenv": "^4.0.0",
53
+ "global": "^4.4.0",
54
+ "ip-anonymize": "^0.1.0",
55
+ "javascript-state-machine": "^3.1.0",
56
+ "lodash": "^4.17.21",
57
+ "sdp-transform": "^2.12.0",
58
+ "uuid": "^3.3.2",
59
+ "webrtc-adapter": "^7.7.0"
60
+ }
43
61
  }
@@ -1,6 +1,6 @@
1
1
  import {isString} from 'lodash';
2
2
 
3
- import ParameterError from '../common/errors/parameter';
3
+ import ParameterError from './errors/parameter';
4
4
 
5
5
  /**
6
6
  * @class Collection
package/src/constants.ts CHANGED
@@ -684,6 +684,8 @@ export const DISPLAY_HINTS = {
684
684
  RAISE_HAND: 'RAISE_HAND',
685
685
  LOWER_ALL_HANDS: 'LOWER_ALL_HANDS',
686
686
  LOWER_SOMEONE_ELSES_HAND: 'LOWER_SOMEONE_ELSES_HAND',
687
+ LEAVE_TRANSFER_HOST_END_MEETING: 'LEAVE_TRANSFER_HOST_END_MEETING',
688
+ LEAVE_END_MEETING: 'LEAVE_END_MEETING',
687
689
  CAPTION_START: 'CAPTION_START',
688
690
  CAPTION_STATUS_ACTIVE: 'CAPTION_STATUS_ACTIVE',
689
691
  DISPLAY_REAL_TIME_TRANSLATION: 'DISPLAY_REAL_TIME_TRANSLATION',
@@ -23,6 +23,7 @@ interface IInMeetingActions {
23
23
  canRaiseHand?: boolean;
24
24
  canLowerAllHands?: boolean;
25
25
  canLowerSomeoneElsesHand?: boolean;
26
+ bothLeaveAndEndMeetingAvailable?: boolean;
26
27
  canEnableClosedCaption?: boolean;
27
28
  canStartTranscribing?: boolean;
28
29
  canStopTranscribing?: boolean;
@@ -64,6 +65,8 @@ export default class InMeetingActions implements IInMeetingActions {
64
65
 
65
66
  canLowerSomeoneElsesHand = null;
66
67
 
68
+ bothLeaveAndEndMeetingAvailable = null;
69
+
67
70
  canEnableClosedCaption = null;
68
71
 
69
72
  canStartTranscribing = null;
@@ -99,6 +102,7 @@ export default class InMeetingActions implements IInMeetingActions {
99
102
  canRaiseHand: this.canRaiseHand,
100
103
  canLowerAllHands: this.canLowerAllHands,
101
104
  canLowerSomeoneElsesHand: this.canLowerSomeoneElsesHand,
105
+ bothLeaveAndEndMeetingAvailable: this.bothLeaveAndEndMeetingAvailable,
102
106
  canEnableClosedCaption: this.canEnableClosedCaption,
103
107
  canStartTranscribing: this.canStartTranscribing,
104
108
  canStopTranscribing: this.canStopTranscribing,
@@ -1889,6 +1889,7 @@ export default class Meeting extends StatelessWebexPlugin {
1889
1889
  canRaiseHand: MeetingUtil.canUserRaiseHand(payload.info.userDisplayHints),
1890
1890
  canLowerAllHands: MeetingUtil.canUserLowerAllHands(payload.info.userDisplayHints),
1891
1891
  canLowerSomeoneElsesHand: MeetingUtil.canUserLowerSomeoneElsesHand(payload.info.userDisplayHints),
1892
+ bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(payload.info.userDisplayHints),
1892
1893
  canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(payload.info.userDisplayHints),
1893
1894
  canStartTranscribing: MeetingUtil.canStartTranscribing(payload.info.userDisplayHints),
1894
1895
  canStopTranscribing: MeetingUtil.canStopTranscribing(payload.info.userDisplayHints),
@@ -3510,7 +3511,7 @@ export default class Meeting extends StatelessWebexPlugin {
3510
3511
  Metrics.postEvent({
3511
3512
  event: eventType.CALL_INITIATED,
3512
3513
  meeting: this,
3513
- data: {trigger: trigger.USER_INTERACTION}
3514
+ data: {trigger: trigger.USER_INTERACTION, isRoapCallEnabled: true}
3514
3515
  });
3515
3516
 
3516
3517
  LoggerProxy.logger.log('Meeting:index#join --> Joining a meeting');
@@ -447,6 +447,8 @@ MeetingUtil.canUserLowerAllHands = (displayHints) => displayHints.includes(DISPL
447
447
 
448
448
  MeetingUtil.canUserLowerSomeoneElsesHand = (displayHints) => displayHints.includes(DISPLAY_HINTS.LOWER_SOMEONE_ELSES_HAND);
449
449
 
450
+ MeetingUtil.bothLeaveAndEndMeetingAvailable = (displayHints) => displayHints.includes(DISPLAY_HINTS.LEAVE_TRANSFER_HOST_END_MEETING) || displayHints.includes(DISPLAY_HINTS.LEAVE_END_MEETING);
451
+
450
452
  MeetingUtil.lockMeeting = (actions, request, locusUrl) => {
451
453
  if (actions && actions.canLock) {
452
454
  return request.lockMeeting({locusUrl, lock: true});
@@ -237,6 +237,9 @@ class Metrics {
237
237
  if (options.joinTimes) {
238
238
  payload.event.joinTimes = options.joinTimes;
239
239
  }
240
+ if (options.isRoapCallEnabled) {
241
+ payload.event.isRoapCallEnabled = options.isRoapCallEnabled;
242
+ }
240
243
  }
241
244
 
242
245
  return payload;
@@ -121,7 +121,7 @@ const isSdpInvalid = (sdp) => {
121
121
 
122
122
  for (const mediaLine of parsedSdp.media) {
123
123
  if (!mediaLine.candidates || mediaLine.candidates?.length === 0) {
124
- LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Ice candadate never completed');
124
+ LoggerProxy.logger.error('PeerConnectionManager:index#isSdpInvalid --> iceCandidate: Ice candidate never completed');
125
125
 
126
126
  return 'iceCandidate: Ice gathering never completed';
127
127
  }
@@ -378,7 +378,7 @@ pc.setRemoteSessionDetails = (
378
378
  };
379
379
 
380
380
  /**
381
- * create offer with a valid paramater
381
+ * Create offer with a valid parameter
382
382
  * @param {Object} peerConnection
383
383
  * @param {Object} meetingProperties
384
384
  * @param {string} meetingProperties.meetingId
@@ -403,7 +403,7 @@ pc.createOffer = (peerConnection, {
403
403
  .createOffer()
404
404
  .then((description) => {
405
405
  // bug https://bugs.chromium.org/p/chromium/issues/detail?id=1020642
406
- // chrome currently generates RTX line irrespective of weither the server side supports it
406
+ // chrome currently generates RTX line irrespective of whether the server side supports it
407
407
  // we are removing apt as well because its associated with rtx line
408
408
 
409
409
  if (!enableRtx) {
@@ -1,4 +1,6 @@
1
1
  /* globals navigator */
2
+ /* eslint prefer-arrow-callback: 0 */
3
+
2
4
  import {assert} from '@webex/test-helper-chai';
3
5
  import {skipInNode} from '@webex/test-helper-mocha';
4
6
  import sinon from 'sinon';
@@ -1,4 +1,4 @@
1
-
1
+ /* eslint prefer-arrow-callback: 0 */
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import {skipInNode, jenkinsOnly} from '@webex/test-helper-mocha';
4
4
  import {patterns} from '@webex/common';
@@ -18,6 +18,7 @@ describe('plugin-meetings', () => {
18
18
  canRaiseHand: null,
19
19
  canLowerAllHands: null,
20
20
  canLowerSomeoneElsesHand: null,
21
+ bothLeaveAndEndMeetingAvailable: null,
21
22
  canEnableClosedCaption: null,
22
23
  canStartTranscribing: null,
23
24
  canStopTranscribing: null,
@@ -52,6 +53,7 @@ describe('plugin-meetings', () => {
52
53
  'canRaiseHand',
53
54
  'canLowerAllHands',
54
55
  'canLowerSomeoneElsesHand',
56
+ 'bothLeaveAndEndMeetingAvailable',
55
57
  'canEnableClosedCaption',
56
58
  'canStopTranscribing',
57
59
  'isClosedCaptionActive',
@@ -21,7 +21,6 @@ import {
21
21
  _MEETING_ID_,
22
22
  LOCUSINFO,
23
23
  } from '@webex/plugin-meetings/src/constants';
24
-
25
24
  import * as StatsAnalyzerModule from '@webex/plugin-meetings/src/statsAnalyzer';
26
25
  import EventsScope from '@webex/plugin-meetings/src/common/events/events-scope';
27
26
  import Meetings, {CONSTANTS} from '@webex/plugin-meetings';
@@ -41,7 +40,7 @@ import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
41
40
  import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
42
41
  import BrowserDetection from '@webex/plugin-meetings/src/common/browser-detection';
43
42
  import Metrics from '@webex/plugin-meetings/src/metrics';
44
- import {eventType} from '@webex/plugin-meetings/src/metrics/config';
43
+ import {trigger, eventType} from '@webex/plugin-meetings/src/metrics/config';
45
44
  import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
46
45
 
47
46
  import locus from '../fixture/locus';
@@ -783,6 +782,8 @@ describe('plugin-meetings', () => {
783
782
  it('should join the meeting and return promise', async () => {
784
783
  const join = meeting.join();
785
784
 
785
+ assert.calledWithMatch(Metrics.postEvent, {event: eventType.CALL_INITIATED, data: {trigger: trigger.USER_INTERACTION, isRoapCallEnabled: true}});
786
+
786
787
  assert.exists(join.then);
787
788
  await join;
788
789
  assert.calledOnce(MeetingUtil.joinMeeting);
@@ -3662,11 +3663,11 @@ describe('plugin-meetings', () => {
3662
3663
  let canUserPauseSpy;
3663
3664
  let canUserResumeSpy;
3664
3665
  let canUserRaiseHandSpy;
3666
+ let bothLeaveAndEndMeetingAvailableSpy;
3665
3667
  let canUserLowerAllHandsSpy;
3666
3668
  let canUserLowerSomeoneElsesHandSpy;
3667
3669
  let waitingForOthersToJoinSpy;
3668
3670
 
3669
-
3670
3671
  beforeEach(() => {
3671
3672
  locusInfoOnSpy = sinon.spy(meeting.locusInfo, 'on');
3672
3673
  canUserLockSpy = sinon.spy(MeetingUtil, 'canUserLock');
@@ -3678,6 +3679,7 @@ describe('plugin-meetings', () => {
3678
3679
  inMeetingActionsSetSpy = sinon.spy(meeting.inMeetingActions, 'set');
3679
3680
  canUserRaiseHandSpy = sinon.spy(MeetingUtil, 'canUserRaiseHand');
3680
3681
  canUserLowerAllHandsSpy = sinon.spy(MeetingUtil, 'canUserLowerAllHands');
3682
+ bothLeaveAndEndMeetingAvailableSpy = sinon.spy(MeetingUtil, 'bothLeaveAndEndMeetingAvailable');
3681
3683
  canUserLowerSomeoneElsesHandSpy = sinon.spy(MeetingUtil, 'canUserLowerSomeoneElsesHand');
3682
3684
  waitingForOthersToJoinSpy = sinon.spy(MeetingUtil, 'waitingForOthersToJoin');
3683
3685
  });
@@ -3714,6 +3716,7 @@ describe('plugin-meetings', () => {
3714
3716
  assert.calledWith(canUserPauseSpy, payload.info.userDisplayHints);
3715
3717
  assert.calledWith(canUserResumeSpy, payload.info.userDisplayHints);
3716
3718
  assert.calledWith(canUserRaiseHandSpy, payload.info.userDisplayHints);
3719
+ assert.calledWith(bothLeaveAndEndMeetingAvailableSpy, payload.info.userDisplayHints);
3717
3720
  assert.calledWith(canUserLowerAllHandsSpy, payload.info.userDisplayHints);
3718
3721
  assert.calledWith(canUserLowerSomeoneElsesHandSpy, payload.info.userDisplayHints);
3719
3722
  assert.calledWith(waitingForOthersToJoinSpy, payload.info.userDisplayHints);
@@ -1,6 +1,5 @@
1
1
  import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
-
4
3
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
5
4
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
6
5
  import LoggerConfig
@@ -250,6 +249,15 @@ describe('plugin-meetings', () => {
250
249
  });
251
250
  });
252
251
 
252
+ describe('bothLeaveAndEndMeetingAvailable', () => {
253
+ it('works as expected', () => {
254
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_TRANSFER_HOST_END_MEETING']), true);
255
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_END_MEETING']), true);
256
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable(['LEAVE_TRANSFER_HOST_END_MEETING', 'LEAVE_END_MEETING']), true);
257
+ assert.deepEqual(MeetingUtil.bothLeaveAndEndMeetingAvailable([]), false);
258
+ });
259
+ });
260
+
253
261
  describe('canUserLock', () => {
254
262
  it('works as expected', () => {
255
263
  assert.deepEqual(MeetingUtil.canUserLock(['LOCK_CONTROL_LOCK', 'LOCK_STATUS_UNLOCKED']), true);