Fixed concurrent modification crash in ServiceRecordAggregator and link clicking in scroll.

This commit is contained in:
Koen J 2024-12-12 14:13:24 +01:00
parent 4981617f7a
commit 6da5c11731
3 changed files with 56 additions and 45 deletions

View File

@ -55,6 +55,7 @@ class ServiceRecordAggregator {
if (_cts != null) throw Exception("Already started.")
_cts = CoroutineScope(Dispatchers.Default).launch {
try {
while (isActive) {
val now = Date()
synchronized(_currentServices) {
@ -71,6 +72,9 @@ class ServiceRecordAggregator {
onServicesUpdated?.invoke(_currentServices.toList())
delay(5000)
}
} catch (e: Throwable) {
Logger.e(TAG, "Unexpected failure in MDNS loop", e)
}
}
}
}
@ -83,6 +87,7 @@ class ServiceRecordAggregator {
}
fun add(packet: DnsPacket) {
val currentServices: List<DnsService>
val dnsResourceRecords = packet.answers + packet.additionals + packet.authorities
val txtRecords = dnsResourceRecords.filter { it.type == ResourceRecordType.TXT.value.toInt() }.map { it to it.getDataReader().readTXTRecord() }
val aRecords = dnsResourceRecords.filter { it.type == ResourceRecordType.A.value.toInt() }.map { it to it.getDataReader().readARecord() }
@ -99,7 +104,7 @@ class ServiceRecordAggregator {
aaaaRecords.forEach { builder.appendLine("AAAA ${it.first.name} ${it.first.type} ${it.first.clazz} TTL ${it.first.timeToLive}: ${it.second.address}") }
Logger.i(TAG, "$builder")*/
val currentServices: MutableList<DnsService>
synchronized(this._currentServices) {
ptrRecords.forEach { record ->
val cachedPtrRecord = _cachedPtrRecords.getOrPut(record.first.name) { mutableListOf() }
val newPtrRecord = CachedDnsPtrRecord(Date(System.currentTimeMillis() + record.first.timeToLive.toLong() * 1000L), record.second.domainName)
@ -126,8 +131,6 @@ class ServiceRecordAggregator {
_cachedSrvRecords[srvRecord.first.name] = CachedDnsSrvRecord(Date(System.currentTimeMillis() + srvRecord.first.timeToLive.toLong() * 1000L), srvRecord.second)
}
//TODO: Maybe this can be debounced?
synchronized(this._currentServices) {
currentServices = getCurrentServices()
this._currentServices.clear()
this._currentServices.addAll(currentServices)

View File

@ -59,7 +59,7 @@ class PlatformLinkMovementMethod(private val _context: Context) : LinkMovementMe
if (linkPressed && pressedLinks != null) {
val dx = event.x - downX
val dy = event.y - downY
if (Math.abs(dx) <= touchSlop && Math.abs(dy) <= touchSlop) {
if (Math.abs(dx) <= touchSlop && Math.abs(dy) <= touchSlop && isTouchInside(widget, event)) {
runBlocking {
for (link in pressedLinks!!) {
Logger.i(TAG) { "Link clicked '${link.url}'." }
@ -101,7 +101,7 @@ class PlatformLinkMovementMethod(private val _context: Context) : LinkMovementMe
}
}
return super.onTouchEvent(widget, buffer, event)
return false
}
private fun findLinksAtTouchPosition(widget: TextView, buffer: Spannable, event: MotionEvent): Array<URLSpan> {
@ -114,6 +114,10 @@ class PlatformLinkMovementMethod(private val _context: Context) : LinkMovementMe
return buffer.getSpans(off, off, URLSpan::class.java)
}
private fun isTouchInside(widget: TextView, event: MotionEvent): Boolean {
return event.x >= 0 && event.x <= widget.width && event.y >= 0 && event.y <= widget.height
}
companion object {
const val TAG = "PlatformLinkMovementMethod"
}

View File

@ -76,7 +76,7 @@ class NonScrollingTextView : androidx.appcompat.widget.AppCompatTextView {
if (linkPressed && _lastTouchedLinks != null) {
val dx = event.x - downX
val dy = event.y - downY
if (Math.abs(dx) <= touchSlop && Math.abs(dy) <= touchSlop) {
if (Math.abs(dx) <= touchSlop && Math.abs(dy) <= touchSlop && isTouchInside(event)) {
runBlocking {
for (link in _lastTouchedLinks!!) {
Logger.i(PlatformLinkMovementMethod.TAG) { "Link clicked '${link.url}'." }
@ -119,7 +119,11 @@ class NonScrollingTextView : androidx.appcompat.widget.AppCompatTextView {
}
}
return super.onTouchEvent(event)
return false
}
private fun isTouchInside(event: MotionEvent): Boolean {
return event.x >= 0 && event.x <= width && event.y >= 0 && event.y <= height
}
companion object {