Foregound service type improvement
Code formating improvements
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
@file:Suppress("DEPRECATION")
|
@file:Suppress("DEPRECATION")
|
||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.Manifest.permission.RECORD_AUDIO
|
import android.Manifest.permission.RECORD_AUDIO
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
@ -78,10 +79,6 @@ import androidx.core.net.toUri
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.tutpro.baresip.Utils.e164Uri
|
import com.tutpro.baresip.Utils.e164Uri
|
||||||
import com.tutpro.baresip.Utils.toCircle
|
import com.tutpro.baresip.Utils.toCircle
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
@ -92,6 +89,10 @@ import java.util.TimerTask
|
|||||||
import kotlin.concurrent.schedule
|
import kotlin.concurrent.schedule
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class BaresipService: Service() {
|
class BaresipService: Service() {
|
||||||
|
|
||||||
@ -333,8 +334,10 @@ class BaresipService: Service() {
|
|||||||
override fun onReceive(ctx: Context, intent: Intent) {
|
override fun onReceive(ctx: Context, intent: Intent) {
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED -> {
|
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED -> {
|
||||||
val state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
|
val state = intent.getIntExtra(
|
||||||
BluetoothHeadset.STATE_DISCONNECTED)
|
BluetoothHeadset.EXTRA_STATE,
|
||||||
|
BluetoothHeadset.STATE_DISCONNECTED
|
||||||
|
)
|
||||||
when (state) {
|
when (state) {
|
||||||
BluetoothHeadset.STATE_CONNECTED -> {
|
BluetoothHeadset.STATE_CONNECTED -> {
|
||||||
Log.d(TAG, "Bluetooth headset is connected")
|
Log.d(TAG, "Bluetooth headset is connected")
|
||||||
@ -412,8 +415,10 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proximityWakeLock = pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
proximityWakeLock = pm.newWakeLock(
|
||||||
"com.tutpro.baresip:proximity_wakelock")
|
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||||
|
"com.tutpro.baresip:proximity_wakelock"
|
||||||
|
)
|
||||||
|
|
||||||
wifiLock = if (VERSION.SDK_INT < 29) {
|
wifiLock = if (VERSION.SDK_INT < 29) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
@ -597,7 +602,7 @@ class BaresipService: Service() {
|
|||||||
userAgent
|
userAgent
|
||||||
else
|
else
|
||||||
"baresip v${BuildConfig.VERSION_NAME} " +
|
"baresip v${BuildConfig.VERSION_NAME} " +
|
||||||
"(Android ${VERSION.RELEASE}/${System.getProperty("os.arch") ?: "?"})"
|
"(Android ${VERSION.RELEASE}/${System.getProperty("os.arch") ?: "?"})"
|
||||||
)
|
)
|
||||||
}.start()
|
}.start()
|
||||||
|
|
||||||
@ -709,7 +714,8 @@ class BaresipService: Service() {
|
|||||||
if (ua.account.telProvider == "") {
|
if (ua.account.telProvider == "") {
|
||||||
Log.w(TAG, "No telephony provider for $aor")
|
Log.w(TAG, "No telephony provider for $aor")
|
||||||
peerUri = ""
|
peerUri = ""
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
peerUri = Utils.telToSip(peerUri, ua.account)
|
peerUri = Utils.telToSip(peerUri, ua.account)
|
||||||
}
|
}
|
||||||
if (peerUri != "") {
|
if (peerUri != "") {
|
||||||
@ -774,12 +780,10 @@ class BaresipService: Service() {
|
|||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
val currentNightMode = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
|
||||||
when (currentNightMode) {
|
when (currentNightMode) {
|
||||||
Configuration.UI_MODE_NIGHT_NO -> {
|
Configuration.UI_MODE_NIGHT_NO ->
|
||||||
darkTheme.value = Preferences(this).displayTheme == AppCompatDelegate.MODE_NIGHT_YES
|
darkTheme.value = Preferences(this).displayTheme == AppCompatDelegate.MODE_NIGHT_YES
|
||||||
}
|
Configuration.UI_MODE_NIGHT_YES ->
|
||||||
Configuration.UI_MODE_NIGHT_YES -> {
|
|
||||||
darkTheme.value = true
|
darkTheme.value = true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,9 +826,9 @@ class BaresipService: Service() {
|
|||||||
if (password != null) {
|
if (password != null) {
|
||||||
Api.account_set_auth_pass(acc.accp, password)
|
Api.account_set_auth_pass(acc.accp, password)
|
||||||
acc.authPass = password
|
acc.authPass = password
|
||||||
} else {
|
|
||||||
Api.account_set_auth_pass(acc.accp, NO_AUTH_PASS)
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Api.account_set_auth_pass(acc.accp, NO_AUTH_PASS)
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "got uaEvent $event/${acc.aor}")
|
Log.d(TAG, "got uaEvent $event/${acc.aor}")
|
||||||
@ -853,7 +857,7 @@ class BaresipService: Service() {
|
|||||||
agc = null
|
agc = null
|
||||||
ns?.release()
|
ns?.release()
|
||||||
ns = null
|
ns = null
|
||||||
if (aecAvailable) {
|
if (aecAvailable)
|
||||||
try {
|
try {
|
||||||
aec = AcousticEchoCanceler.create(sessionId)
|
aec = AcousticEchoCanceler.create(sessionId)
|
||||||
if (aec != null) {
|
if (aec != null) {
|
||||||
@ -863,8 +867,7 @@ class BaresipService: Service() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Exception creating AEC: $e")
|
Log.e(TAG, "Exception creating AEC: $e")
|
||||||
}
|
}
|
||||||
}
|
if (agcAvailable)
|
||||||
if (agcAvailable) {
|
|
||||||
try {
|
try {
|
||||||
agc = AutomaticGainControl.create(sessionId)
|
agc = AutomaticGainControl.create(sessionId)
|
||||||
if (agc != null) {
|
if (agc != null) {
|
||||||
@ -874,8 +877,7 @@ class BaresipService: Service() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Exception creating AGC: $e")
|
Log.e(TAG, "Exception creating AGC: $e")
|
||||||
}
|
}
|
||||||
}
|
if (nsAvailable)
|
||||||
if (nsAvailable) {
|
|
||||||
try {
|
try {
|
||||||
ns = NoiseSuppressor.create(sessionId)
|
ns = NoiseSuppressor.create(sessionId)
|
||||||
if (ns != null) {
|
if (ns != null) {
|
||||||
@ -885,7 +887,6 @@ class BaresipService: Service() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Exception creating NS: $e")
|
Log.e(TAG, "Exception creating NS: $e")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -910,6 +911,7 @@ class BaresipService: Service() {
|
|||||||
for (accountIndex in uas.value.indices) {
|
for (accountIndex in uas.value.indices) {
|
||||||
if (uas.value[accountIndex].account.aor == aor) {
|
if (uas.value[accountIndex].account.aor == aor) {
|
||||||
when (ev[0]) {
|
when (ev[0]) {
|
||||||
|
|
||||||
"registering", "unregistering" -> {
|
"registering", "unregistering" -> {
|
||||||
ua.updateStatus(circleYellow.getValue(colorblind))
|
ua.updateStatus(circleYellow.getValue(colorblind))
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
@ -917,6 +919,7 @@ class BaresipService: Service() {
|
|||||||
registrationUpdate.postValue(System.currentTimeMillis())
|
registrationUpdate.postValue(System.currentTimeMillis())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"registered" -> {
|
"registered" -> {
|
||||||
ua.updateStatus(
|
ua.updateStatus(
|
||||||
if (Api.account_regint(ua.account.accp) == 0)
|
if (Api.account_regint(ua.account.accp) == 0)
|
||||||
@ -929,11 +932,13 @@ class BaresipService: Service() {
|
|||||||
registrationUpdate.postValue(System.currentTimeMillis())
|
registrationUpdate.postValue(System.currentTimeMillis())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"registering failed" -> {
|
"registering failed" -> {
|
||||||
ua.updateStatus(if (Api.account_regint(ua.account.accp) == 0)
|
ua.updateStatus(
|
||||||
R.drawable.circle_white
|
if (Api.account_regint(ua.account.accp) == 0)
|
||||||
else
|
R.drawable.circle_white
|
||||||
circleRed.getValue(colorblind)
|
else
|
||||||
|
circleRed.getValue(colorblind)
|
||||||
)
|
)
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
if (isMainVisible)
|
if (isMainVisible)
|
||||||
@ -944,12 +949,14 @@ class BaresipService: Service() {
|
|||||||
": DNS lookup failed"
|
": DNS lookup failed"
|
||||||
else
|
else
|
||||||
": ${ev[1]}"
|
": ${ev[1]}"
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
""
|
""
|
||||||
toast(String.format(getString(R.string.registering_failed), aor) + reason)
|
toast(String.format(getString(R.string.registering_failed), aor) + reason)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call outgoing" -> {
|
"call outgoing" -> {
|
||||||
if (call!!.status.value == "transferring")
|
if (call!!.status.value == "transferring")
|
||||||
break
|
break
|
||||||
@ -959,18 +966,20 @@ class BaresipService: Service() {
|
|||||||
ensureCommunicationMode()
|
ensureCommunicationMode()
|
||||||
proximitySensing(proximitySensing)
|
proximitySensing(proximitySensing)
|
||||||
}
|
}
|
||||||
|
|
||||||
"call ringing" -> {
|
"call ringing" -> {
|
||||||
playRingBack()
|
playRingBack()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call progress" -> {
|
"call progress" -> {
|
||||||
if ((ev[1].toInt() and Api.SDP_RECVONLY) != 0)
|
if ((ev[1].toInt() and Api.SDP_RECVONLY) != 0)
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
else {
|
else
|
||||||
playRingBack()
|
playRingBack()
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"incoming call" -> {
|
"incoming call" -> {
|
||||||
speakerPhone = speakerPhoneAuto
|
speakerPhone = speakerPhoneAuto
|
||||||
val peerUri = ev[1]
|
val peerUri = ev[1]
|
||||||
@ -983,7 +992,7 @@ class BaresipService: Service() {
|
|||||||
else if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) {
|
else if (ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) {
|
||||||
blockedCall = true
|
blockedCall = true
|
||||||
String.format(
|
String.format(
|
||||||
getString(R.string.call_blocked),
|
getString(R.string.call_blocked),
|
||||||
Utils.friendlyUri(this, peerUri, ua.account)
|
Utils.friendlyUri(this, peerUri, ua.account)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1023,11 +1032,10 @@ class BaresipService: Service() {
|
|||||||
"raw",
|
"raw",
|
||||||
packageName
|
packageName
|
||||||
)
|
)
|
||||||
if (resourceId != 0) {
|
if (resourceId != 0)
|
||||||
ensureCommunicationMode()
|
ensureCommunicationMode()
|
||||||
} else {
|
else
|
||||||
Log.e(TAG, "Callwaiting tone $name.wav not found")
|
Log.e(TAG, "Callwaiting tone $name.wav not found")
|
||||||
}
|
|
||||||
if (ua.account.callHistory) {
|
if (ua.account.callHistory) {
|
||||||
CallHistoryNew(aor, peerUri, "in").add()
|
CallHistoryNew(aor, peerUri, "in").add()
|
||||||
ua.account.missedCalls = true
|
ua.account.missedCalls = true
|
||||||
@ -1039,6 +1047,7 @@ class BaresipService: Service() {
|
|||||||
Api.ua_accept(uap, callp)
|
Api.ua_accept(uap, callp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call incoming" -> {
|
"call incoming" -> {
|
||||||
val peerUri = ev[1]
|
val peerUri = ev[1]
|
||||||
Log.d(TAG, "Incoming call $uap/$callp/$peerUri")
|
Log.d(TAG, "Incoming call $uap/$callp/$peerUri")
|
||||||
@ -1055,6 +1064,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call answered" -> {
|
"call answered" -> {
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
ConnectionService.connections[callp]?.setActive()
|
ConnectionService.connections[callp]?.setActive()
|
||||||
@ -1068,9 +1078,10 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"call redirect" -> {
|
|
||||||
|
"call redirect" ->
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
}
|
|
||||||
"call established" -> {
|
"call established" -> {
|
||||||
ensureCommunicationMode()
|
ensureCommunicationMode()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
@ -1092,6 +1103,7 @@ class BaresipService: Service() {
|
|||||||
if (!isMainVisible)
|
if (!isMainVisible)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call update" -> {
|
"call update" -> {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
@ -1118,7 +1130,8 @@ class BaresipService: Service() {
|
|||||||
call.callOnHold.value = true
|
call.callOnHold.value = true
|
||||||
if (connection?.state != Connection.STATE_HOLDING)
|
if (connection?.state != Connection.STATE_HOLDING)
|
||||||
connection?.setOnHold()
|
connection?.setOnHold()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// Peer un-held us
|
// Peer un-held us
|
||||||
call.showOnHoldNotice.value = false
|
call.showOnHoldNotice.value = false
|
||||||
if (!call.onhold) {
|
if (!call.onhold) {
|
||||||
@ -1127,10 +1140,9 @@ class BaresipService: Service() {
|
|||||||
connection?.setActive()
|
connection?.setActive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (call.state() == Api.CALL_STATE_EARLY) {
|
if (call.state() == Api.CALL_STATE_EARLY)
|
||||||
if ((ev[1].toInt() and Api.SDP_RECVONLY) != 0)
|
if ((ev[1].toInt() and Api.SDP_RECVONLY) != 0)
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
}
|
|
||||||
if (call.status.value == "connected" && !call.held && !call.onhold) {
|
if (call.status.value == "connected" && !call.held && !call.onhold) {
|
||||||
if (call.callOnHold.value || call.showOnHoldNotice.value) {
|
if (call.callOnHold.value || call.showOnHoldNotice.value) {
|
||||||
Log.d(
|
Log.d(
|
||||||
@ -1147,12 +1159,13 @@ class BaresipService: Service() {
|
|||||||
if (!isMainVisible || call?.status?.value != "connected")
|
if (!isMainVisible || call?.status?.value != "connected")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call verified", "call secure" -> {
|
"call verified", "call secure" -> {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
if (ev[0] == "call secure") {
|
if (ev[0] == "call secure")
|
||||||
call.security = R.color.colorTrafficYellow
|
call.security = R.color.colorTrafficYellow
|
||||||
} else {
|
else {
|
||||||
call.security = R.color.colorTrafficGreen
|
call.security = R.color.colorTrafficGreen
|
||||||
call.zid = ev[1]
|
call.zid = ev[1]
|
||||||
}
|
}
|
||||||
@ -1161,6 +1174,7 @@ class BaresipService: Service() {
|
|||||||
if (!isMainVisible)
|
if (!isMainVisible)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"call transfer" -> {
|
"call transfer" -> {
|
||||||
if (!Utils.isVisible()) {
|
if (!Utils.isVisible()) {
|
||||||
val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
@ -1198,16 +1212,26 @@ class BaresipService: Service() {
|
|||||||
val denyIntent = Intent(this, BaresipService::class.java)
|
val denyIntent = Intent(this, BaresipService::class.java)
|
||||||
denyIntent.action = "Transfer Deny"
|
denyIntent.action = "Transfer Deny"
|
||||||
denyIntent.putExtra("callp", callp)
|
denyIntent.putExtra("callp", callp)
|
||||||
val denyPendingIntent = PendingIntent.getService(this,
|
val denyPendingIntent = PendingIntent.getService(
|
||||||
DENY_REQ_CODE, denyIntent, piFlags)
|
this,
|
||||||
nb.addAction(R.drawable.ic_notification_call,
|
DENY_REQ_CODE,
|
||||||
getString(R.string.accept), acceptPendingIntent)
|
denyIntent,
|
||||||
nb.addAction(R.drawable.ic_notification_call_end,
|
piFlags)
|
||||||
getString(R.string.deny), denyPendingIntent)
|
nb.addAction(
|
||||||
|
R.drawable.ic_notification_call,
|
||||||
|
getString(R.string.accept),
|
||||||
|
acceptPendingIntent
|
||||||
|
)
|
||||||
|
nb.addAction(
|
||||||
|
R.drawable.ic_notification_call_end,
|
||||||
|
getString(R.string.deny),
|
||||||
|
denyPendingIntent
|
||||||
|
)
|
||||||
nm.notify(TRANSFER_NOTIFICATION_ID, nb.build())
|
nm.notify(TRANSFER_NOTIFICATION_ID, nb.build())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"transfer failed" -> {
|
"transfer failed" -> {
|
||||||
Log.d(TAG, "AoR $aor call $callp transfer failed: ${ev[1]}")
|
Log.d(TAG, "AoR $aor call $callp transfer failed: ${ev[1]}")
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
@ -1217,6 +1241,7 @@ class BaresipService: Service() {
|
|||||||
if (!isMainVisible)
|
if (!isMainVisible)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
"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]}")
|
||||||
val connection = ConnectionService.connections[callp]
|
val connection = ConnectionService.connections[callp]
|
||||||
@ -1237,15 +1262,12 @@ class BaresipService: Service() {
|
|||||||
call.terminated.value = true
|
call.terminated.value = true
|
||||||
call.remove()
|
call.remove()
|
||||||
val noMoreCalls = synchronized(calls) { !Call.inCall() }
|
val noMoreCalls = synchronized(calls) { !Call.inCall() }
|
||||||
|
|
||||||
stopRinging()
|
stopRinging()
|
||||||
stopMediaPlayer()
|
stopMediaPlayer()
|
||||||
|
|
||||||
if (noMoreCalls) {
|
if (noMoreCalls) {
|
||||||
proximitySensing(false)
|
proximitySensing(false)
|
||||||
abandonAudioFocus(this)
|
abandonAudioFocus(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val newCall = call.newCall
|
val newCall = call.newCall
|
||||||
if (newCall != null) {
|
if (newCall != null) {
|
||||||
newCall.onHoldCall = null
|
newCall.onHoldCall = null
|
||||||
@ -1285,7 +1307,6 @@ class BaresipService: Service() {
|
|||||||
!reason.startsWith("408") &&
|
!reason.startsWith("408") &&
|
||||||
!reason.startsWith("480") &&
|
!reason.startsWith("480") &&
|
||||||
!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
|
||||||
if (ua.account.callHistory) {
|
if (ua.account.callHistory) {
|
||||||
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
val completedElsewhere = missed && ev[2].startsWith("SIP") &&
|
||||||
@ -1298,9 +1319,8 @@ class BaresipService: Service() {
|
|||||||
else
|
else
|
||||||
call.startTime
|
call.startTime
|
||||||
history.rejected = call.rejected
|
history.rejected = call.rejected
|
||||||
if (call.dumpfiles[0] != "") {
|
if (call.dumpfiles[0] != "")
|
||||||
history.recording = call.dumpfiles
|
history.recording = call.dumpfiles
|
||||||
}
|
|
||||||
history.add()
|
history.add()
|
||||||
if (call.startTime != null && call.dumpfiles[0] != "") {
|
if (call.startTime != null && call.dumpfiles[0] != "") {
|
||||||
delay(500.milliseconds)
|
delay(500.milliseconds)
|
||||||
@ -1345,8 +1365,7 @@ class BaresipService: Service() {
|
|||||||
val intent = Intent(this, MainActivity::class.java)
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
|
||||||
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
intent.putExtra("action", "call missed")
|
intent.putExtra("action", "call missed").putExtra("uap", uap)
|
||||||
.putExtra("uap", uap)
|
|
||||||
val pi = PendingIntent.getActivity(
|
val pi = PendingIntent.getActivity(
|
||||||
this,
|
this,
|
||||||
CALL_REQ_CODE,
|
CALL_REQ_CODE,
|
||||||
@ -1355,10 +1374,10 @@ class BaresipService: Service() {
|
|||||||
)
|
)
|
||||||
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
||||||
nb.setSmallIcon(R.drawable.ic_notification_call_missed)
|
nb.setSmallIcon(R.drawable.ic_notification_call_missed)
|
||||||
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
|
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
|
||||||
.setContentIntent(pi)
|
.setContentIntent(pi)
|
||||||
.setCategory(Notification.CATEGORY_CALL)
|
.setCategory(Notification.CATEGORY_CALL)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
var missedCalls = 0
|
var missedCalls = 0
|
||||||
for (notification in nm.activeNotifications)
|
for (notification in nm.activeNotifications)
|
||||||
if (notification.id == CALL_MISSED_NOTIFICATION_ID)
|
if (notification.id == CALL_MISSED_NOTIFICATION_ID)
|
||||||
@ -1370,8 +1389,11 @@ class BaresipService: Service() {
|
|||||||
else {
|
else {
|
||||||
nb.setContentTitle(getString(R.string.missed_calls))
|
nb.setContentTitle(getString(R.string.missed_calls))
|
||||||
nb.setContentText(
|
nb.setContentText(
|
||||||
String.format(getString(R.string.missed_calls_count),
|
String.format(
|
||||||
missedCalls + 1))
|
getString(R.string.missed_calls_count),
|
||||||
|
missedCalls + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
nm.notify(CALL_MISSED_NOTIFICATION_ID, nb.build())
|
nm.notify(CALL_MISSED_NOTIFICATION_ID, nb.build())
|
||||||
}
|
}
|
||||||
@ -1432,8 +1454,7 @@ class BaresipService: Service() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val charsetString = Utils.paramValue(cType.replace(" ", ""),
|
val charsetString = Utils.paramValue(cType.replace(" ", ""), "charset")
|
||||||
"charset")
|
|
||||||
val charset = try {
|
val charset = try {
|
||||||
Charset.forName(charsetString)
|
Charset.forName(charsetString)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
@ -1462,8 +1483,8 @@ class BaresipService: Service() {
|
|||||||
val aor = ua.account.aor
|
val aor = ua.account.aor
|
||||||
|
|
||||||
if ((ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) ||
|
if ((ua.account.blockUnknown && Contact.contactName(peerUri) == peerUri) ||
|
||||||
(ua.account.blockHidden && peerUri.contains("anonymous")) ||
|
(ua.account.blockHidden && peerUri.contains("anonymous")) ||
|
||||||
isBlocked(peerUri)) {
|
isBlocked(peerUri)) {
|
||||||
Log.d(TAG, "Auto-rejecting blocked message from $peerUri")
|
Log.d(TAG, "Auto-rejecting blocked message from $peerUri")
|
||||||
toast(
|
toast(
|
||||||
if (ua.account.blockHidden && peerUri.contains("anonymous"))
|
if (ua.account.blockHidden && peerUri.contains("anonymous"))
|
||||||
@ -1509,10 +1530,8 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
val intent = Intent(this, MainActivity::class.java)
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
||||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
intent.putExtra("action", "message show")
|
intent.putExtra("action", "message show").putExtra("uap", uap).putExtra("peer", peerUri)
|
||||||
.putExtra("uap", uap)
|
|
||||||
.putExtra("peer", peerUri)
|
|
||||||
val pi = PendingIntent.getActivity(
|
val pi = PendingIntent.getActivity(
|
||||||
this,
|
this,
|
||||||
MESSAGE_REQ_CODE,
|
MESSAGE_REQ_CODE,
|
||||||
@ -1546,8 +1565,7 @@ class BaresipService: Service() {
|
|||||||
.build()
|
.build()
|
||||||
val directReplyIntent = Intent(this, BaresipService::class.java)
|
val directReplyIntent = Intent(this, BaresipService::class.java)
|
||||||
directReplyIntent.action = "Message Inline Reply"
|
directReplyIntent.action = "Message Inline Reply"
|
||||||
directReplyIntent.putExtra("uap", uap)
|
directReplyIntent.putExtra("uap", uap).putExtra("peer", peerUri).putExtra("time", timeStamp)
|
||||||
.putExtra("peer", peerUri).putExtra("time", timeStamp)
|
|
||||||
val directReplyPendingIntent = PendingIntent.getService(
|
val directReplyPendingIntent = PendingIntent.getService(
|
||||||
this,
|
this,
|
||||||
DIRECT_REPLY_REQ_CODE,
|
DIRECT_REPLY_REQ_CODE,
|
||||||
@ -1612,19 +1630,19 @@ class BaresipService: Service() {
|
|||||||
val timeStamp = time.toLong()
|
val timeStamp = time.toLong()
|
||||||
for (m in messages.reversed())
|
for (m in messages.reversed())
|
||||||
if (m.timeStamp == timeStamp) {
|
if (m.timeStamp == timeStamp) {
|
||||||
if (responseCode < 300) {
|
if (responseCode < 300)
|
||||||
m.direction = MESSAGE_UP
|
m.direction = MESSAGE_UP
|
||||||
} else {
|
else {
|
||||||
m.direction = MESSAGE_UP_FAIL
|
m.direction = MESSAGE_UP_FAIL
|
||||||
m.responseCode = responseCode
|
m.responseCode = responseCode
|
||||||
m.responseReason = responseReason
|
m.responseReason = responseReason
|
||||||
}
|
}
|
||||||
messageUpdate.postValue(System.currentTimeMillis())
|
messageUpdate.postValue(System.currentTimeMillis())
|
||||||
break
|
break
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
if (m.timeStamp < timeStamp - 60000)
|
if (m.timeStamp < timeStamp - 60000)
|
||||||
break
|
break
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var audioModeChangedListener: AudioManager.OnModeChangedListener? = null
|
private var audioModeChangedListener: AudioManager.OnModeChangedListener? = null
|
||||||
@ -1656,13 +1674,13 @@ class BaresipService: Service() {
|
|||||||
call.destroy()
|
call.destroy()
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
ConnectionService.pendingOutgoingConnection?.let {
|
ConnectionService.pendingOutgoingConnection?.let {
|
||||||
it.setDisconnected(DisconnectCause(DisconnectCause.ERROR))
|
it.setDisconnected(DisconnectCause(DisconnectCause.ERROR))
|
||||||
it.destroy()
|
it.destroy()
|
||||||
ConnectionService.pendingOutgoingConnection = null
|
ConnectionService.pendingOutgoingConnection = null
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, audioDelay)
|
}, audioDelay)
|
||||||
}
|
}
|
||||||
@ -1727,7 +1745,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VERSION.SDK_INT >= 31 && !telephonyCallbackRegistered) {
|
if (VERSION.SDK_INT >= 31 && !telephonyCallbackRegistered)
|
||||||
try {
|
try {
|
||||||
telephonyManager.registerTelephonyCallback(mainExecutor, telephonyCallback)
|
telephonyManager.registerTelephonyCallback(mainExecutor, telephonyCallback)
|
||||||
telephonyCallbackRegistered = true
|
telephonyCallbackRegistered = true
|
||||||
@ -1735,16 +1753,14 @@ class BaresipService: Service() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Failed to register TelephonyCallback: ${e.message}")
|
Log.e(TAG, "Failed to register TelephonyCallback: ${e.message}")
|
||||||
}
|
}
|
||||||
} else if (!telephonyCallbackRegistered) {
|
else if (!telephonyCallbackRegistered) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE)
|
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE)
|
||||||
telephonyCallbackRegistered = true
|
telephonyCallbackRegistered = true
|
||||||
Log.d(TAG, "Registered PhoneStateListener")
|
Log.d(TAG, "Registered PhoneStateListener")
|
||||||
}
|
}
|
||||||
Api.net_debug()
|
Api.net_debug()
|
||||||
postServiceEvent(
|
postServiceEvent(ServiceEvent("started", arrayListOf(callActionUri), System.nanoTime()))
|
||||||
ServiceEvent("started", arrayListOf(callActionUri), System.nanoTime())
|
|
||||||
)
|
|
||||||
callActionUri = ""
|
callActionUri = ""
|
||||||
Log.d(TAG, "Battery optimizations are ignored: " +
|
Log.d(TAG, "Battery optimizations are ignored: " +
|
||||||
"${pm.isIgnoringBatteryOptimizations(packageName)}")
|
"${pm.isIgnoringBatteryOptimizations(packageName)}")
|
||||||
@ -1761,15 +1777,15 @@ class BaresipService: Service() {
|
|||||||
quitTimer.cancel()
|
quitTimer.cancel()
|
||||||
cleanService()
|
cleanService()
|
||||||
isServiceRunning = false
|
isServiceRunning = false
|
||||||
postServiceEvent(
|
postServiceEvent(ServiceEvent("stopped", arrayListOf(error), System.nanoTime()))
|
||||||
ServiceEvent("stopped", arrayListOf(error), System.nanoTime())
|
|
||||||
)
|
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNotificationChannels() {
|
private fun createNotificationChannels() {
|
||||||
val lowChannel = NotificationChannel(LOW_CHANNEL_ID, "No sound, no vibrate",
|
val lowChannel = NotificationChannel(
|
||||||
NotificationManager.IMPORTANCE_LOW)
|
LOW_CHANNEL_ID, "No sound, no vibrate",
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
)
|
||||||
lowChannel.description = "Background status notifications"
|
lowChannel.description = "Background status notifications"
|
||||||
lowChannel.enableVibration(false)
|
lowChannel.enableVibration(false)
|
||||||
lowChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
lowChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
@ -1778,15 +1794,21 @@ class BaresipService: Service() {
|
|||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||||
.build()
|
.build()
|
||||||
val highChannel = NotificationChannel(HIGH_CHANNEL_ID, "Sound, vibrate, and peek",
|
val highChannel = NotificationChannel(
|
||||||
NotificationManager.IMPORTANCE_HIGH)
|
HIGH_CHANNEL_ID,
|
||||||
|
"Sound, vibrate, and peek",
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
)
|
||||||
highChannel.description = "Incoming calls and important alerts"
|
highChannel.description = "Incoming calls and important alerts"
|
||||||
highChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
highChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
highChannel.enableVibration(true)
|
highChannel.enableVibration(true)
|
||||||
highChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, ringAttributes)
|
highChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, ringAttributes)
|
||||||
nm.createNotificationChannel(highChannel)
|
nm.createNotificationChannel(highChannel)
|
||||||
val mediumChannel = NotificationChannel(MEDIUM_CHANNEL_ID, "Sound only",
|
val mediumChannel = NotificationChannel(
|
||||||
NotificationManager.IMPORTANCE_DEFAULT)
|
MEDIUM_CHANNEL_ID,
|
||||||
|
"Sound only",
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
|
)
|
||||||
mediumChannel.description = "Incoming messages"
|
mediumChannel.description = "Incoming messages"
|
||||||
mediumChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
mediumChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
|
||||||
mediumChannel.enableVibration(false)
|
mediumChannel.enableVibration(false)
|
||||||
@ -1866,9 +1888,7 @@ class BaresipService: Service() {
|
|||||||
intent,
|
intent,
|
||||||
PendingIntent.FLAG_IMMUTABLE
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
val deleteIntent =
|
val deleteIntent = Intent(this, BaresipService::class.java).setAction("Notification Dismissed")
|
||||||
Intent(this, BaresipService::class.java)
|
|
||||||
.setAction("Notification Dismissed")
|
|
||||||
val dpi = PendingIntent.getService(
|
val dpi = PendingIntent.getService(
|
||||||
this,
|
this,
|
||||||
STATUS_REQ_CODE,
|
STATUS_REQ_CODE,
|
||||||
@ -1912,7 +1932,8 @@ class BaresipService: Service() {
|
|||||||
else -> getString(R.string.call)
|
else -> getString(R.string.call)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
builder.setStyle(null)
|
builder.setStyle(null)
|
||||||
builder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
builder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
@ -1934,9 +1955,9 @@ class BaresipService: Service() {
|
|||||||
if (i < uas.value.size) {
|
if (i < uas.value.size) {
|
||||||
notificationLayout.setImageViewResource(resId, uas.value[i].status)
|
notificationLayout.setImageViewResource(resId, uas.value[i].status)
|
||||||
notificationLayout.setViewVisibility(resId, View.VISIBLE)
|
notificationLayout.setViewVisibility(resId, View.VISIBLE)
|
||||||
} else {
|
|
||||||
notificationLayout.setViewVisibility(resId, View.INVISIBLE)
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
notificationLayout.setViewVisibility(resId, View.INVISIBLE)
|
||||||
}
|
}
|
||||||
if (uas.value.size > 4)
|
if (uas.value.size > 4)
|
||||||
notificationLayout.setViewVisibility(R.id.etc, View.VISIBLE)
|
notificationLayout.setViewVisibility(R.id.etc, View.VISIBLE)
|
||||||
@ -1970,20 +1991,19 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
||||||
} else {
|
|
||||||
if (isNotificationInCall) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Already in standby, just keep the notification current.
|
|
||||||
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
|
||||||
}
|
}
|
||||||
|
else if (isNotificationInCall) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// 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 notification: ${e.message}")
|
Log.e(TAG, "Failed to update notification: ${e.message}")
|
||||||
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
nm.notify(STATUS_NOTIFICATION_ID, notification)
|
||||||
@ -1993,21 +2013,20 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
private fun foregroundServiceType(activeCall: Call? = null): Int {
|
private fun foregroundServiceType(activeCall: Call? = null): Int {
|
||||||
var type = 0
|
var type = 0
|
||||||
if (VERSION.SDK_INT >= 30) {
|
if (VERSION.SDK_INT >= 29) {
|
||||||
if (activeCall != null) {
|
if (activeCall != null) {
|
||||||
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
|
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
|
||||||
if (ContextCompat.checkSelfPermission(this, RECORD_AUDIO) ==
|
if (VERSION.SDK_INT >= 30) {
|
||||||
PackageManager.PERMISSION_GRANTED)
|
if (ContextCompat.checkSelfPermission(this, RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)
|
||||||
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
|
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (VERSION.SDK_INT >= 34) {
|
if (VERSION.SDK_INT >= 34)
|
||||||
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
|
type = type or ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
|
||||||
}
|
// Fallback for API 29-33 when no active call (specialUse not available)
|
||||||
// Fallback for API 30-33 when no active call (specialUse not available)
|
if (type == 0 && VERSION.SDK_INT >= 29)
|
||||||
if (type == 0 && VERSION.SDK_INT >= 30)
|
|
||||||
type = ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
|
type = ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
|
||||||
|
|
||||||
return type
|
return type
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2057,19 +2076,18 @@ class BaresipService: Service() {
|
|||||||
val e164Uri = e164Uri(uri, ua.account.countryCode)
|
val e164Uri = e164Uri(uri, ua.account.countryCode)
|
||||||
val presentation = telecomCall.details.handlePresentation
|
val presentation = telecomCall.details.handlePresentation
|
||||||
if (ua.account.blockHidden &&
|
if (ua.account.blockHidden &&
|
||||||
(presentation == TelecomManager.PRESENTATION_RESTRICTED ||
|
(presentation == TelecomManager.PRESENTATION_RESTRICTED ||
|
||||||
presentation == TelecomManager.PRESENTATION_UNKNOWN)) {
|
presentation == TelecomManager.PRESENTATION_UNKNOWN)) {
|
||||||
Log.d(TAG, "Auto-rejecting incoming PSTN hidden call")
|
Log.d(TAG, "Auto-rejecting incoming PSTN hidden call")
|
||||||
telecomCall.disconnect()
|
telecomCall.disconnect()
|
||||||
toast(getString(R.string.hidden_call_blocked))
|
toast(getString(R.string.hidden_call_blocked))
|
||||||
if (ua.account.callHistory) {
|
if (ua.account.callHistory)
|
||||||
Blocked(
|
Blocked(
|
||||||
ua.account.aor,
|
ua.account.aor,
|
||||||
uri,
|
uri,
|
||||||
"invite",
|
"invite",
|
||||||
GregorianCalendar().timeInMillis
|
GregorianCalendar().timeInMillis
|
||||||
).add()
|
).add()
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (ua.account.blockUnknown && Contact.contactName(e164Uri) == e164Uri) {
|
if (ua.account.blockUnknown && Contact.contactName(e164Uri) == e164Uri) {
|
||||||
@ -2079,14 +2097,13 @@ class BaresipService: Service() {
|
|||||||
String.format(getString(R.string.call_blocked),
|
String.format(getString(R.string.call_blocked),
|
||||||
Utils.friendlyUri(this, uri, ua.account))
|
Utils.friendlyUri(this, uri, ua.account))
|
||||||
)
|
)
|
||||||
if (ua.account.callHistory) {
|
if (ua.account.callHistory)
|
||||||
Blocked(
|
Blocked(
|
||||||
ua.account.aor,
|
ua.account.aor,
|
||||||
uri,
|
uri,
|
||||||
"invite",
|
"invite",
|
||||||
GregorianCalendar().timeInMillis
|
GregorianCalendar().timeInMillis
|
||||||
).add()
|
).add()
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2179,9 +2196,7 @@ class BaresipService: Service() {
|
|||||||
calls.remove(call)
|
calls.remove(call)
|
||||||
}
|
}
|
||||||
postServiceEvent(
|
postServiceEvent(
|
||||||
ServiceEvent(
|
ServiceEvent("call closed", arrayListOf(uap, callp), System.nanoTime())
|
||||||
"call closed", arrayListOf(uap, callp), System.nanoTime()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!Call.inCall()) {
|
if (!Call.inCall()) {
|
||||||
@ -2226,7 +2241,7 @@ class BaresipService: Service() {
|
|||||||
val mobileUa = UserAgent(0L, account)
|
val mobileUa = UserAgent(0L, account)
|
||||||
val isAirplaneModeOn = Settings.Global.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
val isAirplaneModeOn = Settings.Global.getInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0) != 0
|
||||||
val sm = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as android.telephony.SubscriptionManager
|
val sm = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as android.telephony.SubscriptionManager
|
||||||
val hasActiveSubscription = if (checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) ==
|
val hasActiveSubscription = if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) ==
|
||||||
PackageManager.PERMISSION_GRANTED)
|
PackageManager.PERMISSION_GRANTED)
|
||||||
!sm.activeSubscriptionInfoList.isNullOrEmpty()
|
!sm.activeSubscriptionInfoList.isNullOrEmpty()
|
||||||
else
|
else
|
||||||
@ -2264,14 +2279,12 @@ class BaresipService: Service() {
|
|||||||
ua.status
|
ua.status
|
||||||
else
|
else
|
||||||
R.drawable.circle_white
|
R.drawable.circle_white
|
||||||
} else {
|
|
||||||
if (ua.status == R.drawable.circle_white) {
|
|
||||||
// Show "Red" (not yet in service)
|
|
||||||
circleRed.getValue(colorblind)
|
|
||||||
} else {
|
|
||||||
ua.status
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (ua.status == R.drawable.circle_white)
|
||||||
|
// Show "Red" (not yet in service)
|
||||||
|
circleRed.getValue(colorblind)
|
||||||
|
else
|
||||||
|
ua.status
|
||||||
if (ua.status != status) {
|
if (ua.status != status) {
|
||||||
Log.d(TAG, "Updating Mobile status to $status")
|
Log.d(TAG, "Updating Mobile status to $status")
|
||||||
ua.updateStatus(status)
|
ua.updateStatus(status)
|
||||||
@ -2320,9 +2333,7 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
val diverterUri = call.diverterUri()
|
val diverterUri = call.diverterUri()
|
||||||
val contentText = if (diverterUri != "")
|
val contentText = if (diverterUri != "")
|
||||||
"${getString(R.string.is_calling)} " +
|
"${getString(R.string.is_calling)} (${getString(R.string.diverted_by)} ${Utils.friendlyUri(this, diverterUri, ua.account)})"
|
||||||
"(${getString(R.string.diverted_by)} " +
|
|
||||||
"${Utils.friendlyUri(this, diverterUri, ua.account)})"
|
|
||||||
else
|
else
|
||||||
getString(R.string.is_calling)
|
getString(R.string.is_calling)
|
||||||
val caller = createPerson(this, peerUri, ua.account)
|
val caller = createPerson(this, peerUri, ua.account)
|
||||||
@ -2410,14 +2421,14 @@ class BaresipService: Service() {
|
|||||||
vbTimer = Timer()
|
vbTimer = Timer()
|
||||||
vbTimer!!.schedule(object : TimerTask() {
|
vbTimer!!.schedule(object : TimerTask() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (VERSION.SDK_INT >= 33) {
|
if (VERSION.SDK_INT >= 33)
|
||||||
vibrator.vibrate(
|
vibrator.vibrate(
|
||||||
effect,
|
effect,
|
||||||
android.os.VibrationAttributes.Builder()
|
android.os.VibrationAttributes.Builder()
|
||||||
.setUsage(android.os.VibrationAttributes.USAGE_RINGTONE)
|
.setUsage(android.os.VibrationAttributes.USAGE_RINGTONE)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
} else {
|
else {
|
||||||
val attributes = AudioAttributes.Builder()
|
val attributes = AudioAttributes.Builder()
|
||||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||||
@ -2449,7 +2460,6 @@ class BaresipService: Service() {
|
|||||||
// First, check if the ringer volume is actually non-zero
|
// First, check if the ringer volume is actually non-zero
|
||||||
if (am.getStreamVolume(AudioManager.STREAM_RING) == 0) return false
|
if (am.getStreamVolume(AudioManager.STREAM_RING) == 0) return false
|
||||||
// Finally, check the system "Vibrate for calls" setting.
|
// Finally, check the system "Vibrate for calls" setting.
|
||||||
// Although deprecated, it is the standard way to check the "Also vibrate for calls" toggle.
|
|
||||||
return try {
|
return try {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
Settings.System.getInt(
|
Settings.System.getInt(
|
||||||
@ -2472,14 +2482,12 @@ class BaresipService: Service() {
|
|||||||
)
|
)
|
||||||
val projection = arrayOf(ContactsContract.PhoneLookup.STARRED)
|
val projection = arrayOf(ContactsContract.PhoneLookup.STARRED)
|
||||||
try {
|
try {
|
||||||
val cursor = contentResolver
|
val cursor = contentResolver.query(phoneUri, projection, null, null, null)
|
||||||
.query(phoneUri, projection, null, null, null)
|
|
||||||
cursor?.use {
|
cursor?.use {
|
||||||
if (it.moveToFirst()) {
|
if (it.moveToFirst()) {
|
||||||
val isStarred = it.getInt(0) == 1
|
val isStarred = it.getInt(0) == 1
|
||||||
if (isStarred) {
|
if (isStarred)
|
||||||
Log.d(TAG, "Caller '$callerNumber' is a starred contact.")
|
Log.d(TAG, "Caller '$callerNumber' is a starred contact.")
|
||||||
}
|
|
||||||
return isStarred
|
return isStarred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2507,7 +2515,6 @@ class BaresipService: Service() {
|
|||||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
mediaPlayer = MediaPlayer().apply {
|
mediaPlayer = MediaPlayer().apply {
|
||||||
setAudioAttributes(audioAttributes)
|
setAudioAttributes(audioAttributes)
|
||||||
val afd = resources.openRawResourceFd(resourceId)
|
val afd = resources.openRawResourceFd(resourceId)
|
||||||
@ -2517,9 +2524,9 @@ class BaresipService: Service() {
|
|||||||
prepare()
|
prepare()
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Ringback tone $name.wav not found")
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Log.e(TAG, "Ringback tone $name.wav not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2533,7 +2540,6 @@ class BaresipService: Service() {
|
|||||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
mediaPlayer = MediaPlayer().apply {
|
mediaPlayer = MediaPlayer().apply {
|
||||||
setAudioAttributes(audioAttributes)
|
setAudioAttributes(audioAttributes)
|
||||||
val afd = resources.openRawResourceFd(resourceId)
|
val afd = resources.openRawResourceFd(resourceId)
|
||||||
@ -2546,9 +2552,9 @@ class BaresipService: Service() {
|
|||||||
prepare()
|
prepare()
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Busy tone $name.wav not found")
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Log.e(TAG, "Busy tone $name.wav not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2605,7 +2611,8 @@ class BaresipService: Service() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!Call.inCall() && currentMode == MODE_NORMAL) {
|
}
|
||||||
|
else if (!Call.inCall() && currentMode == MODE_NORMAL) {
|
||||||
if (speakerPhone) {
|
if (speakerPhone) {
|
||||||
Log.d(TAG, "Resetting speakerPhone UI state while idle")
|
Log.d(TAG, "Resetting speakerPhone UI state while idle")
|
||||||
speakerPhone = false
|
speakerPhone = false
|
||||||
@ -2643,15 +2650,17 @@ class BaresipService: Service() {
|
|||||||
else
|
else
|
||||||
android.telecom.CallAudioState.ROUTE_EARPIECE
|
android.telecom.CallAudioState.ROUTE_EARPIECE
|
||||||
)
|
)
|
||||||
} else if (!hasTelecom) {
|
}
|
||||||
|
else if (!hasTelecom) {
|
||||||
Log.d(TAG, "No Telecom connection, using AudioManager for speaker")
|
Log.d(TAG, "No Telecom connection, using AudioManager for speaker")
|
||||||
Utils.setSpeakerPhone(mainExecutor, am, speakerPhone)
|
Utils.setSpeakerPhone(mainExecutor, am, speakerPhone)
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
for (c in Call.calls()) {
|
for (c in Call.calls()) {
|
||||||
ConnectionService.setOutput(c.callp, speakerPhone)
|
ConnectionService.setOutput(c.callp, speakerPhone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
if (am.mode != MODE_NORMAL) {
|
if (am.mode != MODE_NORMAL) {
|
||||||
am.mode = MODE_NORMAL
|
am.mode = MODE_NORMAL
|
||||||
Log.d(TAG, "Manual Mode Guard: Resetting to MODE_NORMAL")
|
Log.d(TAG, "Manual Mode Guard: Resetting to MODE_NORMAL")
|
||||||
@ -2690,11 +2699,7 @@ class BaresipService: Service() {
|
|||||||
speakerPhone = !speakerPhone
|
speakerPhone = !speakerPhone
|
||||||
// Notify the UI to update the icon color
|
// Notify the UI to update the icon color
|
||||||
postServiceEvent(
|
postServiceEvent(
|
||||||
ServiceEvent(
|
ServiceEvent("speaker update,$speakerPhone", arrayListOf(0L, 0L), System.nanoTime())
|
||||||
"speaker update,$speakerPhone",
|
|
||||||
arrayListOf(0L, 0L),
|
|
||||||
System.nanoTime()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
// Apply the new audio route
|
// Apply the new audio route
|
||||||
ensureCommunicationMode()
|
ensureCommunicationMode()
|
||||||
@ -2706,17 +2711,16 @@ class BaresipService: Service() {
|
|||||||
if (!proximityWakeLock.isHeld) {
|
if (!proximityWakeLock.isHeld) {
|
||||||
Log.d(TAG, "Acquiring proximity wake lock")
|
Log.d(TAG, "Acquiring proximity wake lock")
|
||||||
proximityWakeLock.acquire()
|
proximityWakeLock.acquire()
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
Log.d(TAG, "Proximity wake lock already acquired")
|
Log.d(TAG, "Proximity wake lock already acquired")
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (proximityWakeLock.isHeld) {
|
|
||||||
proximityWakeLock.release()
|
|
||||||
Log.d(TAG, "Released proximity wake lock")
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Proximity wake lock is not held")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (proximityWakeLock.isHeld) {
|
||||||
|
proximityWakeLock.release()
|
||||||
|
Log.d(TAG, "Released proximity wake lock")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.d(TAG, "Proximity wake lock is not held")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateNetwork() {
|
private fun updateNetwork() {
|
||||||
@ -2770,11 +2774,9 @@ class BaresipService: Service() {
|
|||||||
wifiLock.acquire()
|
wifiLock.acquire()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (wifiLock.isHeld) {
|
||||||
if (wifiLock.isHeld) {
|
Log.d(TAG, "Releasing WiFi Lock")
|
||||||
Log.d(TAG, "Releasing WiFi Lock")
|
wifiLock.release()
|
||||||
wifiLock.release()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2795,11 +2797,10 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hotSpotIsEnabled) {
|
if (hotSpotIsEnabled)
|
||||||
for ((k, v) in hotSpotAddresses)
|
for ((k, v) in hotSpotAddresses)
|
||||||
if (afMatch(k))
|
if (afMatch(k))
|
||||||
addresses[k] = v
|
addresses[k] = v
|
||||||
}
|
|
||||||
return addresses
|
return addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2833,9 +2834,9 @@ class BaresipService: Service() {
|
|||||||
// Update if change
|
// Update if change
|
||||||
synchronized(dnsServers) {
|
synchronized(dnsServers) {
|
||||||
if (servers != dnsServers) {
|
if (servers != dnsServers) {
|
||||||
if (isServiceRunning && Config.updateDnsServers(servers) != 0) {
|
if (isServiceRunning && Config.updateDnsServers(servers) != 0)
|
||||||
Log.w(TAG, "Failed to update DNS servers '${servers}'")
|
Log.w(TAG, "Failed to update DNS servers '${servers}'")
|
||||||
} else {
|
else {
|
||||||
// Log.d(TAG, "Updated DNS servers: '${servers}'")
|
// Log.d(TAG, "Updated DNS servers: '${servers}'")
|
||||||
dnsServers = servers
|
dnsServers = servers
|
||||||
return true
|
return true
|
||||||
@ -2894,11 +2895,11 @@ class BaresipService: Service() {
|
|||||||
airplaneModeReceiverRegistered = false
|
airplaneModeReceiverRegistered = false
|
||||||
}
|
}
|
||||||
if (telephonyCallbackRegistered) {
|
if (telephonyCallbackRegistered) {
|
||||||
if (VERSION.SDK_INT >= 31) {
|
if (VERSION.SDK_INT >= 31)
|
||||||
try {
|
try {
|
||||||
telephonyManager.unregisterTelephonyCallback(telephonyCallback)
|
telephonyManager.unregisterTelephonyCallback(telephonyCallback)
|
||||||
} catch (_: Exception) {}
|
} catch (_: Exception) {}
|
||||||
} else {
|
else {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
|
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
|
||||||
}
|
}
|
||||||
@ -2927,11 +2928,10 @@ class BaresipService: Service() {
|
|||||||
proximityWakeLock.release()
|
proximityWakeLock.release()
|
||||||
if (this::wifiLock.isInitialized)
|
if (this::wifiLock.isInitialized)
|
||||||
wifiLock.release()
|
wifiLock.release()
|
||||||
if (this::networkCallback.isInitialized) {
|
if (this::networkCallback.isInitialized)
|
||||||
try {
|
try {
|
||||||
cm.unregisterNetworkCallback(networkCallback)
|
cm.unregisterNetworkCallback(networkCallback)
|
||||||
} catch (_: Exception) {}
|
} catch (_: Exception) {}
|
||||||
}
|
|
||||||
if (androidContactsObserverRegistered) {
|
if (androidContactsObserverRegistered) {
|
||||||
try {
|
try {
|
||||||
contentResolver.unregisterContentObserver(androidContactsObserver)
|
contentResolver.unregisterContentObserver(androidContactsObserver)
|
||||||
@ -3003,9 +3003,8 @@ class BaresipService: Service() {
|
|||||||
var blockRules = mutableListOf<BlockRule>()
|
var blockRules = mutableListOf<BlockRule>()
|
||||||
|
|
||||||
fun isBlocked(uri: String): Boolean {
|
fun isBlocked(uri: String): Boolean {
|
||||||
for (rule in blockRules) {
|
for (rule in blockRules)
|
||||||
if (rule.matches(uri)) return true
|
if (rule.matches(uri)) return true
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3112,8 +3111,7 @@ class BaresipService: Service() {
|
|||||||
if (audioFocusRequest != null) {
|
if (audioFocusRequest != null) {
|
||||||
Log.d(TAG, "Abandoning audio focus")
|
Log.d(TAG, "Abandoning audio focus")
|
||||||
val am = ctx.getSystemService(AUDIO_SERVICE) as AudioManager
|
val am = ctx.getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
if (am.abandonAudioFocusRequest(audioFocusRequest!!) ==
|
if (am.abandonAudioFocusRequest(audioFocusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
|
||||||
AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
|
|
||||||
audioFocusRequest = null
|
audioFocusRequest = null
|
||||||
else
|
else
|
||||||
Log.e(TAG, "Failed to abandon audio focus")
|
Log.e(TAG, "Failed to abandon audio focus")
|
||||||
@ -3124,11 +3122,10 @@ class BaresipService: Service() {
|
|||||||
return if (VERSION.SDK_INT < 31)
|
return if (VERSION.SDK_INT < 31)
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
am.isBluetoothScoOn
|
am.isBluetoothScoOn
|
||||||
|
else if (am.communicationDevice != null)
|
||||||
|
am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO
|
||||||
else
|
else
|
||||||
if (am.communicationDevice != null)
|
false
|
||||||
am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO
|
|
||||||
else
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startBluetoothSco(ctx: Context, delay: Long, count: Int) {
|
private fun startBluetoothSco(ctx: Context, delay: Long, count: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user