When incoming call or message arrives and baresip is not running, start baresip and show notification

This commit is contained in:
Juha Heinanen
2026-06-19 16:30:35 +03:00
parent 66e6656161
commit 8218e115ae
4 changed files with 82 additions and 40 deletions

View File

@ -121,6 +121,9 @@ class BaresipService: Service() {
private lateinit var stopState: String
private lateinit var quitTimer: CountDownTimer
private data class PendingMessage(val sender: String, val body: String, val time: Long)
private val pendingMessages = mutableListOf<PendingMessage>()
private var vbTimer: Timer? = null
private var origVolume = mutableMapOf<Int, Int>()
private var linkAddresses = mutableMapOf<String, String>()
@ -473,6 +476,29 @@ class BaresipService: Service() {
"Start" -> {
val sender = intent?.getStringExtra("sender")
val body = intent?.getStringExtra("body")
val time = intent?.getLongExtra("time", 0L) ?: 0L
if (sender != null && body != null && time != 0L) {
Handler(Looper.getMainLooper()).post {
if (isNativeReady) {
val mobileUa = uas.value.find { it.account.isMobile }
if (mobileUa != null)
handleIncomingMessage(mobileUa.uap, sender, body, time)
else
synchronized(pendingMessages) {
pendingMessages.add(PendingMessage(sender, body, time))
}
}
else
synchronized(pendingMessages) {
pendingMessages.add(PendingMessage(sender, body, time))
}
}
}
if (isStartReceived || isServiceRunning) return START_STICKY
isStartReceived = true
if (VERSION.SDK_INT < 31) {
@ -1646,7 +1672,30 @@ class BaresipService: Service() {
fun started() {
Log.d(TAG, "Received 'started' from baresip")
isNativeReady = true
addMobileUserAgent()
Handler(Looper.getMainLooper()).post {
addMobileUserAgent()
val mobileUa = uas.value.find { it.account.isMobile }
if (mobileUa != null)
synchronized(pendingMessages) {
for (m in pendingMessages)
handleIncomingMessage(mobileUa.uap, m.sender, m.body, m.time)
pendingMessages.clear()
}
// Process any calls that arrived while baresip is starting
InCallService.instance?.let { inCallService ->
for (call in inCallService.getCalls()) {
val aor = call.details.intentExtras?.getString("aor")
if (Call.ofCallp(call.hashCode().toLong()) == null) {
Log.d(TAG, "Processing pending external call ${call.hashCode()}")
handleExternalCall(call, aor)
}
}
}
}
if (VERSION.SDK_INT >= 31 && !telephonyCallbackRegistered) {
try {
telephonyManager.registerTelephonyCallback(mainExecutor, telephonyCallback)

View File

@ -23,9 +23,18 @@ class InCallService : InCallService() {
if (handle == baresipHandle) {
Log.d(TAG, "InCallService: Identified as SIP call")
// SIP call is already managed by ConnectionService/BaresipService
} else {
}
else {
Log.d(TAG, "InCallService: Identified as PSTN call from $handle")
val aor = call.details.intentExtras?.getString("aor")
if (BaresipService.instance == null) {
Log.i(TAG, "InCallService: BaresipService not running, starting it")
val intent = Intent(this, BaresipService::class.java)
intent.action = "Start"
androidx.core.content.ContextCompat.startForegroundService(this, intent)
}
BaresipService.instance?.handleExternalCall(call, aor)
}
}

View File

@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.provider.Telephony
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
/**
@ -38,24 +39,13 @@ class MmsReceiver : BroadcastReceiver() {
val body = getMmsText(context, id)
if (body.isNotEmpty()) {
Log.d(TAG, "Extracted MMS text from $address: $body")
val mobileUa = BaresipService.uas.value.find { it.account.isMobile }
if (mobileUa != null) {
// Notify Service for history update, notification, and alert sound
if (BaresipService.isServiceRunning) {
BaresipService.instance?.handleIncomingMessage(mobileUa.uap, "tel:$address", body, date)
} else {
// Service not running, at least save to history
val aor = mobileUa.account.aor
// Check if this message was already added (simple deduplication by timestamp)
val lastMsg = Message.messages().lastOrNull { m -> m.aor == aor }
if (lastMsg == null || lastMsg.timeStamp != date || lastMsg.peerUri != "tel:$address") {
Message(aor, "tel:$address", body, date, MESSAGE_DOWN, 0, "", true).add()
mobileUa.account.unreadMessages = true
}
}
}
Log.d(TAG, "Extracted MMS text from $address, starting service")
val serviceIntent = Intent(context, BaresipService::class.java)
serviceIntent.action = "Start"
serviceIntent.putExtra("sender", "tel:$address")
serviceIntent.putExtra("body", body)
serviceIntent.putExtra("time", date)
ContextCompat.startForegroundService(context, serviceIntent)
}
}
}
@ -90,11 +80,10 @@ class MmsReceiver : BroadcastReceiver() {
val type = it.getString(it.getColumnIndexOrThrow("ct"))
if (type == "text/plain") {
val data = it.getString(it.getColumnIndexOrThrow("_data"))
val body = if (data != null) {
val body = if (data != null)
getPartText(context, it.getString(it.getColumnIndexOrThrow("_id")))
} else {
else
it.getString(it.getColumnIndexOrThrow("text"))
}
if (body != null) sb.append(body)
}
}

View File

@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.provider.Telephony
import androidx.core.content.ContextCompat
class SmsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@ -15,20 +16,14 @@ class SmsReceiver : BroadcastReceiver() {
val body = messages.joinToString("") { it.displayMessageBody ?: "" }
val timestamp = messages[0].timestampMillis
Log.d(TAG, "Received SMS from $sender: $body")
Log.d(TAG, "Received SMS from $sender, starting service")
val mobileUa = BaresipService.uas.value.find { it.account.isMobile }
if (mobileUa != null) {
// Notify Service for history update, notification, and alert sound
if (BaresipService.isServiceRunning) {
BaresipService.instance?.handleIncomingMessage(mobileUa.uap, "tel:$sender", body, timestamp)
} else {
// Service not running, at least save to history
val aor = mobileUa.account.aor
Message(aor, "tel:$sender", body, timestamp, MESSAGE_DOWN, 0, "", true).add()
mobileUa.account.unreadMessages = true
}
}
val serviceIntent = Intent(context, BaresipService::class.java)
serviceIntent.action = "Start"
serviceIntent.putExtra("sender", "tel:$sender")
serviceIntent.putExtra("body", body)
serviceIntent.putExtra("time", timestamp)
ContextCompat.startForegroundService(context, serviceIntent)
}
}