@webex/plugin-meetings 3.0.0-beta.13 → 3.0.0-beta.15
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.
- package/UPGRADING.md +9 -9
- package/browsers.js +19 -24
- package/dist/common/browser-detection.js +1 -0
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js.map +1 -1
- package/dist/common/errors/captcha-error.js +5 -5
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +5 -5
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-meeting.js +6 -6
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/media.js +5 -5
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/parameter.js +5 -5
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +5 -5
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +4 -4
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reconnection.js +5 -5
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +5 -5
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +11 -8
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +2 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +2 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js.map +1 -1
- package/dist/media/internal-media-core-wrapper.js.map +1 -1
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js +1 -1
- package/dist/media/util.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/effectsState.js +1 -1
- package/dist/meeting/effectsState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +118 -89
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +1 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +25 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js +8 -0
- package/dist/meeting/request.type.js.map +1 -0
- package/dist/meeting/state.js +5 -5
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +2 -2
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +48 -48
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +1 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +251 -250
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/request.js +2 -2
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +14 -14
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +31 -31
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +43 -43
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +23 -20
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/multistreamMedia.js +2 -1
- package/dist/multistream/multistreamMedia.js.map +1 -1
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +2 -0
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +8 -8
- package/dist/networkQualityMonitor/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +7 -7
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js.map +1 -1
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js +3 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +4 -4
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +5 -5
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/statsAnalyzer/global.js.map +1 -1
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/transcription/index.js +4 -1
- package/dist/transcription/index.js.map +1 -1
- package/internal-README.md +7 -6
- package/package.json +18 -18
- package/src/common/browser-detection.ts +9 -6
- package/src/common/collection.ts +3 -1
- package/src/common/errors/captcha-error.ts +6 -6
- package/src/common/errors/intent-to-join.ts +6 -6
- package/src/common/errors/join-meeting.ts +12 -8
- package/src/common/errors/media.ts +6 -6
- package/src/common/errors/parameter.ts +9 -6
- package/src/common/errors/password-error.ts +6 -6
- package/src/common/errors/permission.ts +5 -5
- package/src/common/errors/reconnection.ts +6 -6
- package/src/common/errors/stats.ts +6 -6
- package/src/common/errors/webex-errors.ts +7 -5
- package/src/common/errors/webex-meetings-error.ts +1 -1
- package/src/common/events/events-scope.ts +5 -1
- package/src/common/events/events.ts +5 -1
- package/src/common/events/trigger-proxy.ts +8 -3
- package/src/common/events/util.ts +1 -2
- package/src/common/logs/logger-proxy.ts +21 -10
- package/src/common/logs/request.ts +11 -8
- package/src/config.ts +11 -11
- package/src/constants.ts +1 -1
- package/src/index.js +1 -1
- package/src/locus-info/controlsUtils.ts +34 -24
- package/src/locus-info/fullState.ts +15 -11
- package/src/locus-info/hostUtils.ts +4 -3
- package/src/locus-info/index.ts +25 -34
- package/src/locus-info/infoUtils.ts +12 -4
- package/src/locus-info/mediaSharesUtils.ts +4 -4
- package/src/locus-info/parser.ts +45 -68
- package/src/locus-info/selfUtils.ts +106 -57
- package/src/media/index.ts +123 -135
- package/src/media/internal-media-core-wrapper.ts +2 -2
- package/src/media/properties.ts +30 -20
- package/src/media/util.ts +1 -1
- package/src/mediaQualityMetrics/config.ts +46 -46
- package/src/meeting/effectsState.ts +35 -35
- package/src/meeting/in-meeting-actions.ts +7 -3
- package/src/meeting/index.ts +1576 -1291
- package/src/meeting/muteState.ts +62 -31
- package/src/meeting/request.ts +174 -113
- package/src/meeting/request.type.ts +11 -0
- package/src/meeting/state.ts +45 -30
- package/src/meeting/util.ts +101 -70
- package/src/meeting-info/collection.ts +2 -1
- package/src/meeting-info/index.ts +32 -30
- package/src/meeting-info/meeting-info-v2.ts +106 -108
- package/src/meeting-info/request.ts +9 -3
- package/src/meeting-info/util.ts +54 -46
- package/src/meeting-info/utilv2.ts +59 -53
- package/src/meetings/collection.ts +1 -1
- package/src/meetings/index.ts +512 -440
- package/src/meetings/request.ts +26 -24
- package/src/meetings/util.ts +29 -29
- package/src/member/index.ts +55 -49
- package/src/member/util.ts +26 -13
- package/src/members/collection.ts +0 -1
- package/src/members/index.ts +182 -126
- package/src/members/request.ts +46 -14
- package/src/members/util.ts +44 -42
- package/src/metrics/config.ts +254 -81
- package/src/metrics/constants.ts +0 -2
- package/src/metrics/index.ts +84 -71
- package/src/multistream/multistreamMedia.ts +1 -0
- package/src/multistream/receiveSlot.ts +1 -0
- package/src/multistream/receiveSlotManager.ts +1 -0
- package/src/multistream/remoteMedia.ts +1 -1
- package/src/multistream/remoteMediaGroup.ts +2 -1
- package/src/multistream/remoteMediaManager.ts +3 -0
- package/src/networkQualityMonitor/index.ts +20 -23
- package/src/personal-meeting-room/index.ts +12 -16
- package/src/personal-meeting-room/request.ts +10 -3
- package/src/personal-meeting-room/util.ts +3 -3
- package/src/reachability/index.ts +61 -59
- package/src/reachability/request.ts +36 -32
- package/src/reactions/reactions.ts +4 -4
- package/src/reactions/reactions.type.ts +4 -3
- package/src/reconnection-manager/index.ts +139 -84
- package/src/roap/index.ts +46 -38
- package/src/roap/request.ts +44 -31
- package/src/roap/turnDiscovery.ts +59 -30
- package/src/statsAnalyzer/global.ts +30 -33
- package/src/statsAnalyzer/index.ts +432 -175
- package/src/statsAnalyzer/mqaUtil.ts +178 -72
- package/src/transcription/index.ts +34 -32
- package/test/integration/spec/journey.js +663 -462
- package/test/integration/spec/space-meeting.js +318 -203
- package/test/integration/spec/transcription.js +6 -7
- package/test/unit/spec/common/browser-detection.js +9 -28
- package/test/unit/spec/fixture/locus.js +92 -90
- package/test/unit/spec/locus-info/controlsUtils.js +5 -5
- package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
- package/test/unit/spec/locus-info/index.js +1 -2
- package/test/unit/spec/locus-info/infoUtils.js +26 -33
- package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
- package/test/unit/spec/locus-info/lib/SeqCmp.json +513 -685
- package/test/unit/spec/locus-info/parser.js +3 -9
- package/test/unit/spec/locus-info/selfConstant.js +72 -103
- package/test/unit/spec/locus-info/selfUtils.js +21 -12
- package/test/unit/spec/meeting/effectsState.js +36 -46
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -3
- package/test/unit/spec/meeting/index.js +1342 -684
- package/test/unit/spec/meeting/muteState.js +42 -33
- package/test/unit/spec/meeting/request.js +75 -45
- package/test/unit/spec/meeting/utils.js +78 -53
- package/test/unit/spec/meeting-info/meetinginfov2.js +100 -73
- package/test/unit/spec/meeting-info/request.js +7 -9
- package/test/unit/spec/meeting-info/util.js +11 -12
- package/test/unit/spec/meeting-info/utilv2.js +110 -74
- package/test/unit/spec/meetings/collection.js +1 -1
- package/test/unit/spec/meetings/index.js +438 -257
- package/test/unit/spec/meetings/utils.js +14 -12
- package/test/unit/spec/member/index.js +0 -1
- package/test/unit/spec/member/util.js +5 -6
- package/test/unit/spec/members/index.js +104 -54
- package/test/unit/spec/members/request.js +29 -20
- package/test/unit/spec/members/utils.js +8 -5
- package/test/unit/spec/metrics/index.js +16 -21
- package/test/unit/spec/networkQualityMonitor/index.js +21 -15
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
- package/test/unit/spec/reachability/index.ts +9 -11
- package/test/unit/spec/reconnection-manager/index.js +16 -18
- package/test/unit/spec/roap/turnDiscovery.ts +22 -19
- package/test/unit/spec/stats-analyzer/index.js +25 -20
- package/test/utils/cmr.js +44 -42
- package/test/utils/testUtils.js +83 -74
- package/test/utils/webex-config.js +18 -18
- package/test/utils/webex-test-users.js +53 -50
package/src/metrics/index.ts
CHANGED
|
@@ -13,8 +13,13 @@ import {MEETING_ERRORS} from '../constants';
|
|
|
13
13
|
import BrowserDetection from '../common/browser-detection';
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
|
-
error,
|
|
17
|
-
|
|
16
|
+
error,
|
|
17
|
+
eventType,
|
|
18
|
+
errorCodes as ERROR_CODE,
|
|
19
|
+
OS_NAME,
|
|
20
|
+
UNKNOWN,
|
|
21
|
+
CLIENT_NAME,
|
|
22
|
+
mediaType,
|
|
18
23
|
} from './config';
|
|
19
24
|
|
|
20
25
|
const OSMap = {
|
|
@@ -24,15 +29,10 @@ const OSMap = {
|
|
|
24
29
|
Windows: OS_NAME.WINDOWS,
|
|
25
30
|
iOS: OS_NAME.IOS,
|
|
26
31
|
Android: OS_NAME.ANDROID,
|
|
27
|
-
Linux: OS_NAME.LINUX
|
|
32
|
+
Linux: OS_NAME.LINUX,
|
|
28
33
|
};
|
|
29
34
|
|
|
30
|
-
const {
|
|
31
|
-
getOSName,
|
|
32
|
-
getOSVersion,
|
|
33
|
-
getBrowserName,
|
|
34
|
-
getBrowserVersion
|
|
35
|
-
} = BrowserDetection();
|
|
35
|
+
const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
36
36
|
|
|
37
37
|
// Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses
|
|
38
38
|
// For reference : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
|
|
@@ -85,33 +85,33 @@ class Metrics {
|
|
|
85
85
|
webex: any;
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
* Create Metrics Object
|
|
89
|
+
* @constructor
|
|
90
|
+
* @public
|
|
91
|
+
* @memberof Meetings
|
|
92
|
+
*/
|
|
93
93
|
constructor() {
|
|
94
94
|
if (!Metrics.instance) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
/**
|
|
96
|
+
* @instance
|
|
97
|
+
* @type {Array}
|
|
98
|
+
* @private
|
|
99
|
+
* @memberof Metrics
|
|
100
|
+
*/
|
|
101
101
|
this._events = [];
|
|
102
102
|
/**
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
* @instance
|
|
104
|
+
* @type {MeetingCollection}
|
|
105
|
+
* @private
|
|
106
|
+
* @memberof Metrics
|
|
107
|
+
*/
|
|
108
108
|
this.meetingCollection = null;
|
|
109
109
|
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
* @instance
|
|
111
|
+
* @type {MeetingCollection}
|
|
112
|
+
* @private
|
|
113
|
+
* @memberof Metrics
|
|
114
|
+
*/
|
|
115
115
|
this.keys = Object.values(eventType);
|
|
116
116
|
/**
|
|
117
117
|
* @instance
|
|
@@ -122,6 +122,7 @@ class Metrics {
|
|
|
122
122
|
Metrics.instance = this;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// eslint-disable-next-line no-constructor-return
|
|
125
126
|
return Metrics.instance;
|
|
126
127
|
}
|
|
127
128
|
|
|
@@ -147,12 +148,14 @@ class Metrics {
|
|
|
147
148
|
* @param {object} options.event
|
|
148
149
|
* @returns {object} null
|
|
149
150
|
*/
|
|
150
|
-
postEvent(options: {
|
|
151
|
+
postEvent(options: {meeting?: any; meetingId?: string; data?: object; event?: any} | any) {
|
|
151
152
|
const {meetingId, data = {}, event} = options;
|
|
152
153
|
let {meeting} = options;
|
|
153
154
|
|
|
154
155
|
if (this.keys.indexOf(event) === -1) {
|
|
155
|
-
LoggerProxy.logger.error(
|
|
156
|
+
LoggerProxy.logger.error(
|
|
157
|
+
`Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`
|
|
158
|
+
);
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
if (!meeting && meetingId) {
|
|
@@ -169,25 +172,25 @@ class Metrics {
|
|
|
169
172
|
if (event === eventType.MEDIA_QUALITY) {
|
|
170
173
|
data.event = event;
|
|
171
174
|
meeting.sendMediaQualityAnalyzerMetrics(data);
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
175
|
+
} else {
|
|
174
176
|
meeting.callEvents.push(event);
|
|
175
177
|
data.event = event;
|
|
176
178
|
meeting.sendCallAnalyzerMetrics(data);
|
|
177
179
|
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
} else {
|
|
181
|
+
LoggerProxy.logger.info(
|
|
182
|
+
`Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`
|
|
183
|
+
);
|
|
182
184
|
}
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
/**
|
|
186
188
|
* Docs for Call analyzer metrics
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
* https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki
|
|
190
|
+
* https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml
|
|
191
|
+
*/
|
|
190
192
|
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
191
194
|
initPayload(eventType, identifiers, options) {
|
|
192
195
|
const payload: any = {
|
|
193
196
|
eventId: uuid.v4(),
|
|
@@ -204,19 +207,19 @@ class Metrics {
|
|
|
204
207
|
subClientType: options.subClientType,
|
|
205
208
|
os: this.getOsName(),
|
|
206
209
|
browser: getBrowserName(),
|
|
207
|
-
browserVersion: getBrowserVersion()
|
|
208
|
-
}
|
|
210
|
+
browserVersion: getBrowserVersion(),
|
|
211
|
+
},
|
|
209
212
|
},
|
|
210
213
|
originTime: {
|
|
211
|
-
triggered: new Date().toISOString()
|
|
214
|
+
triggered: new Date().toISOString(),
|
|
212
215
|
},
|
|
213
216
|
senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,
|
|
214
217
|
event: {
|
|
215
218
|
name: eventType,
|
|
216
219
|
canProceed: true,
|
|
217
220
|
identifiers,
|
|
218
|
-
eventData: {webClientDomain: window.location.hostname}
|
|
219
|
-
}
|
|
221
|
+
eventData: {webClientDomain: window.location.hostname},
|
|
222
|
+
},
|
|
220
223
|
};
|
|
221
224
|
|
|
222
225
|
// TODO: more options should be checked and some of them should be mandatory in certain conditions
|
|
@@ -279,16 +282,19 @@ class Metrics {
|
|
|
279
282
|
* @memberof Metrics
|
|
280
283
|
*/
|
|
281
284
|
public initMediaPayload(
|
|
285
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
282
286
|
eventType: string,
|
|
283
287
|
identifiers: {
|
|
284
288
|
correlationId: string;
|
|
285
289
|
locusUrl: string;
|
|
286
290
|
locusId: string;
|
|
287
291
|
},
|
|
288
|
-
options:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
options:
|
|
293
|
+
| {
|
|
294
|
+
intervalData: object;
|
|
295
|
+
clientType: string;
|
|
296
|
+
}
|
|
297
|
+
| any = {}
|
|
292
298
|
) {
|
|
293
299
|
const {audioSetupDelay, videoSetupDelay, joinTimes} = options;
|
|
294
300
|
|
|
@@ -309,11 +315,11 @@ class Metrics {
|
|
|
309
315
|
osVersion: getOSVersion() || UNKNOWN,
|
|
310
316
|
subClientType: options.subClientType,
|
|
311
317
|
browser: getBrowserName(),
|
|
312
|
-
browserVersion: getBrowserVersion()
|
|
313
|
-
}
|
|
318
|
+
browserVersion: getBrowserVersion(),
|
|
319
|
+
},
|
|
314
320
|
},
|
|
315
321
|
originTime: {
|
|
316
|
-
triggered: new Date().toISOString()
|
|
322
|
+
triggered: new Date().toISOString(),
|
|
317
323
|
},
|
|
318
324
|
senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,
|
|
319
325
|
event: {
|
|
@@ -323,16 +329,16 @@ class Metrics {
|
|
|
323
329
|
intervals: [options.intervalData],
|
|
324
330
|
joinTimes,
|
|
325
331
|
eventData: {
|
|
326
|
-
webClientDomain: window.location.hostname
|
|
332
|
+
webClientDomain: window.location.hostname,
|
|
327
333
|
},
|
|
328
334
|
sourceMetadata: {
|
|
329
335
|
applicationSoftwareType: CLIENT_NAME,
|
|
330
336
|
applicationSoftwareVersion: this.webex.version,
|
|
331
337
|
mediaEngineSoftwareType: getBrowserName() || 'browser',
|
|
332
338
|
mediaEngineSoftwareVersion: getOSVersion() || UNKNOWN,
|
|
333
|
-
startTime: new Date().toISOString()
|
|
334
|
-
}
|
|
335
|
-
}
|
|
339
|
+
startTime: new Date().toISOString(),
|
|
340
|
+
},
|
|
341
|
+
},
|
|
336
342
|
};
|
|
337
343
|
|
|
338
344
|
return payload;
|
|
@@ -353,8 +359,7 @@ class Metrics {
|
|
|
353
359
|
|
|
354
360
|
if (err && err.statusCode && err.statusCode >= 500) {
|
|
355
361
|
errorCode = 1003;
|
|
356
|
-
}
|
|
357
|
-
else if (err && err.body && err.body.errorCode) {
|
|
362
|
+
} else if (err && err.body && err.body.errorCode) {
|
|
358
363
|
// locus error codes: https://sqbu-github.cisco.com/WebExSquared/locus/blob/master/server/src/main/resources/locus-error-codes.properties
|
|
359
364
|
switch (ERROR_CODE[err.body.errorCode]) {
|
|
360
365
|
case MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:
|
|
@@ -453,17 +458,13 @@ class Metrics {
|
|
|
453
458
|
default:
|
|
454
459
|
errorCode = 4008;
|
|
455
460
|
}
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
461
|
+
} else {
|
|
458
462
|
errorCode = 4008;
|
|
459
463
|
}
|
|
460
464
|
|
|
461
|
-
return this.generateErrorPayload(
|
|
462
|
-
errorCode, showToUser, error.name.LOCUS_RESPONSE, err
|
|
463
|
-
);
|
|
465
|
+
return this.generateErrorPayload(errorCode, showToUser, error.name.LOCUS_RESPONSE, err);
|
|
464
466
|
}
|
|
465
467
|
|
|
466
|
-
|
|
467
468
|
generateErrorPayload(errorCode, shownToUser, name, err) {
|
|
468
469
|
if (error.errors[errorCode]) {
|
|
469
470
|
const errorPayload: any = {
|
|
@@ -472,7 +473,7 @@ class Metrics {
|
|
|
472
473
|
errorDescription: error.errors[errorCode][0],
|
|
473
474
|
errorCode,
|
|
474
475
|
fatal: !includes(error.notFatalErrorList, errorCode),
|
|
475
|
-
name: name || error.name.OTHER
|
|
476
|
+
name: name || error.name.OTHER,
|
|
476
477
|
};
|
|
477
478
|
|
|
478
479
|
if (err && err.body) {
|
|
@@ -499,8 +500,14 @@ class Metrics {
|
|
|
499
500
|
let browserInfo;
|
|
500
501
|
const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);
|
|
501
502
|
|
|
502
|
-
if (
|
|
503
|
-
|
|
503
|
+
if (
|
|
504
|
+
['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !==
|
|
505
|
+
-1
|
|
506
|
+
) {
|
|
507
|
+
browserInfo = util.format(
|
|
508
|
+
'browser=%s',
|
|
509
|
+
`${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`
|
|
510
|
+
);
|
|
504
511
|
}
|
|
505
512
|
const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);
|
|
506
513
|
|
|
@@ -508,12 +515,18 @@ class Metrics {
|
|
|
508
515
|
userAgentOption = `(${browserInfo}`;
|
|
509
516
|
}
|
|
510
517
|
if (osInfo) {
|
|
511
|
-
userAgentOption = userAgentOption
|
|
518
|
+
userAgentOption = userAgentOption
|
|
519
|
+
? `${userAgentOption}; ${clientInfo}; ${osInfo}`
|
|
520
|
+
: `${clientInfo}; (${osInfo}`;
|
|
512
521
|
}
|
|
513
522
|
if (userAgentOption) {
|
|
514
523
|
userAgentOption += ')';
|
|
515
524
|
|
|
516
|
-
return util.format(
|
|
525
|
+
return util.format(
|
|
526
|
+
'webex-js-sdk/%s %s',
|
|
527
|
+
`${process.env.NODE_ENV}-${this.webex.version}`,
|
|
528
|
+
userAgentOption
|
|
529
|
+
);
|
|
517
530
|
}
|
|
518
531
|
|
|
519
532
|
return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${this.webex.version}`);
|
|
@@ -538,7 +551,7 @@ class Metrics {
|
|
|
538
551
|
this.webex.internal.metrics.submitClientMetrics(metricName, {
|
|
539
552
|
type: this.webex.config.metrics.type,
|
|
540
553
|
fields: metricFields,
|
|
541
|
-
tags: metricTags
|
|
554
|
+
tags: metricTags,
|
|
542
555
|
});
|
|
543
556
|
}
|
|
544
557
|
}
|
|
@@ -109,7 +109,7 @@ export class RemoteMedia extends EventsScope {
|
|
|
109
109
|
* @param {boolean} commit - whether to commit the cancellation of the media request
|
|
110
110
|
* @internal
|
|
111
111
|
*/
|
|
112
|
-
public stop(commit
|
|
112
|
+
public stop(commit = true) {
|
|
113
113
|
this.cancelMediaRequest(commit);
|
|
114
114
|
this.receiveSlot?.removeAllListeners();
|
|
115
115
|
this.receiveSlot = undefined;
|
|
@@ -62,6 +62,7 @@ export class RemoteMediaGroup {
|
|
|
62
62
|
// return a shallow copy so that the client cannot modify this.pinnedRemoteMedia array
|
|
63
63
|
return [...this.pinnedRemoteMedia];
|
|
64
64
|
}
|
|
65
|
+
|
|
65
66
|
return [...this.unpinnedRemoteMedia, ...this.pinnedRemoteMedia];
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -189,7 +190,7 @@ export class RemoteMediaGroup {
|
|
|
189
190
|
* @param{boolean} commit whether to commit the cancellation of media requests
|
|
190
191
|
* @internal
|
|
191
192
|
*/
|
|
192
|
-
public stop(commit
|
|
193
|
+
public stop(commit = true) {
|
|
193
194
|
this.unpinnedRemoteMedia.forEach((remoteMedia) => remoteMedia.stop(false));
|
|
194
195
|
this.pinnedRemoteMedia.forEach((remoteMedia) => remoteMedia.stop(false));
|
|
195
196
|
this.cancelActiveSpeakerMediaRequest(false);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable valid-jsdoc */
|
|
1
2
|
import {cloneDeep, remove} from 'lodash';
|
|
2
3
|
import {EventMap} from 'typed-emitter';
|
|
3
4
|
import {MediaConnection as MC} from '@webex/internal-media-core';
|
|
@@ -432,6 +433,7 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
432
433
|
while (this.slots.video.unused.length < maxNumVideoPanesRequired) {
|
|
433
434
|
// eslint-disable-next-line no-await-in-loop
|
|
434
435
|
this.slots.video.unused.push(
|
|
436
|
+
// eslint-disable-next-line no-await-in-loop
|
|
435
437
|
await this.receiveSlotManager.allocateSlot(MC.MediaType.VideoMain)
|
|
436
438
|
);
|
|
437
439
|
}
|
|
@@ -600,6 +602,7 @@ export class RemoteMediaManager extends EventsScope {
|
|
|
600
602
|
while (numSlotsToCreate > 0) {
|
|
601
603
|
// eslint-disable-next-line no-await-in-loop
|
|
602
604
|
this.slots.video.unused.push(
|
|
605
|
+
// eslint-disable-next-line no-await-in-loop
|
|
603
606
|
await this.receiveSlotManager.allocateSlot(MC.MediaType.VideoMain)
|
|
604
607
|
);
|
|
605
608
|
numSlotsToCreate -= 1;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import EventsScope from '../common/events/events-scope';
|
|
2
2
|
import {EVENT_TRIGGERS, STATS} from '../constants';
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
* Meeting - network quality event
|
|
6
|
+
* Emitted on each interval of retrieving stats Analyzer data
|
|
7
|
+
* @event network:quality
|
|
8
|
+
* @type {Object}
|
|
9
|
+
* @property {string} mediaType {video|audio}
|
|
10
|
+
* @property {number} networkQualityScore - value determined in determineUplinkNetworkQuality
|
|
11
|
+
* @memberof NetworkQualityMonitor
|
|
12
|
+
*/
|
|
14
13
|
/**
|
|
15
14
|
* NetworkQualityMonitor class that will emit events based on detected quality
|
|
16
15
|
*
|
|
@@ -42,19 +41,19 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
42
41
|
this.indicatorTypes = Object.freeze({
|
|
43
42
|
PACKETLOSS: 'packetLoss',
|
|
44
43
|
LATENCY: 'latency',
|
|
45
|
-
JITTER: 'jitter'
|
|
44
|
+
JITTER: 'jitter',
|
|
46
45
|
});
|
|
47
46
|
this.frequencyTypes = Object.freeze({
|
|
48
47
|
UPLINK: 'uplink',
|
|
49
|
-
DOWNLINK: 'downlink'
|
|
48
|
+
DOWNLINK: 'downlink',
|
|
50
49
|
});
|
|
51
50
|
this.networkQualityScore = 1;
|
|
52
51
|
this.networkQualityStatus = {
|
|
53
52
|
[this.frequencyTypes.UPLINK]: {
|
|
54
53
|
[STATS.VIDEO_CORRELATE]: {},
|
|
55
54
|
[STATS.AUDIO_CORRELATE]: {},
|
|
56
|
-
[STATS.SHARE_CORRELATE]: {}
|
|
57
|
-
}
|
|
55
|
+
[STATS.SHARE_CORRELATE]: {},
|
|
56
|
+
},
|
|
58
57
|
};
|
|
59
58
|
this.mediaType = null;
|
|
60
59
|
}
|
|
@@ -69,12 +68,12 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
69
68
|
this.emit(
|
|
70
69
|
{
|
|
71
70
|
file: 'networkQualityMonitor',
|
|
72
|
-
function: 'emitNetworkQuality'
|
|
71
|
+
function: 'emitNetworkQuality',
|
|
73
72
|
},
|
|
74
73
|
EVENT_TRIGGERS.NETWORK_QUALITY,
|
|
75
74
|
{
|
|
76
75
|
mediaType: this.mediaType,
|
|
77
|
-
networkQualityScore: this.networkQualityScore
|
|
76
|
+
networkQualityScore: this.networkQualityScore,
|
|
78
77
|
}
|
|
79
78
|
);
|
|
80
79
|
}
|
|
@@ -92,7 +91,6 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
92
91
|
this.mediaType = null;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
|
|
96
94
|
/**
|
|
97
95
|
* filter data to determine uplink network quality, invoked on same interval as stats analyzer remote-inbout-rtp
|
|
98
96
|
* @param {Object} configObj
|
|
@@ -127,8 +125,7 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
127
125
|
* @returns {boolean}
|
|
128
126
|
*/
|
|
129
127
|
const determinePacketLoss = () => {
|
|
130
|
-
if (currentPacketLossRatio >
|
|
131
|
-
this.config.videoPacketLossRatioThreshold) {
|
|
128
|
+
if (currentPacketLossRatio > this.config.videoPacketLossRatioThreshold) {
|
|
132
129
|
this.networkQualityScore = 0;
|
|
133
130
|
|
|
134
131
|
return false;
|
|
@@ -172,7 +169,8 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
172
169
|
* @param {(number|undefined)} value
|
|
173
170
|
* @returns {(number|null)}
|
|
174
171
|
*/
|
|
175
|
-
const determineIfUndefined = (value: number | undefined) =>
|
|
172
|
+
const determineIfUndefined = (value: number | undefined) =>
|
|
173
|
+
typeof value === 'undefined' ? null : value;
|
|
176
174
|
|
|
177
175
|
/**
|
|
178
176
|
* Values for some browsers specifically Safari will be undefined we explicitly set to null
|
|
@@ -182,20 +180,19 @@ export default class NetworkQualityMonitor extends EventsScope {
|
|
|
182
180
|
// PACKET LOSS
|
|
183
181
|
this.networkQualityStatus[UPLINK][mediaType][PACKETLOSS] = {
|
|
184
182
|
acceptable: determinePacketLoss(),
|
|
185
|
-
value: determineIfUndefined(currentPacketLossRatio)
|
|
183
|
+
value: determineIfUndefined(currentPacketLossRatio),
|
|
186
184
|
};
|
|
187
185
|
|
|
188
|
-
|
|
189
186
|
// LATENCY measured in Round trip time
|
|
190
187
|
this.networkQualityStatus[UPLINK][mediaType][LATENCY] = {
|
|
191
188
|
acceptable: determineLatency(),
|
|
192
|
-
value: determineIfUndefined(remoteRtpResults.roundTripTime)
|
|
189
|
+
value: determineIfUndefined(remoteRtpResults.roundTripTime),
|
|
193
190
|
};
|
|
194
191
|
|
|
195
192
|
// JITTER
|
|
196
193
|
this.networkQualityStatus[UPLINK][mediaType][JITTER] = {
|
|
197
194
|
acceptable: deterMineJitter(),
|
|
198
|
-
value: determineIfUndefined(remoteRtpResults.jitter)
|
|
195
|
+
value: determineIfUndefined(remoteRtpResults.jitter),
|
|
199
196
|
};
|
|
200
197
|
|
|
201
198
|
this.updateNetworkQualityStatus();
|
|
@@ -6,7 +6,6 @@ import ParameterError from '../common/errors/parameter';
|
|
|
6
6
|
|
|
7
7
|
import PersonalMeetingRoomRequest from './request';
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* @class PersonalMeetingRoom
|
|
12
11
|
*/
|
|
@@ -36,7 +35,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
36
35
|
* @type {Object}
|
|
37
36
|
* @public
|
|
38
37
|
* @memberof PersonalMeetingRoom
|
|
39
|
-
|
|
38
|
+
*/
|
|
40
39
|
this.pmr = null;
|
|
41
40
|
/**
|
|
42
41
|
* The pmr sip Uri
|
|
@@ -44,7 +43,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
44
43
|
* @type {String}
|
|
45
44
|
* @public
|
|
46
45
|
* @memberof PersonalMeetingRoom
|
|
47
|
-
|
|
46
|
+
*/
|
|
48
47
|
this.sipUri = null;
|
|
49
48
|
/**
|
|
50
49
|
* The pmr link
|
|
@@ -52,7 +51,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
52
51
|
* @type {String}
|
|
53
52
|
* @public
|
|
54
53
|
* @memberof PersonalMeetingRoom
|
|
55
|
-
|
|
54
|
+
*/
|
|
56
55
|
this.link = null;
|
|
57
56
|
/**
|
|
58
57
|
* The pmr server object
|
|
@@ -60,7 +59,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
60
59
|
* @type {Object}
|
|
61
60
|
* @public
|
|
62
61
|
* @memberof PersonalMeetingRoom
|
|
63
|
-
|
|
62
|
+
*/
|
|
64
63
|
this.userId = null;
|
|
65
64
|
/**
|
|
66
65
|
* The pmr name
|
|
@@ -68,7 +67,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
68
67
|
* @type {String}
|
|
69
68
|
* @public
|
|
70
69
|
* @memberof PersonalMeetingRoom
|
|
71
|
-
|
|
70
|
+
*/
|
|
72
71
|
this.name = null;
|
|
73
72
|
/**
|
|
74
73
|
* The meeting info request server interface
|
|
@@ -76,7 +75,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
76
75
|
* @type {MeetingInfo}
|
|
77
76
|
* @private
|
|
78
77
|
* @memberof PersonalMeetingRoom
|
|
79
|
-
|
|
78
|
+
*/
|
|
80
79
|
this.meetingInfo = attrs.meetingInfo;
|
|
81
80
|
/**
|
|
82
81
|
* The pmr server request interface
|
|
@@ -84,7 +83,7 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
84
83
|
* @type {Object}
|
|
85
84
|
* @private
|
|
86
85
|
* @memberof PersonalMeetingRoom
|
|
87
|
-
|
|
86
|
+
*/
|
|
88
87
|
// @ts-ignore
|
|
89
88
|
this.personalMeetingRoomRequest = new PersonalMeetingRoomRequest({}, options);
|
|
90
89
|
}
|
|
@@ -98,20 +97,19 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
98
97
|
* @public
|
|
99
98
|
* @memberof PersonalMeetingRoom
|
|
100
99
|
*/
|
|
101
|
-
public claim(link: string, pin: string, preferred
|
|
100
|
+
public claim(link: string, pin: string, preferred = true) {
|
|
102
101
|
const options = {
|
|
103
102
|
// @ts-ignore
|
|
104
103
|
userId: this.webex.internal.device.userId,
|
|
105
104
|
passcode: pin,
|
|
106
105
|
meetingAddress: link,
|
|
107
|
-
preferred
|
|
106
|
+
preferred,
|
|
108
107
|
};
|
|
109
108
|
|
|
110
109
|
return this.personalMeetingRoomRequest.claimPmr(options).then((pmr) => {
|
|
111
110
|
if (pmr && pmr.body) {
|
|
112
111
|
this.set(pmr.body);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
112
|
+
} else {
|
|
115
113
|
return Promise.reject(new ParameterError('No PMR body provided. PMR values not updated.'));
|
|
116
114
|
}
|
|
117
115
|
|
|
@@ -143,15 +141,13 @@ export default class PersonalMeetingRoom extends StatelessWebexPlugin {
|
|
|
143
141
|
*/
|
|
144
142
|
public get() {
|
|
145
143
|
const options = {
|
|
146
|
-
type: _PERSONAL_ROOM_
|
|
147
|
-
|
|
144
|
+
type: _PERSONAL_ROOM_,
|
|
148
145
|
};
|
|
149
146
|
|
|
150
147
|
return this.meetingInfo.fetchMeetingInfo(options).then((pmr) => {
|
|
151
148
|
if (pmr && pmr.body && pmr.body.isPmr) {
|
|
152
149
|
this.set(pmr.body);
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
150
|
+
} else {
|
|
155
151
|
return Promise.reject(new TypeError('The PMR requested is NOT a PMR. PMR values not set.'));
|
|
156
152
|
}
|
|
157
153
|
|
|
@@ -6,7 +6,6 @@ import ParameterError from '../common/errors/parameter';
|
|
|
6
6
|
|
|
7
7
|
import PersonalMeetingRoomUtil from './util';
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* @class MeetingInfoRequest
|
|
12
11
|
*/
|
|
@@ -20,8 +19,16 @@ export default class PersonalMeetingRoomRequest extends StatelessWebexPlugin {
|
|
|
20
19
|
* @memberof PersonalMeetingRoomRequest
|
|
21
20
|
*/
|
|
22
21
|
claimPmr(options: any) {
|
|
23
|
-
if (
|
|
24
|
-
|
|
22
|
+
if (
|
|
23
|
+
!options ||
|
|
24
|
+
!options.userId ||
|
|
25
|
+
!options.passcode ||
|
|
26
|
+
!options.meetingAddress ||
|
|
27
|
+
!options.preferred
|
|
28
|
+
) {
|
|
29
|
+
throw new ParameterError(
|
|
30
|
+
'Claiming a PMR should be done with userId, passcode, preferred, and meetingAddress in options.'
|
|
31
|
+
);
|
|
25
32
|
}
|
|
26
33
|
const validPin = PersonalMeetingRoomUtil.getClaimPmrPin(options.passcode);
|
|
27
34
|
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
CMR_MEETINGS,
|
|
7
7
|
CLAIM,
|
|
8
8
|
HECATE,
|
|
9
|
-
WEBEX_DOT_COM
|
|
9
|
+
WEBEX_DOT_COM,
|
|
10
10
|
} from '../constants';
|
|
11
11
|
|
|
12
12
|
const PersonalMeetingRoomUtil: any = {};
|
|
@@ -42,8 +42,8 @@ PersonalMeetingRoomUtil.getClaimedRequestParams = (link, pin, options) => ({
|
|
|
42
42
|
userId: options.userId,
|
|
43
43
|
passcode: pin,
|
|
44
44
|
preferred: options.preferred,
|
|
45
|
-
meetingAddress: link
|
|
46
|
-
}
|
|
45
|
+
meetingAddress: link,
|
|
46
|
+
},
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
export default PersonalMeetingRoomUtil;
|