@capgo/capacitor-stream-call 0.0.78 → 0.0.80

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.
@@ -18,6 +18,15 @@
18
18
  android:name="ee.forgr.capacitor.streamcall.StreamCallBackgroundService"
19
19
  android:enabled="true"
20
20
  android:exported="false" />
21
+
22
+ <receiver
23
+ android:name=".AcceptCallReceiver"
24
+ android:enabled="true"
25
+ android:exported="true">
26
+ <intent-filter>
27
+ <action android:name="io.getstream.video.android.action.ACCEPT_CALL" />
28
+ </intent-filter>
29
+ </receiver>
21
30
  </application>
22
31
 
23
32
  <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@@ -0,0 +1,35 @@
1
+ package ee.forgr.capacitor.streamcall
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.util.Log
7
+ import io.getstream.video.android.core.notifications.NotificationHandler
8
+ import io.getstream.video.android.model.streamCallId
9
+
10
+ class AcceptCallReceiver : BroadcastReceiver() {
11
+ override fun onReceive(context: Context?, intent: Intent?) {
12
+ Log.d("AcceptCallReceiver", "onReceive called with action: ${intent?.action}")
13
+ if (intent?.action == NotificationHandler.ACTION_ACCEPT_CALL) {
14
+ val cid = intent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)
15
+ if (cid == null) {
16
+ Log.e("AcceptCallReceiver", "Call CID is null, cannot accept call.")
17
+ return
18
+ }
19
+
20
+ Log.d("AcceptCallReceiver", "Accepting call with CID: $cid")
21
+
22
+ // Create an intent to launch the main activity
23
+ val launchIntent = context?.packageManager?.getLaunchIntentForPackage(context.packageName)
24
+ if (launchIntent != null) {
25
+ launchIntent.action = NotificationHandler.ACTION_ACCEPT_CALL
26
+ launchIntent.putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, cid)
27
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
28
+ context.startActivity(launchIntent)
29
+ Log.d("AcceptCallReceiver", "Started MainActivity to handle ACCEPT_CALL action.")
30
+ } else {
31
+ Log.e("AcceptCallReceiver", "Could not get launch intent for package.")
32
+ }
33
+ }
34
+ }
35
+ }
@@ -68,26 +68,16 @@ class CustomNotificationHandler(
68
68
  )
69
69
 
70
70
  val acceptCallAction = NotificationHandler.ACTION_ACCEPT_CALL
71
- val acceptCallIntent = Intent(acceptCallAction)
72
- // Pass full Parcelable so both new and old handlers succeed
73
- .putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
74
- .setPackage(application.packageName)
75
-
76
- if (targetComponent != null) {
77
- acceptCallIntent.component = targetComponent
71
+ val acceptCallIntent = Intent(acceptCallAction).apply {
72
+ putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
73
+ // Explicitly target our manifest-declared receiver
74
+ setClass(application, AcceptCallReceiver::class.java)
78
75
  }
79
- acceptCallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
80
76
 
81
- Log.d("CustomNotificationHandler", "Constructed Accept Call Intent for PI: action=${acceptCallIntent.action}, cid=${acceptCallIntent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)}, package=${acceptCallIntent.getPackage()}, component=${acceptCallIntent.component?.flattenToString()}, flags=${acceptCallIntent.flags}")
77
+ Log.d("CustomNotificationHandler", "Constructed Accept Call Intent for PI: action=${acceptCallIntent.action}, cid=${acceptCallIntent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)}, component=${acceptCallIntent.component}")
82
78
 
83
- // Create PendingIntent for Accept action using getActivity to launch the app
84
79
  val requestCodeAccept = callId.cid.hashCode() + 1 // Unique request code for the PendingIntent with offset to avoid collisions
85
- val acceptCallPendingIntent = PendingIntent.getActivity(
86
- application,
87
- requestCodeAccept,
88
- acceptCallIntent,
89
- PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
90
- )
80
+ val acceptCallPendingIntent = createAcceptCallPendingIntent(callId, requestCodeAccept, acceptCallIntent)
91
81
  Log.d("CustomNotificationHandler", "Created Accept Call PendingIntent with requestCode: $requestCodeAccept")
92
82
 
93
83
  val rejectCallPendingIntent = intentResolver.searchRejectCallPendingIntent(callId) // Keep using resolver for reject for now, or change it too if needed
@@ -127,6 +117,37 @@ class CustomNotificationHandler(
127
117
  null
128
118
  }
129
119
  }
120
+
121
+ private fun createAcceptCallPendingIntent(
122
+ callId: StreamCallId,
123
+ requestCode: Int,
124
+ acceptCallIntent: Intent
125
+ ): PendingIntent? {
126
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
127
+ val launchIntent = application.packageManager.getLaunchIntentForPackage(application.packageName)
128
+ if (launchIntent != null) {
129
+ launchIntent.action = NotificationHandler.ACTION_ACCEPT_CALL
130
+ launchIntent.putExtra(NotificationHandler.INTENT_EXTRA_CALL_CID, callId)
131
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
132
+ PendingIntent.getActivity(
133
+ application,
134
+ requestCode,
135
+ launchIntent,
136
+ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
137
+ )
138
+ } else {
139
+ Log.e("CustomNotificationHandler", "Could not get launch intent for package to create Accept PI.")
140
+ null
141
+ }
142
+ } else {
143
+ PendingIntent.getBroadcast(
144
+ application,
145
+ requestCode,
146
+ acceptCallIntent,
147
+ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
148
+ )
149
+ }
150
+ }
130
151
 
131
152
  fun customGetIncomingCallNotification(
132
153
  fullScreenPendingIntent: PendingIntent,
@@ -410,6 +410,7 @@ public class StreamCallPlugin : Plugin() {
410
410
 
411
411
  CallContent(
412
412
  call = activeCall,
413
+ enableInPictureInPicture = false,
413
414
  onBackPressed = { /* Handle back press if needed */ },
414
415
  controlsContent = { /* Empty to disable native controls */ },
415
416
  appBarContent = { /* Empty to disable app bar with stop call button */ },
@@ -510,6 +511,7 @@ public class StreamCallPlugin : Plugin() {
510
511
 
511
512
  streamVideoClient = null
512
513
  state = State.NOT_INITIALIZED
514
+ eventHandlersRegistered = false
513
515
 
514
516
  val ret = JSObject()
515
517
  ret.put("success", true)
@@ -550,7 +552,10 @@ public class StreamCallPlugin : Plugin() {
550
552
  android.util.Log.v("StreamCallPlugin", "Plugin's streamVideoClient is null, reusing singleton and registering event handlers")
551
553
  streamVideoClient = StreamVideo.instance()
552
554
  // Register event handlers since streamVideoClient was null
553
- registerEventHandlers()
555
+ if (!eventHandlersRegistered) {
556
+ registerEventHandlers()
557
+ eventHandlersRegistered = true
558
+ }
554
559
  } else {
555
560
  android.util.Log.v("StreamCallPlugin", "Plugin already has streamVideoClient, skipping event handler registration")
556
561
  }
@@ -641,8 +646,10 @@ public class StreamCallPlugin : Plugin() {
641
646
  this.state = State.INITIALIZED
642
647
  return
643
648
  }
644
-
645
- registerEventHandlers()
649
+ if (!eventHandlersRegistered) {
650
+ registerEventHandlers()
651
+ eventHandlersRegistered = true
652
+ }
646
653
 
647
654
  android.util.Log.v("StreamCallPlugin", "Initialization finished")
648
655
  initializationTime = System.currentTimeMillis()
@@ -900,7 +907,7 @@ public class StreamCallPlugin : Plugin() {
900
907
  if (connectionState != RealtimeConnection.Disconnected) {
901
908
  val total = activeCall.state.participantCounts.value?.total
902
909
  android.util.Log.d("StreamCallPlugin", "CallSessionParticipantLeftEvent: Participant left, remaining: $total");
903
- if (total != null && total <= 2) {
910
+ if (total != null && total < 2) {
904
911
  android.util.Log.d("StreamCallPlugin", "CallSessionParticipantLeftEvent: All remote participants have left call ${activeCall.cid}. Ending call.")
905
912
  kotlinx.coroutines.GlobalScope.launch(Dispatchers.IO) {
906
913
  endCallRaw(activeCall)
@@ -1766,7 +1773,7 @@ public class StreamCallPlugin : Plugin() {
1766
1773
 
1767
1774
  // Use call.state.totalParticipants to get participant count (as per StreamVideo Android SDK docs)
1768
1775
  val totalParticipants = call.state.totalParticipants.value ?: 0
1769
- val shouldEndCall = isCreator || totalParticipants <= 2
1776
+ val shouldEndCall = isCreator || totalParticipants <= 1
1770
1777
 
1771
1778
  android.util.Log.d("StreamCallPlugin", "Call $callId - Creator: $createdBy, CurrentUser: $currentUserId, IsCreator: $isCreator, TotalParticipants: $totalParticipants, ShouldEnd: $shouldEndCall")
1772
1779
 
@@ -2375,14 +2382,14 @@ public class StreamCallPlugin : Plugin() {
2375
2382
 
2376
2383
  private val acceptCallReceiver = object : BroadcastReceiver() {
2377
2384
  override fun onReceive(context: Context?, intent: Intent?) {
2378
- android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: Received broadcast with action: ${intent?.action}")
2379
2385
  if (intent?.action == "io.getstream.video.android.action.ACCEPT_CALL") {
2386
+ android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: Received broadcast with action: ${intent.action}")
2380
2387
  val cid = intent.streamCallId(NotificationHandler.INTENT_EXTRA_CALL_CID)
2381
- android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: ACCEPT_CALL broadcast received with cid: $cid")
2382
2388
  if (cid != null) {
2383
- android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: Accepting call with cid: $cid")
2389
+ android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: ACCEPT_CALL broadcast received with cid: $cid")
2384
2390
  val call = streamVideoClient?.call(id = cid.id, type = cid.type)
2385
2391
  if (call != null) {
2392
+ android.util.Log.d("StreamCallPlugin", "BroadcastReceiver: Accepting call with cid: $cid")
2386
2393
  kotlinx.coroutines.GlobalScope.launch {
2387
2394
  internalAcceptCall(call, requestPermissionsAfter = !checkPermissions())
2388
2395
  }
@@ -2421,6 +2428,7 @@ public class StreamCallPlugin : Plugin() {
2421
2428
  }
2422
2429
  }
2423
2430
  private var holder: StreamCallPlugin? = null
2431
+ private var eventHandlersRegistered = false
2424
2432
 
2425
2433
  // Constants for SharedPreferences
2426
2434
  private const val API_KEY_PREFS_NAME = "stream_video_api_key_prefs"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-stream-call",
3
- "version": "0.0.78",
3
+ "version": "0.0.80",
4
4
  "description": "Uses the https://getstream.io/ SDK to implement calling in Capacitor",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",