[RN] Promised-base RTCPeerConnection API
Recent changes in lib-jitsi-meet probably led to (1) our RTCPeerConnection customizations on react-native not being used which is a problem because we need them for at least NAT64 on iOS in order to pass the review in Apple's App Store and (2) unexpected exceptions inside react-native-webrtc. The Promise-based WebRTC API should be merged from react-native-webrtc's upstream but I don't want to do it right now because last time we got multiple bugs in addition.
This commit is contained in:
parent
037e7f59b0
commit
e622829c1c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue