Ver código fonte

[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.
master
Lyubo Marinov 7 anos atrás
pai
commit
e622829c1c

+ 60
- 1
react/features/base/lib-jitsi-meet/native/RTCPeerConnection.js Ver arquivo

@@ -1,3 +1,5 @@
1
+// @flow
2
+
1 3
 import { NativeModules } from 'react-native';
2 4
 import { RTCPeerConnection, RTCSessionDescription } from 'react-native-webrtc';
3 5
 
@@ -33,7 +35,7 @@ const SOCK_STREAM = 1; /* stream socket */
33 35
  *
34 36
  * @class
35 37
  */
36
-export default function _RTCPeerConnection(...args) {
38
+export default function _RTCPeerConnection(...args: any[]) {
37 39
 
38 40
     /* eslint-disable indent, no-invalid-this */
39 41
 
@@ -50,6 +52,8 @@ export default function _RTCPeerConnection(...args) {
50 52
     // _RTCPeerConnection's prototype may (or may not, I don't know) work but I
51 53
     // don't want to try because the following approach appears to work and I
52 54
     // understand it.
55
+
56
+    // $FlowFixMe
53 57
     Object.defineProperty(this, 'onaddstream', {
54 58
         configurable: true,
55 59
         enumerable: true,
@@ -67,6 +71,14 @@ export default function _RTCPeerConnection(...args) {
67 71
 _RTCPeerConnection.prototype = Object.create(RTCPeerConnection.prototype);
68 72
 _RTCPeerConnection.prototype.constructor = _RTCPeerConnection;
69 73
 
74
+_RTCPeerConnection.prototype.addIceCandidate
75
+    = _makePromiseAware(RTCPeerConnection.prototype.addIceCandidate, 1, 0);
76
+
77
+_RTCPeerConnection.prototype.createAnswer
78
+    = _makePromiseAware(RTCPeerConnection.prototype.createAnswer, 0, 1);
79
+_RTCPeerConnection.prototype.createOffer
80
+    = _makePromiseAware(RTCPeerConnection.prototype.createOffer, 0, 1);
81
+
70 82
 _RTCPeerConnection.prototype._invokeOnaddstream = function(...args) {
71 83
     const onaddstream = this._onaddstream;
72 84
 
@@ -90,6 +102,9 @@ _RTCPeerConnection.prototype._queueOnaddstream = function(...args) {
90 102
     this._onaddstreamQueue.push(Array.from(args));
91 103
 };
92 104
 
105
+_RTCPeerConnection.prototype.setLocalDescription
106
+  = _makePromiseAware(RTCPeerConnection.prototype.setLocalDescription, 1, 0);
107
+
93 108
 _RTCPeerConnection.prototype.setRemoteDescription = function(
94 109
         sessionDescription,
95 110
         successCallback,
@@ -128,6 +143,50 @@ function _LOGE(...args) {
128 143
     console && console.error && console.error(...args);
129 144
 }
130 145
 
146
+/**
147
+ * Makes a {@code Promise}-returning function out of a specific void function
148
+ * with {@code successCallback} and {@code failureCallback}.
149
+ *
150
+ * @param {Function} f - The (void) function with {@code successCallback} and
151
+ * {@code failureCallback}.
152
+ * @param {number} beforeCallbacks - The number of arguments before
153
+ * {@code successCallback} and {@code failureCallback}.
154
+ * @param {number} afterCallbacks - The number of arguments after
155
+ * {@code successCallback} and {@code failureCallback}.
156
+ * @returns {Promise}
157
+ */
158
+function _makePromiseAware(
159
+        f: Function,
160
+        beforeCallbacks: number,
161
+        afterCallbacks: number) {
162
+    return function(...args) {
163
+        return new Promise((resolve, reject) => {
164
+
165
+            if (args.length <= beforeCallbacks + afterCallbacks) {
166
+                args.splice(beforeCallbacks, 0, resolve, reject);
167
+            }
168
+
169
+            let fPromise;
170
+
171
+            try {
172
+                // eslint-disable-next-line no-invalid-this
173
+                fPromise = f.apply(this, args);
174
+            } catch (e) {
175
+                reject(e);
176
+            }
177
+
178
+            // If the super implementation returns a Promise from the deprecated
179
+            // invocation by any chance, try to make sense of it.
180
+            if (fPromise) {
181
+                const { then } = fPromise;
182
+
183
+                typeof then === 'function'
184
+                    && then.call(fPromise, resolve, reject);
185
+            }
186
+        });
187
+    };
188
+}
189
+
131 190
 /**
132 191
  * Adapts react-native-webrtc's {@link RTCPeerConnection#setRemoteDescription}
133 192
  * implementation which uses the deprecated, callback-based version to the

+ 6
- 3
react/features/base/lib-jitsi-meet/native/polyfills-webrtc.js Ver arquivo

@@ -15,15 +15,18 @@ import RTCPeerConnection from './RTCPeerConnection';
15 15
     if (typeof global.MediaStreamTrack === 'undefined') {
16 16
         global.MediaStreamTrack = MediaStreamTrack;
17 17
     }
18
+    if (typeof global.RTCIceCandidate === 'undefined') {
19
+        global.RTCIceCandidate = RTCIceCandidate;
20
+    }
21
+    if (typeof global.RTCPeerConnection === 'undefined') {
22
+        global.RTCPeerConnection = RTCPeerConnection;
23
+    }
18 24
     if (typeof global.webkitRTCPeerConnection === 'undefined') {
19 25
         global.webkitRTCPeerConnection = RTCPeerConnection;
20 26
     }
21 27
     if (typeof global.RTCSessionDescription === 'undefined') {
22 28
         global.RTCSessionDescription = RTCSessionDescription;
23 29
     }
24
-    if (typeof global.RTCIceCandidate === 'undefined') {
25
-        global.RTCIceCandidate = RTCIceCandidate;
26
-    }
27 30
 
28 31
     const navigator = global.navigator;
29 32
 

Carregando…
Cancelar
Salvar