Do heavy startup operations in background thread to prevent UI hangs and RemoteServiceException crashes on slow devices

Moved the foreground service promotion to the very start of the command handler to satisfy OS requirements
This commit is contained in:
Juha Heinanen
2026-06-25 20:00:06 +03:00
parent 0fcfc6abc5
commit a18235c2f0

View File

@ -507,6 +507,8 @@ class BaresipService: Service() {
} }
if (isStartReceived || isServiceRunning) return START_STICKY if (isStartReceived || isServiceRunning) return START_STICKY
showStatusNotification()
isStartReceived = true isStartReceived = true
if (VERSION.SDK_INT < 31) { if (VERSION.SDK_INT < 31) {
@ -539,77 +541,77 @@ class BaresipService: Service() {
Config.initialize(this) Config.initialize(this)
} }
if (contactsMode != "android") val userAgent = Config.variable("user_agent")
Contact.restoreBaresipContacts() val software = if (userAgent != "")
if (contactsMode != "baresip") { userAgent
Contact.loadAndroidContacts(this)
registerAndroidContactsObserver()
}
Contact.contactsUpdate()
val history = CallHistory.get()
if (history.isEmpty())
CallHistoryNew.restore()
else else
for (old in history) { "baresip v${BuildConfig.VERSION_NAME} " +
val new = CallHistoryNew(old.aor, old.peerUri, old.direction) "(Android ${VERSION.RELEASE}/${System.getProperty("os.arch") ?: "?"})"
new.stopTime = old.stopTime
new.startTime = old.startTime Thread {
new.recording = old.recording if (contactsMode != "android")
new.add() Contact.restoreBaresipContacts()
if (contactsMode != "baresip") {
Contact.loadAndroidContacts(this)
registerAndroidContactsObserver()
}
Contact.contactsUpdate()
val history = CallHistory.get()
if (history.isEmpty())
CallHistoryNew.restore()
else
for (old in history) {
val new = CallHistoryNew(old.aor, old.peerUri, old.direction)
new.stopTime = old.stopTime
new.startTime = old.startTime
new.recording = old.recording
new.add()
}
Blocked.restore()
BlockRule.restore()
val recordings = File(filesDir, "recordings")
val restored = File(filesPath, "restored")
if (restored.exists()) {
Log.d(TAG, "Clearing recordings")
CallHistoryNew.clearRecordings()
CallHistoryNew.save()
if (recordings.exists())
recordings.deleteRecursively()
restored.delete()
} }
Blocked.restore() File(filesDir, "recordings").mkdir()
BlockRule.restore() File(filesDir, "tmp").mkdir()
val recordings = File(filesDir, "recordings") Message.restore()
val restored = File(filesPath, "restored") hotSpotAddresses = Utils.hotSpotAddresses()
if (restored.exists()) { linkAddresses = linkAddresses()
Log.d(TAG, "Clearing recordings") var addresses = ""
CallHistoryNew.clearRecordings() for (la in linkAddresses)
CallHistoryNew.save() addresses = "$addresses;${la.key};${la.value}"
if (recordings.exists()) Log.i(TAG, "Link addresses: $addresses")
recordings.deleteRecursively() activeNetwork = cm.activeNetwork
restored.delete() Log.i(TAG, "Active network: $activeNetwork")
}
File(filesDir, "recordings").mkdir() registerPhoneAccount()
File(filesDir, "tmp").mkdir()
Message.restore() Log.i(TAG, "AEC/AGC/NS available = $aecAvailable/$agcAvailable/$nsAvailable")
hotSpotAddresses = Utils.hotSpotAddresses()
linkAddresses = linkAddresses()
var addresses = ""
for (la in linkAddresses)
addresses = "$addresses;${la.key};${la.value}"
Log.i(TAG, "Link addresses: $addresses")
activeNetwork = cm.activeNetwork
Log.i(TAG, "Active network: $activeNetwork")
registerPhoneAccount()
Log.i(TAG, "AEC/AGC/NS available = $aecAvailable/$agcAvailable/$nsAvailable")
val userAgent = Config.variable("user_agent")
Thread {
baresipStart( baresipStart(
filesPath, filesPath,
addresses.removePrefix(";"), addresses.removePrefix(";"),
logLevel, logLevel,
if (userAgent != "") software
userAgent
else
"baresip v${BuildConfig.VERSION_NAME} " +
"(Android ${VERSION.RELEASE}/${System.getProperty("os.arch") ?: "?"})"
) )
}.start() }.start()
isServiceRunning = true isServiceRunning = true
showStatusNotification()
if (linkAddresses.isEmpty()) if (linkAddresses.isEmpty())
toast(getString(R.string.no_network), Toast.LENGTH_LONG) toast(getString(R.string.no_network), Toast.LENGTH_LONG)
@ -1244,6 +1246,7 @@ class BaresipService: Service() {
"call closed" -> { "call closed" -> {
Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}") Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}")
nm.cancel(CALL_NOTIFICATION_ID)
val connection = ConnectionService.connections[callp] val connection = ConnectionService.connections[callp]
if (connection != null) { if (connection != null) {
val cause = when { val cause = when {
@ -2177,6 +2180,7 @@ 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()
nm.cancel(CALL_NOTIFICATION_ID)
val call = calls.find { it.callp == callp } val call = calls.find { it.callp == callp }
if (call != null) { if (call != null) {
val uap = call.ua.uap val uap = call.ua.uap