Solved call hangup issues
This commit is contained in:
@@ -1075,7 +1075,6 @@ class BaresipService: Service() {
|
|||||||
if (!Call.inCall())
|
if (!Call.inCall())
|
||||||
proximitySensing(false)
|
proximitySensing(false)
|
||||||
}
|
}
|
||||||
ConnectionService.lastDisconnectTime = System.currentTimeMillis()
|
|
||||||
val connection = ConnectionService.connections[callp]
|
val connection = ConnectionService.connections[callp]
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
val cause = when {
|
val cause = when {
|
||||||
@@ -1086,13 +1085,10 @@ class BaresipService: Service() {
|
|||||||
else -> DisconnectCause.REMOTE
|
else -> DisconnectCause.REMOTE
|
||||||
}
|
}
|
||||||
connection.setDisconnected(DisconnectCause(cause))
|
connection.setDisconnected(DisconnectCause(cause))
|
||||||
Handler(Looper.getMainLooper()).postDelayed({
|
connection.destroy()
|
||||||
connection.destroy()
|
ConnectionService.connections.remove(callp)
|
||||||
ConnectionService.connections.remove(callp)
|
|
||||||
updateStatusNotification()
|
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
nm.cancel(CALL_NOTIFICATION_ID)
|
updateStatusNotification()
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
@@ -1229,6 +1225,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1671,35 +1668,32 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (activeCall != null) {
|
if (activeCall != null) {
|
||||||
if (VERSION.SDK_INT >= 29)
|
if (!isNotificationInCall) {
|
||||||
startForeground(
|
// Only call startForeground when the FIRST call starts.
|
||||||
STATUS_NOTIFICATION_ID,
|
if (VERSION.SDK_INT >= 29)
|
||||||
notification,
|
startForeground(STATUS_NOTIFICATION_ID, notification, foregroundServiceType(activeCall))
|
||||||
foregroundServiceType(activeCall)
|
else
|
||||||
)
|
startForeground(STATUS_NOTIFICATION_ID, notification)
|
||||||
|
isNotificationInCall = true
|
||||||
|
}
|
||||||
else
|
else
|
||||||
startForeground(STATUS_NOTIFICATION_ID, notification)
|
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
||||||
isNotificationInCall = true
|
|
||||||
} else {
|
} else {
|
||||||
// If we are currently in a call notification mode, downgrade to standby FGS.
|
|
||||||
// We call stopForeground(REMOVE) to explicitly clear the system's telephony UI context
|
|
||||||
// that might be persisting the timer/peer info on the lock screen.
|
|
||||||
if (isNotificationInCall) {
|
if (isNotificationInCall) {
|
||||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||||
|
// Only call startForeground to drop the "Call" type when the LAST call ends.
|
||||||
|
if (VERSION.SDK_INT >= 29)
|
||||||
|
startForeground(STATUS_NOTIFICATION_ID, notification, foregroundServiceType())
|
||||||
|
else
|
||||||
|
startForeground(STATUS_NOTIFICATION_ID, notification)
|
||||||
isNotificationInCall = false
|
isNotificationInCall = false
|
||||||
}
|
}
|
||||||
if (VERSION.SDK_INT >= 29)
|
|
||||||
startForeground(
|
|
||||||
STATUS_NOTIFICATION_ID,
|
|
||||||
notification,
|
|
||||||
foregroundServiceType()
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
startForeground(STATUS_NOTIFICATION_ID, notification)
|
// Already in standby, just keep the notification current.
|
||||||
|
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to update foreground notification: ${e.message}")
|
Log.e(TAG, "Failed to update notification: ${e.message}")
|
||||||
// Fallback to standard notification if promotion/update fails
|
|
||||||
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1847,7 +1841,6 @@ class BaresipService: Service() {
|
|||||||
fun handleExternalCallRemoved(telecomCall: android.telecom.Call) {
|
fun handleExternalCallRemoved(telecomCall: android.telecom.Call) {
|
||||||
val callp = telecomCall.hashCode().toLong()
|
val callp = telecomCall.hashCode().toLong()
|
||||||
val call = calls.find { it.callp == callp }
|
val call = calls.find { it.callp == callp }
|
||||||
nm.cancel(CALL_NOTIFICATION_ID)
|
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
|
|||||||
@@ -232,36 +232,48 @@ open class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun calls(): ArrayList<Call> {
|
fun calls(): ArrayList<Call> {
|
||||||
return BaresipService.calls
|
synchronized(BaresipService.calls) {
|
||||||
|
return ArrayList(BaresipService.calls)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ofCallp(callp: Long): Call? {
|
fun ofCallp(callp: Long): Call? {
|
||||||
for (c in BaresipService.calls)
|
synchronized(BaresipService.calls) {
|
||||||
if (c.callp == callp) return c
|
for (c in BaresipService.calls)
|
||||||
return null
|
if (c.callp == callp) return c
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun call(status: String): Call? {
|
fun call(status: String): Call? {
|
||||||
for (c in BaresipService.calls)
|
synchronized(BaresipService.calls) {
|
||||||
if (c.status.value == status) return c
|
for (c in BaresipService.calls)
|
||||||
return null
|
if (c.status.value == status) return c
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun inCall(): Boolean {
|
fun inCall(): Boolean {
|
||||||
return BaresipService.calls.isNotEmpty()
|
synchronized(BaresipService.calls) {
|
||||||
|
return BaresipService.calls.isNotEmpty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasTelecomCall(): Boolean {
|
fun hasTelecomCall(): Boolean {
|
||||||
return BaresipService.calls.any {
|
synchronized(BaresipService.calls) {
|
||||||
it is ExternalCall || ConnectionService.connections.containsKey(it.callp)
|
return BaresipService.calls.any {
|
||||||
} || ConnectionService.pendingOutgoingConnection != null
|
it is ExternalCall || ConnectionService.connections.containsKey(it.callp)
|
||||||
|
} || ConnectionService.pendingOutgoingConnection != null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAnyCallActive(ctx: Context): Boolean {
|
fun isAnyCallActive(ctx: Context): Boolean {
|
||||||
// Check if there exist SIP calls that are not onhold or held
|
synchronized(BaresipService.calls) {
|
||||||
if (BaresipService.calls.any { !it.onhold && !it.held }) return true
|
// Check if there exist SIP calls that are not onhold or held
|
||||||
// MODE_IN_CALL indicates a PSTN call is active
|
if (BaresipService.calls.any { !it.onhold && !it.held }) return true
|
||||||
return Utils.isAudioMode(ctx, AudioManager.MODE_IN_CALL)
|
// MODE_IN_CALL indicates a PSTN call is active
|
||||||
|
return Utils.isAudioMode(ctx, AudioManager.MODE_IN_CALL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,14 +176,11 @@ class ConnectionService : ConnectionService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisconnect() {
|
override fun onDisconnect() {
|
||||||
if (isDisconnecting) {
|
val now = System.currentTimeMillis()
|
||||||
Log.d(TAG, "onDisconnect already in progress for $callp")
|
if (now - lastDisconnectTime < 500) return
|
||||||
return
|
lastDisconnectTime = now
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "Telecom Connection onDisconnect $callp")
|
Log.d(TAG, "Telecom Connection onDisconnect $callp")
|
||||||
isDisconnecting = true
|
|
||||||
lastDisconnectTime = System.currentTimeMillis()
|
|
||||||
|
|
||||||
if (callp == 0L) {
|
if (callp == 0L) {
|
||||||
pendingOutgoingConnection = null
|
pendingOutgoingConnection = null
|
||||||
@@ -191,16 +188,12 @@ class ConnectionService : ConnectionService() {
|
|||||||
destroy()
|
destroy()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val call = Call.ofCallp(callp)
|
|
||||||
if (call != null)
|
Api.ua_hangup(uap, callp, 0, "")
|
||||||
Api.ua_hangup(uap, callp, 0, "")
|
|
||||||
setDisconnected(DisconnectCause(DisconnectCause.LOCAL))
|
setDisconnected(DisconnectCause(DisconnectCause.LOCAL))
|
||||||
connections.remove(callp)
|
connections.remove(callp)
|
||||||
destroy()
|
destroy()
|
||||||
// Allow other disconnects after a short period to prevent the "Telecom Cascade" effect
|
|
||||||
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
|
|
||||||
isDisconnecting = false
|
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAbort() {
|
override fun onAbort() {
|
||||||
|
|||||||
Reference in New Issue
Block a user