@webex/internal-plugin-device 3.6.0-next.1 → 3.6.0-next.3
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/device.js +1 -1
- package/dist/ipNetworkDetector.js +48 -16
- package/dist/ipNetworkDetector.js.map +1 -1
- package/package.json +10 -10
- package/src/ipNetworkDetector.ts +31 -3
- package/test/unit/spec/ipNetworkDetector.js +84 -1
package/dist/device.js
CHANGED
|
@@ -765,7 +765,7 @@ var Device = _webexCore.WebexPlugin.extend((_dec = (0, _webexCore.waitForValue)(
|
|
|
765
765
|
_this9.resetLogoutTimer();
|
|
766
766
|
});
|
|
767
767
|
} /* eslint-enable require-jsdoc */,
|
|
768
|
-
version: "3.6.0-next.
|
|
768
|
+
version: "3.6.0-next.3"
|
|
769
769
|
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight, _dec], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "register", [_common.oneFlight, _dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "register"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "unregister", [_common.oneFlight, _dec3], (0, _getOwnPropertyDescriptor.default)(_obj, "unregister"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "markUrlFailedAndGetNew", [_dec4], (0, _getOwnPropertyDescriptor.default)(_obj, "markUrlFailedAndGetNew"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initialize", [_dec5], (0, _getOwnPropertyDescriptor.default)(_obj, "initialize"), _obj)), _obj)));
|
|
770
770
|
var _default = exports.default = Device;
|
|
771
771
|
//# sourceMappingURL=device.js.map
|
|
@@ -14,6 +14,12 @@ var _webexCore = require("@webex/webex-core");
|
|
|
14
14
|
* Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
var STATE = {
|
|
18
|
+
INITIAL: 'initial',
|
|
19
|
+
IN_PROGRESS: 'in-progress',
|
|
20
|
+
IDLE: 'idle'
|
|
21
|
+
};
|
|
22
|
+
|
|
17
23
|
/**
|
|
18
24
|
* @class
|
|
19
25
|
*/
|
|
@@ -27,9 +33,11 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
|
|
|
27
33
|
// time [ms] it took to receive first IPv6 candidate
|
|
28
34
|
firstMdns: ['number', true, -1],
|
|
29
35
|
// time [ms] it took to receive first mDNS candidate
|
|
30
|
-
totalTime: ['number', true, -1]
|
|
36
|
+
totalTime: ['number', true, -1],
|
|
37
|
+
// total time [ms] it took to do the last IP network detection
|
|
38
|
+
state: ['string', true, STATE.INITIAL],
|
|
39
|
+
pendingDetection: ['object', false, undefined]
|
|
31
40
|
},
|
|
32
|
-
|
|
33
41
|
derived: {
|
|
34
42
|
/**
|
|
35
43
|
* True if we know we're on an IPv4 network,
|
|
@@ -165,35 +173,59 @@ var IpNetworkDetector = _webexCore.WebexPlugin.extend({
|
|
|
165
173
|
* Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
|
|
166
174
|
* supportsIpV4 and supportsIpV6 props to find out the result.
|
|
167
175
|
*
|
|
168
|
-
* @
|
|
176
|
+
* @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet
|
|
177
|
+
* @returns {Promise<void>}
|
|
169
178
|
*/
|
|
170
179
|
detect: function detect() {
|
|
171
|
-
var
|
|
180
|
+
var _arguments = arguments,
|
|
181
|
+
_this2 = this;
|
|
172
182
|
return (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
|
|
173
|
-
var results, pc;
|
|
183
|
+
var force, results, pc, forceParam;
|
|
174
184
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
175
185
|
while (1) switch (_context2.prev = _context2.next) {
|
|
176
186
|
case 0:
|
|
177
|
-
|
|
187
|
+
force = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : false;
|
|
188
|
+
if (!(_this2.state === STATE.IN_PROGRESS)) {
|
|
189
|
+
_context2.next = 4;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
_this2.pendingDetection = {
|
|
193
|
+
force: force
|
|
194
|
+
};
|
|
195
|
+
return _context2.abrupt("return");
|
|
196
|
+
case 4:
|
|
197
|
+
if (!(!force && _this2.state !== STATE.INITIAL && !_this2.receivedOnlyMDnsCandidates())) {
|
|
198
|
+
_context2.next = 6;
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
return _context2.abrupt("return");
|
|
202
|
+
case 6:
|
|
203
|
+
_context2.prev = 6;
|
|
204
|
+
_this2.state = STATE.IN_PROGRESS;
|
|
178
205
|
pc = new RTCPeerConnection();
|
|
179
|
-
_context2.next =
|
|
206
|
+
_context2.next = 11;
|
|
180
207
|
return _this2.gatherLocalCandidates(pc);
|
|
181
|
-
case
|
|
208
|
+
case 11:
|
|
182
209
|
results = _context2.sent;
|
|
183
|
-
case
|
|
184
|
-
_context2.prev =
|
|
210
|
+
case 12:
|
|
211
|
+
_context2.prev = 12;
|
|
185
212
|
pc.close();
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
_this2.state = STATE.IDLE;
|
|
214
|
+
return _context2.finish(12);
|
|
215
|
+
case 16:
|
|
216
|
+
if (_this2.pendingDetection) {
|
|
217
|
+
forceParam = _this2.pendingDetection.force;
|
|
218
|
+
_this2.pendingDetection = undefined;
|
|
219
|
+
_this2.detect(forceParam);
|
|
220
|
+
}
|
|
221
|
+
case 17:
|
|
190
222
|
case "end":
|
|
191
223
|
return _context2.stop();
|
|
192
224
|
}
|
|
193
|
-
}, _callee2, null, [[
|
|
225
|
+
}, _callee2, null, [[6,, 12, 16]]);
|
|
194
226
|
}))();
|
|
195
227
|
},
|
|
196
|
-
version: "3.6.0-next.
|
|
228
|
+
version: "3.6.0-next.3"
|
|
197
229
|
});
|
|
198
230
|
var _default = exports.default = IpNetworkDetector;
|
|
199
231
|
//# sourceMappingURL=ipNetworkDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_webexCore","require","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","derived","supportsIpV4","deps","fn","undefined","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_this2","_callee2","results","_callee2$","_context2","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @returns {Promise<Object>}\n */\n async detect() {\n let results;\n let pc;\n\n try {\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc.close();\n }\n\n return results;\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_webexCore","require","STATE","INITIAL","IN_PROGRESS","IDLE","IpNetworkDetector","WebexPlugin","extend","idAttribute","namespace","props","firstIpV4","firstIpV6","firstMdns","totalTime","state","pendingDetection","undefined","derived","supportsIpV4","deps","fn","receivedOnlyMDnsCandidates","supportsIpV6","gatherLocalCandidates","pc","_this","_asyncToGenerator2","default","_regenerator","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","_promise","resolve","reject","done","startTime","performance","now","doneGatheringIceCandidates","onicecandidate","event","_event$candidate","candidate","address","endsWith","includes","onicegatheringstatechange","iceGatheringState","createDataChannel","createOffer","then","offer","setLocalDescription","catch","e","webex","logger","error","stop","detect","_arguments","arguments","_this2","_callee2","force","results","forceParam","_callee2$","_context2","length","RTCPeerConnection","sent","close","finish","version","_default","exports"],"sources":["ipNetworkDetector.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2023 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\n\nconst STATE = {\n INITIAL: 'initial',\n IN_PROGRESS: 'in-progress',\n IDLE: 'idle',\n};\n\n/**\n * @class\n */\nconst IpNetworkDetector = WebexPlugin.extend({\n idAttribute: 'IpNetworkDetectorId',\n\n namespace: 'Device',\n\n props: {\n firstIpV4: ['number', true, -1], // time [ms] it took to receive first IPv4 candidate\n firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate\n firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate\n totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection\n state: ['string', true, STATE.INITIAL],\n pendingDetection: ['object', false, undefined],\n },\n\n derived: {\n /**\n * True if we know we're on an IPv4 network,\n * False if we know that we are not on an IPv4 network,\n * undefined if we are not sure\n */\n supportsIpV4: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV4 prop\n * @returns {boolean | undefined}\n */\n fn() {\n if (this.firstIpV4 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n /**\n * True if we know we're on an IPv6 network,\n * False if we know that we are not on an IPv6 network,\n * undefined if we are not sure\n */\n supportsIpV6: {\n deps: ['firstIpV4', 'firstIpV6', 'firstMdns', 'totalTime'],\n /**\n * Function for calculating the value of supportsIpV6 prop\n * @returns {boolean | undefined}\n */ fn() {\n if (this.firstIpV6 >= 0) {\n return true;\n }\n if (this.totalTime < 0) {\n // we haven't completed the detection, yet\n return undefined;\n }\n if (this.receivedOnlyMDnsCandidates()) {\n return undefined;\n }\n\n return false;\n },\n },\n },\n\n /**\n * Returns true if we have received only mDNS candidates - browsers usually do that if we don't have any user media permissions\n *\n * @private\n * @returns {boolean}\n */\n receivedOnlyMDnsCandidates() {\n return this.totalTime >= 0 && this.firstMdns >= 0 && this.firstIpV4 < 0 && this.firstIpV6 < 0;\n },\n\n /**\n *\n * @param {RTCPeerConnection} pc Peer connection to use\n * @private\n * @returns {Promise<void>}\n */\n async gatherLocalCandidates(pc: RTCPeerConnection): Promise<void> {\n return new Promise((resolve, reject) => {\n let done = false;\n\n this.firstIpV4 = -1;\n this.firstIpV6 = -1;\n this.firstMdns = -1;\n this.totalTime = -1;\n const startTime = performance.now();\n\n const doneGatheringIceCandidates = () => {\n if (done) {\n return;\n }\n done = true;\n\n this.totalTime = performance.now() - startTime;\n\n resolve();\n };\n\n pc.onicecandidate = (event) => {\n if (event.candidate?.address) {\n if (event.candidate.address.endsWith('.local')) {\n // if we don't have camera/mic permissions, browser just gives us mDNS candidates\n if (this.firstMdns === -1) {\n this.firstMdns = performance.now() - startTime;\n }\n } else if (event.candidate.address.includes(':')) {\n if (this.firstIpV6 === -1) {\n this.firstIpV6 = performance.now() - startTime;\n }\n } else if (this.firstIpV4 === -1) {\n this.firstIpV4 = performance.now() - startTime;\n }\n\n if (this.firstIpV4 >= 0 && this.firstIpV6 >= 0) {\n // if we've got both ipv4 and ipv6 candidates, there is no need to wait for any more candidates, we can resolve now\n resolve();\n }\n } else if (event.candidate === null) {\n doneGatheringIceCandidates();\n }\n };\n\n pc.onicegatheringstatechange = () => {\n if (pc.iceGatheringState === 'complete') {\n doneGatheringIceCandidates();\n }\n };\n\n pc.createDataChannel('data');\n\n pc.createOffer()\n .then((offer) => pc.setLocalDescription(offer))\n .catch((e) => {\n this.webex.logger.error('Failed to detect ip network version:', e);\n reject(e);\n });\n });\n },\n\n /**\n * Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the\n * supportsIpV4 and supportsIpV6 props to find out the result.\n *\n * @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet\n * @returns {Promise<void>}\n */\n async detect(force = false) {\n let results;\n let pc;\n\n if (this.state === STATE.IN_PROGRESS) {\n this.pendingDetection = {force};\n\n return;\n }\n\n if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {\n // we already have the results, no need to do the detection again\n return;\n }\n\n try {\n this.state = STATE.IN_PROGRESS;\n\n pc = new RTCPeerConnection();\n\n results = await this.gatherLocalCandidates(pc);\n } finally {\n pc.close();\n this.state = STATE.IDLE;\n }\n\n if (this.pendingDetection) {\n const {force: forceParam} = this.pendingDetection;\n\n this.pendingDetection = undefined;\n this.detect(forceParam);\n }\n },\n});\n\nexport default IpNetworkDetector;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
26
26
|
"@webex/jest-config-legacy": "0.0.0",
|
|
27
27
|
"@webex/legacy-tools": "0.0.0",
|
|
28
|
-
"@webex/test-helper-chai": "3.6.0-next.
|
|
29
|
-
"@webex/test-helper-mocha": "3.6.0-next.
|
|
30
|
-
"@webex/test-helper-mock-webex": "3.6.0-next.
|
|
31
|
-
"@webex/test-helper-test-users": "3.6.0-next.
|
|
28
|
+
"@webex/test-helper-chai": "3.6.0-next.3",
|
|
29
|
+
"@webex/test-helper-mocha": "3.6.0-next.3",
|
|
30
|
+
"@webex/test-helper-mock-webex": "3.6.0-next.3",
|
|
31
|
+
"@webex/test-helper-test-users": "3.6.0-next.3",
|
|
32
32
|
"chai": "^4.3.4",
|
|
33
33
|
"chai-as-promised": "^7.1.1",
|
|
34
34
|
"eslint": "^8.24.0",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"sinon": "^9.2.4"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@webex/common": "3.6.0-next.
|
|
40
|
-
"@webex/common-timers": "3.6.0-next.
|
|
41
|
-
"@webex/http-core": "3.6.0-next.
|
|
42
|
-
"@webex/internal-plugin-metrics": "3.6.0-next.
|
|
43
|
-
"@webex/webex-core": "3.6.0-next.
|
|
39
|
+
"@webex/common": "3.6.0-next.3",
|
|
40
|
+
"@webex/common-timers": "3.6.0-next.3",
|
|
41
|
+
"@webex/http-core": "3.6.0-next.3",
|
|
42
|
+
"@webex/internal-plugin-metrics": "3.6.0-next.3",
|
|
43
|
+
"@webex/webex-core": "3.6.0-next.3",
|
|
44
44
|
"ampersand-collection": "^2.0.2",
|
|
45
45
|
"ampersand-state": "^5.0.3",
|
|
46
46
|
"lodash": "^4.17.21"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"test:style": "eslint ./src/**/*.*",
|
|
55
55
|
"test:unit": "webex-legacy-tools test --unit --runner jest"
|
|
56
56
|
},
|
|
57
|
-
"version": "3.6.0-next.
|
|
57
|
+
"version": "3.6.0-next.3"
|
|
58
58
|
}
|
package/src/ipNetworkDetector.ts
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import {WebexPlugin} from '@webex/webex-core';
|
|
6
6
|
|
|
7
|
+
const STATE = {
|
|
8
|
+
INITIAL: 'initial',
|
|
9
|
+
IN_PROGRESS: 'in-progress',
|
|
10
|
+
IDLE: 'idle',
|
|
11
|
+
};
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* @class
|
|
9
15
|
*/
|
|
@@ -17,6 +23,8 @@ const IpNetworkDetector = WebexPlugin.extend({
|
|
|
17
23
|
firstIpV6: ['number', true, -1], // time [ms] it took to receive first IPv6 candidate
|
|
18
24
|
firstMdns: ['number', true, -1], // time [ms] it took to receive first mDNS candidate
|
|
19
25
|
totalTime: ['number', true, -1], // total time [ms] it took to do the last IP network detection
|
|
26
|
+
state: ['string', true, STATE.INITIAL],
|
|
27
|
+
pendingDetection: ['object', false, undefined],
|
|
20
28
|
},
|
|
21
29
|
|
|
22
30
|
derived: {
|
|
@@ -155,21 +163,41 @@ const IpNetworkDetector = WebexPlugin.extend({
|
|
|
155
163
|
* Detects if we are on IPv4 and/or IPv6 network. Once it resolves, read the
|
|
156
164
|
* supportsIpV4 and supportsIpV6 props to find out the result.
|
|
157
165
|
*
|
|
158
|
-
* @
|
|
166
|
+
* @param {boolean} force - if false, the detection will only be done if we haven't managed to get any meaningful results yet
|
|
167
|
+
* @returns {Promise<void>}
|
|
159
168
|
*/
|
|
160
|
-
async detect() {
|
|
169
|
+
async detect(force = false) {
|
|
161
170
|
let results;
|
|
162
171
|
let pc;
|
|
163
172
|
|
|
173
|
+
if (this.state === STATE.IN_PROGRESS) {
|
|
174
|
+
this.pendingDetection = {force};
|
|
175
|
+
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!force && this.state !== STATE.INITIAL && !this.receivedOnlyMDnsCandidates()) {
|
|
180
|
+
// we already have the results, no need to do the detection again
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
164
184
|
try {
|
|
185
|
+
this.state = STATE.IN_PROGRESS;
|
|
186
|
+
|
|
165
187
|
pc = new RTCPeerConnection();
|
|
166
188
|
|
|
167
189
|
results = await this.gatherLocalCandidates(pc);
|
|
168
190
|
} finally {
|
|
169
191
|
pc.close();
|
|
192
|
+
this.state = STATE.IDLE;
|
|
170
193
|
}
|
|
171
194
|
|
|
172
|
-
|
|
195
|
+
if (this.pendingDetection) {
|
|
196
|
+
const {force: forceParam} = this.pendingDetection;
|
|
197
|
+
|
|
198
|
+
this.pendingDetection = undefined;
|
|
199
|
+
this.detect(forceParam);
|
|
200
|
+
}
|
|
173
201
|
},
|
|
174
202
|
});
|
|
175
203
|
|
|
@@ -3,6 +3,8 @@ import sinon from 'sinon';
|
|
|
3
3
|
import IpNetworkDetector from '@webex/internal-plugin-device/src/ipNetworkDetector';
|
|
4
4
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
5
5
|
|
|
6
|
+
const flushPromises = () => new Promise(setImmediate);
|
|
7
|
+
|
|
6
8
|
describe('plugin-device', () => {
|
|
7
9
|
describe('IpNetworkDetector', () => {
|
|
8
10
|
let webex;
|
|
@@ -326,7 +328,7 @@ describe('plugin-device', () => {
|
|
|
326
328
|
});
|
|
327
329
|
|
|
328
330
|
// now call detect() again
|
|
329
|
-
const promise2 = ipNetworkDetector.detect();
|
|
331
|
+
const promise2 = ipNetworkDetector.detect(true);
|
|
330
332
|
|
|
331
333
|
// everything should have been reset
|
|
332
334
|
assert.equal(ipNetworkDetector.supportsIpV4, undefined);
|
|
@@ -340,6 +342,87 @@ describe('plugin-device', () => {
|
|
|
340
342
|
await promise2;
|
|
341
343
|
});
|
|
342
344
|
|
|
345
|
+
it('queues another detect() call if one is already in progress', async () => {
|
|
346
|
+
const promise = ipNetworkDetector.detect();
|
|
347
|
+
|
|
348
|
+
simulateCandidate(50, '192.168.0.1');
|
|
349
|
+
|
|
350
|
+
await flushPromises();
|
|
351
|
+
|
|
352
|
+
assert.calledOnce(fakePeerConnection.createDataChannel);
|
|
353
|
+
assert.calledOnce(fakePeerConnection.createOffer);
|
|
354
|
+
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
355
|
+
|
|
356
|
+
// now call detect() again
|
|
357
|
+
ipNetworkDetector.detect(true);
|
|
358
|
+
|
|
359
|
+
// simulate the end of the detection -> another one should be started
|
|
360
|
+
simulateEndOfCandidateGathering(10);
|
|
361
|
+
|
|
362
|
+
await promise;
|
|
363
|
+
|
|
364
|
+
assert.calledTwice(fakePeerConnection.createDataChannel);
|
|
365
|
+
assert.calledTwice(fakePeerConnection.createOffer);
|
|
366
|
+
assert.calledTwice(fakePeerConnection.setLocalDescription);
|
|
367
|
+
|
|
368
|
+
simulateCandidate(50, '2a02:c7c:a0d0:8a00:db9b:d4de:d1f7:4c49');
|
|
369
|
+
simulateEndOfCandidateGathering(10);
|
|
370
|
+
|
|
371
|
+
// results should reflect the last run detection
|
|
372
|
+
checkResults({
|
|
373
|
+
supportsIpV4: false,
|
|
374
|
+
supportsIpV6: true,
|
|
375
|
+
timings: {
|
|
376
|
+
totalTime: 60,
|
|
377
|
+
ipv4: -1,
|
|
378
|
+
ipv6: 50,
|
|
379
|
+
mdns: -1,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
await flushPromises();
|
|
384
|
+
|
|
385
|
+
// no more detections should be started
|
|
386
|
+
assert.calledTwice(fakePeerConnection.createDataChannel);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it.each`
|
|
390
|
+
force | state | receivedOnlyMDnsCandidates | expectedToRunDetection
|
|
391
|
+
${true} | ${'initial'} | ${false} | ${true}
|
|
392
|
+
${true} | ${'idle'} | ${false} | ${true}
|
|
393
|
+
${true} | ${'initial'} | ${true} | ${true}
|
|
394
|
+
${true} | ${'idle'} | ${true} | ${true}
|
|
395
|
+
${false} | ${'initial'} | ${false} | ${true}
|
|
396
|
+
${false} | ${'initial'} | ${true} | ${true}
|
|
397
|
+
${false} | ${'idle'} | ${true} | ${true}
|
|
398
|
+
${false} | ${'idle'} | ${false} | ${false}
|
|
399
|
+
`(
|
|
400
|
+
'force=$force, state=$state, receivedOnlyMDnsCandidates=$receivedOnlyMDnsCandidates => expectedToRunDetection=$expectedToRunDetection',
|
|
401
|
+
async ({force, state, receivedOnlyMDnsCandidates, expectedToRunDetection}) => {
|
|
402
|
+
ipNetworkDetector.state = state;
|
|
403
|
+
sinon
|
|
404
|
+
.stub(ipNetworkDetector, 'receivedOnlyMDnsCandidates')
|
|
405
|
+
.returns(receivedOnlyMDnsCandidates);
|
|
406
|
+
|
|
407
|
+
const result = ipNetworkDetector.detect(force);
|
|
408
|
+
|
|
409
|
+
if (expectedToRunDetection) {
|
|
410
|
+
simulateEndOfCandidateGathering(10);
|
|
411
|
+
}
|
|
412
|
+
await result;
|
|
413
|
+
|
|
414
|
+
if (expectedToRunDetection) {
|
|
415
|
+
assert.calledOnce(fakePeerConnection.createDataChannel);
|
|
416
|
+
assert.calledOnce(fakePeerConnection.createOffer);
|
|
417
|
+
assert.calledOnce(fakePeerConnection.setLocalDescription);
|
|
418
|
+
} else {
|
|
419
|
+
assert.notCalled(fakePeerConnection.createDataChannel);
|
|
420
|
+
assert.notCalled(fakePeerConnection.createOffer);
|
|
421
|
+
assert.notCalled(fakePeerConnection.setLocalDescription);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
|
|
343
426
|
it('rejects if one of RTCPeerConnection operations fails', async () => {
|
|
344
427
|
const fakeError = new Error('fake error');
|
|
345
428
|
|