diff --git a/react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js b/react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js index 6655107bc..280881963 100644 --- a/react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js +++ b/react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js @@ -1,3 +1,5 @@ +// @flow + import { NativeModules } from 'react-native'; import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc'; @@ -33,7 +35,7 @@ const SOCK_STREAM = 1; /* stream socket */ * * @class */ -export default function _RTCPeerConnection(...args) { +export default function _RTCPeerConnection(...args: any[]) { /* eslint-disable indent, no-invalid-this */ @@ -50,6 +52,8 @@ export default function _RTCPeerConnection(...args) { // _RTCPeerConnection's prototype may (or may not, I don't know) work but I // don't want to try because the following approach appears to work and I // understand it. + + // $FlowFixMe Object.defineProperty(this, 'onaddstream', { configurable: true, enumerable: true, @@ -67,6 +71,14 @@ export default function _RTCPeerConnection(...args) { _RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype); _RTCPeerConnection.prototype.constructor = _RTCPeerConnection; +_RTCPeerConnection.prototype.addIceCandidate + = _makePromiseAware(RTCPeerConnection.prototype.addIceCandidate, 1, 0); + +_RTCPeerConnection.prototype.createAnswer + = _makePromiseAware(RTCPeerConnection.prototype.createAnswer, 0, 1); +_RTCPeerConnection.prototype.createOffer + = _makePromiseAware(RTCPeerConnection.prototype.createOffer, 0, 1); + _RTCPeerConnection.prototype._invokeOnaddstream = function(...args) { const onaddstream = this._onaddstream; @@ -90,6 +102,9 @@ _RTCPeerConnection.prototype._queueOnaddstream = function(...args) { this._onaddstreamQueue.push(Array.from(args)); }; +_RTCPeerConnection.prototype.setLocalDescription + = _makePromiseAware(RTCPeerConnection.prototype.setLocalDescription, 1, 0); + _RTCPeerConnection.prototype.setRemoteDescription = function( sessionDescription, successCallback, @@ -128,6 +143,50 @@ function _LOGE(...args) { console && console.error && console.error(...args); } +/** + * Makes a {@code Promise}-returning function out of a specific void function + * with {@code successCallback} and {@code failureCallback}. + * + * @param {Function} f - The (void) function with {@code successCallback} and + * {@code failureCallback}. + * @param {number} beforeCallbacks - The number of arguments before + * {@code successCallback} and {@code failureCallback}. + * @param {number} afterCallbacks - The number of arguments after + * {@code successCallback} and {@code failureCallback}. + * @returns {Promise} + */ +function _makePromiseAware( + f: Function, + beforeCallbacks: number, + afterCallbacks: number) { + return function(...args) { + return new Promise((resolve, reject) => { + + if (args.length <= beforeCallbacks + afterCallbacks) { + args.splice(beforeCallbacks, 0, resolve, reject); + } + + let fPromise; + + try { + // eslint-disable-next-line no-invalid-this + fPromise = f.apply(this, args); + } catch (e) { + reject(e); + } + + // If the super implementation returns a Promise from the deprecated + // invocation by any chance, try to make sense of it. + if (fPromise) { + const { then } = fPromise; + + typeof then === 'function' + && then.call(fPromise, resolve, reject); + } + }); + }; +} + /** * Adapts react-native-webrtc's {@link RTCPeerConnection#setRemoteDescription} * implementation which uses the deprecated, callback-based version to the diff --git a/react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js b/react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js index f86c0787a..67bd03517 100644 --- a/react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js +++ b/react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js @@ -15,15 +15,18 @@ import RTCPeerConnection from './RTCPeerConnection'; if (typeof global.MediaStreamTrack === 'undefined') { global.MediaStreamTrack = MediaStreamTrack; } + if (typeof global.RTCIceCandidate === 'undefined') { + global.RTCIceCandidate = RTCIceCandidate; + } + if (typeof global.RTCPeerConnection === 'undefined') { + global.RTCPeerConnection = RTCPeerConnection; + } if (typeof global.webkitRTCPeerConnection === 'undefined') { global.webkitRTCPeerConnection = RTCPeerConnection; } if (typeof global.RTCSessionDescription === 'undefined') { global.RTCSessionDescription = RTCSessionDescription; } - if (typeof global.RTCIceCandidate === 'undefined') { - global.RTCIceCandidate = RTCIceCandidate; - } const navigator = global.navigator;