@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 (SIMPLIFIED - NO MANUAL AUDIO FOCUS) ---
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
- AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> {
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
- devices.addAll(listOf("Speaker", "Earpiece"))
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 = when {
665
- audioManager?.isBluetoothScoOn == true -> "Bluetooth"
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
- emitAudioDevicesChangedIfNeeded()
776
+ Log.d(TAG, "Audio devices added")
777
+ emitAudioDevicesChanged()
755
778
  }
756
779
 
757
780
  override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>?) {
758
- emitAudioDevicesChangedIfNeeded()
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
- val routeName = when (state.route) {
89
- CallAudioState.ROUTE_SPEAKER -> "Speaker"
90
- CallAudioState.ROUTE_EARPIECE -> "Earpiece"
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qusaieilouti99/call-manager",
3
- "version": "0.1.68",
3
+ "version": "0.1.69",
4
4
  "description": "Call manager",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",