@stream-io/video-react-native-sdk 1.29.2 → 1.29.3-beta.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/android/src/main/AndroidManifest.xml +8 -1
- package/android/src/main/AndroidManifestNew.xml +11 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +42 -5
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +70 -6
- package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +6 -4
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +149 -0
- package/dist/commonjs/hooks/push/index.js +0 -2
- package/dist/commonjs/hooks/push/index.js.map +1 -1
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +121 -0
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +64 -97
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/index.js +1 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/modules/call-manager/CallManager.js +26 -0
- package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
- package/dist/commonjs/providers/StreamCall/index.js +6 -6
- package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
- package/dist/commonjs/utils/StreamVideoRN/index.js +33 -21
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +58 -0
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +1 -0
- package/dist/commonjs/utils/internal/callingx/callingx.js +109 -0
- package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -0
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +52 -3
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/commonjs/utils/push/android.js +155 -202
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +17 -34
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -45
- package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/commonjs/utils/push/internal/utils.js +32 -20
- package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/utils/push/libs/callingx.js +75 -0
- package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
- package/dist/commonjs/utils/push/libs/index.js +8 -19
- package/dist/commonjs/utils/push/libs/index.js.map +1 -1
- package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
- package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/commonjs/utils/push/setupCallingExpEvents.js +108 -0
- package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/hooks/push/index.js +0 -2
- package/dist/module/hooks/push/index.js.map +1 -1
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +114 -0
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +66 -99
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/modules/call-manager/CallManager.js +26 -0
- package/dist/module/modules/call-manager/CallManager.js.map +1 -1
- package/dist/module/providers/StreamCall/index.js +6 -6
- package/dist/module/providers/StreamCall/index.js.map +1 -1
- package/dist/module/utils/StreamVideoRN/index.js +33 -21
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/callingx/audioSessionPromise.js +51 -0
- package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +1 -0
- package/dist/module/utils/internal/callingx/callingx.js +100 -0
- package/dist/module/utils/internal/callingx/callingx.js.map +1 -0
- package/dist/module/utils/internal/registerSDKGlobals.js +52 -3
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
- package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/module/utils/push/android.js +157 -204
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +17 -34
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/utils/push/internal/rxSubjects.js +0 -44
- package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/module/utils/push/internal/utils.js +29 -19
- package/dist/module/utils/push/internal/utils.js.map +1 -1
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/utils/push/libs/callingx.js +67 -0
- package/dist/module/utils/push/libs/callingx.js.map +1 -0
- package/dist/module/utils/push/libs/index.js +1 -2
- package/dist/module/utils/push/libs/index.js.map +1 -1
- package/dist/module/utils/push/libs/notifee/index.js +0 -18
- package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/module/utils/push/setupCallingExpEvents.js +102 -0
- package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/hooks/push/index.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
- package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/modules/call-manager/CallManager.d.ts +5 -0
- package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +20 -2
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +54 -29
- package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
- package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts +16 -0
- package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts.map +1 -0
- package/dist/typescript/utils/internal/callingx/callingx.d.ts +13 -0
- package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -0
- package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
- package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +10 -0
- package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
- package/dist/typescript/utils/push/android.d.ts +1 -2
- package/dist/typescript/utils/push/android.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/rxSubjects.d.ts +0 -33
- package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/utils.d.ts +8 -1
- package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts +1 -2
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
- package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +16 -2
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/index.d.ts +1 -2
- package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -0
- package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/expo-config-plugin/dist/withAndroidManifest.js +1 -33
- package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
- package/expo-config-plugin/dist/withAppDelegate.js +19 -197
- package/expo-config-plugin/dist/withMainActivity.js +1 -1
- package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
- package/ios/StreamInCallManager.m +2 -0
- package/ios/StreamInCallManager.swift +19 -7
- package/ios/StreamVideoReactNative.h +7 -4
- package/ios/StreamVideoReactNative.m +189 -82
- package/package.json +14 -19
- package/src/hooks/push/index.ts +0 -2
- package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +147 -0
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +94 -120
- package/src/index.ts +1 -0
- package/src/modules/call-manager/CallManager.ts +36 -0
- package/src/modules/call-manager/native-module.d.ts +7 -0
- package/src/providers/StreamCall/index.tsx +6 -6
- package/src/utils/StreamVideoRN/index.ts +40 -30
- package/src/utils/StreamVideoRN/types.ts +56 -29
- package/src/utils/internal/callingx/audioSessionPromise.ts +53 -0
- package/src/utils/internal/callingx/callingx.ts +146 -0
- package/src/utils/internal/registerSDKGlobals.ts +47 -4
- package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
- package/src/utils/push/android.ts +231 -309
- package/src/utils/push/internal/ios.ts +28 -44
- package/src/utils/push/internal/rxSubjects.ts +0 -61
- package/src/utils/push/internal/utils.ts +45 -26
- package/src/utils/push/ios.ts +1 -6
- package/src/utils/push/libs/callingx.ts +90 -0
- package/src/utils/push/libs/index.ts +1 -2
- package/src/utils/push/libs/notifee/index.ts +0 -27
- package/src/utils/push/setupCallingExpEvents.ts +130 -0
- package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -3133
- package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +0 -67
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +0 -1
- package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
- package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
- package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
- package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/module/hooks/push/useProcessPushCallEffect.js +0 -60
- package/dist/module/hooks/push/useProcessPushCallEffect.js.map +0 -1
- package/dist/module/utils/push/libs/callkeep.js +0 -11
- package/dist/module/utils/push/libs/callkeep.js.map +0 -1
- package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
- package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
- package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
- package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts +0 -8
- package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
- package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
- package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
- package/src/hooks/push/useProcessPushCallEffect.ts +0 -108
- package/src/utils/push/libs/callkeep.ts +0 -16
- package/src/utils/push/libs/voipPushNotification.ts +0 -17
- package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
package="com.streamvideo.reactnative">
|
|
3
3
|
|
|
4
4
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
|
-
<uses-permission android:name="android.permission.DEVICE_POWER" />
|
|
6
5
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
6
|
+
|
|
7
|
+
<application>
|
|
8
|
+
<service
|
|
9
|
+
android:name="com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService"
|
|
10
|
+
android:exported="false"
|
|
11
|
+
android:stopWithTask="true"
|
|
12
|
+
android:foregroundServiceType="mediaPlayback|camera|microphone" />
|
|
13
|
+
</application>
|
|
7
14
|
</manifest>
|
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
|
|
3
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
4
|
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
5
|
+
|
|
6
|
+
<application>
|
|
7
|
+
<service
|
|
8
|
+
android:name="com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService"
|
|
9
|
+
android:exported="false"
|
|
10
|
+
android:stopWithTask="true"
|
|
11
|
+
android:foregroundServiceType="mediaPlayback|camera|microphone" />
|
|
12
|
+
</application>
|
|
2
13
|
</manifest>
|
|
@@ -15,6 +15,7 @@ import android.os.Build
|
|
|
15
15
|
import android.os.PowerManager
|
|
16
16
|
import android.util.Base64
|
|
17
17
|
import android.util.Log
|
|
18
|
+
import androidx.core.content.ContextCompat
|
|
18
19
|
import com.facebook.react.bridge.Arguments
|
|
19
20
|
import com.facebook.react.bridge.Promise
|
|
20
21
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
@@ -23,8 +24,8 @@ import com.facebook.react.bridge.ReactMethod
|
|
|
23
24
|
import com.facebook.react.bridge.WritableMap
|
|
24
25
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
25
26
|
import com.oney.WebRTCModule.WebRTCModule
|
|
27
|
+
import com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService
|
|
26
28
|
import com.streamvideo.reactnative.util.CallAlivePermissionsHelper
|
|
27
|
-
import com.streamvideo.reactnative.util.CallAliveServiceChecker
|
|
28
29
|
import com.streamvideo.reactnative.util.PiPHelper
|
|
29
30
|
import com.streamvideo.reactnative.util.RingtoneUtil
|
|
30
31
|
import com.streamvideo.reactnative.util.YuvFrame
|
|
@@ -115,11 +116,47 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
115
116
|
promise.resolve(false)
|
|
116
117
|
return
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
// Service is declared in the SDK's own AndroidManifest and merged by default.
|
|
120
|
+
// Permissions are expected to be provided by the app (or via Expo config plugin).
|
|
121
|
+
promise.resolve(true)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@ReactMethod
|
|
126
|
+
fun startKeepCallAliveService(
|
|
127
|
+
callCid: String,
|
|
128
|
+
channelId: String,
|
|
129
|
+
channelName: String,
|
|
130
|
+
title: String,
|
|
131
|
+
body: String,
|
|
132
|
+
smallIconName: String?,
|
|
133
|
+
promise: Promise
|
|
134
|
+
) {
|
|
135
|
+
try {
|
|
136
|
+
val intent = StreamCallKeepAliveHeadlessService.buildStartIntent(
|
|
137
|
+
reactApplicationContext,
|
|
138
|
+
callCid,
|
|
139
|
+
channelId,
|
|
140
|
+
channelName,
|
|
141
|
+
title,
|
|
142
|
+
body,
|
|
143
|
+
smallIconName
|
|
144
|
+
)
|
|
145
|
+
ContextCompat.startForegroundService(reactApplicationContext, intent)
|
|
122
146
|
promise.resolve(true)
|
|
147
|
+
} catch (e: Exception) {
|
|
148
|
+
promise.reject(NAME, "Failed to start keep call alive foreground service", e)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@ReactMethod
|
|
153
|
+
fun stopKeepCallAliveService(promise: Promise) {
|
|
154
|
+
try {
|
|
155
|
+
val intent = StreamCallKeepAliveHeadlessService.buildStopIntent(reactApplicationContext)
|
|
156
|
+
val stopped = reactApplicationContext.stopService(intent)
|
|
157
|
+
promise.resolve(stopped)
|
|
158
|
+
} catch (e: Exception) {
|
|
159
|
+
promise.reject(NAME, "Failed to stop keep call alive foreground service", e)
|
|
123
160
|
}
|
|
124
161
|
}
|
|
125
162
|
|
|
@@ -55,14 +55,78 @@ object WebRtcAudioUtils {
|
|
|
55
55
|
* what might be the root cause.
|
|
56
56
|
*/
|
|
57
57
|
fun logAudioState(tag: String, reactContext: ReactContext) {
|
|
58
|
+
Log.d(tag, getAudioStateLog(reactContext))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns a string containing information about the current audio state.
|
|
63
|
+
* Similar to logAudioState but returns the information instead of logging it.
|
|
64
|
+
*/
|
|
65
|
+
fun getAudioStateLog(reactContext: ReactContext): String {
|
|
66
|
+
val audioManager = reactContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
67
|
+
val sb = StringBuilder()
|
|
68
|
+
|
|
69
|
+
// Volume control stream
|
|
58
70
|
reactContext.currentActivity?.let {
|
|
59
|
-
|
|
71
|
+
sb.appendLine("volumeControlStream: ${streamTypeToString(it.volumeControlStream)}")
|
|
60
72
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
|
|
74
|
+
// Device info
|
|
75
|
+
sb.appendLine("Android SDK: ${Build.VERSION.SDK_INT}, Release: ${Build.VERSION.RELEASE}, Brand: ${Build.BRAND}, Device: ${Build.DEVICE}, Id: ${Build.ID}, Hardware: ${Build.HARDWARE}, Manufacturer: ${Build.MANUFACTURER}, Model: ${Build.MODEL}, Product: ${Build.PRODUCT}")
|
|
76
|
+
|
|
77
|
+
// Basic audio state
|
|
78
|
+
sb.appendLine("Audio State: audio mode: ${modeToString(audioManager.mode)}, has mic: ${hasMicrophone(reactContext)}, mic muted: ${audioManager.isMicrophoneMute}, music active: ${audioManager.isMusicActive}, speakerphone: ${audioManager.isSpeakerphoneOn}, BT SCO: ${audioManager.isBluetoothScoOn}")
|
|
79
|
+
|
|
80
|
+
// Volume info
|
|
81
|
+
val fixedVolume = audioManager.isVolumeFixed
|
|
82
|
+
sb.appendLine(" fixed volume=$fixedVolume")
|
|
83
|
+
if (!fixedVolume) {
|
|
84
|
+
val streams = intArrayOf(
|
|
85
|
+
AudioManager.STREAM_VOICE_CALL,
|
|
86
|
+
AudioManager.STREAM_MUSIC,
|
|
87
|
+
AudioManager.STREAM_RING,
|
|
88
|
+
AudioManager.STREAM_ALARM,
|
|
89
|
+
AudioManager.STREAM_NOTIFICATION,
|
|
90
|
+
AudioManager.STREAM_SYSTEM
|
|
91
|
+
)
|
|
92
|
+
for (stream in streams) {
|
|
93
|
+
val info = StringBuilder()
|
|
94
|
+
info.append(" ${streamTypeToString(stream)}: ")
|
|
95
|
+
info.append("volume=${audioManager.getStreamVolume(stream)}")
|
|
96
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
97
|
+
info.append(", min=${audioManager.getStreamMinVolume(stream)}")
|
|
98
|
+
}
|
|
99
|
+
info.append(", max=${audioManager.getStreamMaxVolume(stream)}")
|
|
100
|
+
info.append(", muted=${audioManager.isStreamMute(stream)}")
|
|
101
|
+
sb.appendLine(info.toString())
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Audio devices
|
|
106
|
+
val inputDevices = audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)
|
|
107
|
+
val outputDevices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
108
|
+
val devices = inputDevices + outputDevices
|
|
109
|
+
if (devices.isNotEmpty()) {
|
|
110
|
+
sb.appendLine("Audio Devices:")
|
|
111
|
+
for (device in devices) {
|
|
112
|
+
val info = StringBuilder()
|
|
113
|
+
info.append(" ${deviceTypeToString(device.type)}")
|
|
114
|
+
info.append(if (device.isSource) "(in): " else "(out): ")
|
|
115
|
+
if (device.channelCounts.isNotEmpty()) {
|
|
116
|
+
info.append("channels=${device.channelCounts.contentToString()}, ")
|
|
117
|
+
}
|
|
118
|
+
if (device.encodings.isNotEmpty()) {
|
|
119
|
+
info.append("encodings=${device.encodings.contentToString()}, ")
|
|
120
|
+
}
|
|
121
|
+
if (device.sampleRates.isNotEmpty()) {
|
|
122
|
+
info.append("sample rates=${device.sampleRates.contentToString()}, ")
|
|
123
|
+
}
|
|
124
|
+
info.append("id=${device.id}")
|
|
125
|
+
sb.appendLine(info.toString())
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return sb.toString()
|
|
66
130
|
}
|
|
67
131
|
|
|
68
132
|
/** Converts AudioDeviceInfo types to local string representation. */
|
package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt
CHANGED
|
@@ -168,10 +168,12 @@ class StreamInCallManagerModule(reactContext: ReactApplicationContext) :
|
|
|
168
168
|
|
|
169
169
|
@ReactMethod
|
|
170
170
|
fun logAudioState() {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
Log.d(TAG, getAudioStateLog())
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
175
|
+
fun getAudioStateLog(): String {
|
|
176
|
+
return WebRtcAudioUtils.getAudioStateLog(reactApplicationContext)
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
@Suppress("unused")
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
package com.streamvideo.reactnative.keepalive
|
|
2
|
+
|
|
3
|
+
import android.app.Notification
|
|
4
|
+
import android.app.NotificationChannel
|
|
5
|
+
import android.app.NotificationManager
|
|
6
|
+
import android.app.PendingIntent
|
|
7
|
+
import android.content.Context
|
|
8
|
+
import android.content.Intent
|
|
9
|
+
import android.content.pm.PackageManager
|
|
10
|
+
import android.os.Build
|
|
11
|
+
import androidx.core.app.NotificationCompat
|
|
12
|
+
|
|
13
|
+
internal object KeepAliveNotification {
|
|
14
|
+
private const val DEFAULT_CHANNEL_DESCRIPTION = "Stream call keep-alive"
|
|
15
|
+
|
|
16
|
+
fun ensureChannel(
|
|
17
|
+
context: Context,
|
|
18
|
+
channelId: String,
|
|
19
|
+
channelName: String
|
|
20
|
+
) {
|
|
21
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
|
22
|
+
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
23
|
+
val existing = manager.getNotificationChannel(channelId)
|
|
24
|
+
if (existing != null) return
|
|
25
|
+
|
|
26
|
+
val channel = NotificationChannel(
|
|
27
|
+
channelId,
|
|
28
|
+
channelName,
|
|
29
|
+
NotificationManager.IMPORTANCE_LOW
|
|
30
|
+
).apply {
|
|
31
|
+
description = DEFAULT_CHANNEL_DESCRIPTION
|
|
32
|
+
setShowBadge(false)
|
|
33
|
+
}
|
|
34
|
+
manager.createNotificationChannel(channel)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fun buildOngoingNotification(
|
|
38
|
+
context: Context,
|
|
39
|
+
channelId: String,
|
|
40
|
+
title: String,
|
|
41
|
+
body: String,
|
|
42
|
+
smallIconName: String?
|
|
43
|
+
): Notification {
|
|
44
|
+
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
|
|
45
|
+
val pendingIntentFlags =
|
|
46
|
+
PendingIntent.FLAG_UPDATE_CURRENT or
|
|
47
|
+
PendingIntent.FLAG_IMMUTABLE
|
|
48
|
+
val contentIntent = if (launchIntent != null) {
|
|
49
|
+
PendingIntent.getActivity(context, 0, launchIntent, pendingIntentFlags)
|
|
50
|
+
} else {
|
|
51
|
+
// Fallback: empty intent to avoid crash if launch activity is missing for some reason
|
|
52
|
+
PendingIntent.getActivity(context, 0, Intent(), pendingIntentFlags)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
val iconResId = resolveSmallIconResId(context, smallIconName)
|
|
56
|
+
return NotificationCompat.Builder(context, channelId)
|
|
57
|
+
.setContentTitle(title)
|
|
58
|
+
.setContentText(body)
|
|
59
|
+
.setOngoing(true)
|
|
60
|
+
.setOnlyAlertOnce(true)
|
|
61
|
+
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
62
|
+
.setContentIntent(contentIntent)
|
|
63
|
+
.setSmallIcon(iconResId)
|
|
64
|
+
.build()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private fun resolveSmallIconResId(context: Context, smallIconName: String?): Int {
|
|
68
|
+
val resources = context.resources
|
|
69
|
+
val packageName = context.packageName
|
|
70
|
+
if (!smallIconName.isNullOrBlank()) {
|
|
71
|
+
val id = resources.getIdentifier(smallIconName, "drawable", packageName)
|
|
72
|
+
if (id != 0) return id
|
|
73
|
+
}
|
|
74
|
+
// Default to the app icon
|
|
75
|
+
return try {
|
|
76
|
+
val appInfo = context.packageManager.getApplicationInfo(packageName, 0)
|
|
77
|
+
appInfo.icon
|
|
78
|
+
} catch (_: PackageManager.NameNotFoundException) {
|
|
79
|
+
android.R.drawable.ic_dialog_info
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
package com.streamvideo.reactnative.keepalive
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.content.pm.PackageManager
|
|
6
|
+
import android.content.pm.ServiceInfo
|
|
7
|
+
import android.os.Build
|
|
8
|
+
import android.util.Log
|
|
9
|
+
import androidx.annotation.RequiresApi
|
|
10
|
+
import androidx.core.app.ServiceCompat
|
|
11
|
+
import androidx.core.content.ContextCompat
|
|
12
|
+
import com.facebook.react.HeadlessJsTaskService
|
|
13
|
+
import com.facebook.react.bridge.Arguments
|
|
14
|
+
import com.facebook.react.jstasks.HeadlessJsTaskConfig
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Foreground service that runs a React Native HeadlessJS task to keep a call alive.
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
class StreamCallKeepAliveHeadlessService : HeadlessJsTaskService() {
|
|
21
|
+
|
|
22
|
+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
23
|
+
val safeIntent = intent ?: Intent()
|
|
24
|
+
val channelId = safeIntent.getStringExtra(EXTRA_CHANNEL_ID) ?: DEFAULT_CHANNEL_ID
|
|
25
|
+
val channelName = safeIntent.getStringExtra(EXTRA_CHANNEL_NAME) ?: DEFAULT_CHANNEL_NAME
|
|
26
|
+
val title = safeIntent.getStringExtra(EXTRA_TITLE) ?: DEFAULT_TITLE
|
|
27
|
+
val body = safeIntent.getStringExtra(EXTRA_BODY) ?: DEFAULT_BODY
|
|
28
|
+
val smallIconName = safeIntent.getStringExtra(EXTRA_SMALL_ICON_NAME)
|
|
29
|
+
|
|
30
|
+
KeepAliveNotification.ensureChannel(this, channelId, channelName)
|
|
31
|
+
val notification = KeepAliveNotification.buildOngoingNotification(
|
|
32
|
+
context = this,
|
|
33
|
+
channelId = channelId,
|
|
34
|
+
title = title,
|
|
35
|
+
body = body,
|
|
36
|
+
smallIconName = smallIconName
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
startForegroundCompat(notification)
|
|
40
|
+
|
|
41
|
+
// Ensure HeadlessJS task is started
|
|
42
|
+
return super.onStartCommand(safeIntent, flags, startId)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun getTaskConfig(intent: Intent?): HeadlessJsTaskConfig? {
|
|
46
|
+
val callCid = intent?.getStringExtra(EXTRA_CALL_CID) ?: return null
|
|
47
|
+
val data = Arguments.createMap().apply {
|
|
48
|
+
putString("callCid", callCid)
|
|
49
|
+
}
|
|
50
|
+
// We intentionally allow long-running work (the JS task can return a never-resolving Promise).
|
|
51
|
+
return HeadlessJsTaskConfig(
|
|
52
|
+
TASK_NAME,
|
|
53
|
+
data,
|
|
54
|
+
0, // timeout (0 = no timeout)
|
|
55
|
+
true // allowedInForeground
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
override fun onDestroy() {
|
|
60
|
+
super.onDestroy()
|
|
61
|
+
stopForeground(STOP_FOREGROUND_REMOVE)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@RequiresApi(Build.VERSION_CODES.R)
|
|
65
|
+
private fun computeForegroundServiceTypes(): Int {
|
|
66
|
+
var types = ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
67
|
+
|
|
68
|
+
val hasCameraPermission =
|
|
69
|
+
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
|
|
70
|
+
if (hasCameraPermission) {
|
|
71
|
+
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
val hasMicrophonePermission =
|
|
75
|
+
ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
|
|
76
|
+
if (hasMicrophonePermission) {
|
|
77
|
+
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return types
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private fun startForegroundCompat(notification: android.app.Notification) {
|
|
84
|
+
try {
|
|
85
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
86
|
+
val types =
|
|
87
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) computeForegroundServiceTypes()
|
|
88
|
+
else ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
89
|
+
startForeground(NOTIFICATION_ID, notification, types)
|
|
90
|
+
} else {
|
|
91
|
+
startForeground(NOTIFICATION_ID, notification)
|
|
92
|
+
}
|
|
93
|
+
} catch (e: Exception) {
|
|
94
|
+
// Avoid crashing the app if the system rejects starting a foreground service (e.g.
|
|
95
|
+
// background start restrictions, invalid notification/channel, or permission issues).
|
|
96
|
+
Log.e(
|
|
97
|
+
TAG,
|
|
98
|
+
"startForegroundCompat: Failed to start foreground service: ${e.message}",
|
|
99
|
+
e
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
companion object {
|
|
105
|
+
private const val TAG = "StreamCallKeepAliveHeadlessService"
|
|
106
|
+
|
|
107
|
+
const val TASK_NAME = "StreamVideoKeepCallAlive"
|
|
108
|
+
|
|
109
|
+
const val EXTRA_CALL_CID = "callCid"
|
|
110
|
+
const val EXTRA_CHANNEL_ID = "channelId"
|
|
111
|
+
const val EXTRA_CHANNEL_NAME = "channelName"
|
|
112
|
+
const val EXTRA_TITLE = "title"
|
|
113
|
+
const val EXTRA_BODY = "body"
|
|
114
|
+
const val EXTRA_SMALL_ICON_NAME = "smallIconName"
|
|
115
|
+
|
|
116
|
+
private const val NOTIFICATION_ID = 6061
|
|
117
|
+
|
|
118
|
+
private const val DEFAULT_CHANNEL_ID = "stream_call_foreground_service"
|
|
119
|
+
private const val DEFAULT_CHANNEL_NAME = "Call in progress"
|
|
120
|
+
private const val DEFAULT_TITLE = "Call in progress"
|
|
121
|
+
private const val DEFAULT_BODY = "Tap to return to the call"
|
|
122
|
+
|
|
123
|
+
fun buildStartIntent(
|
|
124
|
+
context: android.content.Context,
|
|
125
|
+
callCid: String,
|
|
126
|
+
channelId: String,
|
|
127
|
+
channelName: String,
|
|
128
|
+
title: String,
|
|
129
|
+
body: String,
|
|
130
|
+
smallIconName: String?
|
|
131
|
+
): Intent {
|
|
132
|
+
return Intent(context, StreamCallKeepAliveHeadlessService::class.java).apply {
|
|
133
|
+
putExtra(EXTRA_CALL_CID, callCid)
|
|
134
|
+
putExtra(EXTRA_CHANNEL_ID, channelId)
|
|
135
|
+
putExtra(EXTRA_CHANNEL_NAME, channelName)
|
|
136
|
+
putExtra(EXTRA_TITLE, title)
|
|
137
|
+
putExtra(EXTRA_BODY, body)
|
|
138
|
+
if (!smallIconName.isNullOrBlank()) {
|
|
139
|
+
putExtra(EXTRA_SMALL_ICON_NAME, smallIconName)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fun buildStopIntent(context: android.content.Context): Intent {
|
|
145
|
+
return Intent(context, StreamCallKeepAliveHeadlessService::class.java)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.usePushRegisterEffect = void 0;
|
|
7
7
|
var _useIosVoipPushEventsSetupEffect = require("./useIosVoipPushEventsSetupEffect");
|
|
8
|
-
var _useProcessPushCallEffect = require("./useProcessPushCallEffect");
|
|
9
8
|
var _useInitAndroidTokenAndRest = require("./useInitAndroidTokenAndRest");
|
|
10
9
|
var _useIosInitRemoteNotifications = require("./useIosInitRemoteNotifications");
|
|
11
10
|
var _useProcessPushNonRingingCallEffect = require("./useProcessPushNonRingingCallEffect");
|
|
@@ -17,7 +16,6 @@ const usePushRegisterEffect = () => {
|
|
|
17
16
|
(0, _useIosInitRemoteNotifications.useIosInitRemoteNotifications)();
|
|
18
17
|
(0, _useIosVoipPushEventsSetupEffect.useIosVoipPushEventsSetupEffect)();
|
|
19
18
|
(0, _useProcessPushNonRingingCallEffect.useProcessPushNonRingingCallEffect)();
|
|
20
|
-
(0, _useProcessPushCallEffect.useProcessPushCallEffect)();
|
|
21
19
|
(0, _useInitAndroidTokenAndRest.useInitAndroidTokenAndRest)();
|
|
22
20
|
};
|
|
23
21
|
exports.usePushRegisterEffect = usePushRegisterEffect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_useIosVoipPushEventsSetupEffect","require","
|
|
1
|
+
{"version":3,"names":["_useIosVoipPushEventsSetupEffect","require","_useInitAndroidTokenAndRest","_useIosInitRemoteNotifications","_useProcessPushNonRingingCallEffect","usePushRegisterEffect","useIosInitRemoteNotifications","useIosVoipPushEventsSetupEffect","useProcessPushNonRingingCallEffect","useInitAndroidTokenAndRest","exports"],"sourceRoot":"../../../../src","sources":["hooks/push/index.ts"],"mappings":";;;;;;AAAA,IAAAA,gCAAA,GAAAC,OAAA;AACA,IAAAC,2BAAA,GAAAD,OAAA;AACA,IAAAE,8BAAA,GAAAF,OAAA;AACA,IAAAG,mCAAA,GAAAH,OAAA;AAEA;AACA;AACA;AACA;AACO,MAAMI,qBAAqB,GAAGA,CAAA,KAAM;EACzC,IAAAC,4DAA6B,EAAC,CAAC;EAC/B,IAAAC,gEAA+B,EAAC,CAAC;EACjC,IAAAC,sEAAkC,EAAC,CAAC;EACpC,IAAAC,sDAA0B,EAAC,CAAC;AAC9B,CAAC;AAACC,OAAA,CAAAL,qBAAA,GAAAA,qBAAA","ignoreList":[]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useCallingExpWithCallingStateEffect = void 0;
|
|
7
|
+
var _videoClient = require("@stream-io/video-client");
|
|
8
|
+
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var _callingx = require("../../utils/internal/callingx/callingx");
|
|
11
|
+
var _callingx2 = require("../../utils/push/libs/callingx");
|
|
12
|
+
const logger = _videoClient.videoLoggerSystem.getLogger('callingx');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This hook is used to inform sync call state with CallKit/Telecom (i.e. start call, end call, mute/unmute call).
|
|
16
|
+
*/
|
|
17
|
+
const useCallingExpWithCallingStateEffect = () => {
|
|
18
|
+
const {
|
|
19
|
+
useMicrophoneState,
|
|
20
|
+
useParticipants,
|
|
21
|
+
useCallMembers
|
|
22
|
+
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
23
|
+
const activeCall = (0, _videoReactBindings.useCall)();
|
|
24
|
+
const {
|
|
25
|
+
isMute,
|
|
26
|
+
microphone
|
|
27
|
+
} = useMicrophoneState();
|
|
28
|
+
const callMembers = useCallMembers();
|
|
29
|
+
const participants = useParticipants();
|
|
30
|
+
const activeCallCid = activeCall?.cid;
|
|
31
|
+
const currentUserId = activeCall?.currentUserId;
|
|
32
|
+
const callDisplayName = (0, _react.useMemo)(() => (0, _callingx.getCallDisplayName)(callMembers, participants, currentUserId), [callMembers, participants, currentUserId]);
|
|
33
|
+
(0, _react.useEffect)(() => {
|
|
34
|
+
return () => {
|
|
35
|
+
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
36
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
40
|
+
if (!isCallTracked) {
|
|
41
|
+
logger.debug(`useCallingExpWithCallingStateEffect:No active call cid to end in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
//if incoming stream call was unmounted, we need to end the call in CallKit/Telecom
|
|
45
|
+
logger.debug(`useCallingExpWithCallingStateEffect: Ending call in callingx: ${activeCallCid}`);
|
|
46
|
+
callingx.endCallWithReason(activeCallCid, 'local').catch(error => {
|
|
47
|
+
logger.error(`useCallingExpWithCallingStateEffect: Error ending call in callingx: ${activeCallCid}`, error);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
}, [activeCallCid]);
|
|
51
|
+
(0, _react.useEffect)(() => {
|
|
52
|
+
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
53
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
57
|
+
if (!isCallTracked) {
|
|
58
|
+
logger.debug(`useCallingExpWithCallingStateEffect:No active call cid to update callingx: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
callingx.updateDisplay(activeCallCid, activeCallCid, callDisplayName);
|
|
62
|
+
}, [activeCallCid, callDisplayName]);
|
|
63
|
+
|
|
64
|
+
// Sync microphone mute state from app → CallKit
|
|
65
|
+
(0, _react.useEffect)(() => {
|
|
66
|
+
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
67
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
71
|
+
if (!isCallTracked) {
|
|
72
|
+
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
callingx.setMutedCall(activeCallCid, isMute);
|
|
76
|
+
}, [activeCallCid, isMute]);
|
|
77
|
+
|
|
78
|
+
// Sync mute state from CallKit → app (only for system-initiated mute actions)
|
|
79
|
+
(0, _react.useEffect)(() => {
|
|
80
|
+
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
81
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
82
|
+
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} callingx isSetup: ${callingx?.isSetup}`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Listen to mic toggle events from CallKit/Telecom and update stream call microphone state.
|
|
87
|
+
// Only system-initiated mute actions (e.g. user tapped mute on the native CallKit UI)
|
|
88
|
+
// are sent here — app-initiated actions are filtered out on the native side to prevent
|
|
89
|
+
// the feedback loop: app mutes mic → setMutedCall → CallKit delegate → event to JS → loop.
|
|
90
|
+
const subscription = callingx.addEventListener('didPerformSetMutedCallAction', async event => {
|
|
91
|
+
const {
|
|
92
|
+
callId,
|
|
93
|
+
muted
|
|
94
|
+
} = event;
|
|
95
|
+
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
96
|
+
if (!isCallTracked || callId !== activeCallCid) {
|
|
97
|
+
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked} callId: ${callId}`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const isCurrentlyMuted = microphone.state.status === 'disabled';
|
|
101
|
+
if (isCurrentlyMuted === muted) {
|
|
102
|
+
logger.debug(`useCallingExpWithCallingStateEffect: Mic toggle is already in the desired state: ${muted} for call: ${activeCallCid}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
if (muted) {
|
|
107
|
+
await microphone.disable();
|
|
108
|
+
} else {
|
|
109
|
+
await microphone.enable();
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
logger.error(`useCallingExpWithCallingStateEffect: Error toggling mic in calling exp: ${activeCallCid}`, error);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return () => {
|
|
116
|
+
subscription.remove();
|
|
117
|
+
};
|
|
118
|
+
}, [activeCallCid, microphone]);
|
|
119
|
+
};
|
|
120
|
+
exports.useCallingExpWithCallingStateEffect = useCallingExpWithCallingStateEffect;
|
|
121
|
+
//# sourceMappingURL=useCallingExpWithCallingStateEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_videoClient","require","_videoReactBindings","_react","_callingx","_callingx2","logger","videoLoggerSystem","getLogger","useCallingExpWithCallingStateEffect","useMicrophoneState","useParticipants","useCallMembers","useCallStateHooks","activeCall","useCall","isMute","microphone","callMembers","participants","activeCallCid","cid","currentUserId","callDisplayName","useMemo","getCallDisplayName","useEffect","callingx","getCallingxLibIfAvailable","isSetup","isCallTracked","debug","endCallWithReason","catch","error","updateDisplay","setMutedCall","subscription","addEventListener","event","callId","muted","isCurrentlyMuted","state","status","disable","enable","remove","exports"],"sourceRoot":"../../../../src","sources":["hooks/push/useCallingExpWithCallingStateEffect.ts"],"mappings":"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","ignoreList":[]}
|