[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 { NativeModules } from 'react-native';
|
||||||
import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc';
|
import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc';
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ const SOCK_STREAM = 1; /* stream socket */
|
||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
export default function _RTCPeerConnection(...args) {
|
export default function _RTCPeerConnection(...args: any[]) {
|
||||||
|
|
||||||
/* eslint-disable indent, no-invalid-this */
|
/* 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
|
// _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
|
// don't want to try because the following approach appears to work and I
|
||||||
// understand it.
|
// understand it.
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
Object.defineProperty(this, 'onaddstream', {
|
Object.defineProperty(this, 'onaddstream', {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
@ -67,6 +71,14 @@ export default function _RTCPeerConnection(...args) {
|
||||||
_RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);
|
_RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);
|
||||||
_RTCPeerConnection.prototype.constructor = _RTCPeerConnection;
|
_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) {
|
_RTCPeerConnection.prototype._invokeOnaddstream = function(...args) {
|
||||||
const onaddstream = this._onaddstream;
|
const onaddstream = this._onaddstream;
|
||||||
|
|
||||||
|
@ -90,6 +102,9 @@ _RTCPeerConnection.prototype._queueOnaddstream = function(...args) {
|
||||||
this._onaddstreamQueue.push(Array.from(args));
|
this._onaddstreamQueue.push(Array.from(args));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_RTCPeerConnection.prototype.setLocalDescription
|
||||||
|
= _makePromiseAware(RTCPeerConnection.prototype.setLocalDescription, 1, 0);
|
||||||
|
|
||||||
_RTCPeerConnection.prototype.setRemoteDescription = function(
|
_RTCPeerConnection.prototype.setRemoteDescription = function(
|
||||||
sessionDescription,
|
sessionDescription,
|
||||||
successCallback,
|
successCallback,
|
||||||
|
@ -128,6 +143,50 @@ function _LOGE(...args) {
|
||||||
console && console.error && console.error(...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}
|
* Adapts react-native-webrtc's {@link RTCPeerConnection#setRemoteDescription}
|
||||||
* implementation which uses the deprecated, callback-based version to the
|
* implementation which uses the deprecated, callback-based version to the
|
||||||
|
|
|
@ -15,15 +15,18 @@ import RTCPeerConnection from './RTCPeerConnection';
|
||||||
if (typeof global.MediaStreamTrack === 'undefined') {
|
if (typeof global.MediaStreamTrack === 'undefined') {
|
||||||
global.MediaStreamTrack = MediaStreamTrack;
|
global.MediaStreamTrack = MediaStreamTrack;
|
||||||
}
|
}
|
||||||
|
if (typeof global.RTCIceCandidate === 'undefined') {
|
||||||
|
global.RTCIceCandidate = RTCIceCandidate;
|
||||||
|
}
|
||||||
|
if (typeof global.RTCPeerConnection === 'undefined') {
|
||||||
|
global.RTCPeerConnection = RTCPeerConnection;
|
||||||
|
}
|
||||||
if (typeof global.webkitRTCPeerConnection === 'undefined') {
|
if (typeof global.webkitRTCPeerConnection === 'undefined') {
|
||||||
global.webkitRTCPeerConnection = RTCPeerConnection;
|
global.webkitRTCPeerConnection = RTCPeerConnection;
|
||||||
}
|
}
|
||||||
if (typeof global.RTCSessionDescription === 'undefined') {
|
if (typeof global.RTCSessionDescription === 'undefined') {
|
||||||
global.RTCSessionDescription = RTCSessionDescription;
|
global.RTCSessionDescription = RTCSessionDescription;
|
||||||
}
|
}
|
||||||
if (typeof global.RTCIceCandidate === 'undefined') {
|
|
||||||
global.RTCIceCandidate = RTCIceCandidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
const navigator = global.navigator;
|
const navigator = global.navigator;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue