@qusaieilouti99/call-manager 0.1.47 → 0.1.48
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.
|
@@ -24,6 +24,7 @@ import android.telecom.VideoProfile
|
|
|
24
24
|
import android.util.Log
|
|
25
25
|
import android.graphics.Color
|
|
26
26
|
import android.app.Person
|
|
27
|
+
import android.view.WindowManager
|
|
27
28
|
import org.json.JSONArray
|
|
28
29
|
import org.json.JSONObject
|
|
29
30
|
import java.util.UUID
|
|
@@ -49,6 +50,14 @@ object CallEngine {
|
|
|
49
50
|
private var currentCallId: String? = null
|
|
50
51
|
private var canMakeMultipleCalls: Boolean = true
|
|
51
52
|
|
|
53
|
+
// --- Lock Screen Bypass State Management ---
|
|
54
|
+
private var lockScreenBypassActive = false
|
|
55
|
+
private val lockScreenBypassCallbacks = mutableSetOf<LockScreenBypassCallback>()
|
|
56
|
+
|
|
57
|
+
interface LockScreenBypassCallback {
|
|
58
|
+
fun onLockScreenBypassChanged(shouldBypass: Boolean)
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
data class CallInfo(
|
|
53
62
|
val callId: String,
|
|
54
63
|
val callData: String,
|
|
@@ -89,6 +98,34 @@ object CallEngine {
|
|
|
89
98
|
|
|
90
99
|
fun getAppContext(): Context? = appContext
|
|
91
100
|
|
|
101
|
+
// --- Lock Screen Bypass Management (Single Source of Truth) ---
|
|
102
|
+
fun registerLockScreenBypassCallback(callback: LockScreenBypassCallback) {
|
|
103
|
+
lockScreenBypassCallbacks.add(callback)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fun unregisterLockScreenBypassCallback(callback: LockScreenBypassCallback) {
|
|
107
|
+
lockScreenBypassCallbacks.remove(callback)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private fun updateLockScreenBypass() {
|
|
111
|
+
val shouldBypass = isCallActive()
|
|
112
|
+
if (lockScreenBypassActive != shouldBypass) {
|
|
113
|
+
lockScreenBypassActive = shouldBypass
|
|
114
|
+
Log.d(TAG, "Lock screen bypass state changed: $lockScreenBypassActive")
|
|
115
|
+
|
|
116
|
+
// Notify all registered callbacks
|
|
117
|
+
lockScreenBypassCallbacks.forEach { callback ->
|
|
118
|
+
try {
|
|
119
|
+
callback.onLockScreenBypassChanged(shouldBypass)
|
|
120
|
+
} catch (e: Exception) {
|
|
121
|
+
Log.w(TAG, "Error notifying lock screen bypass callback", e)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
fun isLockScreenBypassActive(): Boolean = lockScreenBypassActive
|
|
128
|
+
|
|
92
129
|
// --- Telecom Connection Management ---
|
|
93
130
|
fun addTelecomConnection(callId: String, connection: Connection) {
|
|
94
131
|
telecomConnections[callId] = connection
|
|
@@ -163,7 +200,6 @@ object CallEngine {
|
|
|
163
200
|
telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
|
|
164
201
|
startForegroundService(context)
|
|
165
202
|
Log.d(TAG, "Successfully reported incoming call to TelecomManager for $callId")
|
|
166
|
-
// REMOVED: Don't bring app to foreground for incoming calls - only when answered
|
|
167
203
|
} catch (e: SecurityException) {
|
|
168
204
|
Log.e(TAG, "SecurityException: Failed to report incoming call. Check MANAGE_OWN_CALLS permission: ${e.message}", e)
|
|
169
205
|
endCall(context, callId)
|
|
@@ -171,6 +207,7 @@ object CallEngine {
|
|
|
171
207
|
Log.e(TAG, "Failed to report incoming call: ${e.message}", e)
|
|
172
208
|
endCall(context, callId)
|
|
173
209
|
}
|
|
210
|
+
updateLockScreenBypass()
|
|
174
211
|
notifyCallStateChanged(context)
|
|
175
212
|
}
|
|
176
213
|
|
|
@@ -217,7 +254,6 @@ object CallEngine {
|
|
|
217
254
|
startForegroundService(context)
|
|
218
255
|
Log.d(TAG, "Successfully reported outgoing call to TelecomManager via placeCall for $callId")
|
|
219
256
|
startRingback()
|
|
220
|
-
// CHANGED: Bring app to foreground for outgoing calls
|
|
221
257
|
bringAppToForeground(context)
|
|
222
258
|
keepScreenAwake(context, true)
|
|
223
259
|
if (parsedCallType == "Video") {
|
|
@@ -232,6 +268,7 @@ object CallEngine {
|
|
|
232
268
|
Log.e(TAG, "Failed to start outgoing call via placeCall: ${e.message}", e)
|
|
233
269
|
endCall(context, callId)
|
|
234
270
|
}
|
|
271
|
+
updateLockScreenBypass()
|
|
235
272
|
notifyCallStateChanged(context)
|
|
236
273
|
}
|
|
237
274
|
|
|
@@ -270,8 +307,7 @@ object CallEngine {
|
|
|
270
307
|
keepScreenAwake(context, true)
|
|
271
308
|
resetAudioMode(context)
|
|
272
309
|
|
|
273
|
-
|
|
274
|
-
updateMainActivityLockScreenBypass()
|
|
310
|
+
updateLockScreenBypass()
|
|
275
311
|
|
|
276
312
|
// Emit event
|
|
277
313
|
emitEvent(CallEventType.CALL_ANSWERED, JSONObject().put("callId", callId))
|
|
@@ -280,31 +316,13 @@ object CallEngine {
|
|
|
280
316
|
Log.d(TAG, "Call $callId successfully answered and UI cleaned up")
|
|
281
317
|
}
|
|
282
318
|
|
|
283
|
-
// NEW: Method to update MainActivity lock screen bypass state
|
|
284
|
-
private fun updateMainActivityLockScreenBypass() {
|
|
285
|
-
try {
|
|
286
|
-
// Try to get MainActivity instance through reflection or static reference
|
|
287
|
-
val mainActivityClass = Class.forName("com.pingme2022.MainActivity")
|
|
288
|
-
val getCurrentInstanceMethod = mainActivityClass.getMethod("getCurrentInstance")
|
|
289
|
-
val mainActivityInstance = getCurrentInstanceMethod.invoke(null)
|
|
290
|
-
|
|
291
|
-
if (mainActivityInstance != null) {
|
|
292
|
-
val updateMethod = mainActivityClass.getMethod("updateLockScreenBypass")
|
|
293
|
-
updateMethod.invoke(mainActivityInstance)
|
|
294
|
-
Log.d(TAG, "Updated MainActivity lock screen bypass state")
|
|
295
|
-
} else {
|
|
296
|
-
Log.d(TAG, "MainActivity instance not available for lock screen bypass update")
|
|
297
|
-
}
|
|
298
|
-
} catch (e: Exception) {
|
|
299
|
-
Log.w(TAG, "Could not update MainActivity lock screen bypass: ${e.message}")
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
319
|
fun holdCall(context: Context, callId: String) {
|
|
304
320
|
Log.d(TAG, "holdCall: $callId")
|
|
321
|
+
activeCalls[callId]?.state = CallState.HELD
|
|
305
322
|
val connection = telecomConnections[callId]
|
|
306
323
|
connection?.setOnHold()
|
|
307
324
|
emitEvent(CallEventType.CALL_HELD, JSONObject().put("callId", callId))
|
|
325
|
+
updateLockScreenBypass()
|
|
308
326
|
notifyCallStateChanged(context)
|
|
309
327
|
}
|
|
310
328
|
|
|
@@ -314,6 +332,7 @@ object CallEngine {
|
|
|
314
332
|
val connection = telecomConnections[callId]
|
|
315
333
|
connection?.setActive()
|
|
316
334
|
emitEvent(CallEventType.CALL_UNHELD, JSONObject().put("callId", callId))
|
|
335
|
+
updateLockScreenBypass()
|
|
317
336
|
notifyCallStateChanged(context)
|
|
318
337
|
}
|
|
319
338
|
|
|
@@ -355,6 +374,7 @@ object CallEngine {
|
|
|
355
374
|
|
|
356
375
|
// Final cleanup
|
|
357
376
|
finalCleanup(context)
|
|
377
|
+
updateLockScreenBypass()
|
|
358
378
|
notifyCallStateChanged(context)
|
|
359
379
|
}
|
|
360
380
|
|
|
@@ -392,6 +412,7 @@ object CallEngine {
|
|
|
392
412
|
finalCleanup(context)
|
|
393
413
|
}
|
|
394
414
|
|
|
415
|
+
updateLockScreenBypass()
|
|
395
416
|
emitEvent(CallEventType.CALL_ENDED, JSONObject().put("callId", callId))
|
|
396
417
|
notifyCallStateChanged(context)
|
|
397
418
|
}
|
|
@@ -403,29 +424,6 @@ object CallEngine {
|
|
|
403
424
|
stopForegroundService(context)
|
|
404
425
|
keepScreenAwake(context, false)
|
|
405
426
|
resetAudioMode(context)
|
|
406
|
-
|
|
407
|
-
// ENHANCED: Clear lock screen bypass when calls end
|
|
408
|
-
updateMainActivityLockScreenBypass()
|
|
409
|
-
}
|
|
410
|
-
// NEW: Function to clear lock screen bypass
|
|
411
|
-
private fun clearLockScreenBypass(context: Context) {
|
|
412
|
-
try {
|
|
413
|
-
if (context is Activity) {
|
|
414
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
415
|
-
context.setShowWhenLocked(false)
|
|
416
|
-
context.setTurnScreenOn(false)
|
|
417
|
-
} else {
|
|
418
|
-
context.window.clearFlags(
|
|
419
|
-
android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
420
|
-
android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
|
|
421
|
-
android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
|
422
|
-
)
|
|
423
|
-
}
|
|
424
|
-
Log.d(TAG, "Lock screen bypass flags cleared for Activity")
|
|
425
|
-
}
|
|
426
|
-
} catch (e: Exception) {
|
|
427
|
-
Log.w(TAG, "Could not clear lock screen bypass flags: ${e.message}")
|
|
428
|
-
}
|
|
429
427
|
}
|
|
430
428
|
|
|
431
429
|
fun getActiveCalls(): List<CallInfo> = activeCalls.values.toList()
|
|
@@ -513,7 +511,7 @@ object CallEngine {
|
|
|
513
511
|
context.stopService(intent)
|
|
514
512
|
}
|
|
515
513
|
|
|
516
|
-
//
|
|
514
|
+
// FIXED: Corrected bringAppToForeground method
|
|
517
515
|
fun bringAppToForeground(context: Context) {
|
|
518
516
|
val packageName = context.packageName
|
|
519
517
|
val launchIntent = context.packageManager.getLaunchIntentForPackage(packageName)
|
|
@@ -521,21 +519,9 @@ object CallEngine {
|
|
|
521
519
|
|
|
522
520
|
// Handle lock screen bypass for active calls
|
|
523
521
|
if (isCallActive()) {
|
|
524
|
-
// ENHANCED: Add multiple flags for better lock screen bypass
|
|
525
522
|
launchIntent?.putExtra("BYPASS_LOCK_SCREEN", true)
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
529
|
-
launchIntent?.addFlags(Intent.FLAG_ACTIVITY_SHOW_WHEN_LOCKED or Intent.FLAG_ACTIVITY_TURN_SCREEN_ON)
|
|
530
|
-
} else {
|
|
531
|
-
launchIntent?.addFlags(
|
|
532
|
-
Intent.FLAG_ACTIVITY_SHOW_WHEN_LOCKED or
|
|
533
|
-
Intent.FLAG_ACTIVITY_TURN_SCREEN_ON or
|
|
534
|
-
Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
535
|
-
)
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
Log.d(TAG, "App brought to foreground with lock screen bypass for active call")
|
|
523
|
+
launchIntent?.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
|
524
|
+
Log.d(TAG, "App brought to foreground with lock screen bypass request for active call")
|
|
539
525
|
} else {
|
|
540
526
|
launchIntent?.removeExtra("BYPASS_LOCK_SCREEN")
|
|
541
527
|
Log.d(TAG, "App brought to foreground without lock screen bypass")
|
|
@@ -544,9 +530,9 @@ object CallEngine {
|
|
|
544
530
|
try {
|
|
545
531
|
context.startActivity(launchIntent)
|
|
546
532
|
|
|
547
|
-
//
|
|
533
|
+
// Small delay to ensure activity is created before updating bypass
|
|
548
534
|
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
|
|
549
|
-
|
|
535
|
+
updateLockScreenBypass()
|
|
550
536
|
}, 100)
|
|
551
537
|
|
|
552
538
|
} catch (e: Exception) {
|
|
@@ -554,9 +540,6 @@ object CallEngine {
|
|
|
554
540
|
}
|
|
555
541
|
}
|
|
556
542
|
|
|
557
|
-
// Rest of the methods remain the same...
|
|
558
|
-
// (getAudioDevices, setAudioRoute, keepScreenAwake, etc. - keeping them unchanged for brevity)
|
|
559
|
-
|
|
560
543
|
// --- Audio Device Management ---
|
|
561
544
|
fun getAudioDevices(): AudioRoutesInfo {
|
|
562
545
|
audioManager = appContext?.getSystemService(Context.AUDIO_SERVICE) as? AudioManager ?: run {
|