@qusaieilouti99/call-manager 0.1.146 → 0.1.147
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.
|
@@ -44,7 +44,6 @@ object CallEngine {
|
|
|
44
44
|
fun onCallEnded(callId: String)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
// --- NEW: Restored LockScreenBypassCallback interface ---
|
|
48
47
|
interface LockScreenBypassCallback {
|
|
49
48
|
fun onLockScreenBypassChanged(shouldBypass: Boolean)
|
|
50
49
|
}
|
|
@@ -80,11 +79,9 @@ object CallEngine {
|
|
|
80
79
|
private var eventHandler: ((CallEventType, String) -> Unit)? = null
|
|
81
80
|
private val cachedEvents = mutableListOf<Pair<CallEventType, String>>()
|
|
82
81
|
|
|
83
|
-
// --- Modern Audio Management State ---
|
|
84
82
|
private var userSelectedAudioRoute: String? = null
|
|
85
83
|
private val audioStateLock = Any()
|
|
86
84
|
|
|
87
|
-
// --- NEW: Restored Lock Screen Bypass State ---
|
|
88
85
|
private var lockScreenBypassActive = false
|
|
89
86
|
private val lockScreenBypassCallbacks = mutableSetOf<LockScreenBypassCallback>()
|
|
90
87
|
|
|
@@ -93,7 +90,7 @@ object CallEngine {
|
|
|
93
90
|
if (isInitialized.compareAndSet(false, true)) {
|
|
94
91
|
appContext = context.applicationContext
|
|
95
92
|
audioManager = appContext?.getSystemService(Context.AUDIO_SERVICE) as? AudioManager
|
|
96
|
-
registerAudioDeviceCallback()
|
|
93
|
+
registerAudioDeviceCallback()
|
|
97
94
|
Log.d(TAG, "CallEngine initialized successfully")
|
|
98
95
|
}
|
|
99
96
|
}
|
|
@@ -144,7 +141,6 @@ object CallEngine {
|
|
|
144
141
|
stopRingtone()
|
|
145
142
|
}
|
|
146
143
|
|
|
147
|
-
// --- NEW: Restored Lock Screen Bypass Functions ---
|
|
148
144
|
fun registerLockScreenBypassCallback(callback: LockScreenBypassCallback) {
|
|
149
145
|
lockScreenBypassCallbacks.add(callback)
|
|
150
146
|
}
|
|
@@ -341,11 +337,9 @@ object CallEngine {
|
|
|
341
337
|
startForegroundService()
|
|
342
338
|
keepScreenAwake(true)
|
|
343
339
|
|
|
344
|
-
// Set initial audio route using the new robust system
|
|
345
340
|
synchronized(audioStateLock) {
|
|
346
|
-
userSelectedAudioRoute = null
|
|
341
|
+
userSelectedAudioRoute = null
|
|
347
342
|
}
|
|
348
|
-
// Give the audio system a moment to initialize after the call becomes active
|
|
349
343
|
mainHandler.postDelayed({
|
|
350
344
|
updateAndApplyAudioRoute()
|
|
351
345
|
}, 300)
|
|
@@ -466,10 +460,6 @@ object CallEngine {
|
|
|
466
460
|
it.value.state == CallState.HELD
|
|
467
461
|
}
|
|
468
462
|
|
|
469
|
-
/**
|
|
470
|
-
* Sets the user's desired audio route. This will be respected until a
|
|
471
|
-
* higher-priority device connects or this route becomes unavailable.
|
|
472
|
-
*/
|
|
473
463
|
fun setAudioRoute(route: String) {
|
|
474
464
|
synchronized(audioStateLock) {
|
|
475
465
|
Log.d(TAG, "User requested audio route: $route")
|
|
@@ -478,12 +468,16 @@ object CallEngine {
|
|
|
478
468
|
updateAndApplyAudioRoute()
|
|
479
469
|
}
|
|
480
470
|
|
|
481
|
-
/**
|
|
482
|
-
* Central function to determine and apply the correct audio route.
|
|
483
|
-
* This is the single source of truth for audio routing decisions.
|
|
484
|
-
*/
|
|
485
471
|
private fun updateAndApplyAudioRoute() {
|
|
486
|
-
|
|
472
|
+
// *** CRITICAL FIX ***
|
|
473
|
+
// Check for null currentCallId *before* using it as a key.
|
|
474
|
+
val callId = currentCallId
|
|
475
|
+
if (callId == null) {
|
|
476
|
+
Log.d(TAG, "Skipping audio route update: currentCallId is null.")
|
|
477
|
+
return
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
val call = activeCalls[callId]
|
|
487
481
|
if (call == null || call.state != CallState.ACTIVE) {
|
|
488
482
|
Log.d(TAG, "Skipping audio route update: No active call.")
|
|
489
483
|
return
|
|
@@ -493,11 +487,9 @@ object CallEngine {
|
|
|
493
487
|
val am = audioManager ?: return
|
|
494
488
|
val availableDevices = getAvailableAudioDevices()
|
|
495
489
|
|
|
496
|
-
// Determine the target route based on priority
|
|
497
490
|
val targetRoute = if (userSelectedAudioRoute != null && availableDevices.contains(userSelectedAudioRoute)) {
|
|
498
|
-
userSelectedAudioRoute!!
|
|
491
|
+
userSelectedAudioRoute!!
|
|
499
492
|
} else {
|
|
500
|
-
// Auto-select based on priority
|
|
501
493
|
when {
|
|
502
494
|
availableDevices.contains("Bluetooth") -> "Bluetooth"
|
|
503
495
|
availableDevices.contains("Headset") -> "Headset"
|
|
@@ -508,7 +500,6 @@ object CallEngine {
|
|
|
508
500
|
|
|
509
501
|
Log.d(TAG, "Updating audio route. Available: $availableDevices, User Pref: $userSelectedAudioRoute, Target: $targetRoute")
|
|
510
502
|
|
|
511
|
-
// Apply the target route
|
|
512
503
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
513
504
|
|
|
514
505
|
when (targetRoute) {
|
|
@@ -534,7 +525,6 @@ object CallEngine {
|
|
|
534
525
|
}
|
|
535
526
|
}
|
|
536
527
|
|
|
537
|
-
// After applying, emit the result
|
|
538
528
|
mainHandler.postDelayed({ emitAudioRouteChanged() }, 100)
|
|
539
529
|
}
|
|
540
530
|
}
|
|
@@ -542,8 +532,8 @@ object CallEngine {
|
|
|
542
532
|
private fun getAvailableAudioDevices(): Set<String> {
|
|
543
533
|
val am = audioManager ?: return emptySet()
|
|
544
534
|
val devices = mutableSetOf<String>()
|
|
545
|
-
devices.add("Earpiece")
|
|
546
|
-
devices.add("Speaker")
|
|
535
|
+
devices.add("Earpiece")
|
|
536
|
+
devices.add("Speaker")
|
|
547
537
|
|
|
548
538
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
549
539
|
val audioDevices = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
@@ -591,7 +581,6 @@ object CallEngine {
|
|
|
591
581
|
private val audioDeviceCallback = object : AudioDeviceCallback() {
|
|
592
582
|
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>) {
|
|
593
583
|
Log.d(TAG, "Audio devices added. Triggering audio route update.")
|
|
594
|
-
// A new device was added, reset user preference to allow auto-switch to higher priority device
|
|
595
584
|
synchronized(audioStateLock) {
|
|
596
585
|
userSelectedAudioRoute = null
|
|
597
586
|
}
|
|
@@ -599,7 +588,6 @@ object CallEngine {
|
|
|
599
588
|
}
|
|
600
589
|
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) {
|
|
601
590
|
Log.d(TAG, "Audio devices removed. Triggering audio route update.")
|
|
602
|
-
// A device was removed, if it was the user's selection, clear it
|
|
603
591
|
synchronized(audioStateLock) {
|
|
604
592
|
val removedDeviceTypes = removedDevices.map {
|
|
605
593
|
when(it.type) {
|
|
@@ -624,7 +612,6 @@ object CallEngine {
|
|
|
624
612
|
Log.d(TAG, "Performing cleanup")
|
|
625
613
|
stopForegroundService()
|
|
626
614
|
keepScreenAwake(false)
|
|
627
|
-
// Reset audio state
|
|
628
615
|
synchronized(audioStateLock) {
|
|
629
616
|
userSelectedAudioRoute = null
|
|
630
617
|
}
|
|
@@ -644,7 +631,6 @@ object CallEngine {
|
|
|
644
631
|
description = "Notifications for incoming calls"
|
|
645
632
|
setBypassDnd(true)
|
|
646
633
|
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
|
647
|
-
// **CRITICAL FIX**: Set sound to null. We will manage the ringtone manually.
|
|
648
634
|
setSound(null, null)
|
|
649
635
|
}
|
|
650
636
|
val manager = context.getSystemService(NotificationManager::class.java)
|
|
@@ -655,7 +641,7 @@ object CallEngine {
|
|
|
655
641
|
private fun showIncomingCallUI(callId: String, callerName: String, callType: String, callerPicUrl: String?) {
|
|
656
642
|
val context = requireContext()
|
|
657
643
|
Log.d(TAG, "Showing incoming call UI for $callId")
|
|
658
|
-
createNotificationChannel()
|
|
644
|
+
createNotificationChannel()
|
|
659
645
|
|
|
660
646
|
showCallActivityOverlay(context, callId, callerName, callType, callerPicUrl)
|
|
661
647
|
showStandardNotification(context, callId, callerName, callType, callerPicUrl)
|