@webex/plugin-meetings 3.3.1 → 3.4.0-next.10

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.
Files changed (138) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +7 -2
  3. package/dist/breakouts/index.js.map +1 -1
  4. package/dist/constants.js +11 -4
  5. package/dist/constants.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/locus-info/selfUtils.js +0 -5
  9. package/dist/locus-info/selfUtils.js.map +1 -1
  10. package/dist/media/MediaConnectionAwaiter.js +70 -15
  11. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  12. package/dist/media/index.js +18 -9
  13. package/dist/media/index.js.map +1 -1
  14. package/dist/meeting/connectionStateHandler.js +67 -0
  15. package/dist/meeting/connectionStateHandler.js.map +1 -0
  16. package/dist/meeting/index.js +576 -374
  17. package/dist/meeting/index.js.map +1 -1
  18. package/dist/meeting/locusMediaRequest.js +7 -0
  19. package/dist/meeting/locusMediaRequest.js.map +1 -1
  20. package/dist/meeting/muteState.js +6 -1
  21. package/dist/meeting/muteState.js.map +1 -1
  22. package/dist/meeting/util.js +1 -0
  23. package/dist/meeting/util.js.map +1 -1
  24. package/dist/meeting-info/index.js +4 -4
  25. package/dist/meeting-info/index.js.map +1 -1
  26. package/dist/meeting-info/meeting-info-v2.js +2 -2
  27. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  28. package/dist/meeting-info/util.js +17 -17
  29. package/dist/meeting-info/util.js.map +1 -1
  30. package/dist/meeting-info/utilv2.js +16 -16
  31. package/dist/meeting-info/utilv2.js.map +1 -1
  32. package/dist/meetings/collection.js +1 -1
  33. package/dist/meetings/collection.js.map +1 -1
  34. package/dist/meetings/index.js +41 -35
  35. package/dist/meetings/index.js.map +1 -1
  36. package/dist/meetings/meetings.types.js +8 -0
  37. package/dist/meetings/meetings.types.js.map +1 -1
  38. package/dist/meetings/util.js +3 -2
  39. package/dist/meetings/util.js.map +1 -1
  40. package/dist/metrics/constants.js +2 -1
  41. package/dist/metrics/constants.js.map +1 -1
  42. package/dist/metrics/index.js +57 -0
  43. package/dist/metrics/index.js.map +1 -1
  44. package/dist/personal-meeting-room/index.js +1 -1
  45. package/dist/personal-meeting-room/index.js.map +1 -1
  46. package/dist/reachability/clusterReachability.js +108 -53
  47. package/dist/reachability/clusterReachability.js.map +1 -1
  48. package/dist/reachability/index.js +546 -115
  49. package/dist/reachability/index.js.map +1 -1
  50. package/dist/reconnection-manager/index.js +1 -1
  51. package/dist/reconnection-manager/index.js.map +1 -1
  52. package/dist/rtcMetrics/index.js +26 -6
  53. package/dist/rtcMetrics/index.js.map +1 -1
  54. package/dist/types/constants.d.ts +11 -3
  55. package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
  56. package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
  57. package/dist/types/meeting/index.d.ts +28 -8
  58. package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
  59. package/dist/types/meeting-info/index.d.ts +3 -2
  60. package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
  61. package/dist/types/meeting-info/util.d.ts +5 -4
  62. package/dist/types/meeting-info/utilv2.d.ts +3 -2
  63. package/dist/types/meetings/collection.d.ts +3 -2
  64. package/dist/types/meetings/index.d.ts +6 -4
  65. package/dist/types/meetings/meetings.types.d.ts +9 -0
  66. package/dist/types/metrics/constants.d.ts +1 -0
  67. package/dist/types/metrics/index.d.ts +15 -0
  68. package/dist/types/reachability/clusterReachability.d.ts +31 -3
  69. package/dist/types/reachability/index.d.ts +107 -4
  70. package/dist/types/rtcMetrics/index.d.ts +11 -1
  71. package/dist/webinar/index.js +1 -1
  72. package/package.json +23 -23
  73. package/src/breakouts/index.ts +7 -1
  74. package/src/constants.ts +13 -17
  75. package/src/locus-info/selfUtils.ts +0 -5
  76. package/src/media/MediaConnectionAwaiter.ts +89 -14
  77. package/src/media/index.ts +18 -9
  78. package/src/meeting/connectionStateHandler.ts +65 -0
  79. package/src/meeting/index.ts +541 -298
  80. package/src/meeting/locusMediaRequest.ts +5 -0
  81. package/src/meeting/muteState.ts +6 -1
  82. package/src/meeting/util.ts +1 -0
  83. package/src/meeting-info/index.ts +9 -6
  84. package/src/meeting-info/meeting-info-v2.ts +4 -4
  85. package/src/meeting-info/util.ts +23 -28
  86. package/src/meeting-info/utilv2.ts +18 -24
  87. package/src/meetings/collection.ts +3 -3
  88. package/src/meetings/index.ts +43 -43
  89. package/src/meetings/meetings.types.ts +11 -0
  90. package/src/meetings/util.ts +5 -4
  91. package/src/metrics/constants.ts +1 -0
  92. package/src/metrics/index.ts +44 -0
  93. package/src/personal-meeting-room/index.ts +2 -2
  94. package/src/reachability/clusterReachability.ts +86 -25
  95. package/src/reachability/index.ts +364 -30
  96. package/src/reconnection-manager/index.ts +1 -1
  97. package/src/rtcMetrics/index.ts +25 -5
  98. package/test/unit/spec/breakouts/index.ts +51 -32
  99. package/test/unit/spec/locus-info/selfUtils.js +25 -23
  100. package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
  101. package/test/unit/spec/media/index.ts +75 -34
  102. package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
  103. package/test/unit/spec/meeting/index.js +807 -185
  104. package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
  105. package/test/unit/spec/meeting/muteState.js +24 -0
  106. package/test/unit/spec/meeting-info/index.js +4 -4
  107. package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
  108. package/test/unit/spec/meeting-info/request.js +2 -2
  109. package/test/unit/spec/meeting-info/utilv2.js +41 -49
  110. package/test/unit/spec/meetings/index.js +44 -3
  111. package/test/unit/spec/metrics/index.js +126 -0
  112. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
  113. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
  114. package/test/unit/spec/reachability/clusterReachability.ts +116 -22
  115. package/test/unit/spec/reachability/index.ts +1398 -131
  116. package/test/unit/spec/rtcMetrics/index.ts +32 -0
  117. package/dist/mediaQualityMetrics/config.js +0 -321
  118. package/dist/mediaQualityMetrics/config.js.map +0 -1
  119. package/dist/networkQualityMonitor/index.js +0 -227
  120. package/dist/networkQualityMonitor/index.js.map +0 -1
  121. package/dist/statsAnalyzer/global.js +0 -44
  122. package/dist/statsAnalyzer/global.js.map +0 -1
  123. package/dist/statsAnalyzer/index.js +0 -1072
  124. package/dist/statsAnalyzer/index.js.map +0 -1
  125. package/dist/statsAnalyzer/mqaUtil.js +0 -368
  126. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  127. package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
  128. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  129. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  130. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  131. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  132. package/src/mediaQualityMetrics/config.ts +0 -255
  133. package/src/networkQualityMonitor/index.ts +0 -211
  134. package/src/statsAnalyzer/global.ts +0 -37
  135. package/src/statsAnalyzer/index.ts +0 -1318
  136. package/src/statsAnalyzer/mqaUtil.ts +0 -463
  137. package/test/unit/spec/networkQualityMonitor/index.js +0 -99
  138. package/test/unit/spec/stats-analyzer/index.js +0 -1819
package/package.json CHANGED
@@ -43,13 +43,13 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.3.1",
47
- "@webex/plugin-rooms": "3.3.1",
48
- "@webex/test-helper-chai": "3.3.1",
49
- "@webex/test-helper-mocha": "3.3.1",
50
- "@webex/test-helper-mock-webex": "3.3.1",
51
- "@webex/test-helper-retry": "3.3.1",
52
- "@webex/test-helper-test-users": "3.3.1",
46
+ "@webex/plugin-meetings": "3.4.0-next.10",
47
+ "@webex/plugin-rooms": "3.4.0-next.2",
48
+ "@webex/test-helper-chai": "3.4.0-next.2",
49
+ "@webex/test-helper-mocha": "3.4.0-next.2",
50
+ "@webex/test-helper-mock-webex": "3.4.0-next.2",
51
+ "@webex/test-helper-retry": "3.4.0-next.2",
52
+ "@webex/test-helper-test-users": "3.4.0-next.2",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,20 +61,21 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.3.1",
65
- "@webex/internal-media-core": "2.5.1",
66
- "@webex/internal-plugin-conversation": "3.3.1",
67
- "@webex/internal-plugin-device": "3.3.1",
68
- "@webex/internal-plugin-llm": "3.3.1",
69
- "@webex/internal-plugin-mercury": "3.3.1",
70
- "@webex/internal-plugin-metrics": "3.3.1",
71
- "@webex/internal-plugin-support": "3.3.1",
72
- "@webex/internal-plugin-user": "3.3.1",
73
- "@webex/internal-plugin-voicea": "3.3.1",
74
- "@webex/media-helpers": "3.3.1",
75
- "@webex/plugin-people": "3.3.1",
76
- "@webex/plugin-rooms": "3.3.1",
77
- "@webex/webex-core": "3.3.1",
64
+ "@webex/common": "3.4.0-next.2",
65
+ "@webex/internal-media-core": "2.10.2",
66
+ "@webex/internal-plugin-conversation": "3.4.0-next.2",
67
+ "@webex/internal-plugin-device": "3.4.0-next.2",
68
+ "@webex/internal-plugin-llm": "3.4.0-next.2",
69
+ "@webex/internal-plugin-mercury": "3.4.0-next.2",
70
+ "@webex/internal-plugin-metrics": "3.4.0-next.2",
71
+ "@webex/internal-plugin-support": "3.4.0-next.2",
72
+ "@webex/internal-plugin-user": "3.4.0-next.2",
73
+ "@webex/internal-plugin-voicea": "3.4.0-next.10",
74
+ "@webex/media-helpers": "3.4.0-next.4",
75
+ "@webex/plugin-people": "3.4.0-next.2",
76
+ "@webex/plugin-rooms": "3.4.0-next.2",
77
+ "@webex/web-capabilities": "^1.4.0",
78
+ "@webex/webex-core": "3.4.0-next.2",
78
79
  "ampersand-collection": "^2.0.2",
79
80
  "bowser": "^2.11.0",
80
81
  "btoa": "^1.2.1",
@@ -84,12 +85,11 @@
84
85
  "javascript-state-machine": "^3.1.0",
85
86
  "jwt-decode": "3.1.2",
86
87
  "lodash": "^4.17.21",
87
- "sdp-transform": "^2.12.0",
88
88
  "uuid": "^3.3.2",
89
89
  "webrtc-adapter": "^8.1.2"
90
90
  },
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.3.1"
94
+ "version": "3.4.0-next.10"
95
95
  }
@@ -148,7 +148,6 @@ const Breakouts = WebexPlugin.extend({
148
148
  this.triggerReturnToMainEvent(breakout);
149
149
  });
150
150
  this.listenToCurrentSessionTypeChange();
151
- this.listenToBroadcastMessages();
152
151
  this.listenToBreakoutRosters();
153
152
  this.listenToBreakoutHelp();
154
153
  // @ts-ignore
@@ -161,6 +160,7 @@ const Breakouts = WebexPlugin.extend({
161
160
  */
162
161
  cleanUp() {
163
162
  this.stopListening();
163
+ this.hasSubscribedToMessage = undefined;
164
164
  },
165
165
 
166
166
  /**
@@ -170,6 +170,7 @@ const Breakouts = WebexPlugin.extend({
170
170
  */
171
171
  locusUrlUpdate(locusUrl) {
172
172
  this.set('locusUrl', locusUrl);
173
+ this.listenToBroadcastMessages();
173
174
  const {isInMainSession, mainLocusUrl} = this;
174
175
  if (isInMainSession || !mainLocusUrl) {
175
176
  this.set('mainLocusUrl', locusUrl);
@@ -255,6 +256,10 @@ const Breakouts = WebexPlugin.extend({
255
256
  * @returns {void}
256
257
  */
257
258
  listenToBroadcastMessages() {
259
+ if (!this.webex.internal.llm.isConnected() || this.hasSubscribedToMessage) {
260
+ return;
261
+ }
262
+
258
263
  this.listenTo(this.webex.internal.llm, 'event:breakout.message', (event) => {
259
264
  const {
260
265
  data: {senderUserId, sentTime, message},
@@ -270,6 +275,7 @@ const Breakouts = WebexPlugin.extend({
270
275
  sessionId: this.currentBreakoutSession.sessionId,
271
276
  });
272
277
  });
278
+ this.hasSubscribedToMessage = true;
273
279
  },
274
280
 
275
281
  /**
package/src/constants.ts CHANGED
@@ -250,23 +250,6 @@ export const ASSIGN_ROLES_ERROR_CODES = {
250
250
  ReclaimHostIsHostAlreadyErrorCode: 2409150,
251
251
  };
252
252
 
253
- export const DEFAULT_GET_STATS_FILTER = {
254
- types: [
255
- 'track',
256
- 'transport',
257
- 'candidate-pair',
258
- 'outbound-rtp',
259
- 'outboundrtp',
260
- 'inbound-rtp',
261
- 'inboundrtp',
262
- 'remote-inbound-rtp',
263
- 'remote-outbound-rtp',
264
- 'remote-candidate',
265
- 'local-candidate',
266
- 'media-source',
267
- ],
268
- };
269
-
270
253
  export const RECORDING_STATE = {
271
254
  RECORDING: 'recording',
272
255
  IDLE: 'idle',
@@ -1331,3 +1314,16 @@ export const MEETING_PERMISSION_TOKEN_REFRESH_REASON = 'ttl-join';
1331
1314
 
1332
1315
  // constant for named media group type
1333
1316
  export const NAMED_MEDIA_GROUP_TYPE_AUDIO = 1;
1317
+
1318
+ export const DESTINATION_TYPE = {
1319
+ CONVERSATION_URL: 'CONVERSATION_URL',
1320
+ MEETING_LINK: 'MEETING_LINK',
1321
+ SIP_URI: 'SIP_URI',
1322
+ PERSONAL_ROOM: 'PERSONAL_ROOM',
1323
+ ONE_ON_ONE_CALL: 'ONE_ON_ONE_CALL',
1324
+ LOCUS_ID: 'LOCUS_ID',
1325
+ MEETING_ID: 'MEETING_ID',
1326
+ MEETING_UUID: 'MEETING_UUID',
1327
+ } as const;
1328
+
1329
+ export type DESTINATION_TYPE = Enum<typeof DESTINATION_TYPE>;
@@ -428,11 +428,6 @@ SelfUtils.mutedByOthersChanged = (oldSelf, changedSelf) => {
428
428
  return false;
429
429
  }
430
430
 
431
- // there is no need to trigger user update if no one muted user
432
- if (changedSelf.selfIdentity === changedSelf.modifiedBy) {
433
- return false;
434
- }
435
-
436
431
  return (
437
432
  changedSelf.remoteMuted !== null &&
438
433
  (oldSelf.remoteMuted !== changedSelf.remoteMuted ||
@@ -1,5 +1,5 @@
1
1
  import {Defer} from '@webex/common';
2
- import {ConnectionState, Event} from '@webex/internal-media-core';
2
+ import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
3
3
  import LoggerProxy from '../common/logs/logger-proxy';
4
4
  import {ICE_AND_DTLS_CONNECTION_TIMEOUT} from '../constants';
5
5
 
@@ -15,8 +15,10 @@ export default class MediaConnectionAwaiter {
15
15
  private timer: any;
16
16
  private defer: Defer;
17
17
  private retried: boolean;
18
+ private iceConnected: boolean;
18
19
  private onTimeoutCallback: () => void;
19
- private connectionStateCallback: () => void;
20
+ private peerConnectionStateCallback: () => void;
21
+ private iceConnectionStateCallback: () => void;
20
22
  private iceGatheringStateCallback: () => void;
21
23
 
22
24
  /**
@@ -26,9 +28,11 @@ export default class MediaConnectionAwaiter {
26
28
  this.webrtcMediaConnection = webrtcMediaConnection;
27
29
  this.defer = new Defer();
28
30
  this.retried = false;
31
+ this.iceConnected = false;
29
32
  this.onTimeoutCallback = this.onTimeout.bind(this);
30
- this.connectionStateCallback = this.connectionStateListenerCallback.bind(this);
31
- this.iceGatheringStateCallback = this.iceGatheringStateListenerCallback.bind(this);
33
+ this.peerConnectionStateCallback = this.peerConnectionStateHandler.bind(this);
34
+ this.iceConnectionStateCallback = this.iceConnectionStateHandler.bind(this);
35
+ this.iceGatheringStateCallback = this.iceGatheringStateHandler.bind(this);
32
36
  }
33
37
 
34
38
  /**
@@ -40,6 +44,15 @@ export default class MediaConnectionAwaiter {
40
44
  return this.webrtcMediaConnection.getConnectionState() === ConnectionState.Connected;
41
45
  }
42
46
 
47
+ /**
48
+ * Returns true if the connection is in an unrecoverable "failed" state
49
+ *
50
+ * @returns {boolean}
51
+ */
52
+ private isFailed(): boolean {
53
+ return this.webrtcMediaConnection.getConnectionState() === ConnectionState.Failed;
54
+ }
55
+
43
56
  /**
44
57
  * Returns true if the ICE Gathering is completed, false otherwise.
45
58
  *
@@ -56,22 +69,40 @@ export default class MediaConnectionAwaiter {
56
69
  */
57
70
  private clearCallbacks(): void {
58
71
  this.webrtcMediaConnection.off(
59
- Event.ICE_GATHERING_STATE_CHANGED,
72
+ MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED,
60
73
  this.iceGatheringStateCallback
61
74
  );
62
- this.webrtcMediaConnection.off(Event.CONNECTION_STATE_CHANGED, this.connectionStateCallback);
75
+ this.webrtcMediaConnection.off(
76
+ MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
77
+ this.peerConnectionStateCallback
78
+ );
79
+ this.webrtcMediaConnection.off(
80
+ MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
81
+ this.iceConnectionStateCallback
82
+ );
63
83
  }
64
84
 
65
85
  /**
66
- * Listener for connection state change.
86
+ * On connection state change.
67
87
  *
68
88
  * @returns {void}
69
89
  */
70
- connectionStateListenerCallback(): void {
90
+ connectionStateChange(): void {
71
91
  LoggerProxy.logger.log(
72
- `Media:MediaConnectionAwaiter#connectionStateListenerCallback --> connection state: ${this.webrtcMediaConnection.getConnectionState()}`
92
+ `Media:MediaConnectionAwaiter#connectionStateChange --> connection state: ${this.webrtcMediaConnection.getConnectionState()}`
73
93
  );
74
94
 
95
+ if (this.isFailed()) {
96
+ LoggerProxy.logger.warn(
97
+ 'Media:MediaConnectionAwaiter#connectionStateChange --> ICE failed, rejecting'
98
+ );
99
+ this.clearCallbacks();
100
+
101
+ this.defer.reject({
102
+ iceConnected: this.iceConnected,
103
+ });
104
+ }
105
+
75
106
  if (!this.isConnected()) {
76
107
  return;
77
108
  }
@@ -83,16 +114,50 @@ export default class MediaConnectionAwaiter {
83
114
  this.defer.resolve();
84
115
  }
85
116
 
117
+ /**
118
+ * Listener for peer connection state change.
119
+ *
120
+ * @returns {void}
121
+ */
122
+ peerConnectionStateHandler(): void {
123
+ const peerConnectionState = this.webrtcMediaConnection.getPeerConnectionState();
124
+
125
+ LoggerProxy.logger.log(
126
+ `Media:MediaConnectionAwaiter#peerConnectionStateHandler --> Peer connection state change -> ${peerConnectionState}`
127
+ );
128
+
129
+ this.connectionStateChange();
130
+ }
131
+
132
+ /**
133
+ * Listener for ICE connection state change.
134
+ *
135
+ * @returns {void}
136
+ */
137
+ iceConnectionStateHandler(): void {
138
+ const iceConnectionState = this.webrtcMediaConnection.getIceConnectionState();
139
+
140
+ LoggerProxy.logger.log(
141
+ `Media:MediaConnectionAwaiter#iceConnectionStateHandler --> ICE connection state change -> ${iceConnectionState}`
142
+ );
143
+
144
+ if (iceConnectionState === 'connected' && !this.iceConnected) {
145
+ this.iceConnected = true;
146
+ }
147
+
148
+ this.connectionStateChange();
149
+ }
150
+
86
151
  /**
87
152
  * Listener for ICE gathering state change.
88
153
  *
89
154
  * @returns {void}
90
155
  */
91
- iceGatheringStateListenerCallback(): void {
156
+ iceGatheringStateHandler(): void {
92
157
  const iceGatheringState = this.webrtcMediaConnection.getIceGatheringState();
93
158
 
94
159
  LoggerProxy.logger.log(
95
- `Media:MediaConnectionAwaiter#iceGatheringStateListenerCallback --> ICE gathering state change -> ${iceGatheringState}`
160
+ `Media:MediaConnectionAwaiter#iceGatheringStateHandler --> ICE gathering state change -> ${iceGatheringState}`
96
161
  );
97
162
 
98
163
  if (!this.isIceGatheringCompleted()) {
@@ -147,7 +212,9 @@ export default class MediaConnectionAwaiter {
147
212
 
148
213
  this.clearCallbacks();
149
214
 
150
- this.defer.reject();
215
+ this.defer.reject({
216
+ iceConnected: this.iceConnected,
217
+ });
151
218
  }
152
219
 
153
220
  /**
@@ -160,10 +227,18 @@ export default class MediaConnectionAwaiter {
160
227
  return Promise.resolve();
161
228
  }
162
229
 
163
- this.webrtcMediaConnection.on(Event.CONNECTION_STATE_CHANGED, this.connectionStateCallback);
230
+ this.webrtcMediaConnection.on(
231
+ MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
232
+ this.peerConnectionStateCallback
233
+ );
234
+
235
+ this.webrtcMediaConnection.on(
236
+ MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
237
+ this.iceConnectionStateCallback
238
+ );
164
239
 
165
240
  this.webrtcMediaConnection.on(
166
- Event.ICE_GATHERING_STATE_CHANGED,
241
+ MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED,
167
242
  this.iceGatheringStateCallback
168
243
  );
169
244
 
@@ -104,9 +104,7 @@ Media.getDirection = (forceSendRecv: boolean, receive: boolean, send: boolean) =
104
104
  *
105
105
  * @param {boolean} isMultistream
106
106
  * @param {string} debugId string useful for debugging (will appear in media connection logs)
107
- * @param {object} webex main `webex` object.
108
107
  * @param {string} meetingId id for the meeting using this connection
109
- * @param {string} correlationId id used in requests to correlate to this session
110
108
  * @param {Object} options
111
109
  * @param {Object} [options.mediaProperties] contains mediaDirection and local tracks:
112
110
  * audioTrack, videoTrack, shareVideoTrack, and shareAudioTrack
@@ -120,10 +118,9 @@ Media.getDirection = (forceSendRecv: boolean, receive: boolean, send: boolean) =
120
118
  Media.createMediaConnection = (
121
119
  isMultistream: boolean,
122
120
  debugId: string,
123
- webex: object,
124
121
  meetingId: string,
125
- correlationId: string,
126
122
  options: {
123
+ rtcMetrics?: RtcMetrics;
127
124
  mediaProperties: {
128
125
  mediaDirection?: {
129
126
  receiveAudio: boolean;
@@ -150,6 +147,7 @@ Media.createMediaConnection = (
150
147
  }
151
148
  ) => {
152
149
  const {
150
+ rtcMetrics,
153
151
  mediaProperties,
154
152
  remoteQualityLevel,
155
153
  enableRtx,
@@ -163,6 +161,19 @@ Media.createMediaConnection = (
163
161
  // we might not have any TURN server if TURN discovery failed or wasn't done or
164
162
  // we might get an empty TURN url if we land on a video mesh node
165
163
  if (turnServerInfo?.url) {
164
+ if (!isBrowser('firefox')) {
165
+ let bareTurnServer = turnServerInfo.url;
166
+ bareTurnServer = bareTurnServer.replace('turns:', 'turn:');
167
+ bareTurnServer = bareTurnServer.replace('443', '5004');
168
+
169
+ iceServers.push({
170
+ urls: bareTurnServer,
171
+ username: turnServerInfo.username || '',
172
+ credential: turnServerInfo.password || '',
173
+ });
174
+ }
175
+
176
+ // TURN-TLS server
166
177
  iceServers.push({
167
178
  urls: turnServerInfo.url,
168
179
  username: turnServerInfo.username || '',
@@ -179,15 +190,13 @@ Media.createMediaConnection = (
179
190
  config.bundlePolicy = bundlePolicy;
180
191
  }
181
192
 
182
- const rtcMetrics = new RtcMetrics(webex, meetingId, correlationId);
183
-
184
193
  return new MultistreamRoapMediaConnection(
185
194
  config,
186
195
  meetingId,
187
196
  /* the rtc metrics objects callbacks */
188
- (data) => rtcMetrics.addMetrics(data),
189
- () => rtcMetrics.closeMetrics(),
190
- () => rtcMetrics.sendMetricsInQueue()
197
+ (data) => rtcMetrics?.addMetrics(data),
198
+ () => rtcMetrics?.closeMetrics(),
199
+ () => rtcMetrics?.sendMetricsInQueue()
191
200
  );
192
201
  }
193
202
 
@@ -0,0 +1,65 @@
1
+ import {MediaConnectionEventNames, ConnectionState} from '@webex/internal-media-core';
2
+ import EventsScope from '../common/events/events-scope';
3
+ import {Enum} from '../constants';
4
+
5
+ export const ConnectionStateEvent = {
6
+ stateChanged: 'connectionState:changed',
7
+ } as const;
8
+
9
+ export type ConnectionStateEvent = Enum<typeof ConnectionStateEvent>;
10
+
11
+ export interface ConnectionStateChangedEvent {
12
+ /**
13
+ * Current overall connection state
14
+ */
15
+ state: ConnectionState;
16
+ }
17
+
18
+ /**
19
+ * @class ConnectionStateHandler
20
+ */
21
+ export class ConnectionStateHandler extends EventsScope {
22
+ private webrtcMediaConnection: any;
23
+
24
+ private mediaConnectionState: ConnectionState;
25
+
26
+ /**
27
+ * @param {WebRTCMeeting} webrtcMediaConnection
28
+ */
29
+ constructor(webrtcMediaConnection) {
30
+ super();
31
+
32
+ this.webrtcMediaConnection = webrtcMediaConnection;
33
+
34
+ this.webrtcMediaConnection.on(
35
+ MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED,
36
+ this.handleConnectionStateChange.bind(this)
37
+ );
38
+
39
+ this.webrtcMediaConnection.on(
40
+ MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED,
41
+ this.handleConnectionStateChange.bind(this)
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Handler for connection state change.
47
+ *
48
+ * @returns {void}
49
+ */
50
+ private handleConnectionStateChange(): void {
51
+ const newConnectionState = this.webrtcMediaConnection.getConnectionState();
52
+
53
+ if (newConnectionState !== this.mediaConnectionState) {
54
+ this.mediaConnectionState = newConnectionState;
55
+ this.emit(
56
+ {
57
+ file: 'connectionStateHandler',
58
+ function: 'handleConnectionStateChange',
59
+ },
60
+ ConnectionStateEvent.stateChanged,
61
+ {state: this.mediaConnectionState}
62
+ );
63
+ }
64
+ }
65
+ }