@@ -4,6 +4,7 @@ import android.view.Surface
44import android.view.SurfaceView
55import android.view.SurfaceHolder
66import android.media.AudioFormat
7+ import android.media.AudioDeviceCallback
78import android.media.AudioDeviceInfo
89import android.media.AudioManager
910import android.media.AudioTrack
@@ -24,6 +25,17 @@ class HybridWebrtcView(val context: ThemedReactContext) : HybridWebrtcViewSpec()
2425 private var previousMode: Int? = null
2526 private var previousSpeakerphoneOn: Boolean? = null
2627 private var communicationRouteApplied = false
28+ private var communicationModeApplied = false
29+ private var audioDeviceCallbackRegistered = false
30+ private val audioDeviceCallback = object : AudioDeviceCallback () {
31+ override fun onAudioDevicesAdded (addedDevices : Array <out AudioDeviceInfo >) {
32+ view.post { refreshAudioRouteIfNeeded() }
33+ }
34+
35+ override fun onAudioDevicesRemoved (removedDevices : Array <out AudioDeviceInfo >) {
36+ view.post { refreshAudioRouteIfNeeded() }
37+ }
38+ }
2739
2840 companion object {
2941 private var audioTrack = AudioTrack (
@@ -71,6 +83,8 @@ class HybridWebrtcView(val context: ThemedReactContext) : HybridWebrtcViewSpec()
7183
7284
7385 init {
86+ audioManager.registerAudioDeviceCallback(audioDeviceCallback, null )
87+ audioDeviceCallbackRegistered = true
7488 view.holder.addCallback(object : SurfaceHolder .Callback {
7589 override fun surfaceCreated (holder : SurfaceHolder ) {
7690 updateVideoPipeId(_videoPipeId , holder.surface)
@@ -112,6 +126,10 @@ class HybridWebrtcView(val context: ThemedReactContext) : HybridWebrtcViewSpec()
112126 }
113127
114128 override fun dispose () {
129+ if (audioDeviceCallbackRegistered) {
130+ audioManager.unregisterAudioDeviceCallback(audioDeviceCallback)
131+ audioDeviceCallbackRegistered = false
132+ }
115133 if (this .audioSubscriptionId > 0 ) {
116134 this .unsubscribe(this .audioSubscriptionId)
117135 this .audioSubscriptionId = - 1
@@ -127,12 +145,7 @@ class HybridWebrtcView(val context: ThemedReactContext) : HybridWebrtcViewSpec()
127145 }
128146 previousMode = audioManager.mode
129147 previousSpeakerphoneOn = audioManager.isSpeakerphoneOn
130- audioManager.mode = AudioManager .MODE_IN_COMMUNICATION
131- @Suppress(" DEPRECATION" )
132- run {
133- audioManager.isSpeakerphoneOn = false
134- }
135- routeAudioTrackToPreferredOutput()
148+ applyRouteForCurrentDevices()
136149 communicationRouteApplied = true
137150 }
138151
@@ -141,19 +154,42 @@ class HybridWebrtcView(val context: ThemedReactContext) : HybridWebrtcViewSpec()
141154 return
142155 }
143156 audioTrack.setPreferredDevice(null )
144- previousSpeakerphoneOn?.let { audioManager.isSpeakerphoneOn = it }
145- previousMode?.let { audioManager.mode = it }
157+ if (communicationModeApplied) {
158+ previousSpeakerphoneOn?.let { audioManager.isSpeakerphoneOn = it }
159+ previousMode?.let { audioManager.mode = it }
160+ }
146161 previousSpeakerphoneOn = null
147162 previousMode = null
163+ communicationModeApplied = false
148164 communicationRouteApplied = false
149165 }
150166
151- private fun routeAudioTrackToPreferredOutput () {
152- val target = selectPreferredOutputDevice()
153- if (target != null ) {
154- audioTrack.setPreferredDevice(target)
167+ private fun refreshAudioRouteIfNeeded () {
168+ if (! communicationRouteApplied || audioSubscriptionId <= 0 || _audioPipeId .isNullOrEmpty()) {
169+ return
170+ }
171+ applyRouteForCurrentDevices()
172+ }
173+
174+ private fun applyRouteForCurrentDevices () {
175+ val targetOutput = selectPreferredOutputDevice()
176+ if (targetOutput != null ) {
177+ audioTrack.setPreferredDevice(targetOutput)
178+ if (communicationModeApplied) {
179+ previousSpeakerphoneOn?.let { audioManager.isSpeakerphoneOn = it }
180+ previousMode?.let { audioManager.mode = it }
181+ communicationModeApplied = false
182+ }
155183 } else {
156184 audioTrack.setPreferredDevice(null )
185+ if (! communicationModeApplied) {
186+ audioManager.mode = AudioManager .MODE_IN_COMMUNICATION
187+ @Suppress(" DEPRECATION" )
188+ run {
189+ audioManager.isSpeakerphoneOn = false
190+ }
191+ communicationModeApplied = true
192+ }
157193 }
158194 }
159195
0 commit comments