@webex/plugin-meetings 1.150.1 → 1.151.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.
@@ -51,6 +51,7 @@ import {
51
51
  MEETING_STATE_MACHINE,
52
52
  MEETING_STATE,
53
53
  MEETINGS,
54
+ METRICS_JOIN_TIMES_MAX_DURATION,
54
55
  METRICS_OPERATIONAL_MEASURES,
55
56
  MQA_STATS,
56
57
  NETWORK_STATUS,
@@ -1065,10 +1066,45 @@ export default class Meeting extends StatelessWebexPlugin {
1065
1066
  };
1066
1067
  }
1067
1068
 
1069
+ const localSDPGenRemoteSDPRecv = this.getLocalSDPGenRemoteSDPRecvDelay();
1070
+
1071
+ if (localSDPGenRemoteSDPRecv) {
1072
+ options.joinTimes = {
1073
+ ...options.joinTimes,
1074
+ localSDPGenRemoteSDPRecv
1075
+ };
1076
+ }
1077
+
1078
+ const callInitiateJoinReq = this.getCallInitiateJoinReq();
1079
+
1080
+ if (callInitiateJoinReq) {
1081
+ options.joinTimes = {
1082
+ ...options.joinTimes,
1083
+ callInitiateJoinReq
1084
+ };
1085
+ }
1086
+
1087
+ const joinReqResp = this.getJoinReqResp();
1088
+
1089
+ if (joinReqResp) {
1090
+ options.joinTimes = {
1091
+ ...options.joinTimes,
1092
+ joinReqResp
1093
+ };
1094
+ }
1095
+
1096
+ const getTotalJmt = this.getTotalJmt();
1097
+
1098
+ if (getTotalJmt) {
1099
+ options.joinTimes = {
1100
+ ...options.joinTimes,
1101
+ getTotalJmt
1102
+ };
1103
+ }
1104
+
1068
1105
  if (options.type === MQA_STATS.CA_TYPE) {
1069
1106
  payload = Metrics.initMediaPayload(options.event, identifiers, options);
1070
1107
  }
1071
-
1072
1108
  else {
1073
1109
  payload = Metrics.initPayload(options.event, identifiers, options);
1074
1110
  }
@@ -3372,12 +3408,13 @@ export default class Meeting extends StatelessWebexPlugin {
3372
3408
  }
3373
3409
  }
3374
3410
 
3375
- return MeetingUtil.joinMeetingOptions(this, options).then((join) => {
3376
- this.meetingFiniteStateMachine.join();
3377
- LoggerProxy.logger.log('Meeting:index#join --> Success');
3411
+ return MeetingUtil.joinMeetingOptions(this, options)
3412
+ .then((join) => {
3413
+ this.meetingFiniteStateMachine.join();
3414
+ LoggerProxy.logger.log('Meeting:index#join --> Success');
3378
3415
 
3379
- return join;
3380
- })
3416
+ return join;
3417
+ })
3381
3418
  .then((join) => {
3382
3419
  joinSuccess(join);
3383
3420
  this.deferJoin = undefined;
@@ -3851,7 +3888,8 @@ export default class Meeting extends StatelessWebexPlugin {
3851
3888
  meetingId: this.id,
3852
3889
  remoteQualityLevel: this.mediaProperties.remoteQualityLevel,
3853
3890
  enableRtx: this.config.enableRtx,
3854
- enableExtmap: this.config.enableExtmap
3891
+ enableExtmap: this.config.enableExtmap,
3892
+ setStartLocalSDPGenRemoteSDPRecvDelay: this.setStartLocalSDPGenRemoteSDPRecvDelay.bind(this)
3855
3893
  })
3856
3894
  .then((peerConnection) => this.getDevices().then((devices) => {
3857
3895
  MeetingUtil.handleDeviceLogging(devices);
@@ -5238,9 +5276,9 @@ export default class Meeting extends StatelessWebexPlugin {
5238
5276
  }
5239
5277
 
5240
5278
  /**
5241
- * @param {string} typeMedia 'audio' or 'video'
5242
- * @returns {undefined}
5243
- */
5279
+ * @param {string} typeMedia 'audio' or 'video'
5280
+ * @returns {undefined}
5281
+ */
5244
5282
  setEndSendingMediaDelay(typeMedia) {
5245
5283
  this[`endSendingMediaDelay${typeMedia}`] = performance.now();
5246
5284
  }
@@ -5255,4 +5293,127 @@ export default class Meeting extends StatelessWebexPlugin {
5255
5293
 
5256
5294
  return (start && end) ? end - start : undefined;
5257
5295
  }
5296
+
5297
+ /**
5298
+ *
5299
+ * @returns {undefined}
5300
+ */
5301
+ setStartLocalSDPGenRemoteSDPRecvDelay() {
5302
+ if (!this.startLocalSDPGenRemoteSDPRecvDelay) {
5303
+ this.startLocalSDPGenRemoteSDPRecvDelay = performance.now();
5304
+ this.endLocalSDPGenRemoteSDPRecvDelay = undefined;
5305
+ }
5306
+ }
5307
+
5308
+ /**
5309
+ *
5310
+ * @returns {undefined}
5311
+ */
5312
+ setEndLocalSDPGenRemoteSDPRecvDelay() {
5313
+ if (!this.endLocalSDPGenRemoteSDPRecvDelay) {
5314
+ this.endLocalSDPGenRemoteSDPRecvDelay = performance.now();
5315
+ }
5316
+ }
5317
+
5318
+ /**
5319
+ *
5320
+ * @returns {string} duration between local SDP generation and remote SDP reception
5321
+ */
5322
+ getLocalSDPGenRemoteSDPRecvDelay() {
5323
+ const start = this.startLocalSDPGenRemoteSDPRecvDelay;
5324
+ const end = this.endLocalSDPGenRemoteSDPRecvDelay;
5325
+
5326
+ if (start && end) {
5327
+ const calculatedDelay = end - start;
5328
+
5329
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5330
+ undefined :
5331
+ calculatedDelay;
5332
+ }
5333
+
5334
+ return undefined;
5335
+ }
5336
+
5337
+ /**
5338
+ *
5339
+ * @returns {undefined}
5340
+ */
5341
+ setStartCallInitiateJoinReq() {
5342
+ this.startCallInitiateJoinReq = performance.now();
5343
+ this.endCallInitiateJoinReq = undefined;
5344
+ }
5345
+
5346
+ /**
5347
+ *
5348
+ * @returns {undefined}
5349
+ */
5350
+ setEndCallInitiateJoinReq() {
5351
+ this.endCallInitiateJoinReq = performance.now();
5352
+ }
5353
+
5354
+ /**
5355
+ *
5356
+ * @returns {string} duration between call initiate and sending join request to locus
5357
+ */
5358
+ getCallInitiateJoinReq() {
5359
+ const start = this.startCallInitiateJoinReq;
5360
+ const end = this.endCallInitiateJoinReq;
5361
+
5362
+ if (start && end) {
5363
+ const calculatedDelay = end - start;
5364
+
5365
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5366
+ undefined :
5367
+ calculatedDelay;
5368
+ }
5369
+
5370
+ return undefined;
5371
+ }
5372
+
5373
+ /**
5374
+ *
5375
+ * @returns {undefined}
5376
+ */
5377
+ setStartJoinReqResp() {
5378
+ this.startJoinReqResp = performance.now();
5379
+ this.endJoinReqResp = undefined;
5380
+ }
5381
+
5382
+ /**
5383
+ *
5384
+ * @returns {undefined}
5385
+ */
5386
+ setEndJoinReqResp() {
5387
+ this.endJoinReqResp = performance.now();
5388
+ }
5389
+
5390
+ /**
5391
+ *
5392
+ * @returns {string} duration between sending locus join request and receiving join response
5393
+ */
5394
+ getJoinReqResp() {
5395
+ const start = this.startJoinReqResp;
5396
+ const end = this.endJoinReqResp;
5397
+
5398
+ if (start && end) {
5399
+ const calculatedDelay = end - start;
5400
+
5401
+ return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ?
5402
+ undefined :
5403
+ calculatedDelay;
5404
+ }
5405
+
5406
+ return undefined;
5407
+ }
5408
+
5409
+ /**
5410
+ *
5411
+ * @returns {string} duration between call initiate and successful locus join (even if it is in lobby)
5412
+ */
5413
+ getTotalJmt() {
5414
+ const start = this.startCallInitiateJoinReq;
5415
+ const end = this.endJoinReqResp;
5416
+
5417
+ return (start && end) ? end - start : undefined;
5418
+ }
5258
5419
  }
@@ -48,7 +48,15 @@ const getLocalNetworkPrefix = (localIp) => {
48
48
 
49
49
  const triggerTimers = ({event, meeting, data}) => {
50
50
  switch (event) {
51
+ case eventType.CALL_INITIATED:
52
+ meeting.setStartCallInitiateJoinReq();
53
+ break;
54
+ case eventType.LOCUS_JOIN_REQUEST:
55
+ meeting.setEndCallInitiateJoinReq();
56
+ meeting.setStartJoinReqResp();
57
+ break;
51
58
  case eventType.LOCUS_JOIN_RESPONSE:
59
+ meeting.setEndJoinReqResp();
52
60
  meeting.setStartSetupDelay(mediaType.AUDIO);
53
61
  meeting.setStartSetupDelay(mediaType.VIDEO);
54
62
  meeting.setStartSendingMediaDelay(mediaType.AUDIO);
@@ -60,6 +68,12 @@ const triggerTimers = ({event, meeting, data}) => {
60
68
  case eventType.SENDING_MEDIA_START:
61
69
  meeting.setEndSendingMediaDelay(data.mediaType);
62
70
  break;
71
+ case eventType.LOCAL_SDP_GENERATED:
72
+ meeting.setStartLocalSDPGenRemoteSDPRecvDelay();
73
+ break;
74
+ case eventType.REMOTE_SDP_RECEIVED:
75
+ meeting.setEndLocalSDPGenRemoteSDPRecvDelay();
76
+ break;
63
77
  default:
64
78
  break;
65
79
  }
@@ -144,6 +158,7 @@ class Metrics {
144
158
 
145
159
  if (!meeting && meetingId) {
146
160
  meeting = this.meetingCollection.get(meetingId);
161
+ options.meeting = meeting;
147
162
  }
148
163
 
149
164
  if (meeting) {
@@ -228,6 +243,9 @@ class Metrics {
228
243
  if (options.recoveredBy) {
229
244
  payload.event.recoveredBy = options.recoveredBy;
230
245
  }
246
+ if (options.joinTimes) {
247
+ payload.event.joinTimes = options.joinTimes;
248
+ }
231
249
  }
232
250
 
233
251
  return payload;
@@ -259,7 +277,7 @@ class Metrics {
259
277
  * @memberof Metrics
260
278
  */
261
279
  initMediaPayload(eventType, identifiers, options = {}) {
262
- const {audioSetupDelay, videoSetupDelay} = options;
280
+ const {audioSetupDelay, videoSetupDelay, joinTimes} = options;
263
281
 
264
282
  const payload = {
265
283
  eventId: uuid.v4(),
@@ -290,7 +308,10 @@ class Metrics {
290
308
  canProceed: true,
291
309
  identifiers,
292
310
  intervals: [options.intervalData],
293
- eventData: {webClientDomain: window.location.hostname},
311
+ joinTimes,
312
+ eventData: {
313
+ webClientDomain: window.location.hostname
314
+ },
294
315
  sourceMetadata: {
295
316
  applicationSoftwareType: CLIENT_NAME,
296
317
  applicationSoftwareVersion: this.webex.version,
@@ -288,7 +288,12 @@ pc.addStream = (peerConnection, stream) => {
288
288
  * @param {String} meetingId
289
289
  * @returns {undefined}
290
290
  */
291
- pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) => {
291
+ pc.setRemoteSessionDetails = (
292
+ peerConnection,
293
+ typeStr,
294
+ remoteSdp,
295
+ meetingId,
296
+ ) => {
292
297
  LoggerProxy.logger.log(`PeerConnectionManager:index#setRemoteSessionDetails --> Setting the remote description type: ${typeStr}State: ${peerConnection.signalingState}`);
293
298
  const sdp = remoteSdp;
294
299
 
@@ -314,7 +319,7 @@ pc.setRemoteSessionDetails = (peerConnection, typeStr, remoteSdp, meetingId) =>
314
319
  })
315
320
  )
316
321
  .then(() => {
317
- if (!peerConnection.remoteDescription) {
322
+ if (peerConnection.signalingState === SDP.STABLE) {
318
323
  Metrics.postEvent({
319
324
  event: eventType.REMOTE_SDP_RECEIVED,
320
325
  meetingId
@@ -519,7 +519,10 @@ skipInNode(describe)('plugin-meetings', () => {
519
519
  .then((response) => {
520
520
  assert.equal(response[0].result.memberId, alice.meeting.selfId);
521
521
  }),
522
- testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}]),
522
+ testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
523
+ .then((response) => {
524
+ console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
525
+ }),
523
526
  testUtils.waitForEvents([{scope: alice.meeting, event: 'media:ready'}])
524
527
  .then((response) => {
525
528
  console.log('MEDIA:READY event ', response[0].result);
@@ -549,7 +552,7 @@ skipInNode(describe)('plugin-meetings', () => {
549
552
  }),
550
553
  testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
551
554
  .then((response) => {
552
- console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
555
+ console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
553
556
  }),
554
557
  testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
555
558
  .then((response) => {
@@ -601,7 +604,7 @@ skipInNode(describe)('plugin-meetings', () => {
601
604
  }),
602
605
  testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
603
606
  .then((response) => {
604
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
607
+ console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
605
608
  })
606
609
  ])
607
610
  .then(() => {
@@ -624,7 +627,7 @@ skipInNode(describe)('plugin-meetings', () => {
624
627
  }),
625
628
  testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
626
629
  .then((response) => {
627
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
630
+ console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
628
631
  })
629
632
  ])
630
633
  .then(() => {
@@ -660,7 +663,7 @@ skipInNode(describe)('plugin-meetings', () => {
660
663
  }),
661
664
  testUtils.waitForEvents([{scope: bob.meeting.members, event: 'members:update'}])
662
665
  .then((response) => {
663
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
666
+ console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
664
667
  })
665
668
  ])
666
669
  .then(() => {
@@ -679,7 +682,7 @@ skipInNode(describe)('plugin-meetings', () => {
679
682
  }),
680
683
  testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
681
684
  .then((response) => {
682
- console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response));
685
+ console.log('SCREEN SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
683
686
  }),
684
687
  testUtils.waitForEvents([{scope: bob.meeting, event: 'media:ready'}])
685
688
  .then((response) => {
@@ -715,7 +718,7 @@ skipInNode(describe)('plugin-meetings', () => {
715
718
  }),
716
719
  testUtils.waitForEvents([{scope: alice.meeting.members, event: 'members:update'}])
717
720
  .then((response) => {
718
- console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response));
721
+ console.log('WHITEBOARD SHARE RESPONSE ', JSON.stringify(response, testUtils.getCircularReplacer()));
719
722
  })
720
723
  ])
721
724
  .then(() => {
@@ -236,6 +236,22 @@ const waitUntil = (waitTime) => new Promise((resolve) => {
236
236
 
237
237
  const flushPromises = () => new Promise(setImmediate);
238
238
 
239
+ const getCircularReplacer = () => {
240
+ const seen = new WeakSet();
241
+
242
+ return (_, value) => {
243
+ if (typeof value === 'object' && value !== null) {
244
+ if (seen.has(value)) {
245
+ return;
246
+ }
247
+ seen.add(value);
248
+ }
249
+
250
+ // eslint-disable-next-line consistent-return
251
+ return value;
252
+ };
253
+ };
254
+
239
255
  export default {
240
256
  waitForSpy,
241
257
  waitForStateChange,
@@ -246,6 +262,7 @@ export default {
246
262
  addMedia,
247
263
  waitUntil,
248
264
  delayedTest,
249
- flushPromises
265
+ flushPromises,
266
+ getCircularReplacer
250
267
  };
251
268