@stream-io/video-react-native-sdk 1.30.0 → 1.30.1-beta.1

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.
Files changed (208) hide show
  1. package/android/src/main/AndroidManifest.xml +8 -1
  2. package/android/src/main/AndroidManifestNew.xml +11 -0
  3. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +42 -5
  4. package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +70 -6
  5. package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +6 -4
  6. package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
  7. package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +149 -0
  8. package/dist/commonjs/hooks/push/index.js +0 -2
  9. package/dist/commonjs/hooks/push/index.js.map +1 -1
  10. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +121 -0
  11. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  12. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  13. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  14. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +64 -97
  15. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  16. package/dist/commonjs/index.js +1 -0
  17. package/dist/commonjs/index.js.map +1 -1
  18. package/dist/commonjs/modules/call-manager/CallManager.js +26 -0
  19. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  20. package/dist/commonjs/providers/StreamCall/index.js +6 -6
  21. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  22. package/dist/commonjs/utils/StreamVideoRN/index.js +33 -21
  23. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  24. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +68 -0
  25. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +1 -0
  26. package/dist/commonjs/utils/internal/callingx/callingx.js +123 -0
  27. package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -0
  28. package/dist/commonjs/utils/internal/registerSDKGlobals.js +52 -3
  29. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  30. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
  31. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
  32. package/dist/commonjs/utils/push/android.js +135 -202
  33. package/dist/commonjs/utils/push/android.js.map +1 -1
  34. package/dist/commonjs/utils/push/internal/ios.js +17 -34
  35. package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
  36. package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -45
  37. package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
  38. package/dist/commonjs/utils/push/internal/utils.js +67 -52
  39. package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
  40. package/dist/commonjs/utils/push/ios.js.map +1 -1
  41. package/dist/commonjs/utils/push/libs/callingx.js +78 -0
  42. package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
  43. package/dist/commonjs/utils/push/libs/index.js +8 -19
  44. package/dist/commonjs/utils/push/libs/index.js.map +1 -1
  45. package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
  46. package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
  47. package/dist/commonjs/utils/push/setupCallingExpEvents.js +105 -0
  48. package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
  49. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
  50. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
  51. package/dist/commonjs/version.js +1 -1
  52. package/dist/commonjs/version.js.map +1 -1
  53. package/dist/module/hooks/push/index.js +0 -2
  54. package/dist/module/hooks/push/index.js.map +1 -1
  55. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +114 -0
  56. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  57. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  58. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  59. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +66 -99
  60. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  61. package/dist/module/index.js +1 -0
  62. package/dist/module/index.js.map +1 -1
  63. package/dist/module/modules/call-manager/CallManager.js +26 -0
  64. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  65. package/dist/module/providers/StreamCall/index.js +6 -6
  66. package/dist/module/providers/StreamCall/index.js.map +1 -1
  67. package/dist/module/utils/StreamVideoRN/index.js +33 -21
  68. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  69. package/dist/module/utils/internal/callingx/audioSessionPromise.js +61 -0
  70. package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +1 -0
  71. package/dist/module/utils/internal/callingx/callingx.js +114 -0
  72. package/dist/module/utils/internal/callingx/callingx.js.map +1 -0
  73. package/dist/module/utils/internal/registerSDKGlobals.js +52 -3
  74. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  75. package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
  76. package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
  77. package/dist/module/utils/push/android.js +137 -204
  78. package/dist/module/utils/push/android.js.map +1 -1
  79. package/dist/module/utils/push/internal/ios.js +17 -34
  80. package/dist/module/utils/push/internal/ios.js.map +1 -1
  81. package/dist/module/utils/push/internal/rxSubjects.js +0 -44
  82. package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
  83. package/dist/module/utils/push/internal/utils.js +63 -49
  84. package/dist/module/utils/push/internal/utils.js.map +1 -1
  85. package/dist/module/utils/push/ios.js.map +1 -1
  86. package/dist/module/utils/push/libs/callingx.js +70 -0
  87. package/dist/module/utils/push/libs/callingx.js.map +1 -0
  88. package/dist/module/utils/push/libs/index.js +1 -2
  89. package/dist/module/utils/push/libs/index.js.map +1 -1
  90. package/dist/module/utils/push/libs/notifee/index.js +0 -18
  91. package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
  92. package/dist/module/utils/push/setupCallingExpEvents.js +99 -0
  93. package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
  94. package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
  95. package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
  96. package/dist/module/version.js +1 -1
  97. package/dist/module/version.js.map +1 -1
  98. package/dist/typescript/hooks/push/index.d.ts.map +1 -1
  99. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
  100. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
  101. package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
  102. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  103. package/dist/typescript/index.d.ts +1 -0
  104. package/dist/typescript/index.d.ts.map +1 -1
  105. package/dist/typescript/modules/call-manager/CallManager.d.ts +5 -0
  106. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  107. package/dist/typescript/utils/StreamVideoRN/index.d.ts +20 -2
  108. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  109. package/dist/typescript/utils/StreamVideoRN/types.d.ts +63 -25
  110. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  111. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts +16 -0
  112. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts.map +1 -0
  113. package/dist/typescript/utils/internal/callingx/callingx.d.ts +17 -0
  114. package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -0
  115. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  116. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +10 -0
  117. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
  118. package/dist/typescript/utils/push/android.d.ts +1 -2
  119. package/dist/typescript/utils/push/android.d.ts.map +1 -1
  120. package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
  121. package/dist/typescript/utils/push/internal/rxSubjects.d.ts +0 -33
  122. package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
  123. package/dist/typescript/utils/push/internal/utils.d.ts +14 -8
  124. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  125. package/dist/typescript/utils/push/ios.d.ts +1 -2
  126. package/dist/typescript/utils/push/ios.d.ts.map +1 -1
  127. package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
  128. package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
  129. package/dist/typescript/utils/push/libs/index.d.ts +1 -2
  130. package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
  131. package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
  132. package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
  133. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
  134. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -0
  135. package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
  136. package/dist/typescript/version.d.ts +1 -1
  137. package/dist/typescript/version.d.ts.map +1 -1
  138. package/expo-config-plugin/dist/withAndroidManifest.js +1 -33
  139. package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
  140. package/expo-config-plugin/dist/withAppDelegate.js +19 -197
  141. package/expo-config-plugin/dist/withMainActivity.js +1 -1
  142. package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
  143. package/ios/StreamInCallManager.m +2 -0
  144. package/ios/StreamInCallManager.swift +19 -7
  145. package/ios/StreamVideoReactNative.h +7 -4
  146. package/ios/StreamVideoReactNative.m +189 -82
  147. package/package.json +13 -18
  148. package/src/hooks/push/index.ts +0 -2
  149. package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +147 -0
  150. package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
  151. package/src/hooks/useAndroidKeepCallAliveEffect.ts +94 -120
  152. package/src/index.ts +1 -0
  153. package/src/modules/call-manager/CallManager.ts +36 -0
  154. package/src/modules/call-manager/native-module.d.ts +7 -0
  155. package/src/providers/StreamCall/index.tsx +6 -6
  156. package/src/utils/StreamVideoRN/index.ts +40 -30
  157. package/src/utils/StreamVideoRN/types.ts +65 -25
  158. package/src/utils/internal/callingx/audioSessionPromise.ts +65 -0
  159. package/src/utils/internal/callingx/callingx.ts +165 -0
  160. package/src/utils/internal/registerSDKGlobals.ts +47 -4
  161. package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
  162. package/src/utils/push/android.ts +196 -311
  163. package/src/utils/push/internal/ios.ts +28 -44
  164. package/src/utils/push/internal/rxSubjects.ts +0 -61
  165. package/src/utils/push/internal/utils.ts +104 -63
  166. package/src/utils/push/ios.ts +1 -6
  167. package/src/utils/push/libs/callingx.ts +93 -0
  168. package/src/utils/push/libs/index.ts +1 -2
  169. package/src/utils/push/libs/notifee/index.ts +0 -27
  170. package/src/utils/push/setupCallingExpEvents.ts +135 -0
  171. package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
  172. package/src/version.ts +1 -1
  173. package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
  174. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
  175. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  176. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +0 -67
  177. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +0 -1
  178. package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
  179. package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
  180. package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
  181. package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
  182. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
  183. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
  184. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
  185. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  186. package/dist/module/hooks/push/useProcessPushCallEffect.js +0 -60
  187. package/dist/module/hooks/push/useProcessPushCallEffect.js.map +0 -1
  188. package/dist/module/utils/push/libs/callkeep.js +0 -11
  189. package/dist/module/utils/push/libs/callkeep.js.map +0 -1
  190. package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
  191. package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
  192. package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
  193. package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
  194. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
  195. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
  196. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts +0 -8
  197. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +0 -1
  198. package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
  199. package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
  200. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
  201. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
  202. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
  203. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
  204. package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
  205. package/src/hooks/push/useProcessPushCallEffect.ts +0 -108
  206. package/src/utils/push/libs/callkeep.ts +0 -16
  207. package/src/utils/push/libs/voipPushNotification.ts +0 -17
  208. package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
@@ -1,5 +1,4 @@
1
1
  import {
2
- Call,
3
2
  CallingState,
4
3
  StreamVideoClient,
5
4
  videoLoggerSystem,
@@ -15,30 +14,15 @@ import {
15
14
  getExpoNotificationsLibNoThrow,
16
15
  getFirebaseMessagingLib,
17
16
  getFirebaseMessagingLibNoThrow,
18
- getIncomingCallForegroundServiceTypes,
19
17
  getNotifeeLibThrowIfNotInstalledForPush,
20
18
  type NotifeeLib,
21
19
  } from './libs';
22
- import {
23
- pushAcceptedIncomingCallCId$,
24
- pushAndroidBackgroundDeliveredIncomingCallCId$,
25
- pushNonRingingCallData$,
26
- pushRejectedIncomingCallCId$,
27
- pushTappedIncomingCallCId$,
28
- } from './internal/rxSubjects';
20
+ import { pushNonRingingCallData$ } from './internal/rxSubjects';
29
21
  import { pushUnsubscriptionCallbacks } from './internal/constants';
30
- import {
31
- canAddPushWSSubscriptionsRef,
32
- clearPushWSEventSubscriptions,
33
- processCallFromPushInBackground,
34
- shouldCallBeEnded,
35
- } from './internal/utils';
22
+ import { canListenToWS, shouldCallBeClosed } from './internal/utils';
36
23
  import { setPushLogoutCallback } from '../internal/pushLogoutCallback';
37
- import { getAndroidDefaultRingtoneUrl } from '../getAndroidDefaultRingtoneUrl';
38
24
  import { StreamVideoRN } from '../StreamVideoRN';
39
-
40
- const ACCEPT_CALL_ACTION_ID = 'accept';
41
- const DECLINE_CALL_ACTION_ID = 'decline';
25
+ import { getCallingxLib } from './libs/callingx';
42
26
 
43
27
  type PushConfig = NonNullable<StreamVideoConfig['push']>;
44
28
 
@@ -107,11 +91,10 @@ export async function initAndroidPushToken(
107
91
  await setDeviceToken(token);
108
92
  }
109
93
  }
110
- // TODO: remove the incomingCallChannel check and find a better way once we have telecom integration for android
111
- const messaging =
112
- pushConfig.isExpo && !pushConfig.android.incomingCallChannel
113
- ? getFirebaseMessagingLibNoThrow(true)
114
- : getFirebaseMessagingLib();
94
+
95
+ const messaging = pushConfig.isExpo
96
+ ? getFirebaseMessagingLibNoThrow(true)
97
+ : getFirebaseMessagingLib();
115
98
  if (messaging) {
116
99
  logger.debug(`setting firebase token listeners`);
117
100
  const unsubscribe = messaging().onTokenRefresh((refreshedToken) =>
@@ -127,10 +110,10 @@ export async function initAndroidPushToken(
127
110
  * Creates notification from the push message data.
128
111
  * For Ringing and Non-Ringing calls.
129
112
  */
113
+
130
114
  export const firebaseDataHandler = async (
131
115
  data: FirebaseMessagingTypes.RemoteMessage['data'],
132
116
  ) => {
133
- if (Platform.OS !== 'android') return;
134
117
  /* Example data from firebase
135
118
  "message": {
136
119
  "data": {
@@ -146,227 +129,215 @@ export const firebaseDataHandler = async (
146
129
  // other stuff
147
130
  }
148
131
  */
132
+ if (Platform.OS !== 'android') return;
133
+
134
+ const logger = videoLoggerSystem.getLogger('firebaseDataHandler');
149
135
  const pushConfig = StreamVideoRN.getConfig().push;
150
136
  if (!pushConfig || !data || data.sender !== 'stream.video') {
151
137
  return;
152
138
  }
153
- const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
154
- const notifee = notifeeLib.default;
155
- const settings = await notifee.getNotificationSettings();
156
- if (settings.authorizationStatus !== 1) {
157
- const logger = videoLoggerSystem.getLogger('firebaseDataHandler');
158
- logger.debug(
159
- `Notification permission not granted, unable to post ${data.type} notifications`,
160
- );
161
- return;
162
- }
163
139
 
164
140
  if (data.type === 'call.ring') {
165
141
  const call_cid = data.call_cid as string;
166
- const created_by_id = data.created_by_id as string;
167
- const receiver_id = data.receiver_id as string;
168
-
169
- const video_client = await pushConfig.createStreamVideoClient();
170
- await video_client?.onRingingCall(call_cid);
142
+ const callingx = getCallingxLib();
171
143
 
172
- const shouldCallBeClosed = (callToCheck: Call) => {
173
- const { mustEndCall } = shouldCallBeEnded(
174
- callToCheck,
175
- created_by_id,
176
- receiver_id,
144
+ const client = await pushConfig.createStreamVideoClient();
145
+ if (!client) {
146
+ logger.debug(
147
+ `video client not found, skipping the call.ring notification`,
177
148
  );
178
- return mustEndCall;
179
- };
149
+ await callingx.stopService();
150
+ return;
151
+ }
180
152
 
181
- const canListenToWS = () =>
182
- canAddPushWSSubscriptionsRef.current &&
183
- AppState.currentState !== 'active';
184
153
  const asForegroundService = canListenToWS();
185
154
 
186
155
  if (asForegroundService) {
187
156
  // Listen to call events from WS through fg service
188
157
  // note: this will replace the current empty fg service runner
189
- notifee.registerForegroundService(() => {
190
- return new Promise(async () => {
191
- const client = await pushConfig.createStreamVideoClient();
192
- if (!client) {
193
- videoLoggerSystem
194
- .getLogger('firebaseMessagingOnMessageHandler')
195
- .debug(
196
- `Closing fg service as there is no client to create from push config`,
197
- );
198
- notifee.stopForegroundService();
199
- return;
200
- }
201
- const callFromPush = await client.onRingingCall(call_cid);
202
- let _shouldCallBeClosed = shouldCallBeClosed(callFromPush);
203
- if (_shouldCallBeClosed) {
204
- videoLoggerSystem
205
- .getLogger('firebaseMessagingOnMessageHandler')
206
- .debug(
207
- `Closing fg service callCid: ${call_cid} shouldCallBeClosed: ${_shouldCallBeClosed}`,
158
+ //we need to start service (e.g. by calling display incoming call) and than launch bg task, consider making those steps independent
159
+ await callingx.startBackgroundTask((_: unknown, stopTask: () => void) => {
160
+ return new Promise((resolve) => {
161
+ const finishBackgroundTask = () => {
162
+ callingx.log(
163
+ `Finishing background task for callCid: ${call_cid}`,
164
+ 'debug',
165
+ );
166
+ resolve(undefined);
167
+ stopTask();
168
+ };
169
+
170
+ (async () => {
171
+ try {
172
+ const _client = await pushConfig.createStreamVideoClient();
173
+ if (!_client) {
174
+ logger.debug(
175
+ `Closing fg service as there is no client to create from push config`,
176
+ );
177
+ finishBackgroundTask();
178
+ return;
179
+ }
180
+
181
+ const callFromPush = await _client.onRingingCall(call_cid);
182
+ const { mustEndCall, endCallReason } = shouldCallBeClosed(
183
+ callFromPush,
184
+ data,
208
185
  );
209
- notifee.stopForegroundService();
210
- return;
211
- }
212
- const unsubscribeFunctions: Array<() => void> = [];
213
- // check if service needs to be closed if accept/decline event was done on another device
214
- const unsubscribe = callFromPush.on('all', (event) => {
215
- const _canListenToWS = canListenToWS();
216
- if (!_canListenToWS) {
217
- videoLoggerSystem
218
- .getLogger('firebaseMessagingOnMessageHandler')
219
- .debug(
220
- `Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS}`,
221
- { event },
186
+ if (mustEndCall) {
187
+ logger.debug(
188
+ `Closing fg service callCid: ${call_cid} endCallReason: ${endCallReason}`,
222
189
  );
223
- unsubscribeFunctions.forEach((fn) => fn());
224
- notifee.stopForegroundService();
225
- return;
226
- }
227
- _shouldCallBeClosed = shouldCallBeClosed(callFromPush);
228
- if (_shouldCallBeClosed) {
229
- videoLoggerSystem
230
- .getLogger('firebaseMessagingOnMessageHandler')
231
- .debug(
232
- `Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS} shouldCallBeClosed: ${_shouldCallBeClosed}`,
233
- { event },
190
+
191
+ callingx.log(
192
+ `Ending call with callCid: ${call_cid} endCallReason: ${endCallReason}`,
193
+ 'debug',
234
194
  );
235
- unsubscribeFunctions.forEach((fn) => fn());
236
- notifee.stopForegroundService();
237
- }
238
- });
239
- // check if service needs to be closed if call was left
240
- const subscription = callFromPush.state.callingState$.subscribe(
241
- (callingState) => {
242
- if (
243
- callingState === CallingState.IDLE ||
244
- callingState === CallingState.LEFT
245
- ) {
246
- videoLoggerSystem
247
- .getLogger('firebaseMessagingOnMessageHandler')
248
- .debug(
249
- `Closing fg service from callingState callCid: ${call_cid} callingState: ${callingState}`,
250
- );
251
- unsubscribeFunctions.forEach((fn) => fn());
252
- notifee.stopForegroundService();
195
+ callingx.endCallWithReason(call_cid, endCallReason);
196
+ resolve(undefined);
197
+ return;
253
198
  }
254
- },
255
- );
256
- unsubscribeFunctions.push(unsubscribe);
257
- unsubscribeFunctions.push(() => subscription.unsubscribe());
258
- pushUnsubscriptionCallbacks.get(call_cid)?.forEach((cb) => cb());
259
- pushUnsubscriptionCallbacks.set(call_cid, unsubscribeFunctions);
260
- });
261
- });
262
- }
263
- const incomingCallChannel = pushConfig.android.incomingCallChannel;
264
- const incomingCallNotificationTextGetters =
265
- pushConfig.android.incomingCallNotificationTextGetters;
266
- if (!incomingCallChannel || !incomingCallNotificationTextGetters) {
267
- const logger = videoLoggerSystem.getLogger(
268
- 'firebaseMessagingOnMessageHandler',
269
- );
270
- logger.error(
271
- "Can't show incoming call notification as either or both incomingCallChannel and incomingCallNotificationTextGetters were not provided",
272
- );
273
- return;
274
- }
275
- /*
276
- * Sound has to be set on channel level for android 8 and above and cant be updated later after creation!
277
- * For android 7 and below, sound should be set on notification level
278
- */
279
- // set default ringtone if not provided
280
- if (!incomingCallChannel.sound) {
281
- incomingCallChannel.sound = await getAndroidDefaultRingtoneUrl();
282
- }
283
- await notifee.createChannel(incomingCallChannel);
284
- const { getTitle, getBody, getAcceptButtonTitle, getDeclineButtonTitle } =
285
- incomingCallNotificationTextGetters;
286
- const createdUserName = data.created_by_display_name as string;
287
199
 
288
- const title = getTitle(createdUserName);
289
- const body = getBody(createdUserName);
200
+ const unsubscribeFunctions: Array<() => void> = [];
201
+ // check if service needs to be closed if accept/decline event was done on another device
202
+ const unsubscribe = callFromPush.on('all', (event) => {
203
+ const _canListenToWS = canListenToWS();
204
+ if (!_canListenToWS) {
205
+ logger.debug(
206
+ `Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS}`,
207
+ { event },
208
+ );
209
+ unsubscribeFunctions.forEach((fn) => fn());
290
210
 
291
- videoLoggerSystem
292
- .getLogger('firebaseMessagingOnMessageHandler')
293
- .debug(
294
- `Displaying incoming call notification with callCid: ${call_cid} title: ${title} body: ${body} asForegroundService: ${asForegroundService}`,
295
- );
211
+ finishBackgroundTask();
212
+ return;
213
+ }
296
214
 
297
- const channelId = incomingCallChannel.id;
298
- await notifee.displayNotification({
299
- id: call_cid,
300
- title: getTitle(createdUserName),
301
- body: getBody(createdUserName),
302
- data,
303
- android: {
304
- channelId,
305
- smallIcon: pushConfig.android.smallIcon,
306
- importance: 4, // high importance
307
- foregroundServiceTypes: getIncomingCallForegroundServiceTypes(),
308
- asForegroundService,
309
- ongoing: true,
310
- sound: incomingCallChannel.sound,
311
- vibrationPattern: incomingCallChannel.vibrationPattern,
312
- loopSound: true,
313
- pressAction: {
314
- id: 'default',
315
- launchActivity: 'default', // open the app when the notification is pressed
316
- },
317
- actions: [
318
- {
319
- title: getDeclineButtonTitle?.() ?? 'Decline',
320
- pressAction: {
321
- id: DECLINE_CALL_ACTION_ID,
322
- },
323
- },
324
- {
325
- title: getAcceptButtonTitle?.() ?? 'Accept',
326
- pressAction: {
327
- id: ACCEPT_CALL_ACTION_ID,
328
- launchActivity: 'default', // open the app when the notification is pressed
329
- },
330
- },
331
- ],
332
- category: notifeeLib.AndroidCategory.CALL,
333
- fullScreenAction: {
334
- id: 'stream_ringing_incoming_call',
335
- },
336
- timeoutAfter: 60000, // 60 seconds, after which the notification will be dismissed automatically
337
- },
338
- });
215
+ const {
216
+ mustEndCall: mustEndCallFromEvent,
217
+ endCallReason: endCallReasonFromEvent,
218
+ } = shouldCallBeClosed(callFromPush, data);
219
+ if (mustEndCallFromEvent) {
220
+ logger.debug(
221
+ `Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS} shouldCallBeClosed`,
222
+ { event },
223
+ );
224
+ unsubscribeFunctions.forEach((fn) => fn());
225
+
226
+ callingx.endCallWithReason(call_cid, endCallReasonFromEvent);
227
+ resolve(undefined);
228
+ }
229
+ });
230
+
231
+ // check if service needs to be closed if call was left
232
+ const stateSubscription =
233
+ callFromPush.state.callingState$.subscribe((callingState) => {
234
+ if (
235
+ callingState === CallingState.IDLE ||
236
+ callingState === CallingState.LEFT
237
+ ) {
238
+ logger.debug(
239
+ `Closing fg service from callingState callCid: ${call_cid} callingState: ${callingState}`,
240
+ );
241
+ unsubscribeFunctions.forEach((fn) => fn());
242
+ callingx.log(
243
+ `Ending call with callCid: ${call_cid} callingState: ${callingState}`,
244
+ 'debug',
245
+ );
246
+ resolve(undefined);
247
+ }
248
+ });
249
+
250
+ const endCallSubscription = callingx.addEventListener(
251
+ 'endCall',
252
+ async ({ callId }: { callId: string }) => {
253
+ unsubscribeFunctions.forEach((fn) => fn());
254
+ try {
255
+ await callFromPush.leave({
256
+ reject: true,
257
+ reason: 'decline',
258
+ });
259
+ } catch (error) {
260
+ logger.error(
261
+ `Failed to leave call with callCid: ${call_cid} error: ${error}`,
262
+ );
263
+ } finally {
264
+ callingx.log(
265
+ `Ending call with callCid: ${call_cid} callId: ${callId}`,
266
+ 'debug',
267
+ );
268
+ resolve(undefined);
269
+ }
270
+ },
271
+ );
272
+
273
+ //stop background task when app comes to foreground
274
+ const appStateSubscription = AppState.addEventListener(
275
+ 'change',
276
+ (nextAppState) => {
277
+ const _canListenToWS = canListenToWS();
278
+ callingx.log(
279
+ `AppState changed to: ${nextAppState} for callCid: ${call_cid} canListenToWS: ${_canListenToWS}`,
280
+ 'debug',
281
+ );
282
+ if (!_canListenToWS) {
283
+ unsubscribeFunctions.forEach((fn) => fn());
284
+ finishBackgroundTask();
285
+ return;
286
+ }
287
+ },
288
+ );
289
+
290
+ unsubscribeFunctions.push(unsubscribe);
291
+ unsubscribeFunctions.push(() => stateSubscription.unsubscribe());
292
+ unsubscribeFunctions.push(() => endCallSubscription.remove());
293
+ unsubscribeFunctions.push(() => appStateSubscription.remove());
294
+ pushUnsubscriptionCallbacks.get(call_cid)?.forEach((cb) => cb());
295
+ pushUnsubscriptionCallbacks.set(call_cid, unsubscribeFunctions);
296
+ } catch (error) {
297
+ callingx.log(
298
+ `Failed to start background task with callCid: ${call_cid} error: ${error}`,
299
+ 'error',
300
+ );
301
+ finishBackgroundTask();
302
+ }
303
+ })();
304
+ });
305
+ });
306
+ }
339
307
 
340
308
  if (asForegroundService) {
341
309
  // no need to check if call has be closed as that will be handled by the fg service
342
310
  return;
343
311
  }
344
312
 
345
- // check if call needs to be closed if accept/decline event was done
346
- // before the notification was shown
347
- const client = await pushConfig.createStreamVideoClient();
348
- if (!client) {
349
- return;
350
- }
351
313
  const callFromPush = await client.onRingingCall(call_cid);
352
314
 
353
- if (shouldCallBeClosed(callFromPush)) {
354
- videoLoggerSystem
355
- .getLogger('firebaseMessagingOnMessageHandler')
356
- .debug(
357
- `Removing incoming call notification immediately with callCid: ${call_cid} as it should be closed`,
358
- );
359
- notifee.cancelDisplayedNotification(call_cid);
315
+ const { mustEndCall, endCallReason } = shouldCallBeClosed(
316
+ callFromPush,
317
+ data,
318
+ );
319
+ if (mustEndCall) {
320
+ logger.debug(
321
+ `Removing incoming call notification immediately with callCid: ${call_cid} as it should be closed`,
322
+ );
323
+ callingx.endCallWithReason(call_cid, endCallReason);
360
324
  }
361
325
  } else {
326
+ const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
327
+ const notifee = notifeeLib.default;
328
+ const settings = await notifee.getNotificationSettings();
329
+ if (settings.authorizationStatus !== 1) {
330
+ logger.debug(
331
+ `Notification permission not granted, unable to post ${data.type} notifications`,
332
+ );
333
+ return;
334
+ }
335
+
362
336
  // the other types are call.live_started and call.notification
363
337
  const callChannel = pushConfig.android.callChannel;
364
338
  const callNotificationTextGetters =
365
339
  pushConfig.android.callNotificationTextGetters;
366
340
  if (!callChannel || !callNotificationTextGetters) {
367
- const logger = videoLoggerSystem.getLogger(
368
- 'firebaseMessagingOnMessageHandler',
369
- );
370
341
  logger.debug(
371
342
  "Can't show call notification as either or both callChannel and callNotificationTextGetters is not provided",
372
343
  );
@@ -382,14 +353,12 @@ export const firebaseDataHandler = async (
382
353
  const title = getTitle(type, createdUserName);
383
354
  const body = getBody(type, createdUserName);
384
355
 
385
- videoLoggerSystem
386
- .getLogger('firebaseMessagingOnMessageHandler')
387
- .debug(
388
- `Displaying NonRingingPushEvent ${type} notification with title: ${title} body: ${body}`,
389
- );
356
+ logger.debug(
357
+ `Displaying NonRingingPushEvent ${type} notification with title: ${title} body: ${body}`,
358
+ );
390
359
  await notifee.displayNotification({
391
- title: getTitle(type, createdUserName),
392
- body: getBody(type, createdUserName),
360
+ title,
361
+ body,
393
362
  data,
394
363
  android: {
395
364
  sound: callChannel.sound,
@@ -409,16 +378,10 @@ export const firebaseDataHandler = async (
409
378
  }
410
379
  };
411
380
 
412
- export const onAndroidNotifeeEvent = async ({
413
- event,
414
- isBackground,
415
- }: {
416
- event: Event;
417
- isBackground: boolean;
418
- }) => {
381
+ export const onAndroidNotifeeEvent = async ({ event }: { event: Event }) => {
419
382
  if (Platform.OS !== 'android') return;
420
383
  const { type, detail } = event;
421
- const { notification, pressAction } = detail;
384
+ const { notification } = detail;
422
385
  const notificationId = notification?.id;
423
386
  const data = notification?.data;
424
387
  const pushConfig = StreamVideoRN.getConfig().push;
@@ -434,92 +397,14 @@ export const onAndroidNotifeeEvent = async ({
434
397
  // we can safely cast to string because the data is from "stream.video"
435
398
  const call_cid = data.call_cid as string;
436
399
 
437
- if (data.type === 'call.ring') {
438
- // check if we have observers for the call cid (this means the app is in the foreground state)
439
- const hasObservers =
440
- pushAcceptedIncomingCallCId$.observed &&
441
- pushRejectedIncomingCallCId$.observed;
442
-
443
- const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
444
- const notifee = notifeeLib.default;
445
- // Check if we need to decline the call
446
- const didPressDecline =
447
- type === notifeeLib.EventType.ACTION_PRESS &&
448
- pressAction?.id === DECLINE_CALL_ACTION_ID;
449
- const didDismiss = type === notifeeLib.EventType.DISMISSED;
450
- const mustDecline = didPressDecline || didDismiss;
451
- // Check if we need to accept the call
452
- const mustAccept =
453
- type === notifeeLib.EventType.ACTION_PRESS &&
454
- pressAction?.id === ACCEPT_CALL_ACTION_ID;
455
-
456
- if (
457
- mustAccept ||
458
- mustDecline ||
459
- type === notifeeLib.EventType.ACTION_PRESS
460
- ) {
461
- videoLoggerSystem
462
- .getLogger('onAndroidNotifeeEvent')
463
- .debug(
464
- `clearPushWSEventSubscriptions for callCId: ${call_cid} mustAccept: ${mustAccept} mustDecline: ${mustDecline}`,
465
- );
466
- clearPushWSEventSubscriptions(call_cid);
467
- notifee.stopForegroundService();
468
- }
469
-
470
- if (mustAccept) {
471
- videoLoggerSystem
472
- .getLogger('onAndroidNotifeeEvent')
473
- .debug(`pushAcceptedIncomingCallCId$ added with callCId: ${call_cid}`);
474
- pushAcceptedIncomingCallCId$.next(call_cid);
475
- // NOTE: accept will be handled by the app with rxjs observers as the app will go to foreground always
476
- } else if (mustDecline) {
477
- videoLoggerSystem
478
- .getLogger('onAndroidNotifeeEvent')
479
- .debug(`pushRejectedIncomingCallCId$ added with callCId: ${call_cid}`);
480
- pushRejectedIncomingCallCId$.next(call_cid);
481
- if (hasObservers) {
482
- // if we had observers we can return here as the observers will handle the call as the app is in the foreground state
483
- videoLoggerSystem
484
- .getLogger('onAndroidNotifeeEvent')
485
- .debug(
486
- `Skipped processCallFromPushInBackground for Declining call with callCId: ${call_cid} as the app is in the foreground state`,
487
- );
488
- return;
489
- }
490
- videoLoggerSystem
491
- .getLogger('onAndroidNotifeeEvent')
492
- .debug(
493
- `start processCallFromPushInBackground - Declining call with callCId: ${call_cid}`,
494
- );
495
- await processCallFromPushInBackground(pushConfig, call_cid, 'decline');
496
- } else {
497
- if (type === notifeeLib.EventType.PRESS) {
498
- videoLoggerSystem
499
- .getLogger('onAndroidNotifeeEvent')
500
- .debug(`pushTappedIncomingCallCId$ added with callCId: ${call_cid}`);
501
- pushTappedIncomingCallCId$.next(call_cid);
502
- // pressed state will be handled by the app with rxjs observers as the app will go to foreground always
503
- } else if (isBackground && type === notifeeLib.EventType.DELIVERED) {
504
- videoLoggerSystem
505
- .getLogger('onAndroidNotifeeEvent')
506
- .debug(
507
- `pushAndroidBackgroundDeliveredIncomingCallCId$ added with callCId: ${call_cid}`,
508
- );
509
- pushAndroidBackgroundDeliveredIncomingCallCId$.next(call_cid);
510
- // background delivered state will be handled by the app with rxjs observers as processing needs to happen only when app is opened
511
- }
512
- }
513
- } else {
514
- const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
515
- if (type === notifeeLib.EventType.PRESS) {
516
- videoLoggerSystem
517
- .getLogger('onAndroidNotifeeEvent')
518
- .debug(`onTapNonRingingCallNotification with callCId: ${call_cid}`);
519
- pushConfig.onTapNonRingingCallNotification?.(
520
- call_cid,
521
- data.type as NonRingingPushEvent,
522
- );
523
- }
400
+ const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
401
+ if (type === notifeeLib.EventType.PRESS) {
402
+ videoLoggerSystem
403
+ .getLogger('onAndroidNotifeeEvent')
404
+ .debug(`onTapNonRingingCallNotification with callCId: ${call_cid}`);
405
+ pushConfig.onTapNonRingingCallNotification?.(
406
+ call_cid,
407
+ data.type as NonRingingPushEvent,
408
+ );
524
409
  }
525
410
  };