@webex/plugin-meetings 3.3.1-next.16 → 3.3.1-next.18
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/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/media/MediaConnectionAwaiter.js +50 -13
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +46 -33
- package/dist/meeting/index.js.map +1 -1
- package/dist/types/media/MediaConnectionAwaiter.d.ts +18 -4
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/media/MediaConnectionAwaiter.ts +66 -11
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +19 -7
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +90 -32
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +30 -35
|
@@ -9,8 +9,10 @@ export default class MediaConnectionAwaiter {
|
|
|
9
9
|
private timer;
|
|
10
10
|
private defer;
|
|
11
11
|
private retried;
|
|
12
|
+
private iceConnected;
|
|
12
13
|
private onTimeoutCallback;
|
|
13
|
-
private
|
|
14
|
+
private peerConnectionStateCallback;
|
|
15
|
+
private iceConnectionStateCallback;
|
|
14
16
|
private iceGatheringStateCallback;
|
|
15
17
|
/**
|
|
16
18
|
* @param {MediaConnectionAwaiterProps} mediaConnectionAwaiterProps
|
|
@@ -35,17 +37,29 @@ export default class MediaConnectionAwaiter {
|
|
|
35
37
|
*/
|
|
36
38
|
private clearCallbacks;
|
|
37
39
|
/**
|
|
38
|
-
*
|
|
40
|
+
* On connection state change.
|
|
39
41
|
*
|
|
40
42
|
* @returns {void}
|
|
41
43
|
*/
|
|
42
|
-
|
|
44
|
+
connectionStateChange(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Listener for peer connection state change.
|
|
47
|
+
*
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
peerConnectionStateHandler(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Listener for ICE connection state change.
|
|
53
|
+
*
|
|
54
|
+
* @returns {void}
|
|
55
|
+
*/
|
|
56
|
+
iceConnectionStateHandler(): void;
|
|
43
57
|
/**
|
|
44
58
|
* Listener for ICE gathering state change.
|
|
45
59
|
*
|
|
46
60
|
* @returns {void}
|
|
47
61
|
*/
|
|
48
|
-
|
|
62
|
+
iceGatheringStateHandler(): void;
|
|
49
63
|
/**
|
|
50
64
|
* Function called when the timeout is reached.
|
|
51
65
|
*
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConnectionState } from '@webex/internal-media-core';
|
|
2
|
+
import EventsScope from '../common/events/events-scope';
|
|
3
|
+
import { Enum } from '../constants';
|
|
4
|
+
export declare const ConnectionStateEvent: {
|
|
5
|
+
readonly stateChanged: "connectionState:changed";
|
|
6
|
+
};
|
|
7
|
+
export type ConnectionStateEvent = Enum<typeof ConnectionStateEvent>;
|
|
8
|
+
export interface ConnectionStateChangedEvent {
|
|
9
|
+
/**
|
|
10
|
+
* Current overall connection state
|
|
11
|
+
*/
|
|
12
|
+
state: ConnectionState;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @class ConnectionStateHandler
|
|
16
|
+
*/
|
|
17
|
+
export declare class ConnectionStateHandler extends EventsScope {
|
|
18
|
+
private webrtcMediaConnection;
|
|
19
|
+
private mediaConnectionState;
|
|
20
|
+
/**
|
|
21
|
+
* @param {WebRTCMeeting} webrtcMediaConnection
|
|
22
|
+
*/
|
|
23
|
+
constructor(webrtcMediaConnection: any);
|
|
24
|
+
/**
|
|
25
|
+
* Handler for connection state change.
|
|
26
|
+
*
|
|
27
|
+
* @returns {void}
|
|
28
|
+
*/
|
|
29
|
+
private handleConnectionStateChange;
|
|
30
|
+
}
|
|
@@ -456,6 +456,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
456
456
|
private sdpResponseTimer?;
|
|
457
457
|
private hasMediaConnectionConnectedAtLeastOnce;
|
|
458
458
|
private joinWithMediaRetryInfo?;
|
|
459
|
+
private connectionStateHandler?;
|
|
459
460
|
/**
|
|
460
461
|
* @param {Object} attrs
|
|
461
462
|
* @param {Object} options
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.3.1-next.
|
|
65
|
+
version: "3.3.1-next.18"
|
|
66
66
|
});
|
|
67
67
|
var _default = exports.default = Webinar;
|
|
68
68
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.3.1-next.
|
|
47
|
-
"@webex/plugin-rooms": "3.3.1-next.
|
|
48
|
-
"@webex/test-helper-chai": "3.3.1-next.
|
|
49
|
-
"@webex/test-helper-mocha": "3.3.1-next.
|
|
50
|
-
"@webex/test-helper-mock-webex": "3.3.1-next.
|
|
51
|
-
"@webex/test-helper-retry": "3.3.1-next.
|
|
52
|
-
"@webex/test-helper-test-users": "3.3.1-next.
|
|
46
|
+
"@webex/plugin-meetings": "3.3.1-next.18",
|
|
47
|
+
"@webex/plugin-rooms": "3.3.1-next.5",
|
|
48
|
+
"@webex/test-helper-chai": "3.3.1-next.4",
|
|
49
|
+
"@webex/test-helper-mocha": "3.3.1-next.4",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.3.1-next.4",
|
|
51
|
+
"@webex/test-helper-retry": "3.3.1-next.4",
|
|
52
|
+
"@webex/test-helper-test-users": "3.3.1-next.4",
|
|
53
53
|
"chai": "^4.3.4",
|
|
54
54
|
"chai-as-promised": "^7.1.1",
|
|
55
55
|
"eslint": "^8.24.0",
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"typescript": "^4.7.4"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@webex/common": "3.3.1-next.
|
|
65
|
-
"@webex/internal-media-core": "2.
|
|
66
|
-
"@webex/internal-plugin-conversation": "3.3.1-next.
|
|
67
|
-
"@webex/internal-plugin-device": "3.3.1-next.
|
|
68
|
-
"@webex/internal-plugin-llm": "3.3.1-next.
|
|
69
|
-
"@webex/internal-plugin-mercury": "3.3.1-next.
|
|
70
|
-
"@webex/internal-plugin-metrics": "3.3.1-next.
|
|
71
|
-
"@webex/internal-plugin-support": "3.3.1-next.
|
|
72
|
-
"@webex/internal-plugin-user": "3.3.1-next.
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.3.1-next.
|
|
74
|
-
"@webex/media-helpers": "3.3.1-next.
|
|
75
|
-
"@webex/plugin-people": "3.3.1-next.
|
|
76
|
-
"@webex/plugin-rooms": "3.3.1-next.
|
|
64
|
+
"@webex/common": "3.3.1-next.4",
|
|
65
|
+
"@webex/internal-media-core": "2.6.0",
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.3.1-next.5",
|
|
67
|
+
"@webex/internal-plugin-device": "3.3.1-next.4",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.3.1-next.6",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.3.1-next.5",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.3.1-next.4",
|
|
71
|
+
"@webex/internal-plugin-support": "3.3.1-next.5",
|
|
72
|
+
"@webex/internal-plugin-user": "3.3.1-next.4",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.3.1-next.18",
|
|
74
|
+
"@webex/media-helpers": "3.3.1-next.6",
|
|
75
|
+
"@webex/plugin-people": "3.3.1-next.5",
|
|
76
|
+
"@webex/plugin-rooms": "3.3.1-next.5",
|
|
77
77
|
"@webex/web-capabilities": "^1.3.0",
|
|
78
|
-
"@webex/webex-core": "3.3.1-next.
|
|
78
|
+
"@webex/webex-core": "3.3.1-next.4",
|
|
79
79
|
"ampersand-collection": "^2.0.2",
|
|
80
80
|
"bowser": "^2.11.0",
|
|
81
81
|
"btoa": "^1.2.1",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"//": [
|
|
93
93
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
94
94
|
],
|
|
95
|
-
"version": "3.3.1-next.
|
|
95
|
+
"version": "3.3.1-next.18"
|
|
96
96
|
}
|
|
@@ -15,8 +15,10 @@ export default class MediaConnectionAwaiter {
|
|
|
15
15
|
private timer: any;
|
|
16
16
|
private defer: Defer;
|
|
17
17
|
private retried: boolean;
|
|
18
|
+
private iceConnected: boolean;
|
|
18
19
|
private onTimeoutCallback: () => void;
|
|
19
|
-
private
|
|
20
|
+
private peerConnectionStateCallback: () => void;
|
|
21
|
+
private iceConnectionStateCallback: () => void;
|
|
20
22
|
private iceGatheringStateCallback: () => void;
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -26,9 +28,11 @@ export default class MediaConnectionAwaiter {
|
|
|
26
28
|
this.webrtcMediaConnection = webrtcMediaConnection;
|
|
27
29
|
this.defer = new Defer();
|
|
28
30
|
this.retried = false;
|
|
31
|
+
this.iceConnected = false;
|
|
29
32
|
this.onTimeoutCallback = this.onTimeout.bind(this);
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
33
|
+
this.peerConnectionStateCallback = this.peerConnectionStateHandler.bind(this);
|
|
34
|
+
this.iceConnectionStateCallback = this.iceConnectionStateHandler.bind(this);
|
|
35
|
+
this.iceGatheringStateCallback = this.iceGatheringStateHandler.bind(this);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -59,17 +63,24 @@ export default class MediaConnectionAwaiter {
|
|
|
59
63
|
Event.ICE_GATHERING_STATE_CHANGED,
|
|
60
64
|
this.iceGatheringStateCallback
|
|
61
65
|
);
|
|
62
|
-
this.webrtcMediaConnection.off(
|
|
66
|
+
this.webrtcMediaConnection.off(
|
|
67
|
+
Event.PEER_CONNECTION_STATE_CHANGED,
|
|
68
|
+
this.peerConnectionStateCallback
|
|
69
|
+
);
|
|
70
|
+
this.webrtcMediaConnection.off(
|
|
71
|
+
Event.ICE_CONNECTION_STATE_CHANGED,
|
|
72
|
+
this.iceConnectionStateCallback
|
|
73
|
+
);
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
/**
|
|
66
|
-
*
|
|
77
|
+
* On connection state change.
|
|
67
78
|
*
|
|
68
79
|
* @returns {void}
|
|
69
80
|
*/
|
|
70
|
-
|
|
81
|
+
connectionStateChange(): void {
|
|
71
82
|
LoggerProxy.logger.log(
|
|
72
|
-
`Media:MediaConnectionAwaiter#
|
|
83
|
+
`Media:MediaConnectionAwaiter#connectionStateChange --> connection state: ${this.webrtcMediaConnection.getConnectionState()}`
|
|
73
84
|
);
|
|
74
85
|
|
|
75
86
|
if (!this.isConnected()) {
|
|
@@ -83,16 +94,50 @@ export default class MediaConnectionAwaiter {
|
|
|
83
94
|
this.defer.resolve();
|
|
84
95
|
}
|
|
85
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Listener for peer connection state change.
|
|
99
|
+
*
|
|
100
|
+
* @returns {void}
|
|
101
|
+
*/
|
|
102
|
+
peerConnectionStateHandler(): void {
|
|
103
|
+
const peerConnectionState = this.webrtcMediaConnection.getPeerConnectionState();
|
|
104
|
+
|
|
105
|
+
LoggerProxy.logger.log(
|
|
106
|
+
`Media:MediaConnectionAwaiter#peerConnectionStateHandler --> Peer connection state change -> ${peerConnectionState}`
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
this.connectionStateChange();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Listener for ICE connection state change.
|
|
114
|
+
*
|
|
115
|
+
* @returns {void}
|
|
116
|
+
*/
|
|
117
|
+
iceConnectionStateHandler(): void {
|
|
118
|
+
const iceConnectionState = this.webrtcMediaConnection.getIceConnectionState();
|
|
119
|
+
|
|
120
|
+
LoggerProxy.logger.log(
|
|
121
|
+
`Media:MediaConnectionAwaiter#iceConnectionStateHandler --> ICE connection state change -> ${iceConnectionState}`
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
if (iceConnectionState === 'connected' && !this.iceConnected) {
|
|
125
|
+
this.iceConnected = true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
this.connectionStateChange();
|
|
129
|
+
}
|
|
130
|
+
|
|
86
131
|
/**
|
|
87
132
|
* Listener for ICE gathering state change.
|
|
88
133
|
*
|
|
89
134
|
* @returns {void}
|
|
90
135
|
*/
|
|
91
|
-
|
|
136
|
+
iceGatheringStateHandler(): void {
|
|
92
137
|
const iceGatheringState = this.webrtcMediaConnection.getIceGatheringState();
|
|
93
138
|
|
|
94
139
|
LoggerProxy.logger.log(
|
|
95
|
-
`Media:MediaConnectionAwaiter#
|
|
140
|
+
`Media:MediaConnectionAwaiter#iceGatheringStateHandler --> ICE gathering state change -> ${iceGatheringState}`
|
|
96
141
|
);
|
|
97
142
|
|
|
98
143
|
if (!this.isIceGatheringCompleted()) {
|
|
@@ -147,7 +192,9 @@ export default class MediaConnectionAwaiter {
|
|
|
147
192
|
|
|
148
193
|
this.clearCallbacks();
|
|
149
194
|
|
|
150
|
-
this.defer.reject(
|
|
195
|
+
this.defer.reject({
|
|
196
|
+
iceConnected: this.iceConnected,
|
|
197
|
+
});
|
|
151
198
|
}
|
|
152
199
|
|
|
153
200
|
/**
|
|
@@ -160,7 +207,15 @@ export default class MediaConnectionAwaiter {
|
|
|
160
207
|
return Promise.resolve();
|
|
161
208
|
}
|
|
162
209
|
|
|
163
|
-
this.webrtcMediaConnection.on(
|
|
210
|
+
this.webrtcMediaConnection.on(
|
|
211
|
+
Event.PEER_CONNECTION_STATE_CHANGED,
|
|
212
|
+
this.peerConnectionStateCallback
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
this.webrtcMediaConnection.on(
|
|
216
|
+
Event.ICE_CONNECTION_STATE_CHANGED,
|
|
217
|
+
this.iceConnectionStateCallback
|
|
218
|
+
);
|
|
164
219
|
|
|
165
220
|
this.webrtcMediaConnection.on(
|
|
166
221
|
Event.ICE_GATHERING_STATE_CHANGED,
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {Event, ConnectionState} from '@webex/internal-media-core';
|
|
2
|
+
import EventsScope from '../common/events/events-scope';
|
|
3
|
+
import {Enum} from '../constants';
|
|
4
|
+
|
|
5
|
+
export const ConnectionStateEvent = {
|
|
6
|
+
stateChanged: 'connectionState:changed',
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type ConnectionStateEvent = Enum<typeof ConnectionStateEvent>;
|
|
10
|
+
|
|
11
|
+
export interface ConnectionStateChangedEvent {
|
|
12
|
+
/**
|
|
13
|
+
* Current overall connection state
|
|
14
|
+
*/
|
|
15
|
+
state: ConnectionState;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @class ConnectionStateHandler
|
|
20
|
+
*/
|
|
21
|
+
export class ConnectionStateHandler extends EventsScope {
|
|
22
|
+
private webrtcMediaConnection: any;
|
|
23
|
+
|
|
24
|
+
private mediaConnectionState: ConnectionState;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {WebRTCMeeting} webrtcMediaConnection
|
|
28
|
+
*/
|
|
29
|
+
constructor(webrtcMediaConnection) {
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
this.webrtcMediaConnection = webrtcMediaConnection;
|
|
33
|
+
|
|
34
|
+
this.webrtcMediaConnection.on(
|
|
35
|
+
Event.PEER_CONNECTION_STATE_CHANGED,
|
|
36
|
+
this.handleConnectionStateChange.bind(this)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
this.webrtcMediaConnection.on(
|
|
40
|
+
Event.ICE_CONNECTION_STATE_CHANGED,
|
|
41
|
+
this.handleConnectionStateChange.bind(this)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Handler for connection state change.
|
|
47
|
+
*
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
private handleConnectionStateChange(): void {
|
|
51
|
+
const newConnectionState = this.webrtcMediaConnection.getConnectionState();
|
|
52
|
+
|
|
53
|
+
if (newConnectionState !== this.mediaConnectionState) {
|
|
54
|
+
this.mediaConnectionState = newConnectionState;
|
|
55
|
+
this.emit(
|
|
56
|
+
{
|
|
57
|
+
file: 'connectionStateHandler',
|
|
58
|
+
function: 'handleConnectionStateChange',
|
|
59
|
+
},
|
|
60
|
+
ConnectionStateEvent.stateChanged,
|
|
61
|
+
{state: this.mediaConnectionState}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/meeting/index.ts
CHANGED
|
@@ -153,6 +153,7 @@ import RecordingController from '../recording-controller';
|
|
|
153
153
|
import ControlsOptionsManager from '../controls-options-manager';
|
|
154
154
|
import PermissionError from '../common/errors/permission';
|
|
155
155
|
import {LocusMediaRequest} from './locusMediaRequest';
|
|
156
|
+
import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
|
|
156
157
|
|
|
157
158
|
const logRequest = (request: any, {logText = ''}) => {
|
|
158
159
|
LoggerProxy.logger.info(`${logText} - sending request`);
|
|
@@ -680,6 +681,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
680
681
|
private sdpResponseTimer?: ReturnType<typeof setTimeout>;
|
|
681
682
|
private hasMediaConnectionConnectedAtLeastOnce: boolean;
|
|
682
683
|
private joinWithMediaRetryInfo?: {isRetry: boolean; prevJoinResponse?: any};
|
|
684
|
+
private connectionStateHandler?: ConnectionStateHandler;
|
|
683
685
|
|
|
684
686
|
/**
|
|
685
687
|
* @param {Object} attrs
|
|
@@ -1470,6 +1472,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1470
1472
|
* @memberof Meeting
|
|
1471
1473
|
*/
|
|
1472
1474
|
this.joinWithMediaRetryInfo = {isRetry: false, prevJoinResponse: undefined};
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* Connection state handler
|
|
1478
|
+
* @instance
|
|
1479
|
+
* @type {ConnectionStateHandler}
|
|
1480
|
+
* @private
|
|
1481
|
+
* @memberof Meeting
|
|
1482
|
+
*/
|
|
1483
|
+
this.connectionStateHandler = undefined;
|
|
1473
1484
|
}
|
|
1474
1485
|
|
|
1475
1486
|
/**
|
|
@@ -5851,7 +5862,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5851
5862
|
}
|
|
5852
5863
|
});
|
|
5853
5864
|
|
|
5854
|
-
this.
|
|
5865
|
+
this.connectionStateHandler = new ConnectionStateHandler(
|
|
5866
|
+
this.mediaProperties.webrtcMediaConnection
|
|
5867
|
+
);
|
|
5868
|
+
|
|
5869
|
+
this.connectionStateHandler.on(ConnectionStateEvent.stateChanged, (event) => {
|
|
5855
5870
|
const connectionFailed = () => {
|
|
5856
5871
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.CONNECTION_FAILURE, {
|
|
5857
5872
|
correlation_id: this.correlationId,
|
|
@@ -6269,6 +6284,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6269
6284
|
try {
|
|
6270
6285
|
await this.mediaProperties.waitForMediaConnectionConnected();
|
|
6271
6286
|
} catch (error) {
|
|
6287
|
+
const {iceConnected} = error;
|
|
6288
|
+
|
|
6272
6289
|
if (!this.hasMediaConnectionConnectedAtLeastOnce) {
|
|
6273
6290
|
// Only send CA event for join flow if we haven't successfully connected media yet
|
|
6274
6291
|
// @ts-ignore
|
|
@@ -6288,12 +6305,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6288
6305
|
this.mediaProperties.webrtcMediaConnection?.mediaConnection?.pc
|
|
6289
6306
|
?.signalingState ||
|
|
6290
6307
|
'unknown',
|
|
6291
|
-
|
|
6292
|
-
this.mediaProperties.webrtcMediaConnection?.multistreamConnection?.pc?.pc
|
|
6293
|
-
?.iceConnectionState ||
|
|
6294
|
-
this.mediaProperties.webrtcMediaConnection?.mediaConnection?.pc
|
|
6295
|
-
?.iceConnectionState ||
|
|
6296
|
-
'unknown',
|
|
6308
|
+
iceConnected,
|
|
6297
6309
|
turnServerUsed: this.turnServerUsed,
|
|
6298
6310
|
}),
|
|
6299
6311
|
}
|
|
@@ -19,6 +19,8 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
19
19
|
off: sinon.stub(),
|
|
20
20
|
getConnectionState: sinon.stub().returns(ConnectionState.New),
|
|
21
21
|
getIceGatheringState: sinon.stub().returns('new'),
|
|
22
|
+
getIceConnectionState: sinon.stub().returns('new'),
|
|
23
|
+
getPeerConnectionState: sinon.stub().returns('new'),
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
mediaConnectionAwaiter = new MediaConnectionAwaiter({
|
|
@@ -52,8 +54,11 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
52
54
|
.then(() => {
|
|
53
55
|
promiseResolved = true;
|
|
54
56
|
})
|
|
55
|
-
.catch(() => {
|
|
57
|
+
.catch((error) => {
|
|
56
58
|
promiseRejected = true;
|
|
59
|
+
|
|
60
|
+
const {iceConnected} = error;
|
|
61
|
+
assert.equal(iceConnected, false);
|
|
57
62
|
});
|
|
58
63
|
|
|
59
64
|
await testUtils.flushPromises();
|
|
@@ -61,21 +66,68 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
61
66
|
assert.equal(promiseRejected, false);
|
|
62
67
|
|
|
63
68
|
// check the right listener was registered
|
|
64
|
-
assert.
|
|
65
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
66
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
67
|
-
|
|
69
|
+
assert.calledThrice(mockMC.on);
|
|
70
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
71
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
72
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
73
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
68
74
|
|
|
75
|
+
mockMC.getIceGatheringState.returns('complete');
|
|
76
|
+
iceGatheringListener();
|
|
77
|
+
|
|
78
|
+
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
79
|
+
await testUtils.flushPromises();
|
|
80
|
+
|
|
81
|
+
assert.equal(promiseResolved, false);
|
|
82
|
+
assert.equal(promiseRejected, true);
|
|
83
|
+
|
|
84
|
+
assert.calledThrice(mockMC.off);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('rejects after timeout if dtls state is not connected', async () => {
|
|
88
|
+
mockMC.getConnectionState.returns(ConnectionState.Connecting);
|
|
89
|
+
mockMC.getIceGatheringState.returns('gathering');
|
|
90
|
+
|
|
91
|
+
let promiseResolved = false;
|
|
92
|
+
let promiseRejected = false;
|
|
93
|
+
|
|
94
|
+
mediaConnectionAwaiter
|
|
95
|
+
.waitForMediaConnectionConnected()
|
|
96
|
+
.then(() => {
|
|
97
|
+
promiseResolved = true;
|
|
98
|
+
})
|
|
99
|
+
.catch((error) => {
|
|
100
|
+
promiseRejected = true;
|
|
101
|
+
|
|
102
|
+
const {iceConnected} = error;
|
|
103
|
+
assert.equal(iceConnected, false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await testUtils.flushPromises();
|
|
107
|
+
assert.equal(promiseResolved, false);
|
|
108
|
+
assert.equal(promiseRejected, false);
|
|
109
|
+
|
|
110
|
+
// check the right listener was registered
|
|
111
|
+
assert.calledThrice(mockMC.on);
|
|
112
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
113
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
114
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
115
|
+
const listener = mockMC.on.getCall(1).args[1];
|
|
116
|
+
const iceConnectionListener = mockMC.on.getCall(1).args[1];
|
|
117
|
+
|
|
69
118
|
mockMC.getIceGatheringState.returns('complete');
|
|
70
119
|
listener();
|
|
71
120
|
|
|
121
|
+
mockMC.getIceConnectionState.returns('connected');
|
|
122
|
+
iceConnectionListener();
|
|
123
|
+
|
|
72
124
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
|
|
73
125
|
await testUtils.flushPromises();
|
|
74
126
|
|
|
75
127
|
assert.equal(promiseResolved, false);
|
|
76
128
|
assert.equal(promiseRejected, true);
|
|
77
129
|
|
|
78
|
-
assert.
|
|
130
|
+
assert.calledThrice(mockMC.off);
|
|
79
131
|
});
|
|
80
132
|
|
|
81
133
|
it('resolves after timeout if connection state reach connected/completed', async () => {
|
|
@@ -99,9 +151,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
99
151
|
assert.equal(promiseRejected, false);
|
|
100
152
|
|
|
101
153
|
// check the right listener was registered
|
|
102
|
-
assert.
|
|
103
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
104
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
154
|
+
assert.calledThrice(mockMC.on);
|
|
155
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
156
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
157
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
105
158
|
|
|
106
159
|
mockMC.getConnectionState.returns(ConnectionState.Connected);
|
|
107
160
|
|
|
@@ -111,7 +164,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
111
164
|
assert.equal(promiseResolved, true);
|
|
112
165
|
assert.equal(promiseRejected, false);
|
|
113
166
|
|
|
114
|
-
assert.
|
|
167
|
+
assert.calledThrice(mockMC.off);
|
|
115
168
|
});
|
|
116
169
|
|
|
117
170
|
it(`resolves when media connection reaches "connected" state`, async () => {
|
|
@@ -137,9 +190,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
137
190
|
assert.equal(promiseRejected, false);
|
|
138
191
|
|
|
139
192
|
// check the right listener was registered
|
|
140
|
-
assert.
|
|
141
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
142
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
193
|
+
assert.calledThrice(mockMC.on);
|
|
194
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
195
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
196
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
143
197
|
const listener = mockMC.on.getCall(0).args[1];
|
|
144
198
|
|
|
145
199
|
// call the listener and pretend we are now connected
|
|
@@ -151,7 +205,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
151
205
|
assert.equal(promiseRejected, false);
|
|
152
206
|
|
|
153
207
|
// check that listener was removed
|
|
154
|
-
assert.
|
|
208
|
+
assert.calledThrice(mockMC.off);
|
|
155
209
|
|
|
156
210
|
assert.calledOnce(clearTimeoutSpy);
|
|
157
211
|
});
|
|
@@ -179,9 +233,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
179
233
|
assert.equal(promiseRejected, false);
|
|
180
234
|
|
|
181
235
|
// check the right listener was registered
|
|
182
|
-
assert.
|
|
183
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
184
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
236
|
+
assert.calledThrice(mockMC.on);
|
|
237
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
238
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
239
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
185
240
|
const listener = mockMC.on.getCall(1).args[1];
|
|
186
241
|
|
|
187
242
|
// call the listener and pretend we are now connected
|
|
@@ -197,7 +252,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
197
252
|
assert.equal(promiseRejected, false);
|
|
198
253
|
|
|
199
254
|
// check that listener was removed
|
|
200
|
-
assert.
|
|
255
|
+
assert.calledThrice(mockMC.off);
|
|
201
256
|
|
|
202
257
|
assert.neverCalledWith(clearTimeoutSpy);
|
|
203
258
|
});
|
|
@@ -228,10 +283,11 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
228
283
|
assert.calledOnce(setTimeoutSpy);
|
|
229
284
|
|
|
230
285
|
// check the right listener was registered
|
|
231
|
-
assert.
|
|
232
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
233
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
234
|
-
|
|
286
|
+
assert.calledThrice(mockMC.on);
|
|
287
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
288
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
289
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
290
|
+
const listener = mockMC.on.getCall(2).args[1];
|
|
235
291
|
|
|
236
292
|
// call the listener and pretend we are now connected
|
|
237
293
|
mockMC.getIceGatheringState.returns('complete');
|
|
@@ -249,7 +305,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
249
305
|
assert.equal(promiseRejected, false);
|
|
250
306
|
|
|
251
307
|
// check that listener was removed
|
|
252
|
-
assert.
|
|
308
|
+
assert.calledThrice(mockMC.off);
|
|
253
309
|
});
|
|
254
310
|
|
|
255
311
|
it(`reject with restart timer once if gathering state is not complete`, async () => {
|
|
@@ -276,9 +332,10 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
276
332
|
assert.equal(promiseRejected, false);
|
|
277
333
|
|
|
278
334
|
// check the right listener was registered
|
|
279
|
-
assert.
|
|
280
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
281
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
335
|
+
assert.calledThrice(mockMC.on);
|
|
336
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
337
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
338
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
282
339
|
|
|
283
340
|
await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT * 2);
|
|
284
341
|
await testUtils.flushPromises();
|
|
@@ -287,7 +344,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
287
344
|
assert.equal(promiseRejected, true);
|
|
288
345
|
|
|
289
346
|
// check that listener was removed
|
|
290
|
-
assert.
|
|
347
|
+
assert.calledThrice(mockMC.off);
|
|
291
348
|
|
|
292
349
|
assert.calledOnce(clearTimeoutSpy);
|
|
293
350
|
assert.calledTwice(setTimeoutSpy);
|
|
@@ -317,11 +374,12 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
317
374
|
assert.equal(promiseRejected, false);
|
|
318
375
|
|
|
319
376
|
// check the right listener was registered
|
|
320
|
-
assert.
|
|
321
|
-
assert.equal(mockMC.on.getCall(0).args[0], Event.
|
|
322
|
-
assert.equal(mockMC.on.getCall(1).args[0], Event.
|
|
377
|
+
assert.calledThrice(mockMC.on);
|
|
378
|
+
assert.equal(mockMC.on.getCall(0).args[0], Event.PEER_CONNECTION_STATE_CHANGED);
|
|
379
|
+
assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_CONNECTION_STATE_CHANGED);
|
|
380
|
+
assert.equal(mockMC.on.getCall(2).args[0], Event.ICE_GATHERING_STATE_CHANGED);
|
|
323
381
|
const connectionStateListener = mockMC.on.getCall(0).args[1];
|
|
324
|
-
const iceGatheringListener = mockMC.on.getCall(
|
|
382
|
+
const iceGatheringListener = mockMC.on.getCall(2).args[1];
|
|
325
383
|
|
|
326
384
|
mockMC.getIceGatheringState.returns('complete');
|
|
327
385
|
iceGatheringListener();
|
|
@@ -335,7 +393,7 @@ describe('MediaConnectionAwaiter', () => {
|
|
|
335
393
|
assert.equal(promiseRejected, false);
|
|
336
394
|
|
|
337
395
|
// check that listener was removed
|
|
338
|
-
assert.
|
|
396
|
+
assert.calledThrice(mockMC.off);
|
|
339
397
|
|
|
340
398
|
assert.calledTwice(clearTimeoutSpy);
|
|
341
399
|
assert.calledTwice(setTimeoutSpy);
|