@qusaieilouti99/call-manager 0.1.68 → 0.1.69
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.
|
@@ -629,7 +629,7 @@ object CallEngine {
|
|
|
629
629
|
})
|
|
630
630
|
}
|
|
631
631
|
|
|
632
|
-
// --- Audio Management
|
|
632
|
+
// --- Enhanced Audio Management ---
|
|
633
633
|
fun getAudioDevices(): AudioRoutesInfo {
|
|
634
634
|
val context = requireContext()
|
|
635
635
|
audioManager = audioManager ?: context.getSystemService(Context.AUDIO_SERVICE) as? AudioManager ?: run {
|
|
@@ -637,8 +637,12 @@ object CallEngine {
|
|
|
637
637
|
}
|
|
638
638
|
|
|
639
639
|
val devices = mutableSetOf<String>()
|
|
640
|
-
var currentRoute = "Earpiece"
|
|
641
640
|
|
|
641
|
+
// ALWAYS include Speaker and Earpiece for phone calls
|
|
642
|
+
devices.add("Speaker")
|
|
643
|
+
devices.add("Earpiece")
|
|
644
|
+
|
|
645
|
+
// Check for additional connected devices
|
|
642
646
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
643
647
|
val audioDeviceInfoList = audioManager?.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
644
648
|
audioDeviceInfoList?.forEach { device ->
|
|
@@ -649,24 +653,21 @@ object CallEngine {
|
|
|
649
653
|
AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_WIRED_HEADSET -> {
|
|
650
654
|
devices.add("Headset")
|
|
651
655
|
}
|
|
652
|
-
|
|
653
|
-
devices.add("Speaker")
|
|
654
|
-
}
|
|
655
|
-
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> {
|
|
656
|
-
devices.add("Earpiece")
|
|
657
|
-
}
|
|
656
|
+
// Speaker and Earpiece already added above
|
|
658
657
|
}
|
|
659
658
|
}
|
|
660
659
|
} else {
|
|
661
|
-
|
|
660
|
+
// For older versions, check for Bluetooth and Headset
|
|
661
|
+
if (audioManager?.isBluetoothA2dpOn == true || audioManager?.isBluetoothScoOn == true) {
|
|
662
|
+
devices.add("Bluetooth")
|
|
663
|
+
}
|
|
664
|
+
if (audioManager?.isWiredHeadsetOn == true) {
|
|
665
|
+
devices.add("Headset")
|
|
666
|
+
}
|
|
662
667
|
}
|
|
663
668
|
|
|
664
|
-
currentRoute =
|
|
665
|
-
|
|
666
|
-
audioManager?.isSpeakerphoneOn == true -> "Speaker"
|
|
667
|
-
audioManager?.isWiredHeadsetOn == true -> "Headset"
|
|
668
|
-
else -> "Earpiece"
|
|
669
|
-
}
|
|
669
|
+
val currentRoute = getCurrentAudioRoute()
|
|
670
|
+
Log.d(TAG, "Available audio devices: ${devices.toList()}, current route: $currentRoute")
|
|
670
671
|
|
|
671
672
|
return AudioRoutesInfo(devices.toTypedArray(), currentRoute)
|
|
672
673
|
}
|
|
@@ -678,6 +679,7 @@ object CallEngine {
|
|
|
678
679
|
|
|
679
680
|
val previousRoute = getCurrentAudioRoute()
|
|
680
681
|
|
|
682
|
+
// Reset all routes first
|
|
681
683
|
audioManager?.isSpeakerphoneOn = false
|
|
682
684
|
audioManager?.stopBluetoothSco()
|
|
683
685
|
audioManager?.isBluetoothScoOn = false
|
|
@@ -689,6 +691,7 @@ object CallEngine {
|
|
|
689
691
|
}
|
|
690
692
|
"Earpiece" -> {
|
|
691
693
|
audioManager?.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
694
|
+
// Earpiece is the default - just ensure speaker and bluetooth are off
|
|
692
695
|
}
|
|
693
696
|
"Bluetooth" -> {
|
|
694
697
|
audioManager?.startBluetoothSco()
|
|
@@ -697,6 +700,7 @@ object CallEngine {
|
|
|
697
700
|
}
|
|
698
701
|
"Headset" -> {
|
|
699
702
|
audioManager?.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
703
|
+
// Headset routing is automatic when connected
|
|
700
704
|
}
|
|
701
705
|
else -> {
|
|
702
706
|
Log.w(TAG, "Unknown audio route: $route")
|
|
@@ -704,12 +708,30 @@ object CallEngine {
|
|
|
704
708
|
}
|
|
705
709
|
}
|
|
706
710
|
|
|
711
|
+
val newRoute = getCurrentAudioRoute()
|
|
712
|
+
if (previousRoute != newRoute) {
|
|
713
|
+
// Emit unified event with full context
|
|
714
|
+
emitAudioRouteChanged()
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
707
718
|
val newRoute = getCurrentAudioRoute()
|
|
708
719
|
if (previousRoute != newRoute) {
|
|
709
720
|
emitEvent(CallEventType.AUDIO_ROUTE_CHANGED, JSONObject().put("route", newRoute))
|
|
710
721
|
}
|
|
711
722
|
}
|
|
712
723
|
|
|
724
|
+
// UNIFIED event emission - always sends full audio context
|
|
725
|
+
private fun emitAudioRouteChanged() {
|
|
726
|
+
val audioInfo = getAudioDevices()
|
|
727
|
+
val jsonPayload = JSONObject().apply {
|
|
728
|
+
put("devices", JSONArray(audioInfo.devices.toList()))
|
|
729
|
+
put("currentRoute", audioInfo.currentRoute)
|
|
730
|
+
}
|
|
731
|
+
emitEvent(CallEventType.AUDIO_ROUTE_CHANGED, jsonPayload)
|
|
732
|
+
Log.d(TAG, "Audio route changed: ${audioInfo.currentRoute}, available: ${audioInfo.devices.toList()}")
|
|
733
|
+
}
|
|
734
|
+
|
|
713
735
|
private fun getCurrentAudioRoute(): String {
|
|
714
736
|
return when {
|
|
715
737
|
audioManager?.isBluetoothScoOn == true -> "Bluetooth"
|
|
@@ -748,15 +770,28 @@ object CallEngine {
|
|
|
748
770
|
}
|
|
749
771
|
}
|
|
750
772
|
|
|
751
|
-
// --- Audio Device Callback ---
|
|
773
|
+
// --- Audio Device Callback (simplified) ---
|
|
752
774
|
private val audioDeviceCallback = object : AudioDeviceCallback() {
|
|
753
775
|
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>?) {
|
|
754
|
-
|
|
776
|
+
Log.d(TAG, "Audio devices added")
|
|
777
|
+
emitAudioDevicesChanged()
|
|
755
778
|
}
|
|
756
779
|
|
|
757
780
|
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
|
|
758
|
-
|
|
781
|
+
Log.d(TAG, "Audio devices removed")
|
|
782
|
+
emitAudioDevicesChanged()
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Separate event for when physical devices are added/removed
|
|
787
|
+
private fun emitAudioDevicesChanged() {
|
|
788
|
+
val audioInfo = getAudioDevices()
|
|
789
|
+
val jsonPayload = JSONObject().apply {
|
|
790
|
+
put("devices", JSONArray(audioInfo.devices.toList()))
|
|
791
|
+
put("currentRoute", audioInfo.currentRoute)
|
|
759
792
|
}
|
|
793
|
+
emitEvent(CallEventType.AUDIO_DEVICES_CHANGED, jsonPayload)
|
|
794
|
+
Log.d(TAG, "Audio devices changed: available: ${audioInfo.devices.toList()}")
|
|
760
795
|
}
|
|
761
796
|
|
|
762
797
|
fun registerAudioDeviceCallback() {
|
|
@@ -771,22 +806,6 @@ object CallEngine {
|
|
|
771
806
|
audioManager?.unregisterAudioDeviceCallback(audioDeviceCallback)
|
|
772
807
|
}
|
|
773
808
|
|
|
774
|
-
private fun emitAudioDevicesChangedIfNeeded() {
|
|
775
|
-
val currentAudioInfo = getAudioDevices()
|
|
776
|
-
|
|
777
|
-
if (lastAudioRoutesInfo == null ||
|
|
778
|
-
!currentAudioInfo.devices.contentEquals(lastAudioRoutesInfo!!.devices) ||
|
|
779
|
-
currentAudioInfo.currentRoute != lastAudioRoutesInfo!!.currentRoute) {
|
|
780
|
-
|
|
781
|
-
lastAudioRoutesInfo = currentAudioInfo
|
|
782
|
-
val jsonPayload = JSONObject().apply {
|
|
783
|
-
put("devices", JSONArray(currentAudioInfo.devices.toList()))
|
|
784
|
-
put("currentRoute", currentAudioInfo.currentRoute)
|
|
785
|
-
}
|
|
786
|
-
emitEvent(CallEventType.AUDIO_DEVICES_CHANGED, jsonPayload)
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
809
|
// --- Screen Management ---
|
|
791
810
|
fun keepScreenAwake(keepAwake: Boolean) {
|
|
792
811
|
val context = requireContext()
|
|
@@ -84,19 +84,11 @@ class MyConnection(
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
// Only emit route change if route actually changed
|
|
87
88
|
if (lastAudioState == null || lastAudioState!!.route != state.route) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
CallAudioState.ROUTE_BLUETOOTH -> "Bluetooth"
|
|
92
|
-
CallAudioState.ROUTE_WIRED_HEADSET -> "Headset"
|
|
93
|
-
else -> "Unknown"
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
CallEngine.emitEvent(
|
|
97
|
-
CallEventType.AUDIO_ROUTE_CHANGED,
|
|
98
|
-
JSONObject().put("callId", callId).put("route", routeName)
|
|
99
|
-
)
|
|
89
|
+
// Don't emit here - let CallEngine handle it to avoid duplication
|
|
90
|
+
// The system audio state change will be detected by CallEngine's audio management
|
|
91
|
+
Log.d(TAG, "System audio route changed to: ${state.route} for callId: $callId")
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
lastAudioState = state
|