mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
fix: crashes (#4281)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
7f7d189958
commit
fb6a4c96b8
5 changed files with 74 additions and 17 deletions
|
|
@ -108,6 +108,10 @@
|
|||
android:localeConfig="@xml/locales_config"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<uses-library
|
||||
android:name="org.apache.http.legacy"
|
||||
android:required="false" />
|
||||
|
||||
<!-- Default crash collection and analytics off until we (possibly) turn it on in application.onCreate -->
|
||||
<meta-data
|
||||
android:name="firebase_crashlytics_collection_enabled"
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ constructor(
|
|||
private var backoffDelay = MIN_BACKOFF_MILLIS
|
||||
|
||||
private var socket: Socket? = null
|
||||
private lateinit var outStream: OutputStream
|
||||
private var outStream: OutputStream? = null
|
||||
|
||||
private var connectionStartTime: Long = 0
|
||||
private var packetsReceived: Int = 0
|
||||
|
|
@ -69,15 +69,32 @@ constructor(
|
|||
}
|
||||
|
||||
override fun sendBytes(p: ByteArray) {
|
||||
val stream = outStream
|
||||
if (stream == null) {
|
||||
Logger.w { "[$address] TCP cannot send ${p.size} bytes: outStream is null (connection not established)" }
|
||||
return
|
||||
}
|
||||
|
||||
packetsSent++
|
||||
bytesSent += p.size
|
||||
Logger.d { "[$address] TCP sending packet #$packetsSent - ${p.size} bytes (Total TX: $bytesSent bytes)" }
|
||||
outStream.write(p)
|
||||
try {
|
||||
stream.write(p)
|
||||
} catch (ex: IOException) {
|
||||
Logger.e(ex) { "[$address] TCP write error: ${ex.message}" }
|
||||
onDeviceDisconnect(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun flushBytes() {
|
||||
val stream = outStream ?: return
|
||||
Logger.d { "[$address] TCP flushing output stream" }
|
||||
outStream.flush()
|
||||
try {
|
||||
stream.flush()
|
||||
} catch (ex: IOException) {
|
||||
Logger.e(ex) { "[$address] TCP flush error: ${ex.message}" }
|
||||
onDeviceDisconnect(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDeviceDisconnect(waitForStopped: Boolean) {
|
||||
|
|
@ -98,6 +115,7 @@ constructor(
|
|||
}
|
||||
s.close()
|
||||
socket = null
|
||||
outStream = null
|
||||
}
|
||||
super.onDeviceDisconnect(waitForStopped)
|
||||
}
|
||||
|
|
|
|||
3
app/src/main/res/raw/keep.xml
Normal file
3
app/src/main/res/raw/keep.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:keep="@raw/aboutlibraries" />
|
||||
|
|
@ -55,6 +55,27 @@ class TCPInterfaceTest {
|
|||
assertArrayEquals("Heartbeat bytes should match", expectedHeartbeat, tcpInterface.capturedBytes)
|
||||
}
|
||||
|
||||
// Since startConnect is private, we'd normally need reflection or to make a internal method.
|
||||
// For now, testing keepAlive is a good first step for stability.
|
||||
@Test
|
||||
fun `sendBytes does not crash when outStream is null`() = runTest {
|
||||
val address = "192.168.1.1:4403"
|
||||
val tcpInterface =
|
||||
object : TCPInterface(service, dispatchers, address) {
|
||||
override fun connect() {}
|
||||
}
|
||||
|
||||
// This should not throw UninitializedPropertyAccessException
|
||||
tcpInterface.sendBytes(byteArrayOf(1, 2, 3))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `flushBytes does not crash when outStream is null`() = runTest {
|
||||
val address = "192.168.1.1:4403"
|
||||
val tcpInterface =
|
||||
object : TCPInterface(service, dispatchers, address) {
|
||||
override fun connect() {}
|
||||
}
|
||||
|
||||
// This should not throw UninitializedPropertyAccessException
|
||||
tcpInterface.flushBytes()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.meshtastic.feature.settings
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
|
@ -22,9 +21,11 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
|
||||
import com.mikepenz.aboutlibraries.util.withContext
|
||||
|
|
@ -49,16 +50,26 @@ fun AboutScreen(onNavigateUp: () -> Unit) {
|
|||
},
|
||||
) { paddingValues ->
|
||||
val context = LocalContext.current
|
||||
val libraries = Libs.Builder().withContext(context).build()
|
||||
LibrariesContainer(
|
||||
showAuthor = true,
|
||||
showVersion = true,
|
||||
showDescription = true,
|
||||
showLicenseBadges = true,
|
||||
showFundingBadges = true,
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
||||
libraries = libraries,
|
||||
)
|
||||
val libraries = remember {
|
||||
try {
|
||||
Libs.Builder().withContext(context).build()
|
||||
} catch (e: IllegalStateException) {
|
||||
Logger.w("${e.message}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
if (libraries != null) {
|
||||
LibrariesContainer(
|
||||
showAuthor = true,
|
||||
showVersion = true,
|
||||
showDescription = true,
|
||||
showLicenseBadges = true,
|
||||
showFundingBadges = true,
|
||||
modifier = Modifier.fillMaxSize().padding(paddingValues),
|
||||
libraries = libraries,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue