Improved mute handling so that Android system bar mic icon is not shown when call is muted
This commit is contained in:
@ -255,6 +255,7 @@ static void event_handler(enum bevent_ev ev, struct bevent *event, void *arg)
|
|||||||
len = re_snprintf(event_buf, sizeof event_buf, "transfer failed,%s", prm);
|
len = re_snprintf(event_buf, sizeof event_buf, "transfer failed,%s", prm);
|
||||||
break;
|
break;
|
||||||
case BEVENT_CALL_CLOSED:
|
case BEVENT_CALL_CLOSED:
|
||||||
|
audio_set_source(call_audio(call), "nil", NULL);
|
||||||
tone = call_scode(call) ? translate_errorcode(call_scode(call)) : "";
|
tone = call_scode(call) ? translate_errorcode(call_scode(call)) : "";
|
||||||
len = re_snprintf(event_buf, sizeof event_buf, "call closed,%s,%s", prm, tone);
|
len = re_snprintf(event_buf, sizeof event_buf, "call closed,%s,%s", prm, tone);
|
||||||
break;
|
break;
|
||||||
@ -1375,7 +1376,13 @@ JNIEXPORT void JNICALL Java_com_tutpro_baresip_Api_calls_1mute(
|
|||||||
const struct ua *ua = ua_le->data;
|
const struct ua *ua = ua_le->data;
|
||||||
for (call_le = list_head(ua_calls(ua)); call_le != NULL; call_le = call_le->next) {
|
for (call_le = list_head(ua_calls(ua)); call_le != NULL; call_le = call_le->next) {
|
||||||
const struct call *call = call_le->data;
|
const struct call *call = call_le->data;
|
||||||
audio_mute(call_audio(call), mute);
|
struct audio *audio = call_audio(call);
|
||||||
|
audio_mute(audio, mute);
|
||||||
|
if (mute)
|
||||||
|
audio_set_source(audio, "nil", NULL);
|
||||||
|
else
|
||||||
|
audio_set_source(audio, conf_config()->audio.src_mod,
|
||||||
|
conf_config()->audio.src_dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
re_thread_leave();
|
re_thread_leave();
|
||||||
@ -1909,6 +1916,7 @@ JNIEXPORT void JNICALL
|
|||||||
Java_com_tutpro_baresip_Api_AAudio_1close_1stream(JNIEnv *env, jobject obj)
|
Java_com_tutpro_baresip_Api_AAudio_1close_1stream(JNIEnv *env, jobject obj)
|
||||||
{
|
{
|
||||||
if (AAudio_stream != NULL) {
|
if (AAudio_stream != NULL) {
|
||||||
|
AAudioStream_requestStop(AAudio_stream);
|
||||||
AAudioStream_close(AAudio_stream);
|
AAudioStream_close(AAudio_stream);
|
||||||
AAudio_stream = NULL;
|
AAudio_stream = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1031,18 +1031,20 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
proximitySensing(proximitySensing)
|
proximitySensing(proximitySensing)
|
||||||
|
if (isMicMuted)
|
||||||
|
setMicMute(true)
|
||||||
}
|
}
|
||||||
if (!isMainVisible)
|
if (!isMainVisible)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
"call update" -> {
|
"call update" -> {
|
||||||
val newHeldState = when (ev[1].toInt()) {
|
|
||||||
Api.SDP_INACTIVE, Api.SDP_RECVONLY -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
val connection = ConnectionService.connections[callp]
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
|
val newHeldState = when (ev[1].toInt()) {
|
||||||
|
Api.SDP_INACTIVE, Api.SDP_RECVONLY -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
val connection = ConnectionService.connections[callp]
|
||||||
if (call.held && !newHeldState) {
|
if (call.held && !newHeldState) {
|
||||||
Log.d(TAG, "Call ${call.callp} un-held by peer.")
|
Log.d(TAG, "Call ${call.callp} un-held by peer.")
|
||||||
call.onhold = false
|
call.onhold = false
|
||||||
@ -1173,6 +1175,7 @@ class BaresipService: Service() {
|
|||||||
else -> DisconnectCause.REMOTE
|
else -> DisconnectCause.REMOTE
|
||||||
}
|
}
|
||||||
connection.setDisconnected(DisconnectCause(cause))
|
connection.setDisconnected(DisconnectCause(cause))
|
||||||
|
connection.safeDestroy()
|
||||||
ConnectionService.connections.remove(callp)
|
ConnectionService.connections.remove(callp)
|
||||||
}
|
}
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
@ -1201,15 +1204,8 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
val isConference = call.conferenceCall
|
val isConference = call.conferenceCall
|
||||||
val hasOtherCalls = synchronized(calls) { calls.any { it.ua == ua } }
|
val hasOtherCalls = synchronized(calls) { calls.any { it.ua == ua } }
|
||||||
if (noMoreCalls) {
|
if (noMoreCalls)
|
||||||
aec?.release()
|
releaseAudioEffects()
|
||||||
aec = null
|
|
||||||
agc?.release()
|
|
||||||
agc = null
|
|
||||||
ns?.release()
|
|
||||||
ns = null
|
|
||||||
recorderSessionId = 0
|
|
||||||
}
|
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
if (isConference && !hasOtherCalls) {
|
if (isConference && !hasOtherCalls) {
|
||||||
Log.d(TAG, "Last conference call closed, scheduling mixminus unload")
|
Log.d(TAG, "Last conference call closed, scheduling mixminus unload")
|
||||||
@ -1236,9 +1232,9 @@ class BaresipService: Service() {
|
|||||||
!reason.startsWith("Connection reset by")
|
!reason.startsWith("Connection reset by")
|
||||||
|
|
||||||
val missed = call.dir == "in" && call.startTime == null && !call.rejected
|
val missed = call.dir == "in" && call.startTime == null && !call.rejected
|
||||||
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
|
||||||
ev[2].contains(";cause=200")
|
|
||||||
if (ua.account.callHistory) {
|
if (ua.account.callHistory) {
|
||||||
|
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
||||||
|
ev[2].contains(";cause=200")
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val history = CallHistoryNew(aor, call.peerUri, call.dir)
|
val history = CallHistoryNew(aor, call.peerUri, call.dir)
|
||||||
history.stopTime = GregorianCalendar()
|
history.stopTime = GregorianCalendar()
|
||||||
@ -2512,7 +2508,7 @@ class BaresipService: Service() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (isMicMuted) {
|
if (isMicMuted) {
|
||||||
isMicMuted = false
|
setMicMute(false)
|
||||||
postServiceEvent(
|
postServiceEvent(
|
||||||
ServiceEvent(
|
ServiceEvent(
|
||||||
"mic muted,false",
|
"mic muted,false",
|
||||||
@ -2771,6 +2767,7 @@ class BaresipService: Service() {
|
|||||||
cm.unregisterNetworkCallback(networkCallback)
|
cm.unregisterNetworkCallback(networkCallback)
|
||||||
if (this::androidContactsObserver.isInitialized)
|
if (this::androidContactsObserver.isInitialized)
|
||||||
contentResolver.unregisterContentObserver(androidContactsObserver)
|
contentResolver.unregisterContentObserver(androidContactsObserver)
|
||||||
|
releaseAudioEffects()
|
||||||
isServiceClean = true
|
isServiceClean = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2849,6 +2846,19 @@ class BaresipService: Service() {
|
|||||||
private var btAdapter: BluetoothAdapter? = null
|
private var btAdapter: BluetoothAdapter? = null
|
||||||
private var audioFocusRequest: AudioFocusRequest? = null
|
private var audioFocusRequest: AudioFocusRequest? = null
|
||||||
|
|
||||||
|
private fun releaseAudioEffects() {
|
||||||
|
aec?.enabled = false
|
||||||
|
aec?.release()
|
||||||
|
aec = null
|
||||||
|
agc?.enabled = false
|
||||||
|
agc?.release()
|
||||||
|
agc = null
|
||||||
|
ns?.enabled = false
|
||||||
|
ns?.release()
|
||||||
|
ns = null
|
||||||
|
recorderSessionId = 0
|
||||||
|
}
|
||||||
|
|
||||||
var rt: Ringtone? = null
|
var rt: Ringtone? = null
|
||||||
|
|
||||||
var colorblind = false
|
var colorblind = false
|
||||||
@ -2873,6 +2883,15 @@ class BaresipService: Service() {
|
|||||||
return PhoneAccountHandle(componentName, PHONE_ACCOUNT_ID)
|
return PhoneAccountHandle(componentName, PHONE_ACCOUNT_ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setMicMute(mute: Boolean) {
|
||||||
|
instance?.let {
|
||||||
|
val am = it.getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
|
am.isMicrophoneMute = mute
|
||||||
|
}
|
||||||
|
isMicMuted = mute
|
||||||
|
Api.calls_mute(mute)
|
||||||
|
}
|
||||||
|
|
||||||
fun postServiceEvent(event: ServiceEvent) {
|
fun postServiceEvent(event: ServiceEvent) {
|
||||||
synchronized(serviceEvents) {
|
synchronized(serviceEvents) {
|
||||||
serviceEvents.add(event)
|
serviceEvents.add(event)
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class ConnectionService : ConnectionService() {
|
|||||||
fun onCallClosed(callp: Long) {
|
fun onCallClosed(callp: Long) {
|
||||||
connections[callp]?.let {
|
connections[callp]?.let {
|
||||||
it.setDisconnected(DisconnectCause(DisconnectCause.REMOTE))
|
it.setDisconnected(DisconnectCause(DisconnectCause.REMOTE))
|
||||||
|
it.safeDestroy()
|
||||||
connections.remove(callp)
|
connections.remove(callp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,6 +153,14 @@ class ConnectionService : ConnectionService() {
|
|||||||
inner class BaresipConnection(val uap: Long, var callp: Long) : Connection() {
|
inner class BaresipConnection(val uap: Long, var callp: Long) : Connection() {
|
||||||
|
|
||||||
var isDisconnecting = false
|
var isDisconnecting = false
|
||||||
|
private var isDestroyed = false
|
||||||
|
|
||||||
|
fun safeDestroy() {
|
||||||
|
if (!isDestroyed) {
|
||||||
|
isDestroyed = true
|
||||||
|
destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onAnswer() {
|
override fun onAnswer() {
|
||||||
Log.d(TAG, "Telecom Connection onAnswer $callp")
|
Log.d(TAG, "Telecom Connection onAnswer $callp")
|
||||||
@ -218,8 +227,7 @@ class ConnectionService : ConnectionService() {
|
|||||||
Log.d(TAG, "onCallAudioStateChanged: $state")
|
Log.d(TAG, "onCallAudioStateChanged: $state")
|
||||||
state.let {
|
state.let {
|
||||||
if (BaresipService.isMicMuted != it.isMuted) {
|
if (BaresipService.isMicMuted != it.isMuted) {
|
||||||
BaresipService.isMicMuted = it.isMuted
|
BaresipService.setMicMute(it.isMuted)
|
||||||
Api.calls_mute(it.isMuted)
|
|
||||||
BaresipService.postServiceEvent(
|
BaresipService.postServiceEvent(
|
||||||
ServiceEvent("mic muted,${it.isMuted}", arrayListOf(uap, callp),
|
ServiceEvent("mic muted,${it.isMuted}", arrayListOf(uap, callp),
|
||||||
System.nanoTime())
|
System.nanoTime())
|
||||||
|
|||||||
@ -610,14 +610,12 @@ private fun TopAppBar(
|
|||||||
.combinedClickable(
|
.combinedClickable(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (Call.call("connected") != null) {
|
if (Call.call("connected") != null) {
|
||||||
BaresipService.isMicMuted = !BaresipService.isMicMuted
|
val newMuteState = !BaresipService.isMicMuted
|
||||||
if (BaresipService.isMicMuted) {
|
BaresipService.setMicMute(newMuteState)
|
||||||
|
if (newMuteState)
|
||||||
viewModel.updateMicIcon(Icons.Filled.MicOff)
|
viewModel.updateMicIcon(Icons.Filled.MicOff)
|
||||||
Api.calls_mute(true)
|
else
|
||||||
} else {
|
|
||||||
viewModel.updateMicIcon(Icons.Filled.Mic)
|
viewModel.updateMicIcon(Icons.Filled.Mic)
|
||||||
Api.calls_mute(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
|
|||||||
Reference in New Issue
Block a user