@webex/plugin-meetings 3.0.0-beta.162 → 3.0.0-beta.164
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 +7 -3
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +31 -29
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +4 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +2 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +33 -17
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +699 -682
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +47 -25
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +48 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +24 -10
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +12 -9
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/index.js +1 -487
- package/dist/metrics/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +27 -17
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/request.js +20 -14
- package/dist/roap/request.js.map +1 -1
- package/dist/types/breakouts/events.d.ts +7 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/meeting/index.d.ts +31 -133
- package/dist/types/meeting-info/index.d.ts +6 -1
- package/dist/types/meetings/index.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +4 -128
- package/package.json +19 -19
- package/src/breakouts/breakout.ts +10 -2
- package/src/breakouts/events.ts +51 -32
- package/src/breakouts/index.ts +9 -5
- package/src/constants.ts +0 -2
- package/src/locus-info/index.ts +35 -17
- package/src/meeting/index.ts +474 -536
- package/src/meeting/util.ts +42 -19
- package/src/meeting-info/index.ts +54 -8
- package/src/meeting-info/meeting-info-v2.ts +24 -9
- package/src/meetings/index.ts +11 -6
- package/src/metrics/index.ts +1 -506
- package/src/reconnection-manager/index.ts +27 -17
- package/src/roap/request.ts +21 -9
- package/test/unit/spec/breakouts/breakout.ts +4 -2
- package/test/unit/spec/breakouts/events.ts +24 -18
- package/test/unit/spec/locus-info/index.js +112 -0
- package/test/unit/spec/meeting/index.js +178 -145
- package/test/unit/spec/meeting/utils.js +93 -7
- package/test/unit/spec/meeting-info/index.js +181 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +68 -68
- package/test/unit/spec/meetings/index.js +35 -55
- package/test/unit/spec/metrics/index.js +1 -148
- package/test/unit/spec/reconnection-manager/index.js +51 -2
- package/test/unit/spec/roap/index.ts +8 -2
- package/test/unit/spec/roap/request.ts +43 -5
- package/dist/metrics/config.js +0 -335
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/metrics/config.d.ts +0 -195
- package/src/metrics/config.ts +0 -534
package/src/meeting/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
|
-
import {cloneDeep, isEqual,
|
|
2
|
+
import {cloneDeep, isEqual, defer, isEmpty} from 'lodash';
|
|
3
3
|
// @ts-ignore - Fix this
|
|
4
4
|
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
5
|
+
import {ClientEvent, CALL_DIAGNOSTIC_CONFIG} from '@webex/internal-plugin-metrics';
|
|
5
6
|
import {
|
|
6
7
|
ConnectionState,
|
|
7
8
|
Errors,
|
|
@@ -39,7 +40,6 @@ import MeetingStateMachine from './state';
|
|
|
39
40
|
import {createMuteState} from './muteState';
|
|
40
41
|
import LocusInfo from '../locus-info';
|
|
41
42
|
import Metrics from '../metrics';
|
|
42
|
-
import {trigger, error as MetricsError, eventType} from '../metrics/config';
|
|
43
43
|
import ReconnectionManager from '../reconnection-manager';
|
|
44
44
|
import MeetingRequest from './request';
|
|
45
45
|
import Members from '../members/index';
|
|
@@ -74,7 +74,6 @@ import {
|
|
|
74
74
|
MEETING_STATE_MACHINE,
|
|
75
75
|
MEETING_STATE,
|
|
76
76
|
MEETINGS,
|
|
77
|
-
METRICS_JOIN_TIMES_MAX_DURATION,
|
|
78
77
|
MQA_STATS,
|
|
79
78
|
NETWORK_STATUS,
|
|
80
79
|
ONLINE,
|
|
@@ -1224,6 +1223,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1224
1223
|
};
|
|
1225
1224
|
}
|
|
1226
1225
|
|
|
1226
|
+
/**
|
|
1227
|
+
* Temporary func to return webex object,
|
|
1228
|
+
* in order to access internal plugin metrics
|
|
1229
|
+
* in the utils file.
|
|
1230
|
+
* @internal
|
|
1231
|
+
* @returns {object} webex object
|
|
1232
|
+
*/
|
|
1233
|
+
getWebexObject() {
|
|
1234
|
+
// @ts-ignore
|
|
1235
|
+
return this.webex;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1227
1238
|
/**
|
|
1228
1239
|
* returns meeting is joined
|
|
1229
1240
|
* @private
|
|
@@ -1443,15 +1454,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1443
1454
|
|
|
1444
1455
|
/**
|
|
1445
1456
|
* Posts metrics event for this meeting. Allows the app to send Call Analyzer events.
|
|
1446
|
-
* @param {String} eventName - Call Analyzer event
|
|
1457
|
+
* @param {String} eventName - Call Analyzer event
|
|
1447
1458
|
* @public
|
|
1448
1459
|
* @memberof Meeting
|
|
1449
1460
|
* @returns {Promise}
|
|
1450
1461
|
*/
|
|
1451
|
-
public postMetrics(eventName:
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1462
|
+
public postMetrics(eventName: ClientEvent['name']) {
|
|
1463
|
+
// @ts-ignore
|
|
1464
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
1465
|
+
name: eventName,
|
|
1466
|
+
options: {
|
|
1467
|
+
meetingId: this.id,
|
|
1468
|
+
},
|
|
1455
1469
|
});
|
|
1456
1470
|
}
|
|
1457
1471
|
|
|
@@ -1692,230 +1706,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1692
1706
|
});
|
|
1693
1707
|
}
|
|
1694
1708
|
|
|
1695
|
-
/**
|
|
1696
|
-
* get the metrics payload pre
|
|
1697
|
-
* @param {Object} options
|
|
1698
|
-
* @param {String} options.event
|
|
1699
|
-
* @param {String} options.trackingId
|
|
1700
|
-
* @param {Object} options.locus
|
|
1701
|
-
* @param {Array} options.mediaConnections
|
|
1702
|
-
* @param {Object} options.errors
|
|
1703
|
-
* @returns {Object}
|
|
1704
|
-
* @memberof Meeting
|
|
1705
|
-
*/
|
|
1706
|
-
getAnalyzerMetricsPrePayload(options: {
|
|
1707
|
-
type?: string;
|
|
1708
|
-
event: string;
|
|
1709
|
-
trackingId: string;
|
|
1710
|
-
locus: object;
|
|
1711
|
-
mediaConnections?: Array<any>;
|
|
1712
|
-
errors?: object;
|
|
1713
|
-
meetingLookupUrl?: string;
|
|
1714
|
-
clientType?: any;
|
|
1715
|
-
subClientType?: any;
|
|
1716
|
-
[key: string]: any;
|
|
1717
|
-
}) {
|
|
1718
|
-
if (options) {
|
|
1719
|
-
const {event, trackingId, mediaConnections, meetingLookupUrl} = options;
|
|
1720
|
-
|
|
1721
|
-
if (!event) {
|
|
1722
|
-
LoggerProxy.logger.error(
|
|
1723
|
-
'Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event',
|
|
1724
|
-
event || '',
|
|
1725
|
-
`]: invalid identifers or event type! ${this.correlationId}`
|
|
1726
|
-
);
|
|
1727
|
-
|
|
1728
|
-
return null;
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
const identifiers: any = {
|
|
1732
|
-
correlationId: this.correlationId,
|
|
1733
|
-
userId: this.userId,
|
|
1734
|
-
deviceId: this.deviceUrl,
|
|
1735
|
-
orgId: this.orgId,
|
|
1736
|
-
// @ts-ignore fix type
|
|
1737
|
-
locusUrl: this.webex.internal.services.get('locus'),
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
|
-
if (this.locusUrl && this.locusInfo.fullState) {
|
|
1741
|
-
identifiers.locusUrl = this.locusUrl;
|
|
1742
|
-
identifiers.locusId = this.locusUrl && this.locusUrl.split('/').pop();
|
|
1743
|
-
identifiers.locusStartTime =
|
|
1744
|
-
this.locusInfo.fullState && this.locusInfo.fullState.lastActive;
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
// Check if mediaConnections has been passed in or else use this.mediaConnections
|
|
1748
|
-
if (mediaConnections) {
|
|
1749
|
-
identifiers.mediaAgentAlias = mediaConnections?.[0].mediaAgentAlias;
|
|
1750
|
-
identifiers.mediaAgentGroupId = mediaConnections?.[0].mediaAgentGroupId;
|
|
1751
|
-
identifiers.mediaAgentCluster = mediaConnections?.[0].mediaAgentCluster;
|
|
1752
|
-
} else if (this.mediaConnections) {
|
|
1753
|
-
identifiers.mediaAgentAlias = this.mediaConnections?.[0].mediaAgentAlias;
|
|
1754
|
-
identifiers.mediaAgentGroupId = this.mediaConnections?.[0].mediaAgentGroupId;
|
|
1755
|
-
identifiers.mediaAgentCluster = this.mediaConnections?.[0].mediaAgentCluster;
|
|
1756
|
-
}
|
|
1757
|
-
|
|
1758
|
-
if (meetingLookupUrl) {
|
|
1759
|
-
identifiers.meetingLookupUrl = meetingLookupUrl;
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1762
|
-
if (options.trackingId) {
|
|
1763
|
-
identifiers.trackingId = trackingId;
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
let payload = {};
|
|
1767
|
-
|
|
1768
|
-
const joinRespRxStartAudio = this.getSetupDelayDuration('audio');
|
|
1769
|
-
|
|
1770
|
-
if (joinRespRxStartAudio) {
|
|
1771
|
-
options.audioSetupDelay = {
|
|
1772
|
-
joinRespRxStart: joinRespRxStartAudio,
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
const joinRespRxStartVideo = this.getSetupDelayDuration('video');
|
|
1777
|
-
|
|
1778
|
-
if (joinRespRxStartAudio) {
|
|
1779
|
-
options.videoSetupDelay = {
|
|
1780
|
-
joinRespRxStart: joinRespRxStartVideo,
|
|
1781
|
-
};
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
const joinRespTxStartAudio = this.getSendingMediaDelayDuration('audio');
|
|
1785
|
-
|
|
1786
|
-
if (joinRespTxStartAudio) {
|
|
1787
|
-
options.audioSetupDelay = {
|
|
1788
|
-
...options.audioSetupDelay,
|
|
1789
|
-
joinRespTxStart: joinRespTxStartAudio,
|
|
1790
|
-
};
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1793
|
-
const joinRespTxStartVideo = this.getSendingMediaDelayDuration('video');
|
|
1794
|
-
|
|
1795
|
-
if (joinRespTxStartVideo) {
|
|
1796
|
-
options.videoSetupDelay = {
|
|
1797
|
-
...options.videoSetupDelay,
|
|
1798
|
-
joinRespTxStart: joinRespTxStartVideo,
|
|
1799
|
-
};
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
const localSDPGenRemoteSDPRecv = this.getLocalSDPGenRemoteSDPRecvDelay();
|
|
1803
|
-
|
|
1804
|
-
if (localSDPGenRemoteSDPRecv) {
|
|
1805
|
-
options.joinTimes = {
|
|
1806
|
-
...options.joinTimes,
|
|
1807
|
-
localSDPGenRemoteSDPRecv,
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
const callInitJoinReq = this.getCallInitJoinReq();
|
|
1812
|
-
|
|
1813
|
-
if (callInitJoinReq) {
|
|
1814
|
-
options.joinTimes = {
|
|
1815
|
-
...options.joinTimes,
|
|
1816
|
-
callInitJoinReq,
|
|
1817
|
-
};
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
const joinReqResp = this.getJoinReqResp();
|
|
1821
|
-
|
|
1822
|
-
if (joinReqResp) {
|
|
1823
|
-
options.joinTimes = {
|
|
1824
|
-
...options.joinTimes,
|
|
1825
|
-
joinReqResp,
|
|
1826
|
-
};
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
const totalJmt = this.getTotalJmt();
|
|
1830
|
-
|
|
1831
|
-
if (totalJmt) {
|
|
1832
|
-
options.joinTimes = {
|
|
1833
|
-
...options.joinTimes,
|
|
1834
|
-
totalJmt,
|
|
1835
|
-
};
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
const curUserType = this.getCurUserType();
|
|
1839
|
-
|
|
1840
|
-
if (curUserType) {
|
|
1841
|
-
options.userType = curUserType;
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
const curLoginType = this.getCurLoginType();
|
|
1845
|
-
|
|
1846
|
-
if (curLoginType) {
|
|
1847
|
-
options.loginType = curLoginType;
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
if (this.environment) {
|
|
1851
|
-
options.environment = this.environment;
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
if (options.type === MQA_STATS.CA_TYPE) {
|
|
1855
|
-
payload = Metrics.initMediaPayload(options.event, identifiers, options);
|
|
1856
|
-
} else {
|
|
1857
|
-
payload = Metrics.initPayload(options.event, identifiers, options);
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
return payload;
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
return null;
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
/**
|
|
1867
|
-
* Send the metrics to call-analyzer dashboard
|
|
1868
|
-
* @param {Object} options
|
|
1869
|
-
* @param {String} options.event
|
|
1870
|
-
* @param {String} options.trackingId
|
|
1871
|
-
* @param {Object} options.locus
|
|
1872
|
-
* @param {Object} options.errors
|
|
1873
|
-
* @returns {Promise}
|
|
1874
|
-
* @private
|
|
1875
|
-
* @memberof Meeting
|
|
1876
|
-
*/
|
|
1877
|
-
private sendCallAnalyzerMetrics(options: {
|
|
1878
|
-
event: string;
|
|
1879
|
-
trackingId: string;
|
|
1880
|
-
locus: object;
|
|
1881
|
-
errors: object;
|
|
1882
|
-
}) {
|
|
1883
|
-
const payload = this.getAnalyzerMetricsPrePayload({
|
|
1884
|
-
// @ts-ignore - config coming from registerPlugin
|
|
1885
|
-
...pick(this.config.metrics, ['clientType', 'subClientType']),
|
|
1886
|
-
...options,
|
|
1887
|
-
});
|
|
1888
|
-
|
|
1889
|
-
// @ts-ignore - fix type
|
|
1890
|
-
return this.webex.internal.metrics.submitCallDiagnosticEvents(payload);
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
/**
|
|
1894
|
-
* Send the metrics to Media Quality Analyzer dashboard
|
|
1895
|
-
* @param {Object} options
|
|
1896
|
-
* @param {String} options.event
|
|
1897
|
-
* @param {String} options.trackingId
|
|
1898
|
-
* @param {Object} options.locus
|
|
1899
|
-
* @returns {Promise}
|
|
1900
|
-
* @private
|
|
1901
|
-
* @memberof Meeting
|
|
1902
|
-
*/
|
|
1903
|
-
private sendMediaQualityAnalyzerMetrics(options: {
|
|
1904
|
-
event: string;
|
|
1905
|
-
trackingId: string;
|
|
1906
|
-
locus: object;
|
|
1907
|
-
}) {
|
|
1908
|
-
const payload = this.getAnalyzerMetricsPrePayload({
|
|
1909
|
-
type: MQA_STATS.CA_TYPE,
|
|
1910
|
-
// @ts-ignore - config coming from registerPlugin
|
|
1911
|
-
...pick(this.config.metrics, ['clientType', 'subClientType']),
|
|
1912
|
-
...options,
|
|
1913
|
-
});
|
|
1914
|
-
|
|
1915
|
-
// @ts-ignore
|
|
1916
|
-
return this.webex.internal.metrics.submitCallDiagnosticEvents(payload);
|
|
1917
|
-
}
|
|
1918
|
-
|
|
1919
1709
|
/**
|
|
1920
1710
|
* sets the network status on meeting object
|
|
1921
1711
|
* @param {String} networkStatus
|
|
@@ -2448,7 +2238,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2448
2238
|
},
|
|
2449
2239
|
EVENT_TRIGGERS.MEETING_STARTED_SHARING_LOCAL
|
|
2450
2240
|
);
|
|
2451
|
-
|
|
2241
|
+
// @ts-ignore
|
|
2242
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
2243
|
+
name: 'client.share.floor-granted.local',
|
|
2244
|
+
payload: {
|
|
2245
|
+
mediaType: 'share',
|
|
2246
|
+
},
|
|
2247
|
+
options: {meetingId: this.id},
|
|
2248
|
+
});
|
|
2452
2249
|
break;
|
|
2453
2250
|
|
|
2454
2251
|
case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
|
|
@@ -2464,7 +2261,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2464
2261
|
memberId: whiteboardShare.beneficiaryId,
|
|
2465
2262
|
}
|
|
2466
2263
|
);
|
|
2467
|
-
|
|
2264
|
+
// @ts-ignore
|
|
2265
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
2266
|
+
name: 'client.share.floor-granted.local',
|
|
2267
|
+
payload: {
|
|
2268
|
+
mediaType: 'whiteboard',
|
|
2269
|
+
},
|
|
2270
|
+
options: {
|
|
2271
|
+
meetingId: this.id,
|
|
2272
|
+
},
|
|
2273
|
+
});
|
|
2468
2274
|
break;
|
|
2469
2275
|
|
|
2470
2276
|
case SHARE_STATUS.NO_SHARE:
|
|
@@ -2508,7 +2314,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2508
2314
|
memberId: whiteboardShare.beneficiaryId,
|
|
2509
2315
|
}
|
|
2510
2316
|
);
|
|
2511
|
-
|
|
2317
|
+
// @ts-ignore
|
|
2318
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
2319
|
+
name: 'client.share.floor-granted.local',
|
|
2320
|
+
payload: {
|
|
2321
|
+
mediaType: 'whiteboard',
|
|
2322
|
+
},
|
|
2323
|
+
options: {
|
|
2324
|
+
meetingId: this.id,
|
|
2325
|
+
},
|
|
2326
|
+
});
|
|
2512
2327
|
this.members.locusMediaSharesUpdate(payload);
|
|
2513
2328
|
}
|
|
2514
2329
|
});
|
|
@@ -2907,9 +2722,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2907
2722
|
}
|
|
2908
2723
|
);
|
|
2909
2724
|
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2725
|
+
// @ts-ignore
|
|
2726
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
2727
|
+
name: 'client.lobby.entered',
|
|
2728
|
+
options: {meetingId: this.id},
|
|
2913
2729
|
});
|
|
2914
2730
|
}
|
|
2915
2731
|
});
|
|
@@ -2929,9 +2745,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2929
2745
|
}
|
|
2930
2746
|
);
|
|
2931
2747
|
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2748
|
+
// @ts-ignore
|
|
2749
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
2750
|
+
name: 'client.lobby.exited',
|
|
2751
|
+
options: {meetingId: this.id},
|
|
2935
2752
|
});
|
|
2936
2753
|
}
|
|
2937
2754
|
});
|
|
@@ -3595,9 +3412,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3595
3412
|
|
|
3596
3413
|
// Only send restore event when it was disconnected before and for connected later
|
|
3597
3414
|
if (!this.hasWebsocketConnected) {
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3415
|
+
// @ts-ignore
|
|
3416
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3417
|
+
name: 'client.mercury.connection.restored',
|
|
3418
|
+
options: {meetingId: this.id},
|
|
3601
3419
|
});
|
|
3602
3420
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_RESTORED, {
|
|
3603
3421
|
correlation_id: this.correlationId,
|
|
@@ -3609,9 +3427,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3609
3427
|
// @ts-ignore
|
|
3610
3428
|
this.webex.internal.mercury.on(OFFLINE, () => {
|
|
3611
3429
|
LoggerProxy.logger.error('Meeting:index#setMercuryListener --> Web socket offline');
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3430
|
+
// @ts-ignore
|
|
3431
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3432
|
+
name: 'client.mercury.connection.lost',
|
|
3433
|
+
options: {meetingId: this.id},
|
|
3615
3434
|
});
|
|
3616
3435
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_FAILURE, {
|
|
3617
3436
|
correlation_id: this.correlationId,
|
|
@@ -3677,6 +3496,204 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3677
3496
|
this.correlationId = id;
|
|
3678
3497
|
}
|
|
3679
3498
|
|
|
3499
|
+
/**
|
|
3500
|
+
* Mute the audio for a meeting
|
|
3501
|
+
* @returns {Promise} resolves the data from muting audio {mute, self} or rejects if there is no audio set
|
|
3502
|
+
* @public
|
|
3503
|
+
* @memberof Meeting
|
|
3504
|
+
*/
|
|
3505
|
+
public muteAudio() {
|
|
3506
|
+
if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
|
|
3507
|
+
return Promise.reject(new UserNotJoinedError());
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
// @ts-ignore
|
|
3511
|
+
if (!this.mediaId) {
|
|
3512
|
+
// Happens when addMedia and mute are triggered in succession
|
|
3513
|
+
return Promise.reject(new NoMediaEstablishedYetError());
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3516
|
+
if (!this.audio) {
|
|
3517
|
+
return Promise.reject(new ParameterError('no audio control associated to the meeting'));
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
// First, stop sending the local audio media
|
|
3521
|
+
return logRequest(
|
|
3522
|
+
this.audio
|
|
3523
|
+
.handleClientRequest(this, true)
|
|
3524
|
+
.then(() => {
|
|
3525
|
+
MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
|
|
3526
|
+
// @ts-ignore
|
|
3527
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3528
|
+
name: 'client.muted',
|
|
3529
|
+
payload: {trigger: 'user-interaction', mediaType: 'audio'},
|
|
3530
|
+
options: {meetingId: this.id},
|
|
3531
|
+
});
|
|
3532
|
+
})
|
|
3533
|
+
.catch((error) => {
|
|
3534
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE, {
|
|
3535
|
+
correlation_id: this.correlationId,
|
|
3536
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
3537
|
+
reason: error.message,
|
|
3538
|
+
stack: error.stack,
|
|
3539
|
+
});
|
|
3540
|
+
|
|
3541
|
+
throw error;
|
|
3542
|
+
}),
|
|
3543
|
+
{
|
|
3544
|
+
logText: `Meeting:index#muteAudio --> correlationId=${this.correlationId} muting audio`,
|
|
3545
|
+
}
|
|
3546
|
+
);
|
|
3547
|
+
}
|
|
3548
|
+
|
|
3549
|
+
/**
|
|
3550
|
+
* Unmute meeting audio
|
|
3551
|
+
* @returns {Promise} resolves data from muting audio {mute, self} or rejects if there is no audio set
|
|
3552
|
+
* @public
|
|
3553
|
+
* @memberof Meeting
|
|
3554
|
+
*/
|
|
3555
|
+
public unmuteAudio() {
|
|
3556
|
+
if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
|
|
3557
|
+
return Promise.reject(new UserNotJoinedError());
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
// @ts-ignore
|
|
3561
|
+
if (!this.mediaId) {
|
|
3562
|
+
// Happens when addMedia and mute are triggered in succession
|
|
3563
|
+
return Promise.reject(new NoMediaEstablishedYetError());
|
|
3564
|
+
}
|
|
3565
|
+
|
|
3566
|
+
if (!this.audio) {
|
|
3567
|
+
return Promise.reject(new ParameterError('no audio control associated to the meeting'));
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
// First, send the control to unmute the participant on the server
|
|
3571
|
+
return logRequest(
|
|
3572
|
+
this.audio
|
|
3573
|
+
.handleClientRequest(this, false)
|
|
3574
|
+
.then(() => {
|
|
3575
|
+
MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
|
|
3576
|
+
// @ts-ignore
|
|
3577
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3578
|
+
name: 'client.unmuted',
|
|
3579
|
+
payload: {trigger: 'user-interaction', mediaType: 'audio'},
|
|
3580
|
+
options: {meetingId: this.id},
|
|
3581
|
+
});
|
|
3582
|
+
})
|
|
3583
|
+
.catch((error) => {
|
|
3584
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_AUDIO_FAILURE, {
|
|
3585
|
+
correlation_id: this.correlationId,
|
|
3586
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
3587
|
+
reason: error.message,
|
|
3588
|
+
stack: error.stack,
|
|
3589
|
+
});
|
|
3590
|
+
|
|
3591
|
+
throw error;
|
|
3592
|
+
}),
|
|
3593
|
+
{
|
|
3594
|
+
logText: `Meeting:index#unmuteAudio --> correlationId=${this.correlationId} unmuting audio`,
|
|
3595
|
+
}
|
|
3596
|
+
);
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
/**
|
|
3600
|
+
* Mute the video for a meeting
|
|
3601
|
+
* @returns {Promise} resolves data from muting video {mute, self} or rejects if there is no video set
|
|
3602
|
+
* @public
|
|
3603
|
+
* @memberof Meeting
|
|
3604
|
+
*/
|
|
3605
|
+
public muteVideo() {
|
|
3606
|
+
if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
|
|
3607
|
+
return Promise.reject(new UserNotJoinedError());
|
|
3608
|
+
}
|
|
3609
|
+
|
|
3610
|
+
// @ts-ignore
|
|
3611
|
+
if (!this.mediaId) {
|
|
3612
|
+
// Happens when addMedia and mute are triggered in succession
|
|
3613
|
+
return Promise.reject(new NoMediaEstablishedYetError());
|
|
3614
|
+
}
|
|
3615
|
+
|
|
3616
|
+
if (!this.video) {
|
|
3617
|
+
return Promise.reject(new ParameterError('no video control associated to the meeting'));
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3620
|
+
return logRequest(
|
|
3621
|
+
this.video
|
|
3622
|
+
.handleClientRequest(this, true)
|
|
3623
|
+
.then(() => {
|
|
3624
|
+
MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
|
|
3625
|
+
// @ts-ignore
|
|
3626
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3627
|
+
name: 'client.muted',
|
|
3628
|
+
payload: {trigger: 'user-interaction', mediaType: 'video'},
|
|
3629
|
+
options: {meetingId: this.id},
|
|
3630
|
+
});
|
|
3631
|
+
})
|
|
3632
|
+
.catch((error) => {
|
|
3633
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_VIDEO_FAILURE, {
|
|
3634
|
+
correlation_id: this.correlationId,
|
|
3635
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
3636
|
+
reason: error.message,
|
|
3637
|
+
stack: error.stack,
|
|
3638
|
+
});
|
|
3639
|
+
|
|
3640
|
+
throw error;
|
|
3641
|
+
}),
|
|
3642
|
+
{
|
|
3643
|
+
logText: `Meeting:index#muteVideo --> correlationId=${this.correlationId} muting video`,
|
|
3644
|
+
}
|
|
3645
|
+
);
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
/**
|
|
3649
|
+
* Unmute meeting video
|
|
3650
|
+
* @returns {Promise} resolves data from muting video {mute, self} or rejects if there is no video set
|
|
3651
|
+
* @public
|
|
3652
|
+
* @memberof Meeting
|
|
3653
|
+
*/
|
|
3654
|
+
public unmuteVideo() {
|
|
3655
|
+
if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
|
|
3656
|
+
return Promise.reject(new UserNotJoinedError());
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
// @ts-ignore
|
|
3660
|
+
if (!this.mediaId) {
|
|
3661
|
+
// Happens when addMedia and mute are triggered in succession
|
|
3662
|
+
return Promise.reject(new NoMediaEstablishedYetError());
|
|
3663
|
+
}
|
|
3664
|
+
|
|
3665
|
+
if (!this.video) {
|
|
3666
|
+
return Promise.reject(new ParameterError('no audio control associated to the meeting'));
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
return logRequest(
|
|
3670
|
+
this.video
|
|
3671
|
+
.handleClientRequest(this, false)
|
|
3672
|
+
.then(() => {
|
|
3673
|
+
MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
|
|
3674
|
+
// @ts-ignore
|
|
3675
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
3676
|
+
name: 'client.unmuted',
|
|
3677
|
+
payload: {trigger: 'user-interaction', mediaType: 'video'},
|
|
3678
|
+
options: {meetingId: this.id},
|
|
3679
|
+
});
|
|
3680
|
+
})
|
|
3681
|
+
.catch((error) => {
|
|
3682
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_VIDEO_FAILURE, {
|
|
3683
|
+
correlation_id: this.correlationId,
|
|
3684
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
3685
|
+
reason: error.message,
|
|
3686
|
+
stack: error.stack,
|
|
3687
|
+
});
|
|
3688
|
+
|
|
3689
|
+
throw error;
|
|
3690
|
+
}),
|
|
3691
|
+
{
|
|
3692
|
+
logText: `Meeting:index#unmuteVideo --> correlationId=${this.correlationId} unmuting video`,
|
|
3693
|
+
}
|
|
3694
|
+
);
|
|
3695
|
+
}
|
|
3696
|
+
|
|
3680
3697
|
/**
|
|
3681
3698
|
* Shorthand function to join AND set up media
|
|
3682
3699
|
* @param {Object} options - options to join with media
|
|
@@ -4092,24 +4109,27 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4092
4109
|
this.meetingFiniteStateMachine.reset();
|
|
4093
4110
|
}
|
|
4094
4111
|
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4112
|
+
// @ts-ignore
|
|
4113
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4114
|
+
name: 'client.call.initiated',
|
|
4115
|
+
payload: {trigger: 'user-interaction', isRoapCallEnabled: true},
|
|
4116
|
+
options: {meetingId: this.id},
|
|
4099
4117
|
});
|
|
4100
4118
|
|
|
4101
4119
|
if (!isEmpty(this.meetingInfo)) {
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4120
|
+
// @ts-ignore
|
|
4121
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4122
|
+
name: 'client.meetinginfo.request',
|
|
4123
|
+
options: {meetingId: this.id},
|
|
4105
4124
|
});
|
|
4106
4125
|
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
meetingLookupUrl: this.meetingInfo?.meetingLookupUrl,
|
|
4126
|
+
// @ts-ignore
|
|
4127
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4128
|
+
name: 'client.meetinginfo.response',
|
|
4129
|
+
payload: {
|
|
4130
|
+
identifiers: {meetingLookupUrl: this.meetingInfo?.meetingLookupUrl},
|
|
4112
4131
|
},
|
|
4132
|
+
options: {meetingId: this.id},
|
|
4113
4133
|
});
|
|
4114
4134
|
}
|
|
4115
4135
|
|
|
@@ -4211,13 +4231,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4211
4231
|
this.meetingFiniteStateMachine.fail(error);
|
|
4212
4232
|
LoggerProxy.logger.error('Meeting:index#join --> Failed', error);
|
|
4213
4233
|
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
errors: [Metrics.parseLocusError(error.error, true)],
|
|
4234
|
+
// @ts-ignore
|
|
4235
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4236
|
+
name: 'client.locus.join.response',
|
|
4237
|
+
payload: {
|
|
4238
|
+
identifiers: {meetingLookupUrl: this.meetingInfo?.meetingLookupUrl},
|
|
4220
4239
|
},
|
|
4240
|
+
options: {meetingId: this.id, rawError: error, showToUser: true},
|
|
4221
4241
|
});
|
|
4222
4242
|
|
|
4223
4243
|
// TODO: change this to error codes and pre defined dictionary
|
|
@@ -4421,10 +4441,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4421
4441
|
throw new ParameterError('Cannot move call without a resourceId.');
|
|
4422
4442
|
}
|
|
4423
4443
|
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4444
|
+
// @ts-ignore
|
|
4445
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4446
|
+
name: 'client.media.capabilities',
|
|
4447
|
+
payload: {
|
|
4428
4448
|
mediaCapabilities: {
|
|
4429
4449
|
rx: {
|
|
4430
4450
|
audio: false,
|
|
@@ -4442,9 +4462,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4442
4462
|
},
|
|
4443
4463
|
},
|
|
4444
4464
|
},
|
|
4465
|
+
options: {meetingId: this.id},
|
|
4445
4466
|
});
|
|
4446
4467
|
|
|
4447
|
-
|
|
4468
|
+
// @ts-ignore
|
|
4469
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4470
|
+
name: 'client.call.move-media',
|
|
4471
|
+
options: {meetingId: this.id},
|
|
4472
|
+
});
|
|
4448
4473
|
|
|
4449
4474
|
this.locusInfo.once(LOCUSINFO.EVENTS.SELF_OBSERVING, async () => {
|
|
4450
4475
|
// Clean up the camera , microphone track and re initiate it
|
|
@@ -4523,7 +4548,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4523
4548
|
}
|
|
4524
4549
|
const oldCorrelationId = this.correlationId;
|
|
4525
4550
|
|
|
4526
|
-
|
|
4551
|
+
// @ts-ignore
|
|
4552
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4553
|
+
name: 'client.call.move-media',
|
|
4554
|
+
options: {meetingId: this.id},
|
|
4555
|
+
});
|
|
4527
4556
|
|
|
4528
4557
|
return MeetingUtil.joinMeetingOptions(this)
|
|
4529
4558
|
.then(() =>
|
|
@@ -4575,15 +4604,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4575
4604
|
if (error instanceof Errors.SdpOfferCreationError) {
|
|
4576
4605
|
sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.id);
|
|
4577
4606
|
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4607
|
+
// @ts-ignore
|
|
4608
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4609
|
+
name: 'client.media-engine.local-sdp-generated',
|
|
4610
|
+
payload: {
|
|
4582
4611
|
canProceed: false,
|
|
4583
|
-
errors: [
|
|
4584
|
-
Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
|
|
4585
|
-
],
|
|
4586
4612
|
},
|
|
4613
|
+
options: {meetingId: this.id, rawError: error, showToUser: true},
|
|
4587
4614
|
});
|
|
4588
4615
|
} else if (
|
|
4589
4616
|
error instanceof Errors.SdpOfferHandlingError ||
|
|
@@ -4591,29 +4618,25 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4591
4618
|
) {
|
|
4592
4619
|
sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.id);
|
|
4593
4620
|
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4621
|
+
// @ts-ignore
|
|
4622
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4623
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
4624
|
+
payload: {
|
|
4598
4625
|
canProceed: false,
|
|
4599
|
-
errors: [
|
|
4600
|
-
Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
|
|
4601
|
-
],
|
|
4602
4626
|
},
|
|
4627
|
+
options: {meetingId: this.id, rawError: error, showToUser: true},
|
|
4603
4628
|
});
|
|
4604
4629
|
} else if (error instanceof Errors.SdpError) {
|
|
4605
4630
|
// this covers also the case of Errors.IceGatheringError which extends Errors.SdpError
|
|
4606
4631
|
sendBehavioralMetric(BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE, error, this.id);
|
|
4607
4632
|
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4633
|
+
// @ts-ignore
|
|
4634
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4635
|
+
name: 'client.media-engine.local-sdp-generated',
|
|
4636
|
+
payload: {
|
|
4612
4637
|
canProceed: false,
|
|
4613
|
-
errors: [
|
|
4614
|
-
Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
|
|
4615
|
-
],
|
|
4616
4638
|
},
|
|
4639
|
+
options: {meetingId: this.id, rawError: error, showToUser: true},
|
|
4617
4640
|
});
|
|
4618
4641
|
}
|
|
4619
4642
|
};
|
|
@@ -4636,9 +4659,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4636
4659
|
|
|
4637
4660
|
switch (event.roapMessage.messageType) {
|
|
4638
4661
|
case 'OK':
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4662
|
+
// @ts-ignore
|
|
4663
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4664
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
4665
|
+
options: {meetingId: this.id},
|
|
4642
4666
|
});
|
|
4643
4667
|
|
|
4644
4668
|
logRequest(
|
|
@@ -4654,9 +4678,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4654
4678
|
break;
|
|
4655
4679
|
|
|
4656
4680
|
case 'OFFER':
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4681
|
+
// @ts-ignore
|
|
4682
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4683
|
+
name: 'client.media-engine.local-sdp-generated',
|
|
4684
|
+
options: {meetingId: this.id},
|
|
4660
4685
|
});
|
|
4661
4686
|
|
|
4662
4687
|
logRequest(
|
|
@@ -4674,9 +4699,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4674
4699
|
break;
|
|
4675
4700
|
|
|
4676
4701
|
case 'ANSWER':
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4702
|
+
// @ts-ignore
|
|
4703
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4704
|
+
name: 'client.media-engine.remote-sdp-received',
|
|
4705
|
+
options: {meetingId: this.id},
|
|
4680
4706
|
});
|
|
4681
4707
|
|
|
4682
4708
|
logRequest(
|
|
@@ -4795,15 +4821,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4795
4821
|
this.reconnectionManager.resetReconnectionTimer();
|
|
4796
4822
|
|
|
4797
4823
|
this.reconnect({networkDisconnect: true});
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4824
|
+
// @ts-ignore
|
|
4825
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4826
|
+
name: 'client.ice.end',
|
|
4827
|
+
payload: {
|
|
4802
4828
|
canProceed: false,
|
|
4829
|
+
icePhase: 'IN_MEETING',
|
|
4803
4830
|
errors: [
|
|
4804
|
-
|
|
4831
|
+
// @ts-ignore
|
|
4832
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
|
|
4833
|
+
CALL_DIAGNOSTIC_CONFIG.ICE_FAILURE_CLIENT_CODE
|
|
4834
|
+
),
|
|
4805
4835
|
],
|
|
4806
4836
|
},
|
|
4837
|
+
options: {
|
|
4838
|
+
meetingId: this.id,
|
|
4839
|
+
},
|
|
4807
4840
|
});
|
|
4808
4841
|
|
|
4809
4842
|
this.uploadLogs({
|
|
@@ -4822,10 +4855,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4822
4855
|
);
|
|
4823
4856
|
switch (event.state) {
|
|
4824
4857
|
case ConnectionState.Connecting:
|
|
4825
|
-
|
|
4858
|
+
// @ts-ignore
|
|
4859
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4860
|
+
name: 'client.ice.start',
|
|
4861
|
+
options: {
|
|
4862
|
+
meetingId: this.id,
|
|
4863
|
+
},
|
|
4864
|
+
});
|
|
4826
4865
|
break;
|
|
4827
4866
|
case ConnectionState.Connected:
|
|
4828
|
-
|
|
4867
|
+
// @ts-ignore
|
|
4868
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
4869
|
+
name: 'client.ice.end',
|
|
4870
|
+
options: {
|
|
4871
|
+
meetingId: this.id,
|
|
4872
|
+
},
|
|
4873
|
+
});
|
|
4829
4874
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.CONNECTION_SUCCESS, {
|
|
4830
4875
|
correlation_id: this.correlationId,
|
|
4831
4876
|
locus_id: this.locusId,
|
|
@@ -4929,10 +4974,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4929
4974
|
this.webex.meetings.geoHintInfo?.clientAddress ||
|
|
4930
4975
|
options.data.intervalMetadata.peerReflexiveIP ||
|
|
4931
4976
|
MQA_STATS.DEFAULT_IP;
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4977
|
+
// @ts-ignore
|
|
4978
|
+
this.webex.internal.newMetrics.submitMQE({
|
|
4979
|
+
name: 'client.mediaquality.event',
|
|
4980
|
+
options: {
|
|
4981
|
+
meetingId: this.id,
|
|
4982
|
+
networkType: options.networkType,
|
|
4983
|
+
},
|
|
4984
|
+
payload: {
|
|
4985
|
+
intervals: [options.data],
|
|
4986
|
+
},
|
|
4936
4987
|
});
|
|
4937
4988
|
});
|
|
4938
4989
|
this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STARTED, (data) => {
|
|
@@ -4945,20 +4996,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4945
4996
|
EVENT_TRIGGERS.MEETING_MEDIA_LOCAL_STARTED,
|
|
4946
4997
|
data
|
|
4947
4998
|
);
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4999
|
+
// @ts-ignore
|
|
5000
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5001
|
+
name: 'client.media.tx.start',
|
|
5002
|
+
payload: {mediaType: data.type},
|
|
5003
|
+
options: {
|
|
5004
|
+
meetingId: this.id,
|
|
4953
5005
|
},
|
|
4954
5006
|
});
|
|
4955
5007
|
});
|
|
4956
5008
|
this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STOPPED, (data) => {
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
5009
|
+
// @ts-ignore
|
|
5010
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5011
|
+
name: 'client.media.tx.stop',
|
|
5012
|
+
payload: {mediaType: data.type},
|
|
5013
|
+
options: {
|
|
5014
|
+
meetingId: this.id,
|
|
4962
5015
|
},
|
|
4963
5016
|
});
|
|
4964
5017
|
});
|
|
@@ -4972,20 +5025,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4972
5025
|
EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
|
|
4973
5026
|
data
|
|
4974
5027
|
);
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
5028
|
+
// @ts-ignore
|
|
5029
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5030
|
+
name: 'client.media.rx.start',
|
|
5031
|
+
payload: {mediaType: data.type},
|
|
5032
|
+
options: {
|
|
5033
|
+
meetingId: this.id,
|
|
4980
5034
|
},
|
|
4981
5035
|
});
|
|
4982
5036
|
});
|
|
4983
5037
|
this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STOPPED, (data) => {
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
5038
|
+
// @ts-ignore
|
|
5039
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5040
|
+
name: 'client.media.rx.stop',
|
|
5041
|
+
payload: {mediaType: data.type},
|
|
5042
|
+
options: {
|
|
5043
|
+
meetingId: this.id,
|
|
4989
5044
|
},
|
|
4990
5045
|
});
|
|
4991
5046
|
});
|
|
@@ -5093,10 +5148,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5093
5148
|
bundlePolicy,
|
|
5094
5149
|
} = options;
|
|
5095
5150
|
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5151
|
+
// @ts-ignore
|
|
5152
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5153
|
+
name: 'client.media.capabilities',
|
|
5154
|
+
payload: {
|
|
5100
5155
|
mediaCapabilities: {
|
|
5101
5156
|
rx: {
|
|
5102
5157
|
audio: false,
|
|
@@ -5114,6 +5169,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5114
5169
|
},
|
|
5115
5170
|
},
|
|
5116
5171
|
},
|
|
5172
|
+
options: {meetingId: this.id},
|
|
5117
5173
|
});
|
|
5118
5174
|
|
|
5119
5175
|
// when audioEnabled/videoEnabled is true, we set sendAudio/sendVideo to true even before any tracks are published
|
|
@@ -5266,6 +5322,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5266
5322
|
)
|
|
5267
5323
|
.then(() =>
|
|
5268
5324
|
this.mediaProperties.waitForMediaConnectionConnected().catch(() => {
|
|
5325
|
+
// @ts-ignore
|
|
5326
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5327
|
+
name: 'client.ice.end',
|
|
5328
|
+
payload: {
|
|
5329
|
+
canProceed: false,
|
|
5330
|
+
icePhase: 'JOIN_MEETING_FINAL',
|
|
5331
|
+
errors: [
|
|
5332
|
+
// @ts-ignore
|
|
5333
|
+
this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
|
|
5334
|
+
CALL_DIAGNOSTIC_CONFIG.ICE_FAILURE_CLIENT_CODE
|
|
5335
|
+
),
|
|
5336
|
+
],
|
|
5337
|
+
},
|
|
5338
|
+
options: {
|
|
5339
|
+
meetingId: this.id,
|
|
5340
|
+
},
|
|
5341
|
+
});
|
|
5269
5342
|
throw new Error(
|
|
5270
5343
|
`Timed out waiting for media connection to be connected, correlationId=${this.correlationId}`
|
|
5271
5344
|
);
|
|
@@ -5284,6 +5357,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5284
5357
|
connectionType,
|
|
5285
5358
|
isMultistream: this.isMultistream,
|
|
5286
5359
|
});
|
|
5360
|
+
// @ts-ignore
|
|
5361
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5362
|
+
name: 'client.media-engine.ready',
|
|
5363
|
+
options: {
|
|
5364
|
+
meetingId: this.id,
|
|
5365
|
+
},
|
|
5366
|
+
});
|
|
5287
5367
|
})
|
|
5288
5368
|
.catch((error) => {
|
|
5289
5369
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE, {
|
|
@@ -5546,7 +5626,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5546
5626
|
.then((response) => Promise.resolve(response))
|
|
5547
5627
|
.then((response) => {
|
|
5548
5628
|
this.meetingFiniteStateMachine.ring(type);
|
|
5549
|
-
|
|
5629
|
+
// @ts-ignore
|
|
5630
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5631
|
+
name: 'client.alert.displayed',
|
|
5632
|
+
options: {meetingId: this.id},
|
|
5633
|
+
});
|
|
5550
5634
|
|
|
5551
5635
|
return Promise.resolve({
|
|
5552
5636
|
response,
|
|
@@ -5591,10 +5675,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5591
5675
|
*/
|
|
5592
5676
|
public leave(options: {resourceId?: string; reason?: any} = {} as any) {
|
|
5593
5677
|
const leaveReason = options.reason || MEETING_REMOVED_REASON.CLIENT_LEAVE_REQUEST;
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5678
|
+
/// @ts-ignore
|
|
5679
|
+
this.webex.internal.newMetrics.submitInternalEvent({name: 'internal.reset.join.latencies'});
|
|
5680
|
+
|
|
5681
|
+
// @ts-ignore
|
|
5682
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5683
|
+
name: 'client.call.leave',
|
|
5684
|
+
payload: {
|
|
5685
|
+
trigger: 'user-interaction',
|
|
5686
|
+
canProceed: false,
|
|
5687
|
+
leaveReason,
|
|
5688
|
+
},
|
|
5689
|
+
options: {meetingId: this.id},
|
|
5598
5690
|
});
|
|
5599
5691
|
LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
|
|
5600
5692
|
|
|
@@ -5675,7 +5767,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5675
5767
|
}
|
|
5676
5768
|
|
|
5677
5769
|
if (whiteboard) {
|
|
5678
|
-
|
|
5770
|
+
// @ts-ignore
|
|
5771
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5772
|
+
name: 'client.share.initiated',
|
|
5773
|
+
payload: {
|
|
5774
|
+
mediaType: 'whiteboard',
|
|
5775
|
+
},
|
|
5776
|
+
options: {
|
|
5777
|
+
meetingId: this.id,
|
|
5778
|
+
},
|
|
5779
|
+
});
|
|
5679
5780
|
|
|
5680
5781
|
const body: any = {
|
|
5681
5782
|
disposition: FLOOR_ACTION.GRANTED,
|
|
@@ -5725,7 +5826,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5725
5826
|
const whiteboard = this.locusInfo.mediaShares.find((element) => element.name === 'whiteboard');
|
|
5726
5827
|
|
|
5727
5828
|
if (whiteboard) {
|
|
5728
|
-
|
|
5829
|
+
// @ts-ignore
|
|
5830
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5831
|
+
name: 'client.share.stopped',
|
|
5832
|
+
payload: {
|
|
5833
|
+
mediaType: 'whiteboard',
|
|
5834
|
+
},
|
|
5835
|
+
options: {
|
|
5836
|
+
meetingId: this.id,
|
|
5837
|
+
},
|
|
5838
|
+
});
|
|
5729
5839
|
|
|
5730
5840
|
return this.meetingRequest
|
|
5731
5841
|
.changeMeetingFloor({
|
|
@@ -5777,7 +5887,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5777
5887
|
const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
|
|
5778
5888
|
|
|
5779
5889
|
if (content && this.shareStatus !== SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
|
|
5780
|
-
|
|
5890
|
+
// @ts-ignore
|
|
5891
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5892
|
+
name: 'client.share.initiated',
|
|
5893
|
+
payload: {
|
|
5894
|
+
mediaType: 'share',
|
|
5895
|
+
},
|
|
5896
|
+
options: {meetingId: this.id},
|
|
5897
|
+
});
|
|
5781
5898
|
|
|
5782
5899
|
return this.meetingRequest
|
|
5783
5900
|
.changeMeetingFloor({
|
|
@@ -5838,7 +5955,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5838
5955
|
const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
|
|
5839
5956
|
|
|
5840
5957
|
if (content) {
|
|
5841
|
-
|
|
5958
|
+
// @ts-ignore
|
|
5959
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
5960
|
+
name: 'client.share.stopped',
|
|
5961
|
+
payload: {
|
|
5962
|
+
mediaType: 'share',
|
|
5963
|
+
},
|
|
5964
|
+
options: {meetingId: this.id},
|
|
5965
|
+
});
|
|
5842
5966
|
|
|
5843
5967
|
if (content.floor?.beneficiary.id !== this.selfId) {
|
|
5844
5968
|
// remote participant started sharing and caused our sharing to stop, we don't want to send any floor action request in that case
|
|
@@ -6251,179 +6375,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6251
6375
|
MeetingUtil.handleAudioLogging(mediaProperties.audioTrack);
|
|
6252
6376
|
}
|
|
6253
6377
|
|
|
6254
|
-
/**
|
|
6255
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6256
|
-
* @returns {undefined}
|
|
6257
|
-
*/
|
|
6258
|
-
setStartSetupDelay(typeMedia: string) {
|
|
6259
|
-
this[`startSetupDelay${typeMedia}`] = performance.now();
|
|
6260
|
-
this[`endSetupDelay${typeMedia}`] = undefined;
|
|
6261
|
-
}
|
|
6262
|
-
|
|
6263
|
-
/**
|
|
6264
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6265
|
-
* @returns {undefined}
|
|
6266
|
-
*/
|
|
6267
|
-
setEndSetupDelay(typeMedia: string) {
|
|
6268
|
-
this[`endSetupDelay${typeMedia}`] = performance.now();
|
|
6269
|
-
}
|
|
6270
|
-
|
|
6271
|
-
/**
|
|
6272
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6273
|
-
* @returns {string} duration between start and end of setup
|
|
6274
|
-
*/
|
|
6275
|
-
getSetupDelayDuration(typeMedia: string) {
|
|
6276
|
-
const start = this[`startSetupDelay${typeMedia}`];
|
|
6277
|
-
const end = this[`endSetupDelay${typeMedia}`];
|
|
6278
|
-
|
|
6279
|
-
return start && end ? end - start : undefined;
|
|
6280
|
-
}
|
|
6281
|
-
|
|
6282
|
-
/**
|
|
6283
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6284
|
-
* @returns {undefined}
|
|
6285
|
-
*/
|
|
6286
|
-
setStartSendingMediaDelay(typeMedia: string) {
|
|
6287
|
-
this[`startSendingMediaDelay${typeMedia}`] = performance.now();
|
|
6288
|
-
this[`endSendingMediaDelay${typeMedia}`] = undefined;
|
|
6289
|
-
}
|
|
6290
|
-
|
|
6291
|
-
/**
|
|
6292
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6293
|
-
* @returns {undefined}
|
|
6294
|
-
*/
|
|
6295
|
-
setEndSendingMediaDelay(typeMedia: string) {
|
|
6296
|
-
this[`endSendingMediaDelay${typeMedia}`] = performance.now();
|
|
6297
|
-
}
|
|
6298
|
-
|
|
6299
|
-
/**
|
|
6300
|
-
* @param {string} typeMedia 'audio' or 'video'
|
|
6301
|
-
* @returns {string} duration between join response and first media tx
|
|
6302
|
-
*/
|
|
6303
|
-
getSendingMediaDelayDuration(typeMedia: string) {
|
|
6304
|
-
const start = this[`startSendingMediaDelay${typeMedia}`];
|
|
6305
|
-
const end = this[`endSendingMediaDelay${typeMedia}`];
|
|
6306
|
-
|
|
6307
|
-
return start && end ? end - start : undefined;
|
|
6308
|
-
}
|
|
6309
|
-
|
|
6310
|
-
/**
|
|
6311
|
-
*
|
|
6312
|
-
* @returns {undefined}
|
|
6313
|
-
*/
|
|
6314
|
-
setStartLocalSDPGenRemoteSDPRecvDelay() {
|
|
6315
|
-
if (!this.startLocalSDPGenRemoteSDPRecvDelay) {
|
|
6316
|
-
this.startLocalSDPGenRemoteSDPRecvDelay = performance.now();
|
|
6317
|
-
this.endLocalSDPGenRemoteSDPRecvDelay = undefined;
|
|
6318
|
-
}
|
|
6319
|
-
}
|
|
6320
|
-
|
|
6321
|
-
/**
|
|
6322
|
-
*
|
|
6323
|
-
* @returns {undefined}
|
|
6324
|
-
*/
|
|
6325
|
-
setEndLocalSDPGenRemoteSDPRecvDelay() {
|
|
6326
|
-
if (!this.endLocalSDPGenRemoteSDPRecvDelay) {
|
|
6327
|
-
this.endLocalSDPGenRemoteSDPRecvDelay = performance.now();
|
|
6328
|
-
}
|
|
6329
|
-
}
|
|
6330
|
-
|
|
6331
|
-
/**
|
|
6332
|
-
*
|
|
6333
|
-
* @returns {string} duration between local SDP generation and remote SDP reception
|
|
6334
|
-
*/
|
|
6335
|
-
getLocalSDPGenRemoteSDPRecvDelay() {
|
|
6336
|
-
const start = this.startLocalSDPGenRemoteSDPRecvDelay;
|
|
6337
|
-
const end = this.endLocalSDPGenRemoteSDPRecvDelay;
|
|
6338
|
-
|
|
6339
|
-
if (start && end) {
|
|
6340
|
-
const calculatedDelay = Math.round(end - start);
|
|
6341
|
-
|
|
6342
|
-
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
|
|
6343
|
-
}
|
|
6344
|
-
|
|
6345
|
-
return undefined;
|
|
6346
|
-
}
|
|
6347
|
-
|
|
6348
|
-
/**
|
|
6349
|
-
*
|
|
6350
|
-
* @returns {undefined}
|
|
6351
|
-
*/
|
|
6352
|
-
setStartCallInitJoinReq() {
|
|
6353
|
-
this.startCallInitJoinReq = performance.now();
|
|
6354
|
-
this.endCallInitJoinReq = undefined;
|
|
6355
|
-
}
|
|
6356
|
-
|
|
6357
|
-
/**
|
|
6358
|
-
*
|
|
6359
|
-
* @returns {undefined}
|
|
6360
|
-
*/
|
|
6361
|
-
setEndCallInitJoinReq() {
|
|
6362
|
-
this.endCallInitJoinReq = performance.now();
|
|
6363
|
-
}
|
|
6364
|
-
|
|
6365
|
-
/**
|
|
6366
|
-
*
|
|
6367
|
-
* @returns {string} duration between call initiate and sending join request to locus
|
|
6368
|
-
*/
|
|
6369
|
-
getCallInitJoinReq() {
|
|
6370
|
-
const start = this.startCallInitJoinReq;
|
|
6371
|
-
const end = this.endCallInitJoinReq;
|
|
6372
|
-
|
|
6373
|
-
if (start && end) {
|
|
6374
|
-
const calculatedDelay = end - start;
|
|
6375
|
-
|
|
6376
|
-
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
|
|
6377
|
-
}
|
|
6378
|
-
|
|
6379
|
-
return undefined;
|
|
6380
|
-
}
|
|
6381
|
-
|
|
6382
|
-
/**
|
|
6383
|
-
*
|
|
6384
|
-
* @returns {undefined}
|
|
6385
|
-
*/
|
|
6386
|
-
setStartJoinReqResp() {
|
|
6387
|
-
this.startJoinReqResp = performance.now();
|
|
6388
|
-
this.endJoinReqResp = undefined;
|
|
6389
|
-
}
|
|
6390
|
-
|
|
6391
|
-
/**
|
|
6392
|
-
*
|
|
6393
|
-
* @returns {undefined}
|
|
6394
|
-
*/
|
|
6395
|
-
setEndJoinReqResp() {
|
|
6396
|
-
this.endJoinReqResp = performance.now();
|
|
6397
|
-
}
|
|
6398
|
-
|
|
6399
|
-
/**
|
|
6400
|
-
*
|
|
6401
|
-
* @returns {string} duration between sending locus join request and receiving join response
|
|
6402
|
-
*/
|
|
6403
|
-
getJoinReqResp() {
|
|
6404
|
-
const start = this.startJoinReqResp;
|
|
6405
|
-
const end = this.endJoinReqResp;
|
|
6406
|
-
|
|
6407
|
-
if (start && end) {
|
|
6408
|
-
const calculatedDelay = Math.round(end - start);
|
|
6409
|
-
|
|
6410
|
-
return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
|
|
6411
|
-
}
|
|
6412
|
-
|
|
6413
|
-
return undefined;
|
|
6414
|
-
}
|
|
6415
|
-
|
|
6416
|
-
/**
|
|
6417
|
-
*
|
|
6418
|
-
* @returns {string} duration between call initiate and successful locus join (even if it is in lobby)
|
|
6419
|
-
*/
|
|
6420
|
-
getTotalJmt() {
|
|
6421
|
-
const start = this.startCallInitJoinReq;
|
|
6422
|
-
const end = this.endJoinReqResp;
|
|
6423
|
-
|
|
6424
|
-
return start && end ? Math.round(end - start) : undefined;
|
|
6425
|
-
}
|
|
6426
|
-
|
|
6427
6378
|
/**
|
|
6428
6379
|
*
|
|
6429
6380
|
* @returns {string} one of 'attendee','host','cohost', returns the user type of the current user
|
|
@@ -6445,20 +6396,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6445
6396
|
return null;
|
|
6446
6397
|
}
|
|
6447
6398
|
|
|
6448
|
-
/**
|
|
6449
|
-
*
|
|
6450
|
-
* @returns {string} one of 'login-ci','unverified-guest', returns the login type of the current user
|
|
6451
|
-
*/
|
|
6452
|
-
getCurLoginType() {
|
|
6453
|
-
// @ts-ignore
|
|
6454
|
-
if (this.webex.canAuthorize) {
|
|
6455
|
-
// @ts-ignore
|
|
6456
|
-
return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';
|
|
6457
|
-
}
|
|
6458
|
-
|
|
6459
|
-
return null;
|
|
6460
|
-
}
|
|
6461
|
-
|
|
6462
6399
|
/**
|
|
6463
6400
|
* End the current meeting for all
|
|
6464
6401
|
* @returns {Promise}
|
|
@@ -6466,10 +6403,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6466
6403
|
* @memberof Meeting
|
|
6467
6404
|
*/
|
|
6468
6405
|
public endMeetingForAll() {
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6406
|
+
// @ts-ignore
|
|
6407
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
6408
|
+
name: 'client.call.leave',
|
|
6409
|
+
payload: {trigger: 'user-interaction', canProceed: false},
|
|
6410
|
+
options: {meetingId: this.id},
|
|
6473
6411
|
});
|
|
6474
6412
|
|
|
6475
6413
|
LoggerProxy.logger.log('Meeting:index#endMeetingForAll --> End meeting for All');
|