@webex/plugin-meetings 3.8.0-next.6 → 3.8.0-next.60
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 +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 +1 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +16 -121
- 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 +28 -10
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +20 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +405 -418
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +8 -16
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +13 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +548 -288
- 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 +0 -2
- 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 +13 -2
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +359 -60
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +91 -1
- 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 +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +3 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +23 -0
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +21 -0
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +15 -0
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +9 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/clusterReachability.js +63 -27
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +112 -47
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +14 -0
- package/dist/reachability/reachability.types.js.map +1 -1
- package/dist/reachability/request.js +19 -3
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/util.js +5 -5
- package/dist/recording-controller/util.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 +1 -0
- package/dist/types/constants.d.ts +11 -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 +1 -0
- package/dist/types/locus-info/selfUtils.d.ts +247 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
- package/dist/types/meeting/index.d.ts +54 -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 +80 -0
- package/dist/types/meetings/index.d.ts +38 -0
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/members/index.d.ts +8 -0
- package/dist/types/members/request.d.ts +19 -0
- package/dist/types/members/util.d.ts +13 -0
- package/dist/types/metrics/constants.d.ts +9 -0
- package/dist/types/reachability/clusterReachability.d.ts +15 -7
- package/dist/types/reachability/index.d.ts +10 -1
- package/dist/types/reachability/reachability.types.d.ts +5 -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 +23 -23
- package/src/common/errors/webex-errors.ts +8 -1
- package/src/config.ts +1 -0
- package/src/constants.ts +18 -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 +44 -14
- package/src/locus-info/index.ts +23 -1
- package/src/locus-info/selfUtils.ts +451 -447
- package/src/media/index.ts +11 -21
- package/src/meeting/in-meeting-actions.ts +24 -0
- package/src/meeting/index.ts +364 -92
- package/src/meeting/locusMediaRequest.ts +0 -18
- package/src/meeting/muteState.ts +0 -2
- package/src/meeting/request.ts +36 -1
- package/src/meeting/request.type.ts +7 -0
- package/src/meeting/util.ts +11 -2
- package/src/meeting-info/meeting-info-v2.ts +247 -6
- package/src/meetings/index.ts +107 -1
- package/src/meetings/util.ts +18 -0
- package/src/member/index.ts +11 -0
- package/src/member/util.ts +3 -0
- package/src/members/index.ts +25 -0
- package/src/members/request.ts +26 -0
- package/src/members/util.ts +16 -0
- package/src/metrics/constants.ts +9 -0
- package/src/reachability/clusterReachability.ts +73 -26
- package/src/reachability/index.ts +70 -1
- package/src/reachability/reachability.types.ts +6 -0
- package/src/reachability/request.ts +7 -0
- package/src/reconnection-manager/index.ts +2 -2
- package/src/recording-controller/util.ts +17 -13
- 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/controls-options-manager/util.js +120 -0
- package/test/unit/spec/locus-info/controlsUtils.js +103 -9
- package/test/unit/spec/locus-info/index.js +28 -0
- package/test/unit/spec/media/index.ts +36 -16
- package/test/unit/spec/meeting/in-meeting-actions.ts +15 -4
- package/test/unit/spec/meeting/index.js +518 -34
- package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
- package/test/unit/spec/meeting/muteState.js +0 -2
- package/test/unit/spec/meeting/request.js +32 -1
- package/test/unit/spec/meeting/utils.js +119 -18
- package/test/unit/spec/meeting-info/meetinginfov2.js +443 -114
- package/test/unit/spec/meetings/index.js +120 -2
- package/test/unit/spec/member/index.js +7 -0
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/members/index.js +103 -26
- package/test/unit/spec/members/request.js +45 -22
- package/test/unit/spec/members/utils.js +33 -0
- package/test/unit/spec/reachability/clusterReachability.ts +88 -56
- package/test/unit/spec/reachability/index.ts +101 -0
- package/test/unit/spec/reachability/request.js +47 -2
- 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';
|
@@ -241,6 +238,8 @@ export type CallStateForMetrics = {
|
|
241
238
|
sessionCorrelationId?: string;
|
242
239
|
joinTrigger?: string;
|
243
240
|
loginType?: string;
|
241
|
+
userNameInput?: string;
|
242
|
+
emailInput?: string;
|
244
243
|
};
|
245
244
|
|
246
245
|
export const MEDIA_UPDATE_TYPE = {
|
@@ -263,6 +262,8 @@ type FetchMeetingInfoParams = {
|
|
263
262
|
sendCAevents?: boolean;
|
264
263
|
};
|
265
264
|
|
265
|
+
type MediaReachabilityMetrics = ReachabilityMetrics & {isSubnetReachable: boolean};
|
266
|
+
|
266
267
|
/**
|
267
268
|
* MediaDirection
|
268
269
|
* @typedef {Object} MediaDirection
|
@@ -648,6 +649,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
648
649
|
allowMediaInLobby: boolean;
|
649
650
|
localShareInstanceId: string;
|
650
651
|
remoteShareInstanceId: string;
|
652
|
+
shareCAEventSentStatus: {
|
653
|
+
transmitStart: boolean;
|
654
|
+
transmitStop: boolean;
|
655
|
+
receiveStart: boolean;
|
656
|
+
receiveStop: boolean;
|
657
|
+
};
|
658
|
+
|
651
659
|
turnDiscoverySkippedReason: TurnDiscoverySkipReason;
|
652
660
|
turnServerUsed: boolean;
|
653
661
|
areVoiceaEventsSetup = false;
|
@@ -716,6 +724,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
716
724
|
private rtcMetrics?: RtcMetrics;
|
717
725
|
private uploadLogsTimer?: ReturnType<typeof setTimeout>;
|
718
726
|
private logUploadIntervalIndex: number;
|
727
|
+
private mediaServerIp: string;
|
719
728
|
|
720
729
|
/**
|
721
730
|
* @param {Object} attrs
|
@@ -1420,6 +1429,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1420
1429
|
*/
|
1421
1430
|
this.remoteShareInstanceId = null;
|
1422
1431
|
|
1432
|
+
/**
|
1433
|
+
* Status used for ensuring we do not oversend metrics
|
1434
|
+
* @instance
|
1435
|
+
* @private
|
1436
|
+
* @memberof Meeting
|
1437
|
+
*/
|
1438
|
+
this.shareCAEventSentStatus = {
|
1439
|
+
transmitStart: false,
|
1440
|
+
transmitStop: false,
|
1441
|
+
receiveStart: false,
|
1442
|
+
receiveStop: false,
|
1443
|
+
};
|
1444
|
+
|
1423
1445
|
/**
|
1424
1446
|
* The class that helps to control recording functions: start, stop, pause, resume, etc
|
1425
1447
|
* @instance
|
@@ -1579,6 +1601,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1579
1601
|
* @memberof Meeting
|
1580
1602
|
*/
|
1581
1603
|
this.#isoLocalClientMeetingJoinTime = undefined;
|
1604
|
+
|
1605
|
+
// We clear the error cache of CA events on every new meeting instance
|
1606
|
+
// @ts-ignore - Fix type
|
1607
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.clearErrorCache();
|
1608
|
+
|
1609
|
+
/**
|
1610
|
+
* IP Address of the remote media server
|
1611
|
+
* @instance
|
1612
|
+
* @type {string}
|
1613
|
+
* @private
|
1614
|
+
* @memberof Meeting
|
1615
|
+
*/
|
1616
|
+
this.mediaServerIp = undefined;
|
1582
1617
|
}
|
1583
1618
|
|
1584
1619
|
/**
|
@@ -1627,6 +1662,38 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1627
1662
|
this.callStateForMetrics.correlationId = correlationId;
|
1628
1663
|
}
|
1629
1664
|
|
1665
|
+
/**
|
1666
|
+
* Getter - Returns callStateForMetrics.userNameInput
|
1667
|
+
* @returns {string}
|
1668
|
+
*/
|
1669
|
+
get userNameInput() {
|
1670
|
+
return this.callStateForMetrics?.userNameInput;
|
1671
|
+
}
|
1672
|
+
|
1673
|
+
/**
|
1674
|
+
* Setter - sets callStateForMetrics.userNameInput
|
1675
|
+
* @param {string} userNameInput
|
1676
|
+
*/
|
1677
|
+
set userNameInput(userNameInput: string) {
|
1678
|
+
this.callStateForMetrics.userNameInput = userNameInput;
|
1679
|
+
}
|
1680
|
+
|
1681
|
+
/**
|
1682
|
+
* Getter - Returns callStateForMetrics.emailInput
|
1683
|
+
* @returns {string}
|
1684
|
+
*/
|
1685
|
+
get emailInput() {
|
1686
|
+
return this.callStateForMetrics?.emailInput;
|
1687
|
+
}
|
1688
|
+
|
1689
|
+
/**
|
1690
|
+
* Setter - sets callStateForMetrics.emailInput
|
1691
|
+
* @param {string} emailInput
|
1692
|
+
*/
|
1693
|
+
set emailInput(emailInput: string) {
|
1694
|
+
this.callStateForMetrics.emailInput = emailInput;
|
1695
|
+
}
|
1696
|
+
|
1630
1697
|
/**
|
1631
1698
|
* Getter - Returns callStateForMetrics.sessionCorrelationId
|
1632
1699
|
* @returns {string}
|
@@ -1652,6 +1719,33 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1652
1719
|
return this.#isoLocalClientMeetingJoinTime;
|
1653
1720
|
}
|
1654
1721
|
|
1722
|
+
/**
|
1723
|
+
* Setter - sets isoLocalClientMeetingJoinTime
|
1724
|
+
* This will be set once on meeting join, and not updated again
|
1725
|
+
* this will always produce an ISO string
|
1726
|
+
* If the iso string is invalid, it will fallback to the current system time
|
1727
|
+
* @param {string | undefined} time
|
1728
|
+
*/
|
1729
|
+
set isoLocalClientMeetingJoinTime(time: string | undefined) {
|
1730
|
+
const fallback = new Date().toISOString();
|
1731
|
+
if (!time) {
|
1732
|
+
this.#isoLocalClientMeetingJoinTime = fallback;
|
1733
|
+
} else {
|
1734
|
+
const date = new Date(time);
|
1735
|
+
|
1736
|
+
// Check if the date is valid
|
1737
|
+
if (Number.isNaN(date.getTime())) {
|
1738
|
+
LoggerProxy.logger.info(
|
1739
|
+
// @ts-ignore
|
1740
|
+
`Meeting:index#isoLocalClientMeetingJoinTime --> Invalid date provided: ${time}. Falling back to system clock.`
|
1741
|
+
);
|
1742
|
+
this.#isoLocalClientMeetingJoinTime = fallback;
|
1743
|
+
} else {
|
1744
|
+
this.#isoLocalClientMeetingJoinTime = date.toISOString();
|
1745
|
+
}
|
1746
|
+
}
|
1747
|
+
}
|
1748
|
+
|
1655
1749
|
/**
|
1656
1750
|
* Set meeting info and trigger `MEETING_INFO_AVAILABLE` event
|
1657
1751
|
* @param {any} info
|
@@ -2793,6 +2887,24 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2793
2887
|
{state}
|
2794
2888
|
);
|
2795
2889
|
});
|
2890
|
+
|
2891
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_ANNOTATION_CHANGED, ({state}) => {
|
2892
|
+
Trigger.trigger(
|
2893
|
+
this,
|
2894
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
2895
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_ANNOTATION_UPDATED,
|
2896
|
+
{state}
|
2897
|
+
);
|
2898
|
+
});
|
2899
|
+
|
2900
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_REMOTE_DESKTOP_CONTROL_CHANGED, ({state}) => {
|
2901
|
+
Trigger.trigger(
|
2902
|
+
this,
|
2903
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
2904
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_REMOTE_DESKTOP_CONTROL_UPDATED,
|
2905
|
+
{state}
|
2906
|
+
);
|
2907
|
+
});
|
2796
2908
|
}
|
2797
2909
|
|
2798
2910
|
/**
|
@@ -2965,6 +3077,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
2965
3077
|
case SHARE_STATUS.REMOTE_SHARE_ACTIVE: {
|
2966
3078
|
const sendStartedSharingRemote = () => {
|
2967
3079
|
this.remoteShareInstanceId = contentShare.shareInstanceId;
|
3080
|
+
this.shareCAEventSentStatus.receiveStart = false;
|
3081
|
+
this.shareCAEventSentStatus.receiveStop = false;
|
2968
3082
|
|
2969
3083
|
Trigger.trigger(
|
2970
3084
|
this,
|
@@ -3018,6 +3132,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3018
3132
|
},
|
3019
3133
|
options: {meetingId: this.id},
|
3020
3134
|
});
|
3135
|
+
|
3021
3136
|
break;
|
3022
3137
|
|
3023
3138
|
case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
|
@@ -3058,6 +3173,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3058
3173
|
// if we got here, then some remote participant has stolen
|
3059
3174
|
// the presentation from another remote participant
|
3060
3175
|
this.remoteShareInstanceId = contentShare.shareInstanceId;
|
3176
|
+
this.shareCAEventSentStatus.receiveStart = false;
|
3177
|
+
this.shareCAEventSentStatus.receiveStop = false;
|
3061
3178
|
|
3062
3179
|
Trigger.trigger(
|
3063
3180
|
this,
|
@@ -3741,7 +3858,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3741
3858
|
return Promise.reject(error);
|
3742
3859
|
}
|
3743
3860
|
|
3744
|
-
return this.brbState.enable(enabled, this.sendSlotManager)
|
3861
|
+
return this.brbState.enable(enabled, this.sendSlotManager).then(() => {
|
3862
|
+
if (this.audio && enabled) {
|
3863
|
+
// locus mutes the participant with brb enabled request,
|
3864
|
+
// so we need to explicitly update remote mute for correct logic flow
|
3865
|
+
this.audio.handleServerRemoteMuteUpdate(this, enabled);
|
3866
|
+
}
|
3867
|
+
});
|
3745
3868
|
}
|
3746
3869
|
|
3747
3870
|
/**
|
@@ -3933,7 +4056,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3933
4056
|
canAdmitParticipant: MeetingUtil.canAdmitParticipant(this.userDisplayHints),
|
3934
4057
|
canLock: MeetingUtil.canUserLock(this.userDisplayHints),
|
3935
4058
|
canUnlock: MeetingUtil.canUserUnlock(this.userDisplayHints),
|
3936
|
-
canShareWhiteBoard: MeetingUtil.canShareWhiteBoard(
|
4059
|
+
canShareWhiteBoard: MeetingUtil.canShareWhiteBoard(
|
4060
|
+
this.userDisplayHints,
|
4061
|
+
this.selfUserPolicies
|
4062
|
+
),
|
3937
4063
|
canSetDisallowUnmute: ControlsOptionsUtil.canSetDisallowUnmute(this.userDisplayHints),
|
3938
4064
|
canUnsetDisallowUnmute: ControlsOptionsUtil.canUnsetDisallowUnmute(this.userDisplayHints),
|
3939
4065
|
canSetMuteOnEntry: ControlsOptionsUtil.canSetMuteOnEntry(this.userDisplayHints),
|
@@ -3982,6 +4108,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3982
4108
|
this.inMeetingActions.canSendReactions,
|
3983
4109
|
this.userDisplayHints
|
3984
4110
|
),
|
4111
|
+
requiresPostMeetingDataConsentPrompt: MeetingUtil.requiresPostMeetingDataConsentPrompt(
|
4112
|
+
this.userDisplayHints
|
4113
|
+
),
|
3985
4114
|
canManageBreakout: MeetingUtil.canManageBreakout(this.userDisplayHints),
|
3986
4115
|
canStartBreakout: MeetingUtil.canStartBreakout(this.userDisplayHints),
|
3987
4116
|
canBroadcastMessageToBreakout: MeetingUtil.canBroadcastMessageToBreakout(
|
@@ -3997,6 +4126,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3997
4126
|
this.userDisplayHints
|
3998
4127
|
),
|
3999
4128
|
canUserRenameOthers: MeetingUtil.canUserRenameOthers(this.userDisplayHints),
|
4129
|
+
canMoveToLobby: MeetingUtil.canMoveToLobby(this.userDisplayHints),
|
4000
4130
|
canMuteAll: ControlsOptionsUtil.hasHints({
|
4001
4131
|
requiredHints: [DISPLAY_HINTS.MUTE_ALL],
|
4002
4132
|
displayHints: this.userDisplayHints,
|
@@ -4177,6 +4307,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
4177
4307
|
requiredPolicies: [SELF_POLICY.SUPPORT_ANNOTATION],
|
4178
4308
|
policies: this.selfUserPolicies,
|
4179
4309
|
}),
|
4310
|
+
canEnableAnnotation: ControlsOptionsUtil.hasHints({
|
4311
|
+
requiredHints: [DISPLAY_HINTS.ENABLE_ANNOTATION_MEETING_OPTION],
|
4312
|
+
displayHints: this.userDisplayHints,
|
4313
|
+
}),
|
4314
|
+
canDisableAnnotation: ControlsOptionsUtil.hasHints({
|
4315
|
+
requiredHints: [DISPLAY_HINTS.DISABLE_ANNOTATION_MEETING_OPTION],
|
4316
|
+
displayHints: this.userDisplayHints,
|
4317
|
+
}),
|
4318
|
+
canEnableRemoteDesktopControl: ControlsOptionsUtil.hasHints({
|
4319
|
+
requiredHints: [DISPLAY_HINTS.ENABLE_RDC_MEETING_OPTION],
|
4320
|
+
displayHints: this.userDisplayHints,
|
4321
|
+
}),
|
4322
|
+
canDisableRemoteDesktopControl: ControlsOptionsUtil.hasHints({
|
4323
|
+
requiredHints: [DISPLAY_HINTS.DISABLE_RDC_MEETING_OPTION],
|
4324
|
+
displayHints: this.userDisplayHints,
|
4325
|
+
}),
|
4180
4326
|
}) || changed;
|
4181
4327
|
}
|
4182
4328
|
if (changed) {
|
@@ -5684,8 +5830,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
5684
5830
|
// @ts-ignore
|
5685
5831
|
this.webex.internal.device.meetingStarted();
|
5686
5832
|
|
5687
|
-
this.#isoLocalClientMeetingJoinTime = new Date().toISOString();
|
5688
|
-
|
5689
5833
|
LoggerProxy.logger.log('Meeting:index#join --> Success');
|
5690
5834
|
|
5691
5835
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_SUCCESS, {
|
@@ -6146,10 +6290,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6146
6290
|
},
|
6147
6291
|
options: {meetingId: this.id, rawError: error},
|
6148
6292
|
});
|
6149
|
-
} else if (
|
6150
|
-
error
|
6151
|
-
|
6152
|
-
|
6293
|
+
} else if (error instanceof Errors.SdpOfferHandlingError) {
|
6294
|
+
sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.correlationId);
|
6295
|
+
|
6296
|
+
// @ts-ignore
|
6297
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6298
|
+
name: 'client.media-engine.remote-sdp-received',
|
6299
|
+
payload: {
|
6300
|
+
canProceed: false,
|
6301
|
+
},
|
6302
|
+
options: {meetingId: this.id, rawError: error},
|
6303
|
+
});
|
6304
|
+
} else if (error instanceof Errors.SdpAnswerHandlingError) {
|
6153
6305
|
sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.correlationId);
|
6154
6306
|
|
6155
6307
|
// @ts-ignore
|
@@ -6160,6 +6312,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6160
6312
|
},
|
6161
6313
|
options: {meetingId: this.id, rawError: error},
|
6162
6314
|
});
|
6315
|
+
|
6316
|
+
if (this.deferSDPAnswer) {
|
6317
|
+
clearTimeout(this.sdpResponseTimer);
|
6318
|
+
this.sdpResponseTimer = undefined;
|
6319
|
+
|
6320
|
+
this.deferSDPAnswer.reject();
|
6321
|
+
}
|
6163
6322
|
} else if (error instanceof Errors.SdpError) {
|
6164
6323
|
// this covers also the case of Errors.IceGatheringError which extends Errors.SdpError
|
6165
6324
|
sendBehavioralMetric(BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE, error, this.correlationId);
|
@@ -6187,6 +6346,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6187
6346
|
? MeetingsUtil.getMediaServer(roapMessage.sdp)
|
6188
6347
|
: undefined;
|
6189
6348
|
|
6349
|
+
const mediaServerIp =
|
6350
|
+
roapMessage.messageType === 'ANSWER'
|
6351
|
+
? MeetingsUtil.getMediaServerIp(roapMessage.sdp)
|
6352
|
+
: undefined;
|
6353
|
+
|
6190
6354
|
if (this.isMultistream && mediaServer && mediaServer !== 'homer') {
|
6191
6355
|
throw new MultistreamNotSupportedError(
|
6192
6356
|
`Client asked for multistream backend (Homer), but got ${mediaServer} instead`
|
@@ -6197,6 +6361,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6197
6361
|
if (mediaServer) {
|
6198
6362
|
this.mediaProperties.webrtcMediaConnection.mediaServer = mediaServer;
|
6199
6363
|
}
|
6364
|
+
|
6365
|
+
if (this.isMultistream && mediaServerIp) {
|
6366
|
+
this.mediaServerIp = mediaServerIp;
|
6367
|
+
}
|
6200
6368
|
};
|
6201
6369
|
|
6202
6370
|
/**
|
@@ -6654,20 +6822,20 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6654
6822
|
* @memberof Meetings
|
6655
6823
|
*/
|
6656
6824
|
setupStatsAnalyzerEventHandlers = () => {
|
6657
|
-
this.statsAnalyzer.on(StatsAnalyzerEventNames.MEDIA_QUALITY, (
|
6658
|
-
//
|
6659
|
-
|
6660
|
-
|
6661
|
-
|
6662
|
-
|
6663
|
-
|
6664
|
-
|
6665
|
-
|
6825
|
+
this.statsAnalyzer.on(StatsAnalyzerEventNames.MEDIA_QUALITY, (event) => {
|
6826
|
+
// Add IP address from geoHintInfo if missing.
|
6827
|
+
if (event.data.intervalMetadata.maskedPeerReflexiveIP === '0.0.0.0') {
|
6828
|
+
// @ts-ignore fix type
|
6829
|
+
const clientAddressFromGeoHint = this.webex.meetings.geoHintInfo?.clientAddress;
|
6830
|
+
if (clientAddressFromGeoHint) {
|
6831
|
+
event.data.intervalMetadata.maskedPeerReflexiveIP =
|
6832
|
+
CallDiagnosticUtils.anonymizeIPAddress(clientAddressFromGeoHint);
|
6833
|
+
}
|
6834
|
+
}
|
6666
6835
|
|
6836
|
+
// Count members that are in the meeting.
|
6667
6837
|
const {members} = this.getMembers().membersCollection;
|
6668
|
-
|
6669
|
-
// Count members that are in the meeting
|
6670
|
-
options.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
6838
|
+
event.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
6671
6839
|
(member: Member) => member.isInMeeting
|
6672
6840
|
).length;
|
6673
6841
|
|
@@ -6676,10 +6844,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6676
6844
|
name: 'client.mediaquality.event',
|
6677
6845
|
options: {
|
6678
6846
|
meetingId: this.id,
|
6679
|
-
networkType:
|
6847
|
+
networkType: this.statsAnalyzer.getNetworkType(),
|
6680
6848
|
},
|
6681
6849
|
payload: {
|
6682
|
-
intervals: [
|
6850
|
+
intervals: [event.data],
|
6683
6851
|
},
|
6684
6852
|
});
|
6685
6853
|
});
|
@@ -6694,30 +6862,42 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6694
6862
|
EVENT_TRIGGERS.MEETING_MEDIA_LOCAL_STARTED,
|
6695
6863
|
data
|
6696
6864
|
);
|
6697
|
-
|
6698
|
-
|
6699
|
-
|
6700
|
-
|
6701
|
-
|
6702
|
-
|
6703
|
-
|
6704
|
-
|
6705
|
-
|
6706
|
-
|
6707
|
-
|
6865
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.transmitStart) {
|
6866
|
+
// @ts-ignore
|
6867
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6868
|
+
name: 'client.media.tx.start',
|
6869
|
+
payload: {
|
6870
|
+
mediaType: data.mediaType,
|
6871
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
6872
|
+
},
|
6873
|
+
options: {
|
6874
|
+
meetingId: this.id,
|
6875
|
+
},
|
6876
|
+
});
|
6877
|
+
|
6878
|
+
if (data.mediaType === 'share') {
|
6879
|
+
this.shareCAEventSentStatus.transmitStart = true;
|
6880
|
+
}
|
6881
|
+
}
|
6708
6882
|
});
|
6709
6883
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.LOCAL_MEDIA_STOPPED, (data) => {
|
6710
|
-
|
6711
|
-
|
6712
|
-
|
6713
|
-
|
6714
|
-
|
6715
|
-
|
6716
|
-
|
6717
|
-
|
6718
|
-
|
6719
|
-
|
6720
|
-
|
6884
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.transmitStop) {
|
6885
|
+
// @ts-ignore
|
6886
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6887
|
+
name: 'client.media.tx.stop',
|
6888
|
+
payload: {
|
6889
|
+
mediaType: data.mediaType,
|
6890
|
+
shareInstanceId: data.mediaType === 'share' ? this.localShareInstanceId : undefined,
|
6891
|
+
},
|
6892
|
+
options: {
|
6893
|
+
meetingId: this.id,
|
6894
|
+
},
|
6895
|
+
});
|
6896
|
+
|
6897
|
+
if (data.mediaType === 'share') {
|
6898
|
+
this.shareCAEventSentStatus.transmitStop = true;
|
6899
|
+
}
|
6900
|
+
}
|
6721
6901
|
});
|
6722
6902
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STARTED, (data) => {
|
6723
6903
|
Trigger.trigger(
|
@@ -6729,57 +6909,65 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6729
6909
|
EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
|
6730
6910
|
data
|
6731
6911
|
);
|
6732
|
-
|
6733
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
6734
|
-
name: 'client.media.rx.start',
|
6735
|
-
payload: {
|
6736
|
-
mediaType: data.mediaType,
|
6737
|
-
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6738
|
-
},
|
6739
|
-
options: {
|
6740
|
-
meetingId: this.id,
|
6741
|
-
},
|
6742
|
-
});
|
6743
|
-
|
6744
|
-
if (data.mediaType === 'share') {
|
6912
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.receiveStart) {
|
6745
6913
|
// @ts-ignore
|
6746
6914
|
this.webex.internal.newMetrics.submitClientEvent({
|
6747
|
-
name: 'client.media.
|
6915
|
+
name: 'client.media.rx.start',
|
6748
6916
|
payload: {
|
6749
|
-
mediaType:
|
6750
|
-
shareInstanceId: this.remoteShareInstanceId,
|
6917
|
+
mediaType: data.mediaType,
|
6918
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6751
6919
|
},
|
6752
6920
|
options: {
|
6753
6921
|
meetingId: this.id,
|
6754
6922
|
},
|
6755
6923
|
});
|
6924
|
+
|
6925
|
+
if (data.mediaType === 'share') {
|
6926
|
+
// @ts-ignore
|
6927
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6928
|
+
name: 'client.media.render.start',
|
6929
|
+
payload: {
|
6930
|
+
mediaType: 'share',
|
6931
|
+
shareInstanceId: this.remoteShareInstanceId,
|
6932
|
+
},
|
6933
|
+
options: {
|
6934
|
+
meetingId: this.id,
|
6935
|
+
},
|
6936
|
+
});
|
6937
|
+
|
6938
|
+
this.shareCAEventSentStatus.receiveStart = true;
|
6939
|
+
}
|
6756
6940
|
}
|
6757
6941
|
});
|
6758
6942
|
this.statsAnalyzer.on(StatsAnalyzerEventNames.REMOTE_MEDIA_STOPPED, (data) => {
|
6759
|
-
|
6760
|
-
this.webex.internal.newMetrics.submitClientEvent({
|
6761
|
-
name: 'client.media.rx.stop',
|
6762
|
-
payload: {
|
6763
|
-
mediaType: data.mediaType,
|
6764
|
-
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6765
|
-
},
|
6766
|
-
options: {
|
6767
|
-
meetingId: this.id,
|
6768
|
-
},
|
6769
|
-
});
|
6770
|
-
|
6771
|
-
if (data.mediaType === 'share') {
|
6943
|
+
if (data.mediaType !== 'share' || !this.shareCAEventSentStatus.receiveStop) {
|
6772
6944
|
// @ts-ignore
|
6773
6945
|
this.webex.internal.newMetrics.submitClientEvent({
|
6774
|
-
name: 'client.media.
|
6946
|
+
name: 'client.media.rx.stop',
|
6775
6947
|
payload: {
|
6776
|
-
mediaType:
|
6777
|
-
shareInstanceId: this.remoteShareInstanceId,
|
6948
|
+
mediaType: data.mediaType,
|
6949
|
+
shareInstanceId: data.mediaType === 'share' ? this.remoteShareInstanceId : undefined,
|
6778
6950
|
},
|
6779
6951
|
options: {
|
6780
6952
|
meetingId: this.id,
|
6781
6953
|
},
|
6782
6954
|
});
|
6955
|
+
|
6956
|
+
if (data.mediaType === 'share') {
|
6957
|
+
// @ts-ignore
|
6958
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
6959
|
+
name: 'client.media.render.stop',
|
6960
|
+
payload: {
|
6961
|
+
mediaType: 'share',
|
6962
|
+
shareInstanceId: this.remoteShareInstanceId,
|
6963
|
+
},
|
6964
|
+
options: {
|
6965
|
+
meetingId: this.id,
|
6966
|
+
},
|
6967
|
+
});
|
6968
|
+
|
6969
|
+
this.shareCAEventSentStatus.receiveStop = true;
|
6970
|
+
}
|
6783
6971
|
}
|
6784
6972
|
});
|
6785
6973
|
};
|
@@ -6796,7 +6984,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6796
6984
|
* @param {AddMediaOptions} [options] Options for enabling/disabling audio/video
|
6797
6985
|
* @returns {RoapMediaConnection | MultistreamRoapMediaConnection}
|
6798
6986
|
*/
|
6799
|
-
private async createMediaConnection(
|
6987
|
+
private async createMediaConnection(
|
6988
|
+
turnServerInfo?: TurnServerInfo,
|
6989
|
+
bundlePolicy?: BundlePolicy
|
6990
|
+
) {
|
6800
6991
|
this.rtcMetrics = this.isMultistream
|
6801
6992
|
? // @ts-ignore
|
6802
6993
|
new RtcMetrics(this.webex, {meetingId: this.id}, this.correlationId)
|
@@ -6821,6 +7012,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6821
7012
|
bundlePolicy,
|
6822
7013
|
// @ts-ignore - config coming from registerPlugin
|
6823
7014
|
iceCandidatesTimeout: this.config.iceCandidatesGatheringTimeout,
|
7015
|
+
// @ts-ignore - config coming from registerPlugin
|
7016
|
+
disableAudioMainDtx: this.config.experimental.disableAudioMainDtx,
|
6824
7017
|
}
|
6825
7018
|
);
|
6826
7019
|
|
@@ -6971,12 +7164,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6971
7164
|
},
|
6972
7165
|
options: {
|
6973
7166
|
meetingId: this.id,
|
7167
|
+
rawError: error,
|
6974
7168
|
},
|
6975
7169
|
});
|
6976
7170
|
}
|
6977
|
-
|
7171
|
+
|
7172
|
+
const timedOutError = new Error(
|
6978
7173
|
`Timed out waiting for media connection to be connected, correlationId=${this.correlationId}`
|
6979
7174
|
);
|
7175
|
+
|
7176
|
+
timedOutError.cause = error;
|
7177
|
+
|
7178
|
+
throw timedOutError;
|
6980
7179
|
}
|
6981
7180
|
}
|
6982
7181
|
|
@@ -6997,6 +7196,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6997
7196
|
networkQualityMonitor: this.networkQualityMonitor,
|
6998
7197
|
isMultistream: this.isMultistream,
|
6999
7198
|
});
|
7199
|
+
this.shareCAEventSentStatus = {
|
7200
|
+
transmitStart: false,
|
7201
|
+
transmitStop: false,
|
7202
|
+
receiveStart: false,
|
7203
|
+
receiveStop: false,
|
7204
|
+
};
|
7000
7205
|
this.setupStatsAnalyzerEventHandlers();
|
7001
7206
|
this.networkQualityMonitor.on(
|
7002
7207
|
NetworkQualityEventNames.NETWORK_QUALITY,
|
@@ -7031,6 +7236,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7031
7236
|
ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT / 1000
|
7032
7237
|
} seconds`
|
7033
7238
|
);
|
7239
|
+
|
7240
|
+
const error = new Error('Timed out waiting for REMOTE SDP ANSWER');
|
7241
|
+
|
7034
7242
|
// @ts-ignore
|
7035
7243
|
this.webex.internal.newMetrics.submitClientEvent({
|
7036
7244
|
name: 'client.media-engine.remote-sdp-received',
|
@@ -7043,10 +7251,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7043
7251
|
}),
|
7044
7252
|
],
|
7045
7253
|
},
|
7046
|
-
options: {meetingId: this.id, rawError:
|
7254
|
+
options: {meetingId: this.id, rawError: error},
|
7047
7255
|
});
|
7048
7256
|
|
7049
|
-
deferSDPAnswer.reject(
|
7257
|
+
deferSDPAnswer.reject(error);
|
7050
7258
|
}, ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT);
|
7051
7259
|
|
7052
7260
|
LoggerProxy.logger.info(`${LOG_HEADER} waiting for REMOTE SDP ANSWER...`);
|
@@ -7151,7 +7359,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7151
7359
|
error
|
7152
7360
|
);
|
7153
7361
|
|
7154
|
-
throw new AddMediaFailed();
|
7362
|
+
throw new AddMediaFailed(error);
|
7155
7363
|
}
|
7156
7364
|
}
|
7157
7365
|
|
@@ -7566,10 +7774,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7566
7774
|
|
7567
7775
|
const {connectionType, selectedCandidatePairChanges, numTransports} =
|
7568
7776
|
await this.mediaProperties.getCurrentConnectionInfo();
|
7569
|
-
|
7570
|
-
const reachabilityStats = await this.webex.meetings.reachability.getReachabilityMetrics();
|
7777
|
+
|
7571
7778
|
const iceCandidateErrors = Object.fromEntries(this.iceCandidateErrors);
|
7572
7779
|
|
7780
|
+
const reachabilityMetrics = await this.getMediaReachabilityMetricFields();
|
7781
|
+
|
7573
7782
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_SUCCESS, {
|
7574
7783
|
correlation_id: this.correlationId,
|
7575
7784
|
locus_id: this.locusUrl.split('/').pop(),
|
@@ -7579,7 +7788,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7579
7788
|
isMultistream: this.isMultistream,
|
7580
7789
|
retriedWithTurnServer: this.addMediaData.retriedWithTurnServer,
|
7581
7790
|
isJoinWithMediaRetry: this.joinWithMediaRetryInfo.isRetry,
|
7582
|
-
...
|
7791
|
+
...reachabilityMetrics,
|
7583
7792
|
...iceCandidateErrors,
|
7584
7793
|
iceCandidatesCount: this.iceCandidatesCount,
|
7585
7794
|
});
|
@@ -7601,7 +7810,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7601
7810
|
LoggerProxy.logger.error(`${LOG_HEADER} failed to establish media connection: `, error);
|
7602
7811
|
|
7603
7812
|
// @ts-ignore
|
7604
|
-
const reachabilityMetrics = await this.
|
7813
|
+
const reachabilityMetrics = await this.getMediaReachabilityMetricFields();
|
7605
7814
|
|
7606
7815
|
const {selectedCandidatePairChanges, numTransports} =
|
7607
7816
|
await this.mediaProperties.getCurrentConnectionInfo();
|
@@ -8681,6 +8890,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
8681
8890
|
LoggerProxy.logger.log(
|
8682
8891
|
`Meeting:index#handleShareVideoStreamMuteStateChange --> Share video stream mute state changed to muted ${muted}`
|
8683
8892
|
);
|
8893
|
+
|
8894
|
+
const shareVideoStreamSettings = this.mediaProperties?.shareVideoStream?.getSettings();
|
8895
|
+
|
8684
8896
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE, {
|
8685
8897
|
correlationId: this.correlationId,
|
8686
8898
|
muted,
|
@@ -8689,8 +8901,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
8689
8901
|
// SDK to TypeScript 5, which may affect other packages, use bracket notation for now, since
|
8690
8902
|
// all we're doing here is adding metrics.
|
8691
8903
|
// eslint-disable-next-line dot-notation
|
8692
|
-
displaySurface:
|
8904
|
+
displaySurface: shareVideoStreamSettings?.['displaySurface'],
|
8693
8905
|
isMultistream: this.isMultistream,
|
8906
|
+
frameRate: shareVideoStreamSettings?.frameRate,
|
8694
8907
|
});
|
8695
8908
|
};
|
8696
8909
|
|
@@ -9017,6 +9230,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9017
9230
|
});
|
9018
9231
|
}
|
9019
9232
|
|
9233
|
+
/**
|
9234
|
+
* Method to set post meeting data consent.
|
9235
|
+
*
|
9236
|
+
* @param {boolean} accept - whether consent accepted or declined
|
9237
|
+
* @returns {Promise}
|
9238
|
+
* @public
|
9239
|
+
* @memberof Meeting
|
9240
|
+
*/
|
9241
|
+
public setPostMeetingDataConsent(accept: boolean) {
|
9242
|
+
return this.meetingRequest.setPostMeetingDataConsent({
|
9243
|
+
postMeetingDataConsent: accept,
|
9244
|
+
locusUrl: this.locusUrl,
|
9245
|
+
deviceUrl: this.deviceUrl,
|
9246
|
+
selfId: this.members.selfId,
|
9247
|
+
});
|
9248
|
+
}
|
9249
|
+
|
9020
9250
|
/**
|
9021
9251
|
* Throws if we don't have a media connection created
|
9022
9252
|
*
|
@@ -9257,6 +9487,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9257
9487
|
|
9258
9488
|
if (floorRequestNeeded) {
|
9259
9489
|
this.localShareInstanceId = uuid.v4();
|
9490
|
+
this.shareCAEventSentStatus.transmitStart = false;
|
9491
|
+
this.shareCAEventSentStatus.transmitStop = false;
|
9260
9492
|
|
9261
9493
|
// @ts-ignore
|
9262
9494
|
this.webex.internal.newMetrics.submitClientEvent({
|
@@ -9384,4 +9616,44 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
9384
9616
|
|
9385
9617
|
return Promise.resolve();
|
9386
9618
|
}
|
9619
|
+
|
9620
|
+
/**
|
9621
|
+
* Gets the media reachability metrics
|
9622
|
+
*
|
9623
|
+
* @returns {Promise<MediaReachabilityMetrics>}
|
9624
|
+
*/
|
9625
|
+
private async getMediaReachabilityMetricFields(): Promise<MediaReachabilityMetrics> {
|
9626
|
+
const reachabilityMetrics: ReachabilityMetrics =
|
9627
|
+
// @ts-ignore
|
9628
|
+
await this.webex.meetings.reachability.getReachabilityMetrics();
|
9629
|
+
|
9630
|
+
const successKeys: Array<keyof ReachabilityMetrics> = [
|
9631
|
+
'reachability_public_udp_success',
|
9632
|
+
'reachability_public_tcp_success',
|
9633
|
+
'reachability_public_xtls_success',
|
9634
|
+
'reachability_vmn_udp_success',
|
9635
|
+
'reachability_vmn_tcp_success',
|
9636
|
+
'reachability_vmn_xtls_success',
|
9637
|
+
];
|
9638
|
+
|
9639
|
+
const totalSuccessCases = successKeys.reduce((total, key) => {
|
9640
|
+
const value = reachabilityMetrics[key];
|
9641
|
+
if (typeof value === 'number') {
|
9642
|
+
return total + value;
|
9643
|
+
}
|
9644
|
+
|
9645
|
+
return total;
|
9646
|
+
}, 0);
|
9647
|
+
|
9648
|
+
let isSubnetReachable = null;
|
9649
|
+
if (totalSuccessCases > 0) {
|
9650
|
+
// @ts-ignore
|
9651
|
+
isSubnetReachable = this.webex.meetings.reachability.isSubnetReachable(this.mediaServerIp);
|
9652
|
+
}
|
9653
|
+
|
9654
|
+
return {
|
9655
|
+
...reachabilityMetrics,
|
9656
|
+
isSubnetReachable,
|
9657
|
+
};
|
9658
|
+
}
|
9387
9659
|
}
|