react-native-altibbi 0.1.0
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/LICENSE +20 -0
- package/README.md +190 -0
- package/android/build.gradle +104 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/altibbi/AltibbiModule.kt +18 -0
- package/android/src/main/java/com/altibbi/AltibbiPackage.kt +18 -0
- package/android/src/main/java/com/altibbi/OTCustomAudioDevice.java +1146 -0
- package/android/src/main/java/com/altibbi/OTPublisherLayout.java +61 -0
- package/android/src/main/java/com/altibbi/OTPublisherViewManager.java +30 -0
- package/android/src/main/java/com/altibbi/OTRN.java +101 -0
- package/android/src/main/java/com/altibbi/OTScreenCapturer.java +120 -0
- package/android/src/main/java/com/altibbi/OTSessionManager.java +1281 -0
- package/android/src/main/java/com/altibbi/OTSubscriberLayout.java +68 -0
- package/android/src/main/java/com/altibbi/OTSubscriberViewManager.java +30 -0
- package/android/src/main/java/com/altibbi/Socket.kt +294 -0
- package/android/src/main/java/com/altibbi/SocketEventEmitter.kt +25 -0
- package/android/src/main/java/com/altibbi/utils/EventUtils.java +189 -0
- package/android/src/main/java/com/altibbi/utils/Utils.java +135 -0
- package/ios/Altibbi-Bridging-Header.h +6 -0
- package/ios/Altibbi.mm +10 -0
- package/ios/Altibbi.swift +4 -0
- package/ios/OTCustomAudioDriver.swift +696 -0
- package/ios/OTPublisher.m +16 -0
- package/ios/OTPublisherManager.swift +21 -0
- package/ios/OTPublisherView.swift +28 -0
- package/ios/OTRN.swift +27 -0
- package/ios/OTScreenCapture.h +27 -0
- package/ios/OTScreenCapture.m +171 -0
- package/ios/OTSessionManager.m +127 -0
- package/ios/OTSessionManager.swift +866 -0
- package/ios/OTSubscriber.m +15 -0
- package/ios/OTSubscriberManager.swift +21 -0
- package/ios/OTSubscriberView.swift +29 -0
- package/ios/OpenTokReactNative.h +13 -0
- package/ios/OpenTokReactNative.m +13 -0
- package/ios/SocketReactNative.m +38 -0
- package/ios/SocketReactNative.swift +276 -0
- package/ios/Utils/EventUtils.swift +143 -0
- package/ios/Utils/Utils.swift +126 -0
- package/lib/commonjs/connection.js +200 -0
- package/lib/commonjs/connection.js.map +1 -0
- package/lib/commonjs/data.js +12 -0
- package/lib/commonjs/data.js.map +1 -0
- package/lib/commonjs/index.js +275 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/scoket.js +245 -0
- package/lib/commonjs/scoket.js.map +1 -0
- package/lib/commonjs/service.js +21 -0
- package/lib/commonjs/service.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/video/OT.js +57 -0
- package/lib/commonjs/video/OT.js.map +1 -0
- package/lib/commonjs/video/OTError.js +17 -0
- package/lib/commonjs/video/OTError.js.map +1 -0
- package/lib/commonjs/video/OTPublisher.js +171 -0
- package/lib/commonjs/video/OTPublisher.js.map +1 -0
- package/lib/commonjs/video/OTSession.js +205 -0
- package/lib/commonjs/video/OTSession.js.map +1 -0
- package/lib/commonjs/video/OTSubscriber.js +185 -0
- package/lib/commonjs/video/OTSubscriber.js.map +1 -0
- package/lib/commonjs/video/contexts/OTContext.js +11 -0
- package/lib/commonjs/video/contexts/OTContext.js.map +1 -0
- package/lib/commonjs/video/helpers/OTHelper.js +92 -0
- package/lib/commonjs/video/helpers/OTHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTPublisherHelper.js +117 -0
- package/lib/commonjs/video/helpers/OTPublisherHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTSessionHelper.js +206 -0
- package/lib/commonjs/video/helpers/OTSessionHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTSubscriberHelper.js +121 -0
- package/lib/commonjs/video/helpers/OTSubscriberHelper.js.map +1 -0
- package/lib/commonjs/video/index.js +42 -0
- package/lib/commonjs/video/index.js.map +1 -0
- package/lib/commonjs/video/views/OTPublisherView.js +26 -0
- package/lib/commonjs/video/views/OTPublisherView.js.map +1 -0
- package/lib/commonjs/video/views/OTSubscriberView.js +25 -0
- package/lib/commonjs/video/views/OTSubscriberView.js.map +1 -0
- package/lib/module/connection.js +180 -0
- package/lib/module/connection.js.map +1 -0
- package/lib/module/data.js +6 -0
- package/lib/module/data.js.map +1 -0
- package/lib/module/index.js +12 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/scoket.js +235 -0
- package/lib/module/scoket.js.map +1 -0
- package/lib/module/service.js +14 -0
- package/lib/module/service.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/video/OT.js +49 -0
- package/lib/module/video/OT.js.map +1 -0
- package/lib/module/video/OTError.js +10 -0
- package/lib/module/video/OTError.js.map +1 -0
- package/lib/module/video/OTPublisher.js +162 -0
- package/lib/module/video/OTPublisher.js.map +1 -0
- package/lib/module/video/OTSession.js +195 -0
- package/lib/module/video/OTSession.js.map +1 -0
- package/lib/module/video/OTSubscriber.js +175 -0
- package/lib/module/video/OTSubscriber.js.map +1 -0
- package/lib/module/video/contexts/OTContext.js +4 -0
- package/lib/module/video/contexts/OTContext.js.map +1 -0
- package/lib/module/video/helpers/OTHelper.js +82 -0
- package/lib/module/video/helpers/OTHelper.js.map +1 -0
- package/lib/module/video/helpers/OTPublisherHelper.js +110 -0
- package/lib/module/video/helpers/OTPublisherHelper.js.map +1 -0
- package/lib/module/video/helpers/OTSessionHelper.js +195 -0
- package/lib/module/video/helpers/OTSessionHelper.js.map +1 -0
- package/lib/module/video/helpers/OTSubscriberHelper.js +112 -0
- package/lib/module/video/helpers/OTSubscriberHelper.js.map +1 -0
- package/lib/module/video/index.js +7 -0
- package/lib/module/video/index.js.map +1 -0
- package/lib/module/video/views/OTPublisherView.js +18 -0
- package/lib/module/video/views/OTPublisherView.js.map +1 -0
- package/lib/module/video/views/OTSubscriberView.js +17 -0
- package/lib/module/video/views/OTSubscriberView.js.map +1 -0
- package/lib/typescript/src/connection.d.ts +40 -0
- package/lib/typescript/src/connection.d.ts.map +1 -0
- package/lib/typescript/src/data.d.ts +7 -0
- package/lib/typescript/src/data.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +12 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/scoket.d.ts +100 -0
- package/lib/typescript/src/scoket.d.ts.map +1 -0
- package/lib/typescript/src/service.d.ts +9 -0
- package/lib/typescript/src/service.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +22 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +178 -0
- package/react-native-altibbi.podspec +46 -0
- package/src/connection.ts +255 -0
- package/src/data.ts +21 -0
- package/src/index.tsx +80 -0
- package/src/scoket.ts +365 -0
- package/src/service.ts +20 -0
- package/src/types.ts +22 -0
- package/src/video/OT.js +65 -0
- package/src/video/OTError.js +14 -0
- package/src/video/OTPublisher.js +193 -0
- package/src/video/OTSession.js +168 -0
- package/src/video/OTSubscriber.js +148 -0
- package/src/video/contexts/OTContext.js +5 -0
- package/src/video/helpers/OTHelper.js +91 -0
- package/src/video/helpers/OTPublisherHelper.js +122 -0
- package/src/video/helpers/OTSessionHelper.js +233 -0
- package/src/video/helpers/OTSubscriberHelper.js +125 -0
- package/src/video/index.js +13 -0
- package/src/video/views/OTPublisherView.js +19 -0
- package/src/video/views/OTSubscriberView.js +18 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
package com.altibbi;
|
|
2
|
+
|
|
3
|
+
import android.opengl.GLSurfaceView;
|
|
4
|
+
import android.view.ViewGroup;
|
|
5
|
+
import android.widget.FrameLayout;
|
|
6
|
+
|
|
7
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
8
|
+
import com.opentok.android.BaseVideoRenderer;
|
|
9
|
+
import com.opentok.android.Session;
|
|
10
|
+
import com.opentok.android.Subscriber;
|
|
11
|
+
|
|
12
|
+
import java.util.concurrent.ConcurrentHashMap;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
public class OTSubscriberLayout extends FrameLayout{
|
|
17
|
+
|
|
18
|
+
public OTRN sharedState;
|
|
19
|
+
|
|
20
|
+
public OTSubscriberLayout(ThemedReactContext reactContext) {
|
|
21
|
+
|
|
22
|
+
super(reactContext);
|
|
23
|
+
sharedState = OTRN.getSharedState();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public void createSubscriberView(String streamId) {
|
|
27
|
+
|
|
28
|
+
ConcurrentHashMap<String, Subscriber> mSubscribers = sharedState.getSubscribers();
|
|
29
|
+
ConcurrentHashMap<String, String> androidOnTopMap = sharedState.getAndroidOnTopMap();
|
|
30
|
+
ConcurrentHashMap<String, String> androidZOrderMap = sharedState.getAndroidZOrderMap();
|
|
31
|
+
Subscriber mSubscriber = mSubscribers.get(streamId);
|
|
32
|
+
FrameLayout mSubscriberViewContainer = new FrameLayout(getContext());
|
|
33
|
+
String pubOrSub = "";
|
|
34
|
+
String zOrder = "";
|
|
35
|
+
if (mSubscriber != null) {
|
|
36
|
+
Session session = mSubscriber.getSession();
|
|
37
|
+
if (session != null) {
|
|
38
|
+
String sessionId = session.getSessionId();
|
|
39
|
+
if (sessionId != null) {
|
|
40
|
+
if (androidOnTopMap.get(sessionId) != null) {
|
|
41
|
+
pubOrSub = androidOnTopMap.get(sessionId);
|
|
42
|
+
}
|
|
43
|
+
if (androidZOrderMap.get(sessionId) != null) {
|
|
44
|
+
zOrder = androidZOrderMap.get(sessionId);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (mSubscriber.getView().getParent() != null) {
|
|
49
|
+
((ViewGroup)mSubscriber.getView().getParent()).removeView(mSubscriber.getView());
|
|
50
|
+
}
|
|
51
|
+
mSubscriber.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE,
|
|
52
|
+
BaseVideoRenderer.STYLE_VIDEO_FILL);
|
|
53
|
+
if (pubOrSub.equals("subscriber") && mSubscriber.getView() instanceof GLSurfaceView) {
|
|
54
|
+
if (zOrder.equals("mediaOverlay")) {
|
|
55
|
+
((GLSurfaceView) mSubscriber.getView()).setZOrderMediaOverlay(true);
|
|
56
|
+
} else {
|
|
57
|
+
((GLSurfaceView) mSubscriber.getView()).setZOrderOnTop(true);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
ConcurrentHashMap<String, FrameLayout> mSubscriberViewContainers = sharedState.getSubscriberViewContainers();
|
|
61
|
+
mSubscriberViewContainers.put(streamId, mSubscriberViewContainer);
|
|
62
|
+
addView(mSubscriberViewContainer, 0);
|
|
63
|
+
mSubscriberViewContainer.addView(mSubscriber.getView());
|
|
64
|
+
requestLayout();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package com.altibbi;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
5
|
+
import com.facebook.react.uimanager.ViewGroupManager;
|
|
6
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
public class OTSubscriberViewManager extends ViewGroupManager<OTSubscriberLayout> {
|
|
10
|
+
|
|
11
|
+
@Override
|
|
12
|
+
public String getName() {
|
|
13
|
+
|
|
14
|
+
return this.getClass().getSimpleName();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Override
|
|
18
|
+
protected OTSubscriberLayout createViewInstance(ThemedReactContext reactContext) {
|
|
19
|
+
|
|
20
|
+
return new OTSubscriberLayout(reactContext);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@ReactProp(name = "streamId")
|
|
24
|
+
public void setStreamId(OTSubscriberLayout view, String streamId) {
|
|
25
|
+
if (streamId != null) {
|
|
26
|
+
view.createSubscriberView(streamId);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
package com.altibbi
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.facebook.react.bridge.*
|
|
5
|
+
import com.google.gson.Gson
|
|
6
|
+
import com.pusher.client.ChannelAuthorizer
|
|
7
|
+
import com.pusher.client.Pusher
|
|
8
|
+
import com.pusher.client.PusherOptions
|
|
9
|
+
import com.pusher.client.channel.*
|
|
10
|
+
import com.pusher.client.connection.ConnectionEventListener
|
|
11
|
+
import com.pusher.client.connection.ConnectionState
|
|
12
|
+
import com.pusher.client.connection.ConnectionStateChange
|
|
13
|
+
import com.pusher.client.util.HttpChannelAuthorizer
|
|
14
|
+
import java.net.InetSocketAddress
|
|
15
|
+
import java.net.Proxy
|
|
16
|
+
import java.util.concurrent.Semaphore
|
|
17
|
+
|
|
18
|
+
class Socket(reactContext: ReactApplicationContext) :
|
|
19
|
+
ReactContextBaseJavaModule(reactContext),
|
|
20
|
+
ConnectionEventListener, ChannelEventListener, SubscriptionEventListener,
|
|
21
|
+
PrivateChannelEventListener, PrivateEncryptedChannelEventListener, PresenceChannelEventListener,
|
|
22
|
+
ChannelAuthorizer {
|
|
23
|
+
|
|
24
|
+
private var pusher: Pusher? = null
|
|
25
|
+
private val TAG = "SocketReactNative"
|
|
26
|
+
private val authorizerMutex = mutableMapOf<String, Semaphore>()
|
|
27
|
+
private val authorizerResult = mutableMapOf<String, ReadableMap>()
|
|
28
|
+
|
|
29
|
+
private val socketEventEmitter = SocketEventEmitter(reactContext)
|
|
30
|
+
|
|
31
|
+
override fun getName(): String {
|
|
32
|
+
return "SocketReactNative"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
fun addListener(eventName: String?) {
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@ReactMethod
|
|
41
|
+
fun removeListeners(count: Int?) {
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@ReactMethod
|
|
46
|
+
fun initialize(
|
|
47
|
+
arguments: ReadableMap,
|
|
48
|
+
promise:Promise
|
|
49
|
+
){
|
|
50
|
+
try {
|
|
51
|
+
if (pusher != null) {
|
|
52
|
+
pusher!!.disconnect()
|
|
53
|
+
}
|
|
54
|
+
val options = PusherOptions()
|
|
55
|
+
if (arguments.hasKey("cluster")) options.setCluster(arguments.getString("cluster"))
|
|
56
|
+
if (arguments.hasKey("useTLS")) options.isUseTLS =
|
|
57
|
+
arguments.getBoolean("useTLS")
|
|
58
|
+
if (arguments.hasKey("activityTimeout")) options.activityTimeout =
|
|
59
|
+
arguments.getInt("activityTimeout").toLong()
|
|
60
|
+
if (arguments.hasKey("pongTimeout")) options.pongTimeout =
|
|
61
|
+
arguments.getInt("pongTimeout").toLong()
|
|
62
|
+
if (arguments.hasKey("maxReconnectionAttempts")) options.maxReconnectionAttempts =
|
|
63
|
+
arguments.getInt("maxReconnectionAttempts")
|
|
64
|
+
if (arguments.hasKey("maxReconnectGapInSeconds")) options.maxReconnectGapInSeconds =
|
|
65
|
+
arguments.getInt("maxReconnectGapInSeconds")
|
|
66
|
+
if (arguments.hasKey("authEndpoint")) options.channelAuthorizer =
|
|
67
|
+
HttpChannelAuthorizer(arguments.getString("authEndpoint"))
|
|
68
|
+
if (arguments.hasKey("authorizer") && arguments.getBoolean("authorizer")) options.channelAuthorizer =
|
|
69
|
+
this
|
|
70
|
+
if (arguments.hasKey("proxy")) {
|
|
71
|
+
val (host, port) = arguments.getString("proxy")!!.split(':')
|
|
72
|
+
options.proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port.toInt()))
|
|
73
|
+
}
|
|
74
|
+
pusher = Pusher(arguments.getString("apiKey"), options)
|
|
75
|
+
Log.i(TAG, "Start $pusher")
|
|
76
|
+
promise.resolve(null)
|
|
77
|
+
}catch (e : Exception){
|
|
78
|
+
promise.reject(TAG,e.message,null)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@ReactMethod
|
|
83
|
+
fun connect(promise: Promise) {
|
|
84
|
+
pusher!!.connect(this, ConnectionState.ALL)
|
|
85
|
+
promise.resolve(null)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@ReactMethod
|
|
89
|
+
fun disconnect(promise: Promise) {
|
|
90
|
+
pusher!!.disconnect()
|
|
91
|
+
promise.resolve(null)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@ReactMethod
|
|
95
|
+
fun subscribe(channelName: String, promise: Promise) {
|
|
96
|
+
try{
|
|
97
|
+
val channel = when {
|
|
98
|
+
channelName.startsWith("private-encrypted-") -> pusher!!.subscribePrivateEncrypted(
|
|
99
|
+
channelName, this
|
|
100
|
+
)
|
|
101
|
+
channelName.startsWith("private-") -> pusher!!.subscribePrivate(channelName, this)
|
|
102
|
+
channelName.startsWith("presence-") -> pusher!!.subscribePresence(
|
|
103
|
+
channelName, this
|
|
104
|
+
)
|
|
105
|
+
else -> pusher!!.subscribe(channelName, this)
|
|
106
|
+
}
|
|
107
|
+
channel.bindGlobal(this)
|
|
108
|
+
promise.resolve(null)
|
|
109
|
+
}catch (e: Exception){
|
|
110
|
+
promise.reject("Error", "Failed to subscribe to channel: $channelName", e)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@ReactMethod
|
|
115
|
+
fun unsubscribe(channelName: String, promise: Promise) {
|
|
116
|
+
pusher!!.unsubscribe(channelName)
|
|
117
|
+
promise.resolve(null)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@ReactMethod
|
|
121
|
+
fun trigger(channelName: String, eventName: String, data: String, promise: Promise) {
|
|
122
|
+
try {
|
|
123
|
+
when {
|
|
124
|
+
channelName.startsWith("private-encrypted-") -> throw Exception("It's not currently possible to send a message using private encrypted channels.")
|
|
125
|
+
channelName.startsWith("private-") -> pusher!!.getPrivateChannel(channelName)
|
|
126
|
+
.trigger(eventName, data)
|
|
127
|
+
channelName.startsWith("presence-") -> pusher!!.getPresenceChannel(channelName)
|
|
128
|
+
.trigger(eventName, data)
|
|
129
|
+
else -> throw Exception("Messages can only be sent to private and presence channels.")
|
|
130
|
+
}
|
|
131
|
+
promise.resolve(null)
|
|
132
|
+
} catch (e: Exception) {
|
|
133
|
+
promise.reject(e)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@ReactMethod
|
|
138
|
+
fun getSocketId(promise: Promise) {
|
|
139
|
+
val socketId = pusher!!.connection.socketId
|
|
140
|
+
promise.resolve(socketId)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
override fun authorize(channelName: String, socketId: String): String? {
|
|
145
|
+
socketEventEmitter.emit(
|
|
146
|
+
"onAuthorizer", mapOf(
|
|
147
|
+
"channelName" to channelName,
|
|
148
|
+
"socketId" to socketId
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
val key = channelName + socketId
|
|
152
|
+
authorizerMutex[key] = Semaphore(0)
|
|
153
|
+
authorizerMutex[key]!!.acquire()
|
|
154
|
+
val authParams = authorizerResult.remove(key)!!
|
|
155
|
+
val gson = Gson()
|
|
156
|
+
return gson.toJson(authParams.toHashMap())
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@ReactMethod
|
|
160
|
+
fun onAuthorizer(channelName: String, socketId: String, data: ReadableMap, promise: Promise) {
|
|
161
|
+
val key = channelName + socketId
|
|
162
|
+
authorizerResult[key] = data
|
|
163
|
+
authorizerMutex[key]!!.release()
|
|
164
|
+
authorizerMutex.remove(key)
|
|
165
|
+
promise.resolve(null)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
override fun onConnectionStateChange(change: ConnectionStateChange?) {
|
|
170
|
+
socketEventEmitter.emit("onConnectionStateChange", mapOf(
|
|
171
|
+
"previousState" to change?.previousState.toString(),
|
|
172
|
+
"currentState" to change?.currentState.toString()
|
|
173
|
+
))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
override fun onError(message: String?, code: String?, e: Exception?) {
|
|
177
|
+
socketEventEmitter.emit(
|
|
178
|
+
"onError", mapOf(
|
|
179
|
+
"message" to message,
|
|
180
|
+
"code" to code,
|
|
181
|
+
"error" to e.toString()
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
override fun onError(message: String, e: Exception) {
|
|
187
|
+
onError(message, "", e)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
override fun onEvent(event: PusherEvent) {
|
|
191
|
+
// The java sdk transforms some events from pusher_internal
|
|
192
|
+
// to pusher:... events, we translate them back.
|
|
193
|
+
val finalEvent = if (event.eventName === "pusher:subscription_count") {
|
|
194
|
+
PusherEvent(
|
|
195
|
+
"pusher_internal:subscription_count",
|
|
196
|
+
event.channelName,
|
|
197
|
+
event.userId,
|
|
198
|
+
event.data)
|
|
199
|
+
} else {
|
|
200
|
+
event
|
|
201
|
+
}
|
|
202
|
+
socketEventEmitter.emit(
|
|
203
|
+
"onEvent", mapOf(
|
|
204
|
+
"channelName" to finalEvent.channelName,
|
|
205
|
+
"eventName" to finalEvent.eventName,
|
|
206
|
+
"userId" to finalEvent.userId,
|
|
207
|
+
"data" to finalEvent.data
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
override fun onSubscriptionSucceeded(channelName: String) {
|
|
213
|
+
// For presence channels we wait for the onUsersInformationReceived event.
|
|
214
|
+
if (!channelName.startsWith("presence-")) {
|
|
215
|
+
socketEventEmitter.emit(
|
|
216
|
+
"onEvent", mapOf(
|
|
217
|
+
"channelName" to channelName,
|
|
218
|
+
"eventName" to "pusher_internal:subscription_succeeded",
|
|
219
|
+
"data" to emptyMap<String, String>()
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
override fun onAuthenticationFailure(message: String, e: Exception) {
|
|
226
|
+
socketEventEmitter.emit(
|
|
227
|
+
"onSubscriptionError", mapOf(
|
|
228
|
+
"message" to message,
|
|
229
|
+
"error" to e.toString()
|
|
230
|
+
)
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
override fun onUsersInformationReceived(channelName: String?, users: MutableSet<User>?) {
|
|
235
|
+
val gson = Gson()
|
|
236
|
+
val channel = pusher!!.getPresenceChannel(channelName)
|
|
237
|
+
val hash = mutableMapOf<String, Any?>()
|
|
238
|
+
// convert users back to original structure.
|
|
239
|
+
for (user in users!!) {
|
|
240
|
+
hash[user.id] = gson.fromJson(user.info, Map::class.java)
|
|
241
|
+
}
|
|
242
|
+
val data = mapOf(
|
|
243
|
+
"presence" to mapOf(
|
|
244
|
+
"count" to users.size,
|
|
245
|
+
"ids" to users.map { it.id },
|
|
246
|
+
"hash" to hash
|
|
247
|
+
)
|
|
248
|
+
)
|
|
249
|
+
socketEventEmitter.emit(
|
|
250
|
+
"onEvent", mapOf(
|
|
251
|
+
"channelName" to channelName,
|
|
252
|
+
"eventName" to "pusher_internal:subscription_succeeded",
|
|
253
|
+
"userId" to channel.me.id,
|
|
254
|
+
"data" to data
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
override fun userSubscribed(channelName: String, user: User) {
|
|
260
|
+
val gson = Gson()
|
|
261
|
+
socketEventEmitter.emit(
|
|
262
|
+
"onMemberAdded", mapOf(
|
|
263
|
+
"channelName" to channelName,
|
|
264
|
+
"user" to mapOf(
|
|
265
|
+
"userId" to user.id,
|
|
266
|
+
"userInfo" to gson.fromJson(user.info, Map::class.java)
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
override fun userUnsubscribed(channelName: String, user: User) {
|
|
273
|
+
val gson = Gson()
|
|
274
|
+
socketEventEmitter.emit(
|
|
275
|
+
"onMemberRemoved", mapOf(
|
|
276
|
+
"channelName" to channelName,
|
|
277
|
+
"user" to mapOf(
|
|
278
|
+
"userId" to user.id,
|
|
279
|
+
"userInfo" to gson.fromJson(user.info, Map::class.java)
|
|
280
|
+
)
|
|
281
|
+
)
|
|
282
|
+
)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
override fun onDecryptionFailure(event: String?, reason: String?) {
|
|
286
|
+
socketEventEmitter.emit(
|
|
287
|
+
"onDecryptionFailure", mapOf(
|
|
288
|
+
"event" to event,
|
|
289
|
+
"reason" to reason
|
|
290
|
+
)
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.altibbi
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
6
|
+
|
|
7
|
+
class SocketEventEmitter (private val context: ReactApplicationContext) {
|
|
8
|
+
|
|
9
|
+
companion object {
|
|
10
|
+
private const val EVENT_PREFIX = "SocketReactNative"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fun emit(eventName: String, params: Any?) {
|
|
14
|
+
val jsModule = this.context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
15
|
+
val socketEventName = "${EVENT_PREFIX}:${eventName}"
|
|
16
|
+
|
|
17
|
+
if (params is Map<*, *>) {
|
|
18
|
+
jsModule.emit(socketEventName, Arguments.makeNativeMap(params as Map<String, Any>))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (params is String) {
|
|
22
|
+
jsModule.emit(socketEventName, params)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
package com.altibbi.utils;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments;
|
|
4
|
+
import com.facebook.react.bridge.WritableArray;
|
|
5
|
+
import com.facebook.react.bridge.WritableMap;
|
|
6
|
+
import com.opentok.android.Connection;
|
|
7
|
+
import com.opentok.android.MediaUtils;
|
|
8
|
+
import com.opentok.android.OpentokError;
|
|
9
|
+
import com.opentok.android.PublisherKit;
|
|
10
|
+
import com.opentok.android.Session;
|
|
11
|
+
import com.opentok.android.Stream;
|
|
12
|
+
import com.opentok.android.SubscriberKit;
|
|
13
|
+
|
|
14
|
+
public final class EventUtils {
|
|
15
|
+
|
|
16
|
+
public static WritableMap prepareJSConnectionMap(Connection connection) {
|
|
17
|
+
|
|
18
|
+
WritableMap connectionInfo = Arguments.createMap();
|
|
19
|
+
if (connection != null) {
|
|
20
|
+
connectionInfo.putString("connectionId", connection.getConnectionId());
|
|
21
|
+
connectionInfo.putString("creationTime", connection.getCreationTime().toString());
|
|
22
|
+
connectionInfo.putString("data", connection.getData());
|
|
23
|
+
}
|
|
24
|
+
return connectionInfo;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public static WritableMap prepareJSStreamMap(Stream stream, Session session) {
|
|
28
|
+
|
|
29
|
+
WritableMap streamInfo = Arguments.createMap();
|
|
30
|
+
if (stream != null) {
|
|
31
|
+
streamInfo.putString("streamId", stream.getStreamId());
|
|
32
|
+
streamInfo.putInt("height", stream.getVideoHeight());
|
|
33
|
+
streamInfo.putInt("width", stream.getVideoWidth());
|
|
34
|
+
streamInfo.putString("creationTime", stream.getCreationTime().toString());
|
|
35
|
+
streamInfo.putString("connectionId", stream.getConnection().getConnectionId());
|
|
36
|
+
streamInfo.putString("sessionId", session.getSessionId());
|
|
37
|
+
streamInfo.putMap("connection", prepareJSConnectionMap(stream.getConnection()));
|
|
38
|
+
streamInfo.putString("name", stream.getName());
|
|
39
|
+
streamInfo.putBoolean("hasAudio", stream.hasAudio());
|
|
40
|
+
streamInfo.putBoolean("hasVideo", stream.hasVideo());
|
|
41
|
+
if (stream.getStreamVideoType().equals(Stream.StreamVideoType.StreamVideoTypeScreen)) {
|
|
42
|
+
streamInfo.putString("videoType", "screen");
|
|
43
|
+
} else {
|
|
44
|
+
streamInfo.putString("videoType", "camera");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return streamInfo;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public static WritableMap prepareJSErrorMap(OpentokError error) {
|
|
51
|
+
|
|
52
|
+
WritableMap errorInfo = Arguments.createMap();
|
|
53
|
+
errorInfo.putString("message", error.getMessage());
|
|
54
|
+
errorInfo.putString("code", error.getErrorCode().toString());
|
|
55
|
+
return errorInfo;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static WritableMap prepareJSSessionMap(Session session) {
|
|
59
|
+
|
|
60
|
+
WritableMap sessionInfo = Arguments.createMap();
|
|
61
|
+
sessionInfo.putString("sessionId", session.getSessionId());
|
|
62
|
+
if (session.getConnection() != null) {
|
|
63
|
+
WritableMap connectionInfo = prepareJSConnectionMap(session.getConnection());
|
|
64
|
+
sessionInfo.putMap("connection", connectionInfo);
|
|
65
|
+
}
|
|
66
|
+
return sessionInfo;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public static WritableMap prepareStreamPropertyChangedEventData(String changedProperty, String oldValue, String newValue, Stream stream, Session session) {
|
|
70
|
+
|
|
71
|
+
WritableMap streamPropertyEventData = Arguments.createMap();
|
|
72
|
+
streamPropertyEventData.putString("changedProperty", changedProperty);
|
|
73
|
+
streamPropertyEventData.putString("oldValue", oldValue);
|
|
74
|
+
streamPropertyEventData.putString("newValue", newValue);
|
|
75
|
+
streamPropertyEventData.putMap("stream", prepareJSStreamMap(stream, session));
|
|
76
|
+
return streamPropertyEventData;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static WritableMap prepareStreamPropertyChangedEventData(String changedProperty, WritableMap oldValue, WritableMap newValue, Stream stream, Session session) {
|
|
80
|
+
|
|
81
|
+
WritableMap streamPropertyEventData = Arguments.createMap();
|
|
82
|
+
streamPropertyEventData.putString("changedProperty", changedProperty);
|
|
83
|
+
streamPropertyEventData.putMap("oldValue", oldValue);
|
|
84
|
+
streamPropertyEventData.putMap("newValue", newValue);
|
|
85
|
+
streamPropertyEventData.putMap("stream", prepareJSStreamMap(stream, session));
|
|
86
|
+
return streamPropertyEventData;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public static WritableMap prepareStreamPropertyChangedEventData(String changedProperty, Boolean oldValue, Boolean newValue, Stream stream, Session session) {
|
|
90
|
+
|
|
91
|
+
WritableMap streamPropertyEventData = Arguments.createMap();
|
|
92
|
+
streamPropertyEventData.putString("changedProperty", changedProperty);
|
|
93
|
+
streamPropertyEventData.putBoolean("oldValue", oldValue);
|
|
94
|
+
streamPropertyEventData.putBoolean("newValue", newValue);
|
|
95
|
+
streamPropertyEventData.putMap("stream", prepareJSStreamMap(stream, session));
|
|
96
|
+
return streamPropertyEventData;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public static WritableMap prepareAudioNetworkStats(SubscriberKit.SubscriberAudioStats stats) {
|
|
100
|
+
|
|
101
|
+
WritableMap audioStats = Arguments.createMap();
|
|
102
|
+
audioStats.putInt("audioPacketsLost", stats.audioPacketsLost);
|
|
103
|
+
audioStats.putInt("audioBytesReceived", stats.audioBytesReceived);
|
|
104
|
+
audioStats.putInt("audioPacketsReceived", stats.audioPacketsReceived);
|
|
105
|
+
audioStats.putDouble("timestamp", stats.timeStamp);
|
|
106
|
+
return audioStats;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public static WritableMap prepareVideoNetworkStats(SubscriberKit.SubscriberVideoStats stats) {
|
|
110
|
+
|
|
111
|
+
WritableMap videoStats = Arguments.createMap();
|
|
112
|
+
videoStats.putInt("videoPacketsLost", stats.videoPacketsLost);
|
|
113
|
+
videoStats.putInt("videoBytesReceived", stats.videoBytesReceived);
|
|
114
|
+
videoStats.putInt("videoPacketsReceived", stats.videoPacketsReceived);
|
|
115
|
+
videoStats.putDouble("timestamp", stats.timeStamp);
|
|
116
|
+
return videoStats;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public static WritableArray preparePublisherRtcStats(PublisherKit.PublisherRtcStats[] stats) {
|
|
120
|
+
WritableArray statsArrayMap = Arguments.createArray();
|
|
121
|
+
for (PublisherKit.PublisherRtcStats stat : stats) {
|
|
122
|
+
WritableMap statMap = Arguments.createMap();
|
|
123
|
+
statMap.putString("connectionId", stat.connectionId);
|
|
124
|
+
statMap.putString("jsonArrayOfReports", stat.jsonArrayOfReports);
|
|
125
|
+
statsArrayMap.pushMap(statMap);
|
|
126
|
+
}
|
|
127
|
+
return statsArrayMap;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public static WritableArray preparePublisherAudioStats(PublisherKit.PublisherAudioStats[] stats) {
|
|
131
|
+
WritableArray statsArrayMap = Arguments.createArray();
|
|
132
|
+
for (PublisherKit.PublisherAudioStats stat : stats) {
|
|
133
|
+
WritableMap audioStats = Arguments.createMap();
|
|
134
|
+
audioStats.putString("connectionId", stat.connectionId);
|
|
135
|
+
audioStats.putString("subscriberId", stat.subscriberId);
|
|
136
|
+
audioStats.putDouble("audioBytesSent", stat.audioBytesSent);
|
|
137
|
+
audioStats.putDouble("audioPacketsLost", stat.audioPacketsLost);
|
|
138
|
+
audioStats.putDouble("audioPacketsSent", stat.audioPacketsSent);
|
|
139
|
+
audioStats.putDouble("startTime", stat.startTime);
|
|
140
|
+
statsArrayMap.pushMap(audioStats);
|
|
141
|
+
}
|
|
142
|
+
return statsArrayMap;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public static WritableArray preparePublisherVideoStats(PublisherKit.PublisherVideoStats[] stats) {
|
|
146
|
+
WritableArray statsArrayMap = Arguments.createArray();
|
|
147
|
+
for (PublisherKit.PublisherVideoStats stat : stats) {
|
|
148
|
+
WritableMap videoStats = Arguments.createMap();
|
|
149
|
+
videoStats.putString("connectionId", stat.connectionId);
|
|
150
|
+
videoStats.putString("subscriberId", stat.subscriberId);
|
|
151
|
+
videoStats.putDouble("videoBytesSent", stat.videoBytesSent);
|
|
152
|
+
videoStats.putDouble("videoPacketsLost", stat.videoPacketsLost);
|
|
153
|
+
videoStats.putDouble("videoPacketsSent", stat.videoPacketsSent);
|
|
154
|
+
videoStats.putDouble("startTime", stat.startTime);
|
|
155
|
+
statsArrayMap.pushMap(videoStats);
|
|
156
|
+
}
|
|
157
|
+
return statsArrayMap;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public static WritableMap prepareMediaCodecsMap(MediaUtils.SupportedCodecs supportedCodecs) {
|
|
161
|
+
WritableMap codecsMap = Arguments.createMap();
|
|
162
|
+
WritableArray videoDecoderCodecsArray = Arguments.createArray();
|
|
163
|
+
WritableArray videoEncoderCodecsArray = Arguments.createArray();
|
|
164
|
+
for (MediaUtils.VideoCodecType decoderCodec : supportedCodecs.videoDecoderCodecs ) {
|
|
165
|
+
if (decoderCodec.equals(MediaUtils.VideoCodecType.VIDEO_CODEC_H264)) {
|
|
166
|
+
videoDecoderCodecsArray.pushString("H.264");
|
|
167
|
+
} else {
|
|
168
|
+
videoDecoderCodecsArray.pushString("VP8");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (MediaUtils.VideoCodecType encoderCodec : supportedCodecs.videoEncoderCodecs ) {
|
|
172
|
+
if (encoderCodec.equals(MediaUtils.VideoCodecType.VIDEO_CODEC_H264)) {
|
|
173
|
+
videoEncoderCodecsArray.pushString("H.264");
|
|
174
|
+
} else {
|
|
175
|
+
videoEncoderCodecsArray.pushString("VP8");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
codecsMap.putArray("videoDecoderCodecs", videoDecoderCodecsArray);
|
|
179
|
+
codecsMap.putArray("videoEncoderCodecs", videoEncoderCodecsArray);
|
|
180
|
+
return codecsMap;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static WritableMap createError(String message) {
|
|
184
|
+
|
|
185
|
+
WritableMap errorInfo = Arguments.createMap();
|
|
186
|
+
errorInfo.putString("message", message);
|
|
187
|
+
return errorInfo;
|
|
188
|
+
}
|
|
189
|
+
}
|