@webex/plugin-meetings 3.8.0-next.66 → 3.8.0-next.68

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.
@@ -458,7 +458,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
458
458
  }, _callee7);
459
459
  }))();
460
460
  },
461
- version: "3.8.0-next.66"
461
+ version: "3.8.0-next.68"
462
462
  });
463
463
  var _default = exports.default = Webinar;
464
464
  //# sourceMappingURL=index.js.map
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.8.0-next.66",
47
- "@webex/plugin-rooms": "3.8.0-next.23",
48
- "@webex/test-helper-chai": "3.8.0-next.19",
49
- "@webex/test-helper-mocha": "3.8.0-next.19",
50
- "@webex/test-helper-mock-webex": "3.8.0-next.19",
51
- "@webex/test-helper-retry": "3.8.0-next.19",
52
- "@webex/test-helper-test-users": "3.8.0-next.19",
46
+ "@webex/plugin-meetings": "3.8.0-next.68",
47
+ "@webex/plugin-rooms": "3.8.0-next.24",
48
+ "@webex/test-helper-chai": "3.8.0-next.20",
49
+ "@webex/test-helper-mocha": "3.8.0-next.20",
50
+ "@webex/test-helper-mock-webex": "3.8.0-next.20",
51
+ "@webex/test-helper-retry": "3.8.0-next.20",
52
+ "@webex/test-helper-test-users": "3.8.0-next.20",
53
53
  "chai": "^4.3.4",
54
54
  "chai-as-promised": "^7.1.1",
55
55
  "eslint": "^8.24.0",
@@ -61,23 +61,23 @@
61
61
  "typescript": "^4.7.4"
62
62
  },
63
63
  "dependencies": {
64
- "@webex/common": "3.8.0-next.19",
64
+ "@webex/common": "3.8.0-next.20",
65
65
  "@webex/event-dictionary-ts": "^1.0.1753",
66
66
  "@webex/internal-media-core": "2.16.0",
67
- "@webex/internal-plugin-conversation": "3.8.0-next.23",
68
- "@webex/internal-plugin-device": "3.8.0-next.19",
69
- "@webex/internal-plugin-llm": "3.8.0-next.22",
70
- "@webex/internal-plugin-mercury": "3.8.0-next.21",
71
- "@webex/internal-plugin-metrics": "3.8.0-next.19",
72
- "@webex/internal-plugin-support": "3.8.0-next.23",
73
- "@webex/internal-plugin-user": "3.8.0-next.19",
74
- "@webex/internal-plugin-voicea": "3.8.0-next.66",
75
- "@webex/media-helpers": "3.8.0-next.23",
76
- "@webex/plugin-people": "3.8.0-next.21",
77
- "@webex/plugin-rooms": "3.8.0-next.23",
67
+ "@webex/internal-plugin-conversation": "3.8.0-next.24",
68
+ "@webex/internal-plugin-device": "3.8.0-next.20",
69
+ "@webex/internal-plugin-llm": "3.8.0-next.23",
70
+ "@webex/internal-plugin-mercury": "3.8.0-next.22",
71
+ "@webex/internal-plugin-metrics": "3.8.0-next.20",
72
+ "@webex/internal-plugin-support": "3.8.0-next.24",
73
+ "@webex/internal-plugin-user": "3.8.0-next.20",
74
+ "@webex/internal-plugin-voicea": "3.8.0-next.68",
75
+ "@webex/media-helpers": "3.8.0-next.24",
76
+ "@webex/plugin-people": "3.8.0-next.22",
77
+ "@webex/plugin-rooms": "3.8.0-next.24",
78
78
  "@webex/ts-sdp": "^1.8.1",
79
79
  "@webex/web-capabilities": "^1.4.0",
80
- "@webex/webex-core": "3.8.0-next.19",
80
+ "@webex/webex-core": "3.8.0-next.20",
81
81
  "ampersand-collection": "^2.0.2",
82
82
  "bowser": "^2.11.0",
83
83
  "btoa": "^1.2.1",
@@ -93,5 +93,5 @@
93
93
  "//": [
94
94
  "TODO: upgrade jwt-decode when moving to node 18"
95
95
  ],
96
- "version": "3.8.0-next.66"
96
+ "version": "3.8.0-next.68"
97
97
  }
package/src/config.ts CHANGED
@@ -98,5 +98,6 @@ export default {
98
98
  enableReachabilityChecks: true,
99
99
  reachabilityGetClusterTimeout: 5000,
100
100
  logUploadIntervalMultiplicationFactor: 0, // if set to 0 or undefined, logs won't be uploaded periodically, if you want periodic logs, recommended value is 1
101
+ stopIceGatheringAfterFirstRelayCandidate: false,
101
102
  },
102
103
  };
@@ -16,6 +16,7 @@ import {
16
16
  LocalMicrophoneStream,
17
17
  } from '@webex/media-helpers';
18
18
  import {RtcMetrics} from '@webex/internal-plugin-metrics';
19
+ import {BrowserInfo} from '@webex/web-capabilities';
19
20
  import LoggerProxy from '../common/logs/logger-proxy';
20
21
  import {MEDIA_TRACK_CONSTRAINT} from '../constants';
21
22
  import Config from '../config';
@@ -143,6 +144,7 @@ Media.createMediaConnection = (
143
144
  bundlePolicy?: BundlePolicy;
144
145
  iceCandidatesTimeout?: number;
145
146
  disableAudioMainDtx?: boolean;
147
+ stopIceGatheringAfterFirstRelayCandidate?: boolean;
146
148
  }
147
149
  ) => {
148
150
  const {
@@ -155,6 +157,7 @@ Media.createMediaConnection = (
155
157
  bundlePolicy,
156
158
  iceCandidatesTimeout,
157
159
  disableAudioMainDtx,
160
+ stopIceGatheringAfterFirstRelayCandidate,
158
161
  } = options;
159
162
 
160
163
  const iceServers = [];
@@ -182,6 +185,12 @@ Media.createMediaConnection = (
182
185
  config.disableAudioMainDtx = disableAudioMainDtx;
183
186
  }
184
187
 
188
+ if (BrowserInfo.isFirefox()) {
189
+ config.doFullIce = true;
190
+
191
+ config.stopIceGatheringAfterFirstRelayCandidate = stopIceGatheringAfterFirstRelayCandidate;
192
+ }
193
+
185
194
  return new MultistreamRoapMediaConnection(
186
195
  config,
187
196
  meetingId,
@@ -7022,6 +7022,9 @@ export default class Meeting extends StatelessWebexPlugin {
7022
7022
  iceCandidatesTimeout: this.config.iceCandidatesGatheringTimeout,
7023
7023
  // @ts-ignore - config coming from registerPlugin
7024
7024
  disableAudioMainDtx: this.config.experimental.disableAudioMainDtx,
7025
+ stopIceGatheringAfterFirstRelayCandidate:
7026
+ // @ts-ignore - config coming from registerPlugin
7027
+ this.config.stopIceGatheringAfterFirstRelayCandidate,
7025
7028
  }
7026
7029
  );
7027
7030
 
@@ -827,6 +827,27 @@ export default class Meetings extends WebexPlugin {
827
827
  }
828
828
  }
829
829
 
830
+ /**
831
+ * API to toggle stopping ICE Candidates Gathering after first relay candidate,
832
+ * needs to be called before webex.meetings.joinWithMedia()
833
+ *
834
+ * @param {Boolean} newValue
835
+ * @private
836
+ * @memberof Meetings
837
+ * @returns {undefined}
838
+ */
839
+ private _toggleStopIceGatheringAfterFirstRelayCandidate(newValue: boolean) {
840
+ if (typeof newValue !== 'boolean') {
841
+ return;
842
+ }
843
+
844
+ // @ts-ignore
845
+ if (this.config.stopIceGatheringAfterFirstRelayCandidate !== newValue) {
846
+ // @ts-ignore
847
+ this.config.stopIceGatheringAfterFirstRelayCandidate = newValue;
848
+ }
849
+ }
850
+
830
851
  /**
831
852
  * Executes a registration step and updates the registration status.
832
853
  * @param {Function} step - The registration step to execute.
@@ -4,6 +4,7 @@ import Media from '@webex/plugin-meetings/src/media/index';
4
4
  import {assert} from '@webex/test-helper-chai';
5
5
  import sinon from 'sinon';
6
6
  import StaticConfig from '@webex/plugin-meetings/src/common/config';
7
+ import { BrowserInfo } from '@webex/web-capabilities';
7
8
 
8
9
  describe('createMediaConnection', () => {
9
10
  let clock;
@@ -197,7 +198,68 @@ describe('createMediaConnection', () => {
197
198
 
198
199
  sendMetricsInQueueCallback();
199
200
  assert.calledOnce(rtcMetrics.sendMetricsInQueue);
201
+ });
202
+
203
+ it('multistream non-firefox does not care about stopIceGatheringAfterFirstRelayCandidate', () => {
204
+ const multistreamRoapMediaConnectionConstructorStub = sinon
205
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
206
+ .returns(fakeRoapMediaConnection);
207
+
208
+ Media.createMediaConnection(true, 'some debug id', 'meeting id', {
209
+ stopIceGatheringAfterFirstRelayCandidate: true,
210
+ });
211
+ assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
212
+ assert.calledWith(
213
+ multistreamRoapMediaConnectionConstructorStub,
214
+ {
215
+ iceServers: []
216
+ },
217
+ 'meeting id'
218
+ );
219
+ });
220
+
221
+ it('multistream firefox stops gathering after first relay if stopIceGatheringAfterFirstRelayCandidate is true', () => {
222
+ const multistreamRoapMediaConnectionConstructorStub = sinon
223
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
224
+ .returns(fakeRoapMediaConnection);
225
+
226
+ sinon.stub(BrowserInfo, 'isFirefox').returns(true);
227
+
228
+ Media.createMediaConnection(true, 'some debug id', 'meeting id', {
229
+ stopIceGatheringAfterFirstRelayCandidate: true,
230
+ });
231
+ assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
232
+ assert.calledWith(
233
+ multistreamRoapMediaConnectionConstructorStub,
234
+ {
235
+ iceServers: [],
236
+ doFullIce: true,
237
+ stopIceGatheringAfterFirstRelayCandidate: true,
238
+ },
239
+ 'meeting id'
240
+ );
241
+ });
242
+
243
+ it('multistream firefox continues gathering if stopIceGatheringAfterFirstRelayCandidate is false', () => {
244
+ const multistreamRoapMediaConnectionConstructorStub = sinon
245
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
246
+ .returns(fakeRoapMediaConnection);
247
+
248
+ sinon.stub(BrowserInfo, 'isFirefox').returns(true);
200
249
 
250
+ Media.createMediaConnection(true, 'some debug id', 'meeting id', {
251
+ stopIceGatheringAfterFirstRelayCandidate: false,
252
+ });
253
+ assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
254
+ assert.calledWith(
255
+ multistreamRoapMediaConnectionConstructorStub,
256
+ {
257
+ iceServers: [],
258
+ doFullIce: true,
259
+ stopIceGatheringAfterFirstRelayCandidate: false,
260
+ },
261
+ 'meeting id'
262
+ );
201
263
  });
202
264
 
203
265
  [
@@ -413,6 +413,19 @@ describe('plugin-meetings', () => {
413
413
  });
414
414
  });
415
415
 
416
+ describe('#_toggleStopIceGatheringAfterFirstRelayCandidate', () => {
417
+ it('should have _toggleStopIceGatheringAfterFirstRelayCandidate', () => {
418
+ assert.equal(typeof webex.meetings._toggleStopIceGatheringAfterFirstRelayCandidate, 'function');
419
+ });
420
+
421
+ describe('success', () => {
422
+ it('should update meetings to stop ICE candidates gathering after first relay candidate', () => {
423
+ webex.meetings._toggleStopIceGatheringAfterFirstRelayCandidate(true);
424
+ assert.equal(webex.meetings.config.stopIceGatheringAfterFirstRelayCandidate, true);
425
+ });
426
+ });
427
+ });
428
+
416
429
  describe('Public API Contracts', () => {
417
430
  describe('#register', () => {
418
431
  it('emits an event and resolves when register succeeds', async () => {