@webex/plugin-meetings 3.8.0-web-workers-keepalive.1 → 3.8.1-next.1
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/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +70 -6
- package/dist/breakouts/index.js.map +1 -1
- package/dist/common/errors/webex-errors.js +12 -2
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +22 -123
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +2 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +52 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +30 -10
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +83 -12
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +432 -418
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +17 -17
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +94 -6
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/brbState.js +9 -2
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +17 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +568 -328
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +0 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +4 -4
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +30 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +9 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +19 -13
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +5 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.js +76 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +14 -0
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +45 -9
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +3 -0
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +335 -356
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +137 -29
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +38 -0
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +36 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/clusterReachability.js +23 -31
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +42 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/turnDiscovery.js +45 -27
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/roap/types.js +17 -0
- package/dist/roap/types.js.map +1 -0
- package/dist/types/common/errors/webex-errors.d.ts +7 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +15 -85
- package/dist/types/controls-options-manager/enums.d.ts +3 -1
- package/dist/types/controls-options-manager/types.d.ts +7 -1
- package/dist/types/locus-info/index.d.ts +3 -3
- package/dist/types/locus-info/selfUtils.d.ts +216 -1
- package/dist/types/media/properties.d.ts +15 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +16 -0
- package/dist/types/meeting/index.d.ts +35 -1
- package/dist/types/meeting/muteState.d.ts +0 -1
- package/dist/types/meeting/request.d.ts +12 -1
- package/dist/types/meeting/request.type.d.ts +6 -0
- package/dist/types/meeting/util.d.ts +3 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +2 -1
- package/dist/types/meetings/index.d.ts +28 -0
- package/dist/types/member/index.d.ts +20 -6
- package/dist/types/member/types.d.ts +73 -14
- package/dist/types/member/util.d.ts +156 -1
- package/dist/types/members/collection.d.ts +6 -5
- package/dist/types/members/index.d.ts +32 -43
- package/dist/types/members/request.d.ts +26 -0
- package/dist/types/members/util.d.ts +27 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reachability/clusterReachability.d.ts +2 -6
- package/dist/types/reachability/index.d.ts +8 -0
- package/dist/types/roap/index.d.ts +3 -2
- package/dist/types/roap/turnDiscovery.d.ts +5 -17
- package/dist/types/roap/types.d.ts +16 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +24 -23
- package/src/breakouts/index.ts +69 -0
- package/src/common/errors/webex-errors.ts +8 -1
- package/src/config.ts +2 -0
- package/src/constants.ts +23 -90
- package/src/controls-options-manager/enums.ts +2 -0
- package/src/controls-options-manager/types.ts +11 -1
- package/src/controls-options-manager/util.ts +62 -0
- package/src/locus-info/controlsUtils.ts +48 -12
- package/src/locus-info/index.ts +88 -13
- package/src/locus-info/selfUtils.ts +496 -442
- package/src/media/index.ts +23 -21
- package/src/media/properties.ts +96 -0
- package/src/meeting/brbState.ts +11 -2
- package/src/meeting/in-meeting-actions.ts +32 -0
- package/src/meeting/index.ts +356 -87
- package/src/meeting/locusMediaRequest.ts +0 -18
- package/src/meeting/muteState.ts +4 -4
- package/src/meeting/request.ts +36 -1
- package/src/meeting/request.type.ts +7 -0
- package/src/meeting/util.ts +9 -1
- package/src/meeting-info/meeting-info-v2.ts +7 -2
- package/src/meeting-info/utilv2.ts +5 -0
- package/src/meetings/index.ts +76 -0
- package/src/meetings/util.ts +18 -0
- package/src/member/index.ts +57 -22
- package/src/member/types.ts +82 -16
- package/src/member/util.ts +357 -353
- package/src/members/collection.ts +4 -3
- package/src/members/index.ts +137 -18
- package/src/members/request.ts +44 -0
- package/src/members/util.ts +43 -1
- package/src/metrics/constants.ts +1 -0
- package/src/reachability/clusterReachability.ts +26 -25
- package/src/reachability/index.ts +55 -1
- package/src/reconnection-manager/index.ts +2 -2
- package/src/roap/index.ts +3 -7
- package/src/roap/turnDiscovery.ts +34 -39
- package/src/roap/types.ts +23 -0
- package/test/unit/spec/breakouts/index.ts +167 -95
- package/test/unit/spec/controls-options-manager/util.js +120 -0
- package/test/unit/spec/locus-info/controlsUtils.js +131 -9
- package/test/unit/spec/locus-info/index.js +195 -73
- package/test/unit/spec/locus-info/selfUtils.js +98 -24
- package/test/unit/spec/media/index.ts +150 -18
- package/test/unit/spec/media/properties.ts +130 -0
- package/test/unit/spec/meeting/brbState.ts +40 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +19 -4
- package/test/unit/spec/meeting/index.js +553 -36
- package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
- package/test/unit/spec/meeting/muteState.js +73 -2
- package/test/unit/spec/meeting/request.js +32 -1
- package/test/unit/spec/meeting/utils.js +79 -33
- package/test/unit/spec/meeting-info/meetinginfov2.js +41 -0
- package/test/unit/spec/meeting-info/utilv2.js +19 -0
- package/test/unit/spec/meetings/index.js +68 -1
- package/test/unit/spec/members/index.js +304 -78
- package/test/unit/spec/members/request.js +68 -22
- package/test/unit/spec/members/utils.js +75 -0
- package/test/unit/spec/reachability/clusterReachability.ts +41 -55
- package/test/unit/spec/reachability/index.ts +89 -0
- package/test/unit/spec/reconnection-manager/index.js +4 -4
- package/test/unit/spec/roap/turnDiscovery.ts +110 -28
package/src/meeting/index.ts
CHANGED
@@ -60,11 +60,8 @@ import {
|
|
60
60
|
import LoggerProxy from '../common/logs/logger-proxy';
|
61
61
|
import EventsUtil from '../common/events/util';
|
62
62
|
import Trigger from '../common/events/trigger-proxy';
|
63
|
-
import Roap, {
|
64
|
-
|
65
|
-
type TurnServerInfo,
|
66
|
-
type TurnDiscoverySkipReason,
|
67
|
-
} from '../roap/index';
|
63
|
+
import Roap, {type TurnDiscoveryResult, type TurnDiscoverySkipReason} from '../roap/index';
|
64
|
+
import {type TurnServerInfo} from '../roap/types';
|
68
65
|
import Media, {type BundlePolicy} from '../media';
|
69
66
|
import MediaProperties from '../media/properties';
|
70
67
|
import MeetingStateMachine from './state';
|
@@ -103,7 +100,6 @@ import {
|
|
103
100
|
MEETING_STATE_MACHINE,
|
104
101
|
MEETING_STATE,
|
105
102
|
MEETINGS,
|
106
|
-
MQA_STATS,
|
107
103
|
NETWORK_STATUS,
|
108
104
|
ONLINE,
|
109
105
|
OFFLINE,
|
@@ -167,6 +163,7 @@ import Member from '../member';
|
|
167
163
|
import {BrbState, createBrbState} from './brbState';
|
168
164
|
import MultistreamNotSupportedError from '../common/errors/multistream-not-supported-error';
|
169
165
|
import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
166
|
+
import {ReachabilityMetrics} from '../reachability/reachability.types';
|
170
167
|
|
171
168
|
// default callback so we don't call an undefined function, but in practice it should never be used
|
172
169
|
const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
|
@@ -265,6 +262,11 @@ type FetchMeetingInfoParams = {
|
|
265
262
|
sendCAevents?: boolean;
|
266
263
|
};
|
267
264
|
|
265
|
+
type MediaReachabilityMetrics = ReachabilityMetrics & {
|
266
|
+
isSubnetReachable: boolean;
|
267
|
+
selectedCluster: string | null;
|
268
|
+
};
|
269
|
+
|
268
270
|
/**
|
269
271
|
* MediaDirection
|
270
272
|
* @typedef {Object} MediaDirection
|
@@ -650,6 +652,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
650
652
|
allowMediaInLobby: boolean;
|
651
653
|
localShareInstanceId: string;
|
652
654
|
remoteShareInstanceId: string;
|
655
|
+
shareCAEventSentStatus: {
|
656
|
+
transmitStart: boolean;
|
657
|
+
transmitStop: boolean;
|
658
|
+
receiveStart: boolean;
|
659
|
+
receiveStop: boolean;
|
660
|
+
};
|
661
|
+
|
653
662
|
turnDiscoverySkippedReason: TurnDiscoverySkipReason;
|
654
663
|
turnServerUsed: boolean;
|
655
664
|
areVoiceaEventsSetup = false;
|
@@ -718,6 +727,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
718
727
|
private rtcMetrics?: RtcMetrics;
|
719
728
|
private uploadLogsTimer?: ReturnType<typeof setTimeout>;
|
720
729
|
private logUploadIntervalIndex: number;
|
730
|
+
private mediaServerIp: string;
|
721
731
|
|
722
732
|
/**
|
723
733
|
* @param {Object} attrs
|
@@ -1334,7 +1344,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1334
1344
|
captions: [],
|
1335
1345
|
isListening: false,
|
1336
1346
|
commandText: '',
|
1337
|
-
languageOptions: {},
|
1347
|
+
languageOptions: {currentSpokenLanguage: 'en'},
|
1338
1348
|
showCaptionBox: false,
|
1339
1349
|
transcribingRequestStatus: 'INACTIVE',
|
1340
1350
|
isCaptioning: false,
|
@@ -1422,6 +1432,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1422
1432
|
*/
|
1423
1433
|
this.remoteShareInstanceId = null;
|
1424
1434
|
|
1435
|
+
/**
|
1436
|
+
* Status used for ensuring we do not oversend metrics
|
1437
|
+
* @instance
|
1438
|
+
* @private
|
1439
|
+
* @memberof Meeting
|
1440
|
+
*/
|
1441
|
+
this.shareCAEventSentStatus = {
|
1442
|
+
transmitStart: false,
|
1443
|
+
transmitStop: false,
|
1444
|
+
receiveStart: false,
|
1445
|
+
receiveStop: false,
|
1446
|
+
};
|
1447
|
+
|
1425
1448
|
/**
|
1426
1449
|
* The class that helps to control recording functions: start, stop, pause, resume, etc
|
1427
1450
|
* @instance
|
@@ -1581,6 +1604,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1581
1604
|
* @memberof Meeting
|
1582
1605
|
*/
|
1583
1606
|
this.#isoLocalClientMeetingJoinTime = undefined;
|
1607
|
+
|
1608
|
+
// We clear the error cache of CA events on every new meeting instance
|
1609
|
+
// @ts-ignore - Fix type
|
1610
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.clearErrorCache();
|
1611
|
+
|
1612
|
+
/**
|
1613
|
+
* IP Address of the remote media server
|
1614
|
+
* @instance
|
1615
|
+
* @type {string}
|
1616
|
+
* @private
|
1617
|
+
* @memberof Meeting
|
1618
|
+
*/
|
1619
|
+
this.mediaServerIp = undefined;
|
1584
1620
|
}
|
1585
1621
|
|
1586
1622
|
/**
|
@@ -2604,6 +2640,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2604
2640
|
this.locusInfo.on(EVENTS.LOCUS_INFO_UPDATE_PARTICIPANTS, (payload) => {
|
2605
2641
|
this.members.locusParticipantsUpdate(payload);
|
2606
2642
|
});
|
2643
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.PARTICIPANT_REASON_CHANGED, (payload) => {
|
2644
|
+
Trigger.trigger(
|
2645
|
+
this,
|
2646
|
+
{
|
2647
|
+
file: 'meeting/index',
|
2648
|
+
function: 'setUpLocusParticipantsListener',
|
2649
|
+
},
|
2650
|
+
EVENT_TRIGGERS.MEETING_PARTICIPANT_REASON_CHANGED,
|
2651
|
+
{
|
2652
|
+
payload,
|
2653
|
+
}
|
2654
|
+
);
|
2655
|
+
});
|
2607
2656
|
}
|
2608
2657
|
|
2609
2658
|
/**
|
@@ -2704,6 +2753,27 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2704
2753
|
}
|
2705
2754
|
);
|
2706
2755
|
|
2756
|
+
this.locusInfo.on(
|
2757
|
+
LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
|
2758
|
+
({spokenLanguage}) => {
|
2759
|
+
if (spokenLanguage) {
|
2760
|
+
this.transcription.languageOptions.currentSpokenLanguage = spokenLanguage;
|
2761
|
+
// @ts-ignore
|
2762
|
+
this.webex.internal.voicea.onSpokenLanguageUpdate(spokenLanguage);
|
2763
|
+
|
2764
|
+
Trigger.trigger(
|
2765
|
+
this,
|
2766
|
+
{
|
2767
|
+
file: 'meeting/index',
|
2768
|
+
function: 'setupLocusControlsListener',
|
2769
|
+
},
|
2770
|
+
EVENT_TRIGGERS.MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
|
2771
|
+
{spokenLanguage}
|
2772
|
+
);
|
2773
|
+
}
|
2774
|
+
}
|
2775
|
+
);
|
2776
|
+
|
2707
2777
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_MEETING_MANUAL_CAPTION_UPDATED, ({enable}) => {
|
2708
2778
|
Trigger.trigger(
|
2709
2779
|
this,
|
@@ -2854,6 +2924,24 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2854
2924
|
{state}
|
2855
2925
|
);
|
2856
2926
|
});
|
2927
|
+
|
2928
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ANNOTATION_CHANGED, ({state}) => {
|
2929
|
+
Trigger.trigger(
|
2930
|
+
this,
|
2931
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
2932
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_ANNOTATION_UPDATED,
|
2933
|
+
{state}
|
2934
|
+
);
|
2935
|
+
});
|
2936
|
+
|
2937
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED, ({state}) => {
|
2938
|
+
Trigger.trigger(
|
2939
|
+
this,
|
2940
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
2941
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_REMOTE_DESKTOP_CONTROL_UPDATED,
|
2942
|
+
{state}
|
2943
|
+
);
|
2944
|
+
});
|
2857
2945
|
}
|
2858
2946
|
|
2859
2947
|
/**
|
@@ -3026,6 +3114,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3026
3114
|
case SHARE_STATUS.REMOTE_SHARE_ACTIVE: {
|
3027
3115
|
const sendStartedSharingRemote = () => {
|
3028
3116
|
this.remoteShareInstanceId = contentShare.shareInstanceId;
|
3117
|
+
this.shareCAEventSentStatus.receiveStart = false;
|
3118
|
+
this.shareCAEventSentStatus.receiveStop = false;
|
3029
3119
|
|
3030
3120
|
Trigger.trigger(
|
3031
3121
|
this,
|
@@ -3079,6 +3169,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3079
3169
|
},
|
3080
3170
|
options: {meetingId: this.id},
|
3081
3171
|
});
|
3172
|
+
|
3082
3173
|
break;
|
3083
3174
|
|
3084
3175
|
case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
|
@@ -3119,6 +3210,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3119
3210
|
// if we got here, then some remote participant has stolen
|
3120
3211
|
// the presentation from another remote participant
|
3121
3212
|
this.remoteShareInstanceId = contentShare.shareInstanceId;
|
3213
|
+
this.shareCAEventSentStatus.receiveStart = false;
|
3214
|
+
this.shareCAEventSentStatus.receiveStop = false;
|
3122
3215
|
|
3123
3216
|
Trigger.trigger(
|
3124
3217
|
this,
|
@@ -3747,6 +3840,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3747
3840
|
return this.members.cancelPhoneInvite(invitee);
|
3748
3841
|
}
|
3749
3842
|
|
3843
|
+
/**
|
3844
|
+
* Cancel an SIP call invitation made during a meeting
|
3845
|
+
* @param {Object} invitee
|
3846
|
+
* @param {String} invitee.memberId
|
3847
|
+
* @returns {Promise} see #members.cancelSIPInvite
|
3848
|
+
* @public
|
3849
|
+
* @memberof Meeting
|
3850
|
+
*/
|
3851
|
+
public cancelSIPInvite(invitee: {memberId: string}) {
|
3852
|
+
return this.members.cancelSIPInvite(invitee);
|
3853
|
+
}
|
3854
|
+
|
3750
3855
|
/**
|
3751
3856
|
* Admit the guest(s) to the call once they are waiting.
|
3752
3857
|
* If the host/cohost is in a breakout session, the locus url
|
@@ -3802,7 +3907,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3802
3907
|
return Promise.reject(error);
|
3803
3908
|
}
|
3804
3909
|
|
3805
|
-
return this.brbState
|
3910
|
+
return this.brbState
|
3911
|
+
.enable(enabled, this.sendSlotManager)
|
3912
|
+
.then(() => {
|
3913
|
+
if (this.audio && enabled) {
|
3914
|
+
// locus mutes the participant with brb enabled request,
|
3915
|
+
// so we need to explicitly update remote mute for correct logic flow
|
3916
|
+
this.audio.handleServerRemoteMuteUpdate(this, enabled);
|
3917
|
+
}
|
3918
|
+
})
|
3919
|
+
.catch((error) => Promise.reject(error));
|
3806
3920
|
}
|
3807
3921
|
|
3808
3922
|
/**
|
@@ -3994,7 +4108,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3994
4108
|
canAdmitParticipant: MeetingUtil.canAdmitParticipant(this.userDisplayHints),
|
3995
4109
|
canLock: MeetingUtil.canUserLock(this.userDisplayHints),
|
3996
4110
|
canUnlock: MeetingUtil.canUserUnlock(this.userDisplayHints),
|
3997
|
-
canShareWhiteBoard: MeetingUtil.canShareWhiteBoard(
|
4111
|
+
canShareWhiteBoard: MeetingUtil.canShareWhiteBoard(
|
4112
|
+
this.userDisplayHints,
|
4113
|
+
this.selfUserPolicies
|
4114
|
+
),
|
3998
4115
|
canSetDisallowUnmute: ControlsOptionsUtil.canSetDisallowUnmute(this.userDisplayHints),
|
3999
4116
|
canUnsetDisallowUnmute: ControlsOptionsUtil.canUnsetDisallowUnmute(this.userDisplayHints),
|
4000
4117
|
canSetMuteOnEntry: ControlsOptionsUtil.canSetMuteOnEntry(this.userDisplayHints),
|
@@ -4043,6 +4160,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4043
4160
|
this.inMeetingActions.canSendReactions,
|
4044
4161
|
this.userDisplayHints
|
4045
4162
|
),
|
4163
|
+
requiresPostMeetingDataConsentPrompt: MeetingUtil.requiresPostMeetingDataConsentPrompt(
|
4164
|
+
this.userDisplayHints
|
4165
|
+
),
|
4046
4166
|
canManageBreakout: MeetingUtil.canManageBreakout(this.userDisplayHints),
|
4047
4167
|
canStartBreakout: MeetingUtil.canStartBreakout(this.userDisplayHints),
|
4048
4168
|
canBroadcastMessageToBreakout: MeetingUtil.canBroadcastMessageToBreakout(
|
@@ -4058,6 +4178,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4058
4178
|
this.userDisplayHints
|
4059
4179
|
),
|
4060
4180
|
canUserRenameOthers: MeetingUtil.canUserRenameOthers(this.userDisplayHints),
|
4181
|
+
canMoveToLobby: MeetingUtil.canMoveToLobby(this.userDisplayHints),
|
4061
4182
|
canMuteAll: ControlsOptionsUtil.hasHints({
|
4062
4183
|
requiredHints: [DISPLAY_HINTS.MUTE_ALL],
|
4063
4184
|
displayHints: this.userDisplayHints,
|
@@ -4192,6 +4313,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4192
4313
|
requiredPolicies: [SELF_POLICY.SUPPORT_FILE_TRANSFER],
|
4193
4314
|
policies: this.selfUserPolicies,
|
4194
4315
|
}),
|
4316
|
+
canRealtimeCloseCaption: ControlsOptionsUtil.hasPolicies({
|
4317
|
+
requiredPolicies: [SELF_POLICY.SUPPORT_REALTIME_CLOSE_CAPTION],
|
4318
|
+
policies: this.selfUserPolicies,
|
4319
|
+
}),
|
4320
|
+
canRealtimeCloseCaptionManual: ControlsOptionsUtil.hasPolicies({
|
4321
|
+
requiredPolicies: [SELF_POLICY.SUPPORT_REALTIME_CLOSE_CAPTION_MANUAL],
|
4322
|
+
policies: this.selfUserPolicies,
|
4323
|
+
}),
|
4195
4324
|
canChat: ControlsOptionsUtil.hasPolicies({
|
4196
4325
|
requiredPolicies: [SELF_POLICY.SUPPORT_CHAT],
|
4197
4326
|
policies: this.selfUserPolicies,
|
@@ -4238,6 +4367,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4238
4367
|
requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
|
4239
4368
|
policies: this.selfUserPolicies,
|
4240
4369
|
}),
|
4370
|
+
canEnableAnnotation: ControlsOptionsUtil.hasHints({
|
4371
|
+
requiredHints: [DISPLAY_HINTS.ENABLE_ANNOTATION_MEETING_OPTION],
|
4372
|
+
displayHints: this.userDisplayHints,
|
4373
|
+
}),
|
4374
|
+
canDisableAnnotation: ControlsOptionsUtil.hasHints({
|
4375
|
+
requiredHints: [DISPLAY_HINTS.DISABLE_ANNOTATION_MEETING_OPTION],
|
4376
|
+
displayHints: this.userDisplayHints,
|
4377
|
+
}),
|
4378
|
+
canEnableRemoteDesktopControl: ControlsOptionsUtil.hasHints({
|
4379
|
+
requiredHints: [DISPLAY_HINTS.ENABLE_RDC_MEETING_OPTION],
|
4380
|
+
displayHints: this.userDisplayHints,
|
4381
|
+
}),
|
4382
|
+
canDisableRemoteDesktopControl: ControlsOptionsUtil.hasHints({
|
4383
|
+
requiredHints: [DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION],
|
4384
|
+
displayHints: this.userDisplayHints,
|
4385
|
+
}),
|
4241
4386
|
}) || changed;
|
4242
4387
|
}
|
4243
4388
|
if (changed) {
|
@@ -6261,6 +6406,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6261
6406
|
? MeetingsUtil.getMediaServer(roapMessage.sdp)
|
6262
6407
|
: undefined;
|
6263
6408
|
|
6409
|
+
const mediaServerIp =
|
6410
|
+
roapMessage.messageType === 'ANSWER'
|
6411
|
+
? MeetingsUtil.getMediaServerIp(roapMessage.sdp)
|
6412
|
+
: undefined;
|
6413
|
+
|
6264
6414
|
if (this.isMultistream && mediaServer && mediaServer !== 'homer') {
|
6265
6415
|
throw new MultistreamNotSupportedError(
|
6266
6416
|
`Client asked for multistream backend (Homer), but got ${mediaServer} instead`
|
@@ -6271,6 +6421,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6271
6421
|
if (mediaServer) {
|
6272
6422
|
this.mediaProperties.webrtcMediaConnection.mediaServer = mediaServer;
|
6273
6423
|
}
|
6424
|
+
|
6425
|
+
if (this.isMultistream && mediaServerIp) {
|
6426
|
+
this.mediaServerIp = mediaServerIp;
|
6427
|
+
}
|
6274
6428
|
};
|
6275
6429
|
|
6276
6430
|
/**
|
@@ -6728,20 +6882,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6728
6882
|
* @memberof Meetings
|
6729
6883
|
*/
|
6730
6884
|
setupStatsAnalyzerEventHandlers = () => {
|
6731
|
-
this.statsAnalyzer.on(StatsAnalyzerEventNames.MEDIA_QUALITY, (
|
6732
|
-
//
|
6733
|
-
|
6734
|
-
|
6735
|
-
|
6736
|
-
|
6737
|
-
|
6738
|
-
|
6739
|
-
|
6885
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.MEDIA_QUALITY, (event) => {
|
6886
|
+
// Add IP address from geoHintInfo if missing.
|
6887
|
+
if (event.data.intervalMetadata.maskedPeerReflexiveIP === '0.0.0.0') {
|
6888
|
+
// @ts-ignore fix type
|
6889
|
+
const clientAddressFromGeoHint = this.webex.meetings.geoHintInfo?.clientAddress;
|
6890
|
+
if (clientAddressFromGeoHint) {
|
6891
|
+
event.data.intervalMetadata.maskedPeerReflexiveIP =
|
6892
|
+
CallDiagnosticUtils.anonymizeIPAddress(clientAddressFromGeoHint);
|
6893
|
+
}
|
6894
|
+
}
|
6740
6895
|
|
6896
|
+
// Count members that are in the meeting.
|
6741
6897
|
const {members} = this.getMembers().membersCollection;
|
6742
|
-
|
6743
|
-
// Count members that are in the meeting
|
6744
|
-
options.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
6898
|
+
event.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
6745
6899
|
(member: Member) => member.isInMeeting
|
6746
6900
|
).length;
|
6747
6901
|
|
@@ -6750,10 +6904,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6750
6904
|
name: 'client.mediaquality.event',
|
6751
6905
|
options: {
|
6752
6906
|
meetingId: this.id,
|
6753
|
-
networkType:
|
6907
|
+
networkType: this.statsAnalyzer.getNetworkType(),
|
6754
6908
|
},
|
6755
6909
|
payload: {
|
6756
|
-
intervals: [
|
6910
|
+
intervals: [event.data],
|
6757
6911
|
},
|
6758
6912
|
});
|
6759
6913
|
});
|
@@ -6768,30 +6922,42 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6768
6922
|
EVENT_TRIGGERS.MEETING_MEDIA_LOCAL_STARTED,
|
6769
6923
|
data
|
6770
6924
|
);
|
6771
|
-
|
6772
|
-
|
6773
|
-
|
6774
|
-
|
6775
|
-
|
6776
|
-
|
6777
|
-
|
6778
|
-
|
6779
|
-
|
6780
|
-
|
6781
|
-
|
6925
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.transmitStart) {
|
6926
|
+
// @ts-ignore
|
6927
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6928
|
+
name: 'client.media.tx.start',
|
6929
|
+
payload: {
|
6930
|
+
mediaType: data.mediaType,
|
6931
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
6932
|
+
},
|
6933
|
+
options: {
|
6934
|
+
meetingId: this.id,
|
6935
|
+
},
|
6936
|
+
});
|
6937
|
+
|
6938
|
+
if (data.mediaType === 'share') {
|
6939
|
+
this.shareCAEventSentStatus.transmitStart = true;
|
6940
|
+
}
|
6941
|
+
}
|
6782
6942
|
});
|
6783
6943
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.LOCAL_MEDIA_STOPPED, (data) => {
|
6784
|
-
|
6785
|
-
|
6786
|
-
|
6787
|
-
|
6788
|
-
|
6789
|
-
|
6790
|
-
|
6791
|
-
|
6792
|
-
|
6793
|
-
|
6794
|
-
|
6944
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.transmitStop) {
|
6945
|
+
// @ts-ignore
|
6946
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6947
|
+
name: 'client.media.tx.stop',
|
6948
|
+
payload: {
|
6949
|
+
mediaType: data.mediaType,
|
6950
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
6951
|
+
},
|
6952
|
+
options: {
|
6953
|
+
meetingId: this.id,
|
6954
|
+
},
|
6955
|
+
});
|
6956
|
+
|
6957
|
+
if (data.mediaType === 'share') {
|
6958
|
+
this.shareCAEventSentStatus.transmitStop = true;
|
6959
|
+
}
|
6960
|
+
}
|
6795
6961
|
});
|
6796
6962
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STARTED, (data) => {
|
6797
6963
|
Trigger.trigger(
|
@@ -6803,57 +6969,65 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6803
6969
|
EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
|
6804
6970
|
data
|
6805
6971
|
);
|
6806
|
-
|
6807
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
6808
|
-
name: 'client.media.rx.start',
|
6809
|
-
payload: {
|
6810
|
-
mediaType: data.mediaType,
|
6811
|
-
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6812
|
-
},
|
6813
|
-
options: {
|
6814
|
-
meetingId: this.id,
|
6815
|
-
},
|
6816
|
-
});
|
6817
|
-
|
6818
|
-
if (data.mediaType === 'share') {
|
6972
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.receiveStart) {
|
6819
6973
|
// @ts-ignore
|
6820
6974
|
this.webex.internal.newMetrics.submitClientEvent({
|
6821
|
-
name: 'client.media.
|
6975
|
+
name: 'client.media.rx.start',
|
6822
6976
|
payload: {
|
6823
|
-
mediaType:
|
6824
|
-
shareInstanceId: this.remoteShareInstanceId,
|
6977
|
+
mediaType: data.mediaType,
|
6978
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6825
6979
|
},
|
6826
6980
|
options: {
|
6827
6981
|
meetingId: this.id,
|
6828
6982
|
},
|
6829
6983
|
});
|
6984
|
+
|
6985
|
+
if (data.mediaType === 'share') {
|
6986
|
+
// @ts-ignore
|
6987
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6988
|
+
name: 'client.media.render.start',
|
6989
|
+
payload: {
|
6990
|
+
mediaType: 'share',
|
6991
|
+
shareInstanceId: this.remoteShareInstanceId,
|
6992
|
+
},
|
6993
|
+
options: {
|
6994
|
+
meetingId: this.id,
|
6995
|
+
},
|
6996
|
+
});
|
6997
|
+
|
6998
|
+
this.shareCAEventSentStatus.receiveStart = true;
|
6999
|
+
}
|
6830
7000
|
}
|
6831
7001
|
});
|
6832
7002
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STOPPED, (data) => {
|
6833
|
-
|
6834
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
6835
|
-
name: 'client.media.rx.stop',
|
6836
|
-
payload: {
|
6837
|
-
mediaType: data.mediaType,
|
6838
|
-
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6839
|
-
},
|
6840
|
-
options: {
|
6841
|
-
meetingId: this.id,
|
6842
|
-
},
|
6843
|
-
});
|
6844
|
-
|
6845
|
-
if (data.mediaType === 'share') {
|
7003
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.receiveStop) {
|
6846
7004
|
// @ts-ignore
|
6847
7005
|
this.webex.internal.newMetrics.submitClientEvent({
|
6848
|
-
name: 'client.media.
|
7006
|
+
name: 'client.media.rx.stop',
|
6849
7007
|
payload: {
|
6850
|
-
mediaType:
|
6851
|
-
shareInstanceId: this.remoteShareInstanceId,
|
7008
|
+
mediaType: data.mediaType,
|
7009
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6852
7010
|
},
|
6853
7011
|
options: {
|
6854
7012
|
meetingId: this.id,
|
6855
7013
|
},
|
6856
7014
|
});
|
7015
|
+
|
7016
|
+
if (data.mediaType === 'share') {
|
7017
|
+
// @ts-ignore
|
7018
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
7019
|
+
name: 'client.media.render.stop',
|
7020
|
+
payload: {
|
7021
|
+
mediaType: 'share',
|
7022
|
+
shareInstanceId: this.remoteShareInstanceId,
|
7023
|
+
},
|
7024
|
+
options: {
|
7025
|
+
meetingId: this.id,
|
7026
|
+
},
|
7027
|
+
});
|
7028
|
+
|
7029
|
+
this.shareCAEventSentStatus.receiveStop = true;
|
7030
|
+
}
|
6857
7031
|
}
|
6858
7032
|
});
|
6859
7033
|
};
|
@@ -6870,7 +7044,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6870
7044
|
* @param {AddMediaOptions} [options] Options for enabling/disabling audio/video
|
6871
7045
|
* @returns {RoapMediaConnection | MultistreamRoapMediaConnection}
|
6872
7046
|
*/
|
6873
|
-
private async createMediaConnection(
|
7047
|
+
private async createMediaConnection(
|
7048
|
+
turnServerInfo?: TurnServerInfo,
|
7049
|
+
bundlePolicy?: BundlePolicy
|
7050
|
+
) {
|
6874
7051
|
this.rtcMetrics = this.isMultistream
|
6875
7052
|
? // @ts-ignore
|
6876
7053
|
new RtcMetrics(this.webex, {meetingId: this.id}, this.correlationId)
|
@@ -6895,6 +7072,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6895
7072
|
bundlePolicy,
|
6896
7073
|
// @ts-ignore - config coming from registerPlugin
|
6897
7074
|
iceCandidatesTimeout: this.config.iceCandidatesGatheringTimeout,
|
7075
|
+
// @ts-ignore - config coming from registerPlugin
|
7076
|
+
disableAudioMainDtx: this.config.experimental.disableAudioMainDtx,
|
7077
|
+
// @ts-ignore - config coming from registerPlugin
|
7078
|
+
enableAudioTwcc: this.config.enableAudioTwccForMultistream,
|
7079
|
+
stopIceGatheringAfterFirstRelayCandidate:
|
7080
|
+
// @ts-ignore - config coming from registerPlugin
|
7081
|
+
this.config.stopIceGatheringAfterFirstRelayCandidate,
|
6898
7082
|
}
|
6899
7083
|
);
|
6900
7084
|
|
@@ -7045,12 +7229,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7045
7229
|
},
|
7046
7230
|
options: {
|
7047
7231
|
meetingId: this.id,
|
7232
|
+
rawError: error,
|
7048
7233
|
},
|
7049
7234
|
});
|
7050
7235
|
}
|
7051
|
-
|
7236
|
+
|
7237
|
+
const timedOutError = new Error(
|
7052
7238
|
`Timed out waiting for media connection to be connected, correlationId=${this.correlationId}`
|
7053
7239
|
);
|
7240
|
+
|
7241
|
+
timedOutError.cause = error;
|
7242
|
+
|
7243
|
+
throw timedOutError;
|
7054
7244
|
}
|
7055
7245
|
}
|
7056
7246
|
|
@@ -7071,6 +7261,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7071
7261
|
networkQualityMonitor: this.networkQualityMonitor,
|
7072
7262
|
isMultistream: this.isMultistream,
|
7073
7263
|
});
|
7264
|
+
this.shareCAEventSentStatus = {
|
7265
|
+
transmitStart: false,
|
7266
|
+
transmitStop: false,
|
7267
|
+
receiveStart: false,
|
7268
|
+
receiveStop: false,
|
7269
|
+
};
|
7074
7270
|
this.setupStatsAnalyzerEventHandlers();
|
7075
7271
|
this.networkQualityMonitor.on(
|
7076
7272
|
NetworkQualityEventNames.NETWORK_QUALITY,
|
@@ -7105,6 +7301,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7105
7301
|
ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT / 1000
|
7106
7302
|
} seconds`
|
7107
7303
|
);
|
7304
|
+
|
7305
|
+
const error = new Error('Timed out waiting for REMOTE SDP ANSWER');
|
7306
|
+
|
7108
7307
|
// @ts-ignore
|
7109
7308
|
this.webex.internal.newMetrics.submitClientEvent({
|
7110
7309
|
name: 'client.media-engine.remote-sdp-received',
|
@@ -7117,10 +7316,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7117
7316
|
}),
|
7118
7317
|
],
|
7119
7318
|
},
|
7120
|
-
options: {meetingId: this.id, rawError:
|
7319
|
+
options: {meetingId: this.id, rawError: error},
|
7121
7320
|
});
|
7122
7321
|
|
7123
|
-
deferSDPAnswer.reject(
|
7322
|
+
deferSDPAnswer.reject(error);
|
7124
7323
|
}, ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT);
|
7125
7324
|
|
7126
7325
|
LoggerProxy.logger.info(`${LOG_HEADER} waiting for REMOTE SDP ANSWER...`);
|
@@ -7225,7 +7424,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7225
7424
|
error
|
7226
7425
|
);
|
7227
7426
|
|
7228
|
-
throw new AddMediaFailed();
|
7427
|
+
throw new AddMediaFailed(error);
|
7229
7428
|
}
|
7230
7429
|
}
|
7231
7430
|
|
@@ -7638,28 +7837,33 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7638
7837
|
await this.enqueueScreenShareFloorRequest();
|
7639
7838
|
}
|
7640
7839
|
|
7641
|
-
const {connectionType, selectedCandidatePairChanges, numTransports} =
|
7840
|
+
const {connectionType, ipVersion, selectedCandidatePairChanges, numTransports} =
|
7642
7841
|
await this.mediaProperties.getCurrentConnectionInfo();
|
7643
|
-
|
7644
|
-
const reachabilityStats = await this.webex.meetings.reachability.getReachabilityMetrics();
|
7842
|
+
|
7645
7843
|
const iceCandidateErrors = Object.fromEntries(this.iceCandidateErrors);
|
7646
7844
|
|
7845
|
+
const reachabilityMetrics = await this.getMediaReachabilityMetricFields();
|
7846
|
+
|
7647
7847
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_SUCCESS, {
|
7648
7848
|
correlation_id: this.correlationId,
|
7649
7849
|
locus_id: this.locusUrl.split('/').pop(),
|
7650
7850
|
connectionType,
|
7851
|
+
ipVersion,
|
7651
7852
|
selectedCandidatePairChanges,
|
7652
7853
|
numTransports,
|
7653
7854
|
isMultistream: this.isMultistream,
|
7654
7855
|
retriedWithTurnServer: this.addMediaData.retriedWithTurnServer,
|
7655
7856
|
isJoinWithMediaRetry: this.joinWithMediaRetryInfo.isRetry,
|
7656
|
-
...
|
7857
|
+
...reachabilityMetrics,
|
7657
7858
|
...iceCandidateErrors,
|
7658
7859
|
iceCandidatesCount: this.iceCandidatesCount,
|
7659
7860
|
});
|
7660
7861
|
// @ts-ignore
|
7661
7862
|
this.webex.internal.newMetrics.submitClientEvent({
|
7662
7863
|
name: 'client.media-engine.ready',
|
7864
|
+
payload: {
|
7865
|
+
ipVersion,
|
7866
|
+
},
|
7663
7867
|
options: {
|
7664
7868
|
meetingId: this.id,
|
7665
7869
|
},
|
@@ -7675,7 +7879,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7675
7879
|
LoggerProxy.logger.error(`${LOG_HEADER} failed to establish media connection: `, error);
|
7676
7880
|
|
7677
7881
|
// @ts-ignore
|
7678
|
-
const reachabilityMetrics = await this.
|
7882
|
+
const reachabilityMetrics = await this.getMediaReachabilityMetricFields();
|
7679
7883
|
|
7680
7884
|
const {selectedCandidatePairChanges, numTransports} =
|
7681
7885
|
await this.mediaProperties.getCurrentConnectionInfo();
|
@@ -9095,6 +9299,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9095
9299
|
});
|
9096
9300
|
}
|
9097
9301
|
|
9302
|
+
/**
|
9303
|
+
* Method to set post meeting data consent.
|
9304
|
+
*
|
9305
|
+
* @param {boolean} accept - whether consent accepted or declined
|
9306
|
+
* @returns {Promise}
|
9307
|
+
* @public
|
9308
|
+
* @memberof Meeting
|
9309
|
+
*/
|
9310
|
+
public setPostMeetingDataConsent(accept: boolean) {
|
9311
|
+
return this.meetingRequest.setPostMeetingDataConsent({
|
9312
|
+
postMeetingDataConsent: accept,
|
9313
|
+
locusUrl: this.locusUrl,
|
9314
|
+
deviceUrl: this.deviceUrl,
|
9315
|
+
selfId: this.members.selfId,
|
9316
|
+
});
|
9317
|
+
}
|
9318
|
+
|
9098
9319
|
/**
|
9099
9320
|
* Throws if we don't have a media connection created
|
9100
9321
|
*
|
@@ -9335,6 +9556,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9335
9556
|
|
9336
9557
|
if (floorRequestNeeded) {
|
9337
9558
|
this.localShareInstanceId = uuid.v4();
|
9559
|
+
this.shareCAEventSentStatus.transmitStart = false;
|
9560
|
+
this.shareCAEventSentStatus.transmitStop = false;
|
9338
9561
|
|
9339
9562
|
// @ts-ignore
|
9340
9563
|
this.webex.internal.newMetrics.submitClientEvent({
|
@@ -9462,4 +9685,50 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9462
9685
|
|
9463
9686
|
return Promise.resolve();
|
9464
9687
|
}
|
9688
|
+
|
9689
|
+
/**
|
9690
|
+
* Gets the media reachability metrics
|
9691
|
+
*
|
9692
|
+
* @returns {Promise<MediaReachabilityMetrics>}
|
9693
|
+
*/
|
9694
|
+
private async getMediaReachabilityMetricFields(): Promise<MediaReachabilityMetrics> {
|
9695
|
+
const reachabilityMetrics: ReachabilityMetrics =
|
9696
|
+
// @ts-ignore
|
9697
|
+
await this.webex.meetings.reachability.getReachabilityMetrics();
|
9698
|
+
|
9699
|
+
const successKeys: Array<keyof ReachabilityMetrics> = [
|
9700
|
+
'reachability_public_udp_success',
|
9701
|
+
'reachability_public_tcp_success',
|
9702
|
+
'reachability_public_xtls_success',
|
9703
|
+
'reachability_vmn_udp_success',
|
9704
|
+
'reachability_vmn_tcp_success',
|
9705
|
+
'reachability_vmn_xtls_success',
|
9706
|
+
];
|
9707
|
+
|
9708
|
+
const totalSuccessCases = successKeys.reduce((total, key) => {
|
9709
|
+
const value = reachabilityMetrics[key];
|
9710
|
+
if (typeof value === 'number') {
|
9711
|
+
return total + value;
|
9712
|
+
}
|
9713
|
+
|
9714
|
+
return total;
|
9715
|
+
}, 0);
|
9716
|
+
|
9717
|
+
let isSubnetReachable = null;
|
9718
|
+
if (totalSuccessCases > 0) {
|
9719
|
+
// @ts-ignore
|
9720
|
+
isSubnetReachable = this.webex.meetings.reachability.isSubnetReachable(this.mediaServerIp);
|
9721
|
+
}
|
9722
|
+
|
9723
|
+
let selectedCluster = null;
|
9724
|
+
if (this.mediaConnections && this.mediaConnections.length > 0) {
|
9725
|
+
selectedCluster = this.mediaConnections[0].mediaAgentCluster;
|
9726
|
+
}
|
9727
|
+
|
9728
|
+
return {
|
9729
|
+
...reachabilityMetrics,
|
9730
|
+
isSubnetReachable,
|
9731
|
+
selectedCluster,
|
9732
|
+
};
|
9733
|
+
}
|
9465
9734
|
}
|