Handle service events recursively from queue (no need for timers)

Fixed removal of onhold notice
This commit is contained in:
Juha Heinanen
2022-02-06 09:30:29 +02:00
parent 0a0ebf3f85
commit 40185013af
2 changed files with 57 additions and 41 deletions
@@ -69,8 +69,6 @@ class BaresipService: Service() {
private var hotSpotIsEnabled = false private var hotSpotIsEnabled = false
private var hotSpotAddresses = mapOf<String, String>() private var hotSpotAddresses = mapOf<String, String>()
private var mediaPlayer: MediaPlayer? = null private var mediaPlayer: MediaPlayer? = null
private val serviceEvents = mutableListOf<Event<ServiceEvent>>()
private var previousEvent: Long = 0
@SuppressLint("WakelockTimeout") @SuppressLint("WakelockTimeout")
override fun onCreate() { override fun onCreate() {
@@ -883,22 +881,18 @@ class BaresipService: Service() {
} }
} }
// In order to avoid observer missing events, post them at least 50ms apart postServiceEvent(ServiceEvent(newEvent ?: event, arrayListOf(uap, callp), System.nanoTime()))
val currentTime = System.currentTimeMillis()
val e = Event(ServiceEvent(newEvent ?: event, arrayListOf(uap, callp), currentTime))
if (previousEvent + 50 > currentTime) {
val delay = previousEvent + 50 - currentTime
previousEvent = currentTime + delay
serviceEvents.add(e)
Timer().schedule(delay) {
if (serviceEvents.isNotEmpty())
serviceEvent.postValue(serviceEvents.removeFirst())
}
} else {
previousEvent = currentTime
serviceEvent.postValue(e)
} }
private fun postServiceEvent(event: ServiceEvent) {
serviceEvents.add(event)
if (serviceEvents.size == 1) {
Log.d(TAG, "Posted service event ${event.event} at ${event.timeStamp}")
serviceEvent.postValue(Event(event.timeStamp))
} else {
Log.d(TAG, "Added service event ${event.event}")
}
} }
@SuppressLint("UnspecifiedImmutableFlag") @SuppressLint("UnspecifiedImmutableFlag")
@@ -980,8 +974,7 @@ class BaresipService: Service() {
return return
} }
nt.play() nt.play()
serviceEvent.postValue(Event(ServiceEvent("message show", arrayListOf(uap, peer), postServiceEvent(ServiceEvent("message show", arrayListOf(uap, peer), System.nanoTime()))
timeStamp)))
} }
@Keep @Keep
@@ -1020,8 +1013,7 @@ class BaresipService: Service() {
fun started() { fun started() {
Log.d(TAG, "Received 'started' from baresip") Log.d(TAG, "Received 'started' from baresip")
Api.net_debug() Api.net_debug()
serviceEvent.postValue(Event(ServiceEvent("started", arrayListOf(callActionUri), postServiceEvent(ServiceEvent("started", arrayListOf(callActionUri), System.nanoTime()))
System.currentTimeMillis())))
callActionUri = "" callActionUri = ""
if (VERSION.SDK_INT >= 23) if (VERSION.SDK_INT >= 23)
Log.d(TAG, "Battery optimizations are ignored: " + Log.d(TAG, "Battery optimizations are ignored: " +
@@ -1034,8 +1026,7 @@ class BaresipService: Service() {
fun stopped(error: String) { fun stopped(error: String) {
Log.d(TAG, "Received 'stopped' from baresip with param '$error'") Log.d(TAG, "Received 'stopped' from baresip with param '$error'")
isServiceRunning = false isServiceRunning = false
serviceEvent.postValue(Event(ServiceEvent("stopped", arrayListOf(error), postServiceEvent(ServiceEvent("stopped", arrayListOf(error), System.nanoTime()))
System.currentTimeMillis())))
stopForeground(true) stopForeground(true)
stopSelf() stopSelf()
} }
@@ -1473,7 +1464,8 @@ class BaresipService: Service() {
val chatTexts: MutableMap<String, String> = mutableMapOf() val chatTexts: MutableMap<String, String> = mutableMapOf()
val activities = mutableListOf<String>() val activities = mutableListOf<String>()
var dnsServers = listOf<InetAddress>() var dnsServers = listOf<InetAddress>()
var serviceEvent = MutableLiveData<Event<ServiceEvent>>() val serviceEvent = MutableLiveData<Event<Long>>()
val serviceEvents = mutableListOf<ServiceEvent>()
} }
@@ -72,7 +72,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var am: AudioManager private lateinit var am: AudioManager
private lateinit var kgm: KeyguardManager private lateinit var kgm: KeyguardManager
private lateinit var screenEventReceiver: BroadcastReceiver private lateinit var screenEventReceiver: BroadcastReceiver
private lateinit var serviceEventObserver: Observer<Event<ServiceEvent>> private lateinit var serviceEventObserver: Observer<Event<Long>>
private lateinit var quitTimer: CountDownTimer private lateinit var quitTimer: CountDownTimer
private lateinit var stopState: String private lateinit var stopState: String
private var micIcon: MenuItem? = null private var micIcon: MenuItem? = null
@@ -154,11 +154,12 @@ class MainActivity : AppCompatActivity() {
am = getSystemService(AUDIO_SERVICE) as AudioManager am = getSystemService(AUDIO_SERVICE) as AudioManager
kgm = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager kgm = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
serviceEventObserver = Observer<Event<ServiceEvent>> { serviceEventObserver = Observer<Event<Long>> {
val serviceEvent = it.getContentIfNotHandled() val event = it.getContentIfNotHandled()
if (serviceEvent != null) { Log.d(TAG, "Observed event $event")
Log.d(TAG, "Observed event ${serviceEvent.event}") if (event != null && BaresipService.serviceEvents.isNotEmpty()) {
handleServiceEvent(serviceEvent.event, serviceEvent.params) val first = BaresipService.serviceEvents.first()
handleServiceEvent(first.event, first.params)
} }
} }
@@ -732,6 +733,7 @@ class MainActivity : AppCompatActivity() {
Log.d(TAG, "Main onDestroy") Log.d(TAG, "Main onDestroy")
this.unregisterReceiver(screenEventReceiver) this.unregisterReceiver(screenEventReceiver)
BaresipService.serviceEvent.removeObserver(serviceEventObserver) BaresipService.serviceEvent.removeObserver(serviceEventObserver)
BaresipService.serviceEvents.clear()
BaresipService.activities.clear() BaresipService.activities.clear()
} }
@@ -906,10 +908,24 @@ class MainActivity : AppCompatActivity() {
} }
private fun handleServiceEvent(event: String, params: ArrayList<String>) { private fun handleServiceEvent(event: String, params: ArrayList<String>) {
fun handleNextEvent(logMessage: String? = null) {
if (logMessage != null)
Log.w(TAG, logMessage)
if (BaresipService.serviceEvents.isNotEmpty()) {
BaresipService.serviceEvents.removeFirst()
if (BaresipService.serviceEvents.isNotEmpty()) {
val e = BaresipService.serviceEvents.first()
handleServiceEvent(e.event, e.params)
}
}
}
if (taskId == -1) { if (taskId == -1) {
Log.d(TAG, "Omit service event '$event' for task -1") handleNextEvent("Omit service event '$event' for task -1")
return return
} }
if (event == "started") { if (event == "started") {
val callActionUri = params[0] val callActionUri = params[0]
Log.d(TAG, "Handling service event 'started' with '$callActionUri'") Log.d(TAG, "Handling service event 'started' with '$callActionUri'")
@@ -920,7 +936,7 @@ class MainActivity : AppCompatActivity() {
if (BaresipService.uas.size > 0) { if (BaresipService.uas.size > 0) {
ua = BaresipService.uas[0] ua = BaresipService.uas[0]
} else { } else {
Log.w(TAG, "No UAs to make the call to '$callActionUri'") handleNextEvent("No UAs to make the call to '$callActionUri'")
return return
} }
spinToAor(ua.account.aor) spinToAor(ua.account.aor)
@@ -933,8 +949,10 @@ class MainActivity : AppCompatActivity() {
aorSpinner.tag = UserAgent.uas()[0].account.aor aorSpinner.tag = UserAgent.uas()[0].account.aor
} }
} }
handleNextEvent()
return return
} }
if (event == "stopped") { if (event == "stopped") {
Log.d(TAG, "Handling service event 'stopped' with param '${params[0]}'") Log.d(TAG, "Handling service event 'stopped' with param '${params[0]}'")
if (params[0] != "") { if (params[0] != "") {
@@ -962,13 +980,15 @@ class MainActivity : AppCompatActivity() {
val uap = params[0] val uap = params[0]
val ua = UserAgent.ofUap(uap) val ua = UserAgent.ofUap(uap)
if (ua == null) { if (ua == null) {
Log.w(TAG, "handleServiceEvent '$event' did not find ua $uap") handleNextEvent("handleServiceEvent '$event' did not find ua $uap")
return return
} }
val ev = event.split(",") val ev = event.split(",")
Log.d(TAG, "Handling service event '${ev[0]}' for $uap") Log.d(TAG, "Handling service event '${ev[0]}' for $uap")
val acc = ua.account val acc = ua.account
val aor = ua.account.aor val aor = ua.account.aor
for (account_index in UserAgent.uas().indices) { for (account_index in UserAgent.uas().indices) {
if (UserAgent.uas()[account_index].account.aor == aor) { if (UserAgent.uas()[account_index].account.aor == aor) {
when (ev[0]) { when (ev[0]) {
@@ -986,11 +1006,13 @@ class MainActivity : AppCompatActivity() {
} else { } else {
Log.d(TAG, "Reordering to front") Log.d(TAG, "Reordering to front")
BaresipService.activities.clear() BaresipService.activities.clear()
BaresipService.serviceEvents.clear()
val i = Intent(applicationContext, MainActivity::class.java) val i = Intent(applicationContext, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
i.putExtra("action", "call show") i.putExtra("action", "call show")
i.putExtra("callp", callp) i.putExtra("callp", callp)
startActivity(i) startActivity(i)
return
} }
} }
"call answered" -> { "call answered" -> {
@@ -1010,7 +1032,7 @@ class MainActivity : AppCompatActivity() {
val callp = params[1] val callp = params[1]
val call = Call.ofCallp(callp) val call = Call.ofCallp(callp)
if (call == null) { if (call == null) {
Log.w(TAG, "Call $callp to be verified is not found") handleNextEvent("Call $callp to be verified is not found")
return return
} }
val titleView = View.inflate(this, R.layout.alert_title, null) as TextView val titleView = View.inflate(this, R.layout.alert_title, null) as TextView
@@ -1052,7 +1074,7 @@ class MainActivity : AppCompatActivity() {
val callp = params[1] val callp = params[1]
val call = Call.ofCallp(callp) val call = Call.ofCallp(callp)
if (call == null) { if (call == null) {
Log.w(TAG, "Call $callp that is verified is not found") handleNextEvent("Call $callp that is verified is not found")
return return
} }
val tag: String = if (call.security == R.drawable.box_yellow) val tag: String = if (call.security == R.drawable.box_yellow)
@@ -1069,6 +1091,7 @@ class MainActivity : AppCompatActivity() {
if (!BaresipService.isMainVisible) { if (!BaresipService.isMainVisible) {
Log.d(TAG, "Reordering to front") Log.d(TAG, "Reordering to front")
BaresipService.activities.clear() BaresipService.activities.clear()
BaresipService.serviceEvents.clear()
val i = Intent(applicationContext, MainActivity::class.java) val i = Intent(applicationContext, MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
i.putExtra("action", event) i.putExtra("action", event)
@@ -1127,12 +1150,11 @@ class MainActivity : AppCompatActivity() {
Utils.setShowWhenLocked(this, false) Utils.setShowWhenLocked(this, false)
} }
"message", "message show", "message reply" -> { "message", "message show", "message reply" -> {
val peer = params[1]
val i = Intent(applicationContext, ChatActivity::class.java) val i = Intent(applicationContext, ChatActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP i.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
val b = Bundle() val b = Bundle()
b.putString("aor", aor) b.putString("aor", aor)
b.putString("peer", peer) b.putString("peer", params[1])
b.putBoolean("focus", ev[0] == "message reply") b.putBoolean("focus", ev[0] == "message reply")
i.putExtras(b) i.putExtras(b)
chatRequests.launch(i) chatRequests.launch(i)
@@ -1159,6 +1181,9 @@ class MainActivity : AppCompatActivity() {
break break
} }
} }
handleNextEvent()
} }
private fun reStart() { private fun reStart() {
@@ -1836,16 +1861,15 @@ class MainActivity : AppCompatActivity() {
dialpadButton.isEnabled = false dialpadButton.isEnabled = false
infoButton.isEnabled = true infoButton.isEnabled = true
callControl.visibility = View.VISIBLE callControl.visibility = View.VISIBLE
Handler(Looper.getMainLooper()).postDelayed({
onHoldNotice.visibility = if (call.held) View.VISIBLE else View.GONE
}, 100)
if (call.held) { if (call.held) {
imm.hideSoftInputFromWindow(dtmf.windowToken, 0) imm.hideSoftInputFromWindow(dtmf.windowToken, 0)
dtmf.isEnabled = false dtmf.isEnabled = false
Handler(Looper.getMainLooper()).postDelayed({
onHoldNotice.visibility = View.VISIBLE
}, 250)
} else { } else {
dtmf.isEnabled = true dtmf.isEnabled = true
dtmf.requestFocus() dtmf.requestFocus()
onHoldNotice.visibility = View.GONE
if (resources.configuration.orientation == ORIENTATION_PORTRAIT) if (resources.configuration.orientation == ORIENTATION_PORTRAIT)
imm.showSoftInput(dtmf, InputMethodManager.SHOW_IMPLICIT) imm.showSoftInput(dtmf, InputMethodManager.SHOW_IMPLICIT)
if (dtmfWatcher != null) dtmf.removeTextChangedListener(dtmfWatcher) if (dtmfWatcher != null) dtmf.removeTextChangedListener(dtmfWatcher)