@qusaieilouti99/call-manager 0.1.37 → 0.1.39
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/java/com/margelo/nitro/qusaieilouti99/callmanager/CallEngine.kt +46 -57
- package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallForegroundService.kt +2 -2
- package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallManager.kt +10 -23
- package/package.json +1 -1
|
@@ -12,16 +12,16 @@ import android.media.MediaPlayer
|
|
|
12
12
|
import android.media.RingtoneManager
|
|
13
13
|
import android.net.Uri
|
|
14
14
|
import android.os.Build
|
|
15
|
-
import android.os.Bundle
|
|
15
|
+
import android.os.Bundle
|
|
16
16
|
import android.os.PowerManager
|
|
17
|
-
import android.telecom.CallAudioState
|
|
18
|
-
import android.telecom.Connection
|
|
19
|
-
import android.telecom.DisconnectCause
|
|
20
|
-
import android.telecom.PhoneAccount
|
|
21
|
-
import android.telecom.PhoneAccountHandle
|
|
22
|
-
import android.telecom.TelecomManager
|
|
23
|
-
import android.telecom.VideoProfile
|
|
24
|
-
import android.util.Log
|
|
17
|
+
import android.telecom.CallAudioState
|
|
18
|
+
import android.telecom.Connection
|
|
19
|
+
import android.telecom.DisconnectCause
|
|
20
|
+
import android.telecom.PhoneAccount
|
|
21
|
+
import android.telecom.PhoneAccountHandle
|
|
22
|
+
import android.telecom.TelecomManager
|
|
23
|
+
import android.telecom.VideoProfile
|
|
24
|
+
import android.util.Log
|
|
25
25
|
import android.graphics.Color
|
|
26
26
|
import android.app.Person
|
|
27
27
|
import org.json.JSONArray
|
|
@@ -38,22 +38,22 @@ object CallEngine {
|
|
|
38
38
|
private const val FOREGROUND_NOTIF_ID = 1001
|
|
39
39
|
|
|
40
40
|
private var ringtone: android.media.Ringtone? = null
|
|
41
|
-
private var ringbackPlayer: MediaPlayer? = null
|
|
41
|
+
private var ringbackPlayer: MediaPlayer? = null
|
|
42
42
|
private var audioManager: AudioManager? = null
|
|
43
43
|
private var wakeLock: PowerManager.WakeLock? = null
|
|
44
44
|
private var appContext: Context? = null
|
|
45
45
|
|
|
46
46
|
// --- Multi-call state ---
|
|
47
|
-
private val activeCalls = ConcurrentHashMap<String, CallInfo>()
|
|
48
|
-
private val telecomConnections = ConcurrentHashMap<String, Connection>()
|
|
49
|
-
private var currentCallId: String? = null
|
|
47
|
+
private val activeCalls = ConcurrentHashMap<String, CallInfo>()
|
|
48
|
+
private val telecomConnections = ConcurrentHashMap<String, Connection>()
|
|
49
|
+
private var currentCallId: String? = null
|
|
50
50
|
private var canMakeMultipleCalls: Boolean = true
|
|
51
51
|
|
|
52
52
|
data class CallInfo(
|
|
53
53
|
val callId: String,
|
|
54
54
|
val callData: String,
|
|
55
55
|
var state: CallState,
|
|
56
|
-
val callType: String = "Audio"
|
|
56
|
+
val callType: String = "Audio"
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
enum class CallState {
|
|
@@ -62,12 +62,11 @@ object CallEngine {
|
|
|
62
62
|
|
|
63
63
|
// --- Event handler for JS ---
|
|
64
64
|
private var eventHandler: ((CallEventType, String) -> Unit)? = null
|
|
65
|
-
private val cachedEvents = mutableListOf<Pair<CallEventType, String>>()
|
|
65
|
+
private val cachedEvents = mutableListOf<Pair<CallEventType, String>>()
|
|
66
66
|
|
|
67
67
|
fun setEventHandler(handler: ((CallEventType, String) -> Unit)?) {
|
|
68
68
|
Log.d(TAG, "setEventHandler called. Handler present: ${handler != null}")
|
|
69
69
|
eventHandler = handler
|
|
70
|
-
// Emit cached events if a handler is now available
|
|
71
70
|
handler?.let { h ->
|
|
72
71
|
if (cachedEvents.isNotEmpty()) {
|
|
73
72
|
Log.d(TAG, "Emitting ${cachedEvents.size} cached events.")
|
|
@@ -133,12 +132,12 @@ object CallEngine {
|
|
|
133
132
|
json.optString("name", "Unknown")
|
|
134
133
|
} catch (e: Exception) { "Unknown" }
|
|
135
134
|
|
|
136
|
-
val parsedCallType = try {
|
|
135
|
+
val parsedCallType = try {
|
|
137
136
|
val json = JSONObject(callData)
|
|
138
137
|
json.optString("callType", "Audio")
|
|
139
138
|
} catch (e: Exception) { "Audio" }
|
|
140
139
|
|
|
141
|
-
val isVideoCallBoolean = parsedCallType == "Video"
|
|
140
|
+
val isVideoCallBoolean = parsedCallType == "Video"
|
|
142
141
|
|
|
143
142
|
if (!canMakeMultipleCalls && activeCalls.isNotEmpty()) {
|
|
144
143
|
Log.d(TAG, "Can't make multiple calls, holding existing calls.")
|
|
@@ -154,8 +153,8 @@ object CallEngine {
|
|
|
154
153
|
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
155
154
|
val phoneAccountHandle = getPhoneAccountHandle(context)
|
|
156
155
|
val extras = Bundle().apply {
|
|
157
|
-
putString(MyConnectionService.EXTRA_CALL_DATA, callData)
|
|
158
|
-
putBoolean(MyConnectionService.EXTRA_IS_VIDEO_CALL_BOOLEAN, isVideoCallBoolean)
|
|
156
|
+
putString(MyConnectionService.EXTRA_CALL_DATA, callData)
|
|
157
|
+
putBoolean(MyConnectionService.EXTRA_IS_VIDEO_CALL_BOOLEAN, isVideoCallBoolean)
|
|
159
158
|
}
|
|
160
159
|
try {
|
|
161
160
|
telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
|
|
@@ -171,6 +170,7 @@ object CallEngine {
|
|
|
171
170
|
notifyCallStateChanged(context)
|
|
172
171
|
}
|
|
173
172
|
|
|
173
|
+
// CORRECTED: Uses TelecomManager.placeCall for outgoing calls.
|
|
174
174
|
fun startOutgoingCall(context: Context, callId: String, callData: String) {
|
|
175
175
|
appContext = context.applicationContext
|
|
176
176
|
Log.d(TAG, "startOutgoingCall: $callId, $callData")
|
|
@@ -180,12 +180,12 @@ object CallEngine {
|
|
|
180
180
|
json.optString("name", "Unknown")
|
|
181
181
|
} catch (e: Exception) { "Unknown" }
|
|
182
182
|
|
|
183
|
-
val parsedCallType = try {
|
|
183
|
+
val parsedCallType = try {
|
|
184
184
|
val json = JSONObject(callData)
|
|
185
185
|
json.optString("callType", "Audio")
|
|
186
186
|
} catch (e: Exception) { "Audio" }
|
|
187
187
|
|
|
188
|
-
val isVideoCallBoolean = parsedCallType == "Video"
|
|
188
|
+
val isVideoCallBoolean = parsedCallType == "Video"
|
|
189
189
|
|
|
190
190
|
if (!canMakeMultipleCalls && activeCalls.isNotEmpty()) {
|
|
191
191
|
Log.d(TAG, "Can't make multiple calls, holding existing calls before outgoing.")
|
|
@@ -199,33 +199,33 @@ object CallEngine {
|
|
|
199
199
|
registerPhoneAccount(context)
|
|
200
200
|
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
201
201
|
val phoneAccountHandle = getPhoneAccountHandle(context)
|
|
202
|
+
|
|
203
|
+
val addressUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, callId, null)
|
|
204
|
+
|
|
202
205
|
val extras = Bundle().apply {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
+
putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
|
|
207
|
+
putString(MyConnectionService.EXTRA_CALL_DATA, callData)
|
|
208
|
+
putBoolean(MyConnectionService.EXTRA_IS_VIDEO_CALL_BOOLEAN, isVideoCallBoolean)
|
|
206
209
|
putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, isVideoCallBoolean)
|
|
207
210
|
}
|
|
208
211
|
|
|
209
212
|
try {
|
|
210
|
-
|
|
211
|
-
// or the minSdkVersion is too low for this method (requires API 23+).
|
|
212
|
-
// Imports already checked; assuming minSdkVersion 26+.
|
|
213
|
-
telecomManager.addNewOutgoingCall(phoneAccountHandle, extras)
|
|
213
|
+
telecomManager.placeCall(addressUri, extras)
|
|
214
214
|
startForegroundService(context)
|
|
215
|
-
Log.d(TAG, "Successfully reported outgoing call to TelecomManager for $callId")
|
|
215
|
+
Log.d(TAG, "Successfully reported outgoing call to TelecomManager via placeCall for $callId")
|
|
216
216
|
startRingback()
|
|
217
217
|
bringAppToForeground(context)
|
|
218
218
|
keepScreenAwake(context, true)
|
|
219
|
-
if (parsedCallType == "Video") {
|
|
219
|
+
if (parsedCallType == "Video") {
|
|
220
220
|
setAudioRoute(context, "Speaker")
|
|
221
221
|
} else {
|
|
222
|
-
setAudioRoute(context, "Earpiece")
|
|
222
|
+
setAudioRoute(context, "Earpiece")
|
|
223
223
|
}
|
|
224
224
|
} catch (e: SecurityException) {
|
|
225
|
-
Log.e(TAG, "SecurityException: Failed to start outgoing call. Check MANAGE_OWN_CALLS permission: ${e.message}", e)
|
|
225
|
+
Log.e(TAG, "SecurityException: Failed to start outgoing call via placeCall. Check MANAGE_OWN_CALLS permission: ${e.message}", e)
|
|
226
226
|
endCall(context, callId)
|
|
227
227
|
} catch (e: Exception) {
|
|
228
|
-
Log.e(TAG, "Failed to start outgoing call: ${e.message}", e)
|
|
228
|
+
Log.e(TAG, "Failed to start outgoing call via placeCall: ${e.message}", e)
|
|
229
229
|
endCall(context, callId)
|
|
230
230
|
}
|
|
231
231
|
notifyCallStateChanged(context)
|
|
@@ -262,7 +262,6 @@ object CallEngine {
|
|
|
262
262
|
|
|
263
263
|
fun holdCall(context: Context, callId: String) {
|
|
264
264
|
Log.d(TAG, "holdCall: $callId")
|
|
265
|
-
activeCalls[callId]?.state = CallState.HELD
|
|
266
265
|
val connection = telecomConnections[callId]
|
|
267
266
|
connection?.setOnHold()
|
|
268
267
|
emitEvent(CallEventType.CALL_HELD, JSONObject().put("callId", callId))
|
|
@@ -316,7 +315,7 @@ object CallEngine {
|
|
|
316
315
|
removeTelecomConnection(callId)
|
|
317
316
|
Log.d(TAG, "Telecom Connection for $callId disconnected and destroyed.")
|
|
318
317
|
} else {
|
|
319
|
-
Log.
|
|
318
|
+
Log.d(TAG, "No Telecom Connection found for callId=$callId. Likely an outgoing call not initially handled by Telecom.")
|
|
320
319
|
}
|
|
321
320
|
|
|
322
321
|
if (activeCalls.isEmpty()) {
|
|
@@ -445,11 +444,10 @@ object CallEngine {
|
|
|
445
444
|
|
|
446
445
|
// --- Audio Device Management ---
|
|
447
446
|
|
|
448
|
-
// Returns the generated AudioRoutesInfo data class
|
|
449
447
|
fun getAudioDevices(): AudioRoutesInfo {
|
|
450
|
-
audioManager =
|
|
448
|
+
audioManager = appContext?.getSystemService(Context.AUDIO_SERVICE) as? AudioManager ?: run {
|
|
451
449
|
Log.e(TAG, "getAudioDevices: AudioManager is null or appContext is not set. Returning default.")
|
|
452
|
-
return AudioRoutesInfo(emptyArray(), "Unknown")
|
|
450
|
+
return AudioRoutesInfo(emptyArray(), "Unknown")
|
|
453
451
|
}
|
|
454
452
|
val devices = mutableListOf<String>()
|
|
455
453
|
var currentRoute: String = "Unknown"
|
|
@@ -460,7 +458,7 @@ object CallEngine {
|
|
|
460
458
|
when (device.type) {
|
|
461
459
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> {
|
|
462
460
|
devices.add("Bluetooth")
|
|
463
|
-
if (audioManager?.isBluetoothScoOn == true && !device.isSource) currentRoute = "Bluetooth"
|
|
461
|
+
if (audioManager?.isBluetoothScoOn == true && !device.isSource) currentRoute = "Bluetooth"
|
|
464
462
|
}
|
|
465
463
|
AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_WIRED_HEADSET -> {
|
|
466
464
|
devices.add("Headset")
|
|
@@ -472,8 +470,6 @@ object CallEngine {
|
|
|
472
470
|
}
|
|
473
471
|
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> {
|
|
474
472
|
devices.add("Earpiece")
|
|
475
|
-
// Earpiece is active if speaker, bluetooth, and headset are off
|
|
476
|
-
// This heuristic is tricky, relies on other routes being off
|
|
477
473
|
if (audioManager?.isSpeakerphoneOn == false && audioManager?.isWiredHeadsetOn == false && audioManager?.isBluetoothScoOn == false && !device.isSource) {
|
|
478
474
|
currentRoute = "Earpiece"
|
|
479
475
|
}
|
|
@@ -482,17 +478,15 @@ object CallEngine {
|
|
|
482
478
|
}
|
|
483
479
|
}
|
|
484
480
|
} else {
|
|
485
|
-
// Fallback for older APIs. Detection is less reliable.
|
|
486
481
|
devices.add("Speaker")
|
|
487
482
|
devices.add("Earpiece")
|
|
488
483
|
if (audioManager?.isSpeakerphoneOn == true) currentRoute = "Speaker"
|
|
489
|
-
else currentRoute = "Earpiece"
|
|
484
|
+
else currentRoute = "Earpiece"
|
|
490
485
|
}
|
|
491
486
|
|
|
492
487
|
val distinctDevices = devices.distinct().toTypedArray()
|
|
493
488
|
|
|
494
|
-
|
|
495
|
-
if (currentRoute == "Unknown" || currentRoute == "Earpiece") { // If still unknown or defaulted to earpiece
|
|
489
|
+
if (currentRoute == "Unknown" || currentRoute == "Earpiece") {
|
|
496
490
|
if (audioManager?.isBluetoothScoOn == true) {
|
|
497
491
|
currentRoute = "Bluetooth"
|
|
498
492
|
} else if (audioManager?.isSpeakerphoneOn == true) {
|
|
@@ -500,7 +494,7 @@ object CallEngine {
|
|
|
500
494
|
} else if (audioManager?.isWiredHeadsetOn == true) {
|
|
501
495
|
currentRoute = "Headset"
|
|
502
496
|
} else {
|
|
503
|
-
currentRoute = "Earpiece"
|
|
497
|
+
currentRoute = "Earpiece"
|
|
504
498
|
}
|
|
505
499
|
}
|
|
506
500
|
|
|
@@ -542,8 +536,6 @@ object CallEngine {
|
|
|
542
536
|
Log.w(TAG, "Unknown audio route: $route. No action taken.")
|
|
543
537
|
}
|
|
544
538
|
}
|
|
545
|
-
// Emit event immediately with the requested route.
|
|
546
|
-
// The actual route change will be confirmed by onCallAudioStateChanged callback.
|
|
547
539
|
emitEvent(CallEventType.AUDIO_ROUTE_CHANGED, JSONObject().put("route", route))
|
|
548
540
|
}
|
|
549
541
|
|
|
@@ -615,12 +607,12 @@ object CallEngine {
|
|
|
615
607
|
Log.w(TAG, "Cannot emit AudioDevicesChanged: appContext is null.")
|
|
616
608
|
return
|
|
617
609
|
}
|
|
618
|
-
val audioInfo = getAudioDevices()
|
|
619
|
-
val jsonPayload = JSONObject().apply {
|
|
610
|
+
val audioInfo = getAudioDevices()
|
|
611
|
+
val jsonPayload = JSONObject().apply {
|
|
620
612
|
put("devices", JSONArray(audioInfo.devices.toList()))
|
|
621
613
|
put("currentRoute", audioInfo.currentRoute)
|
|
622
614
|
}
|
|
623
|
-
emitEvent(CallEventType.AUDIO_DEVICES_CHANGED, jsonPayload)
|
|
615
|
+
emitEvent(CallEventType.AUDIO_DEVICES_CHANGED, jsonPayload)
|
|
624
616
|
}
|
|
625
617
|
|
|
626
618
|
// --- Call State Change Notification ---
|
|
@@ -669,12 +661,13 @@ object CallEngine {
|
|
|
669
661
|
}
|
|
670
662
|
}
|
|
671
663
|
|
|
664
|
+
// PhoneAccount registration is used for both INCOMING and OUTGOING calls when interacting with Telecom
|
|
672
665
|
private fun registerPhoneAccount(context: Context) {
|
|
673
666
|
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
|
674
667
|
val phoneAccountHandle = getPhoneAccountHandle(context)
|
|
675
668
|
if (telecomManager.getPhoneAccount(phoneAccountHandle) == null) {
|
|
676
669
|
val phoneAccount = PhoneAccount.builder(phoneAccountHandle, "PingMe Call")
|
|
677
|
-
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED or PhoneAccount.
|
|
670
|
+
.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED or PhoneAccount.CAPABILITY_HOLD)
|
|
678
671
|
.build()
|
|
679
672
|
try {
|
|
680
673
|
telecomManager.registerPhoneAccount(phoneAccount)
|
|
@@ -697,7 +690,6 @@ object CallEngine {
|
|
|
697
690
|
}
|
|
698
691
|
|
|
699
692
|
// --- Ringtone Management (for incoming calls, pre-Android S) ---
|
|
700
|
-
// Can rely on default ringtone without adding custom file for incoming calls.
|
|
701
693
|
fun playRingtone(context: Context) {
|
|
702
694
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
703
695
|
Log.d(TAG, "playRingtone: Android S+ detected, system will handle ringtone via Telecom.")
|
|
@@ -730,15 +722,12 @@ object CallEngine {
|
|
|
730
722
|
}
|
|
731
723
|
|
|
732
724
|
// --- Ringback Tone Management (for outgoing calls) ---
|
|
733
|
-
// Requires `res/raw/ringback_tone.mp3` for custom outgoing ringback.
|
|
734
725
|
private fun startRingback() {
|
|
735
726
|
if (ringbackPlayer != null && ringbackPlayer!!.isPlaying) {
|
|
736
727
|
Log.d(TAG, "Ringback tone already playing.")
|
|
737
728
|
return
|
|
738
729
|
}
|
|
739
730
|
try {
|
|
740
|
-
// Ensure you have `res/raw/ringback_tone.mp3` in your project for this to work.
|
|
741
|
-
// If you don't want a custom ringback, you can play a silent audio file or do nothing here.
|
|
742
731
|
val ringbackUri = Uri.parse("android.resource://${appContext?.packageName}/raw/ringback_tone")
|
|
743
732
|
ringbackPlayer = MediaPlayer.create(appContext, ringbackUri)
|
|
744
733
|
if (ringbackPlayer == null) {
|
package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallForegroundService.kt
CHANGED
|
@@ -8,7 +8,7 @@ import android.content.Intent
|
|
|
8
8
|
import android.os.Build
|
|
9
9
|
import android.util.Log
|
|
10
10
|
import android.os.IBinder
|
|
11
|
-
import android.app.NotificationManager
|
|
11
|
+
import android.app.NotificationManager
|
|
12
12
|
|
|
13
13
|
class CallForegroundService : Service() {
|
|
14
14
|
|
|
@@ -61,7 +61,7 @@ class CallForegroundService : Service() {
|
|
|
61
61
|
NotificationManager.IMPORTANCE_LOW
|
|
62
62
|
)
|
|
63
63
|
channel.description = "Notification for ongoing calls"
|
|
64
|
-
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
64
|
+
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
65
65
|
manager.createNotificationChannel(channel)
|
|
66
66
|
Log.d(TAG, "Foreground notification channel '$CHANNEL_ID' created/updated.")
|
|
67
67
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package com.margelo.nitro.qusaieilouti99.callmanager
|
|
2
2
|
|
|
3
3
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
4
|
-
import android.util.Log
|
|
4
|
+
import android.util.Log
|
|
5
5
|
import org.json.JSONArray
|
|
6
6
|
import org.json.JSONObject
|
|
7
7
|
|
|
@@ -10,7 +10,6 @@ class CallManager : HybridCallManagerSpec() {
|
|
|
10
10
|
|
|
11
11
|
private val TAG = "CallManager"
|
|
12
12
|
|
|
13
|
-
// Listener type now directly matches the generated Func_void_CallEventType_std__string
|
|
14
13
|
private var currentListener: Func_void_CallEventType_std__string? = null
|
|
15
14
|
|
|
16
15
|
override fun endCall(callId: String) {
|
|
@@ -27,14 +26,13 @@ class CallManager : HybridCallManagerSpec() {
|
|
|
27
26
|
} ?: Log.e(TAG, "App context not set for silenceRingtone.")
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
// Return type changed to AudioRoutesInfo from String
|
|
31
29
|
override fun getAudioDevices(): AudioRoutesInfo {
|
|
32
30
|
Log.d(TAG, "getAudioDevices requested.")
|
|
33
31
|
return CallEngine.getAppContext()?.let {
|
|
34
|
-
CallEngine.getAudioDevices()
|
|
32
|
+
CallEngine.getAudioDevices()
|
|
35
33
|
} ?: run {
|
|
36
34
|
Log.e(TAG, "App context not set for getAudioDevices. Returning empty AudioRoutesInfo.")
|
|
37
|
-
AudioRoutesInfo(emptyArray(), "Unknown")
|
|
35
|
+
AudioRoutesInfo(emptyArray(), "Unknown")
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
38
|
|
|
@@ -52,29 +50,18 @@ class CallManager : HybridCallManagerSpec() {
|
|
|
52
50
|
} ?: Log.e(TAG, "App context not set for keepAwake.")
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
// Corrected addListener signature to match generated HybridCallManagerSpec
|
|
56
53
|
override fun addListener(
|
|
57
|
-
listener:
|
|
58
|
-
):
|
|
54
|
+
listener: (event: CallEventType, payload: String) -> Unit
|
|
55
|
+
): () -> Unit {
|
|
59
56
|
Log.d(TAG, "addListener called with listener: $listener")
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Return a Nitro-generated Func_void for the remove function
|
|
66
|
-
return Func_void_java {
|
|
67
|
-
if (currentListener === listener) { // Compare against the original listener passed
|
|
68
|
-
CallEngine.setEventHandler(null)
|
|
69
|
-
currentListener = null
|
|
70
|
-
Log.d(TAG, "Listener removed.")
|
|
71
|
-
} else {
|
|
72
|
-
Log.d(TAG, "Attempted to remove a listener that was not current.")
|
|
73
|
-
}
|
|
57
|
+
// Wrap the listener in your event system
|
|
58
|
+
CallEngine.setEventHandler(listener)
|
|
59
|
+
return {
|
|
60
|
+
CallEngine.setEventHandler(null)
|
|
61
|
+
Log.d(TAG, "Listener removed.")
|
|
74
62
|
}
|
|
75
63
|
}
|
|
76
64
|
|
|
77
|
-
// Removed callType param, now extracted from callData
|
|
78
65
|
override fun startOutgoingCall(callId: String, callData: String) {
|
|
79
66
|
Log.d(TAG, "startOutgoingCall requested: callId=$callId, callData=$callData")
|
|
80
67
|
CallEngine.getAppContext()?.let {
|