@qusaieilouti99/call-manager 0.1.77 → 0.1.79

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 (28) hide show
  1. package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallActivity.kt +120 -152
  2. package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallEngine.kt +1035 -1044
  3. package/android/src/main/java/com/margelo/nitro/qusaieilouti99/callmanager/CallManager.kt +11 -0
  4. package/ios/AudioManager.swift +285 -0
  5. package/ios/CallEngine.swift +635 -0
  6. package/ios/CallInfo.swift +66 -0
  7. package/ios/CallKitManager.swift +238 -0
  8. package/ios/CallManager.swift +145 -3
  9. package/ios/VoIPTokenManager.swift +158 -0
  10. package/lib/module/CallManager.nitro.js.map +1 -1
  11. package/lib/typescript/src/CallManager.nitro.d.ts +2 -0
  12. package/lib/typescript/src/CallManager.nitro.d.ts.map +1 -1
  13. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  14. package/nitrogen/generated/android/c++/JHybridCallManagerSpec.cpp +20 -0
  15. package/nitrogen/generated/android/c++/JHybridCallManagerSpec.hpp +2 -0
  16. package/nitrogen/generated/android/kotlin/com/margelo/nitro/qusaieilouti99/callmanager/Func_void_std__string.kt +80 -0
  17. package/nitrogen/generated/android/kotlin/com/margelo/nitro/qusaieilouti99/callmanager/HybridCallManagerSpec.kt +13 -0
  18. package/nitrogen/generated/android/qusaieilouti99_callmanagerOnLoad.cpp +2 -0
  19. package/nitrogen/generated/ios/CallManager-Swift-Cxx-Bridge.cpp +8 -0
  20. package/nitrogen/generated/ios/CallManager-Swift-Cxx-Bridge.hpp +22 -0
  21. package/nitrogen/generated/ios/c++/HybridCallManagerSpecSwift.hpp +14 -0
  22. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
  23. package/nitrogen/generated/ios/swift/HybridCallManagerSpec.swift +2 -0
  24. package/nitrogen/generated/ios/swift/HybridCallManagerSpec_cxx.swift +31 -0
  25. package/nitrogen/generated/shared/c++/HybridCallManagerSpec.cpp +2 -0
  26. package/nitrogen/generated/shared/c++/HybridCallManagerSpec.hpp +2 -0
  27. package/package.json +1 -1
  28. package/src/CallManager.nitro.ts +8 -0
@@ -1,7 +1,7 @@
1
+ // File: CallActivity.kt
1
2
  package com.margelo.nitro.qusaieilouti99.callmanager
2
3
 
3
4
  import android.app.Activity
4
- import android.content.Intent
5
5
  import android.os.Build
6
6
  import android.os.Bundle
7
7
  import android.os.Handler
@@ -10,168 +10,136 @@ import android.util.Log
10
10
  import android.view.WindowManager
11
11
  import android.widget.Button
12
12
  import android.widget.TextView
13
- import android.content.BroadcastReceiver
14
- import android.content.Context
15
- import android.content.IntentFilter
16
13
 
17
- class CallActivity : Activity() {
18
-
19
- private enum class FinishReason {
20
- ANSWER, DECLINE, TIMEOUT, MANUAL_DISMISS, EXTERNAL_END
14
+ /**
15
+ * Full‐screen incoming‐call UI. Implements CallEndListener
16
+ * so it always auto‐finishes when the engine ends the call.
17
+ */
18
+ class CallActivity : Activity(), CallEngine.CallEndListener {
19
+
20
+ private enum class FinishReason {
21
+ ANSWER, DECLINE, TIMEOUT, MANUAL_DISMISS, EXTERNAL_END
22
+ }
23
+
24
+ private var finishReason: FinishReason? = null
25
+ private var callId: String = ""
26
+ private var callType: String = "Audio"
27
+
28
+ private val timeoutHandler = Handler(Looper.getMainLooper())
29
+ private val timeoutRunnable = Runnable {
30
+ Log.d(TAG, "CallActivity timeout triggered for callId: $callId")
31
+ finishReason = FinishReason.TIMEOUT
32
+ CallEngine.stopRingtone()
33
+ CallEngine.cancelIncomingCallUI()
34
+ CallEngine.endCall(callId)
35
+ finishCallActivity()
36
+ }
37
+
38
+ override fun onCreate(savedInstanceState: Bundle?) {
39
+ super.onCreate(savedInstanceState)
40
+ Log.d(TAG, "CallActivity onCreate")
41
+
42
+ // Lock‐screen bypass
43
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
44
+ setShowWhenLocked(true)
45
+ setTurnScreenOn(true)
46
+ } else {
47
+ window.addFlags(
48
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
49
+ WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
50
+ WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
51
+ )
21
52
  }
22
53
 
23
- private var finishReason: FinishReason? = null
24
- private var callId: String = ""
25
- private var callType: String = "Audio"
26
-
27
- private val timeoutHandler = Handler(Looper.getMainLooper())
28
- private val timeoutRunnable = Runnable {
29
- Log.d(TAG, "CallActivity timeout triggered for callId: $callId")
30
- finishReason = FinishReason.TIMEOUT
31
- CallEngine.stopRingtone()
32
- CallEngine.cancelIncomingCallUI()
33
- CallEngine.endCall(callId)
34
- finishCallActivity()
35
- }
54
+ setContentView(R.layout.activity_call)
36
55
 
37
- private val closeReceiver = object : BroadcastReceiver() {
38
- override fun onReceive(context: Context?, intent: Intent?) {
39
- val receivedCallId = intent?.getStringExtra("callId")
40
- Log.d(TAG, "Broadcast received for callId: $receivedCallId, current callId: $callId")
41
-
42
- if (receivedCallId == callId || receivedCallId.isNullOrEmpty()) {
43
- Log.d(TAG, "Received close broadcast for $callId")
44
- finishReason = FinishReason.EXTERNAL_END
45
-
46
- // Ensure we're on main thread and activity isn't finishing
47
- runOnUiThread {
48
- if (!isFinishing) {
49
- finishCallActivity()
50
- }
51
- }
52
- }
53
- }
54
- }
56
+ // Read incoming‐call params
57
+ callId = intent.getStringExtra("callId") ?: ""
58
+ callType = intent.getStringExtra("callType") ?: "Audio"
59
+ Log.d(TAG, "CallActivity received callId: $callId, callType: $callType")
55
60
 
56
- override fun onCreate(savedInstanceState: Bundle?) {
57
- super.onCreate(savedInstanceState)
58
- Log.d(TAG, "CallActivity onCreate")
59
-
60
- // Modern way to handle lock screen bypass (API 27+)
61
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
62
- setShowWhenLocked(true)
63
- setTurnScreenOn(true)
64
- } else {
65
- // Legacy approach for older versions
66
- window.addFlags(
67
- WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
68
- WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
69
- WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
70
- )
71
- }
72
-
73
- setContentView(R.layout.activity_call)
74
-
75
- callId = intent.getStringExtra("callId") ?: ""
76
- callType = intent.getStringExtra("callType") ?: "Audio"
77
- Log.d(TAG, "CallActivity received callId: $callId, callType: $callType")
78
-
79
- // FIXED: Don't immediately cancel ringtone and notification - let them play
80
- // CallEngine.cancelIncomingCallUI() // REMOVED
81
-
82
- val callerName = intent.getStringExtra("callerName") ?: "Unknown"
83
- val nameView = findViewById<TextView>(R.id.caller_name)
84
- val answerBtn = findViewById<Button>(R.id.answer_btn)
85
- val declineBtn = findViewById<Button>(R.id.decline_btn)
86
-
87
- nameView.text = callerName
88
-
89
- answerBtn.setOnClickListener {
90
- Log.d(TAG, "CallActivity: Answer button clicked for callId: $callId")
91
- finishReason = FinishReason.ANSWER
92
- // Stop ringtone and notification when user answers
93
- CallEngine.stopRingtone()
94
- CallEngine.cancelIncomingCallUI()
95
- CallEngine.answerCall(callId)
96
- finishCallActivity()
97
- }
98
-
99
- declineBtn.setOnClickListener {
100
- Log.d(TAG, "CallActivity: Decline button clicked for callId: $callId")
101
- finishReason = FinishReason.DECLINE
102
- // Stop ringtone and notification when user declines
103
- CallEngine.stopRingtone()
104
- CallEngine.cancelIncomingCallUI()
105
- CallEngine.endCall(callId)
106
- finishCallActivity()
107
- }
108
-
109
- // Enhanced broadcast receiver registration
110
- val filter = IntentFilter("com.qusaieilouti99.callmanager.CLOSE_CALL_ACTIVITY")
111
- try {
112
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
113
- registerReceiver(closeReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
114
- } else {
115
- registerReceiver(closeReceiver, filter)
116
- }
117
- Log.d(TAG, "Broadcast receiver registered successfully for callId: $callId")
118
- } catch (e: Exception) {
119
- Log.e(TAG, "Failed to register broadcast receiver: ${e.message}", e)
120
- }
121
-
122
- // Set timeout for incoming call
123
- timeoutHandler.postDelayed(timeoutRunnable, 60_000)
124
- Log.d(TAG, "CallActivity onCreate - END")
125
- }
61
+ // Register for call‐end callbacks BEFORE timeout or user can dismiss
62
+ CallEngine.registerCallEndListener(this)
63
+
64
+ // Bind UI
65
+ val callerName = intent.getStringExtra("callerName") ?: "Unknown"
66
+ findViewById<TextView>(R.id.caller_name).text = callerName
126
67
 
127
- override fun onDestroy() {
128
- super.onDestroy()
129
- Log.d(TAG, "CallActivity onDestroy for callId: $callId. Reason: $finishReason")
130
-
131
- // Clean up timeout handler
132
- timeoutHandler.removeCallbacks(timeoutRunnable)
133
-
134
- // Unregister broadcast receiver with better error handling
135
- try {
136
- unregisterReceiver(closeReceiver)
137
- Log.d(TAG, "Broadcast receiver unregistered for callId: $callId")
138
- } catch (e: IllegalArgumentException) {
139
- Log.w(TAG, "Receiver was not registered: ${e.message}")
140
- } catch (e: Exception) {
141
- Log.e(TAG, "Error unregistering receiver: ${e.message}", e)
142
- }
143
-
144
- // Clean up ringtone and notification if call wasn't answered
145
- if (finishReason != FinishReason.ANSWER) {
146
- CallEngine.stopRingtone()
147
- CallEngine.cancelIncomingCallUI()
148
- }
68
+ findViewById<Button>(R.id.answer_btn).setOnClickListener {
69
+ Log.d(TAG, "Answer clicked for callId: $callId")
70
+ finishReason = FinishReason.ANSWER
71
+ CallEngine.stopRingtone()
72
+ CallEngine.cancelIncomingCallUI()
73
+ CallEngine.answerCall(callId)
74
+ finishCallActivity()
149
75
  }
150
76
 
151
- override fun onBackPressed() {
152
- Log.d(TAG, "CallActivity onBackPressed for callId: $callId. Treating as decline/dismiss.")
153
- finishReason = FinishReason.MANUAL_DISMISS
154
- CallEngine.stopRingtone()
155
- CallEngine.cancelIncomingCallUI()
156
- CallEngine.endCall(callId)
157
- finishCallActivity()
77
+ findViewById<Button>(R.id.decline_btn).setOnClickListener {
78
+ Log.d(TAG, "Decline clicked for callId: $callId")
79
+ finishReason = FinishReason.DECLINE
80
+ CallEngine.stopRingtone()
81
+ CallEngine.cancelIncomingCallUI()
82
+ CallEngine.endCall(callId)
83
+ finishCallActivity()
158
84
  }
159
85
 
160
- private fun finishCallActivity() {
161
- if (isFinishing) {
162
- Log.d(TAG, "Activity is already finishing, skipping finishCallActivity")
163
- return
164
- }
165
-
166
- Log.d(TAG, "Finishing CallActivity for callId: $callId")
167
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
168
- finishAndRemoveTask()
169
- } else {
170
- finish()
171
- }
86
+ // Start auto‐timeout
87
+ timeoutHandler.postDelayed(timeoutRunnable, 60_000)
88
+ Log.d(TAG, "CallActivity setup complete")
89
+ }
90
+
91
+ override fun onDestroy() {
92
+ super.onDestroy()
93
+ Log.d(TAG, "CallActivity onDestroy for callId: $callId. Reason: $finishReason")
94
+
95
+ // Unregister listener
96
+ CallEngine.unregisterCallEndListener(this)
97
+
98
+ // Cancel timeout
99
+ timeoutHandler.removeCallbacks(timeoutRunnable)
100
+
101
+ // If user never answered, clean up ringtone/UI
102
+ if (finishReason != FinishReason.ANSWER) {
103
+ CallEngine.stopRingtone()
104
+ CallEngine.cancelIncomingCallUI()
172
105
  }
106
+ }
107
+
108
+ override fun onBackPressed() {
109
+ Log.d(TAG, "onBackPressed for callId: $callId → treat as decline")
110
+ finishReason = FinishReason.MANUAL_DISMISS
111
+ CallEngine.stopRingtone()
112
+ CallEngine.cancelIncomingCallUI()
113
+ CallEngine.endCall(callId)
114
+ finishCallActivity()
115
+ }
116
+
117
+ /**
118
+ * Called by CallEngine whenever ANY call ends.
119
+ * We only care about our own callId.
120
+ */
121
+ override fun onCallEnded(endedCallId: String) {
122
+ if (endedCallId == callId && !isFinishing) {
123
+ Log.d(TAG, "CallActivity onCallEnded callback for callId: $callId")
124
+ finishReason = FinishReason.EXTERNAL_END
125
+ runOnUiThread { finishCallActivity() }
126
+ }
127
+ }
173
128
 
174
- companion object {
175
- private const val TAG = "CallActivity"
129
+ private fun finishCallActivity() {
130
+ if (isFinishing) {
131
+ Log.d(TAG, "Already finishing, skip.")
132
+ return
133
+ }
134
+ Log.d(TAG, "Finishing CallActivity for callId: $callId")
135
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
136
+ finishAndRemoveTask()
137
+ } else {
138
+ finish()
176
139
  }
140
+ }
141
+
142
+ companion object {
143
+ private const val TAG = "CallActivity"
144
+ }
177
145
  }