add support for text based crash dumps

This commit is contained in:
Chloe committed 2026-03-19 15:25:59 -07:00
1 parent 69188075a3
commit 714f750f77
7 files changed
+53 -22

No files matched your search

+1 -1
View File
@@ -103,7 +103,7 @@
</intent-filter>
</activity>
<activity
android:name=".preferences.GeodeLogViewActivity"
android:name=".preferences.TextViewActivity"
android:exported="false"
android:theme="@style/Theme.GeodeLauncher">
</activity>
@@ -13,7 +13,8 @@ import kotlin.time.Instant
data class CrashDump(
val filename: String,
val lastModified: Instant
val lastModified: Instant,
val fullPath: String,
)
class CrashViewModel(crashDirectory: File) : BaseDirectoryViewModel<CrashDump>(crashDirectory) {
@@ -41,16 +42,19 @@ class CrashViewModel(crashDirectory: File) : BaseDirectoryViewModel<CrashDump>(c
val children = crashDirectory.listFiles {
// ignore indicator files (including old file)
_, name -> name != LaunchUtils.CRASH_INDICATOR_NAME && name != "last-pid"
_, name -> !LaunchUtils.CRASH_INDICATOR_NAMES.contains(name)
} ?: return emptyList()
hasIndicator = File(crashDirectory, LaunchUtils.CRASH_INDICATOR_NAME).exists()
hasIndicator = LaunchUtils.CRASH_INDICATOR_NAMES.any {
File(crashDirectory, it).exists()
}
return children
.map {
CrashDump(
filename = it.name,
lastModified = Instant.fromEpochMilliseconds(it.lastModified())
lastModified = Instant.fromEpochMilliseconds(it.lastModified()),
fullPath = it.path,
)
}
.sortedByDescending { it.lastModified }
@@ -58,7 +62,12 @@ class CrashViewModel(crashDirectory: File) : BaseDirectoryViewModel<CrashDump>(c
fun clearIndicator() {
viewModelScope.launch(Dispatchers.IO) {
File(baseDirectory, LaunchUtils.CRASH_INDICATOR_NAME).delete()
LaunchUtils.CRASH_INDICATOR_NAMES.forEach {
val crashFile = File(baseDirectory, it)
if (crashFile.exists()) {
crashFile.delete()
}
}
hasIndicator = false
}
@@ -66,7 +75,8 @@ class CrashViewModel(crashDirectory: File) : BaseDirectoryViewModel<CrashDump>(c
fun createIndicator() {
viewModelScope.launch(Dispatchers.IO) {
File(baseDirectory, LaunchUtils.CRASH_INDICATOR_NAME).createNewFile()
val crashFile = File(baseDirectory, LaunchUtils.CRASH_INDICATOR_NAMES.first())
crashFile.createNewFile()
hasIndicator = true
}
@@ -14,6 +14,7 @@ data class GeodeLog(
val filename: String,
val lastModified: Instant,
val fileSize: Long,
val fullPath: String,
)
class GeodeLogsViewModel(crashDirectory: File) : BaseDirectoryViewModel<GeodeLog>(crashDirectory) {
@@ -43,7 +44,8 @@ class GeodeLogsViewModel(crashDirectory: File) : BaseDirectoryViewModel<GeodeLog
GeodeLog(
filename = it.name,
lastModified = Instant.fromEpochMilliseconds(it.lastModified()),
fileSize = it.length()
fileSize = it.length(),
fullPath = it.path,
)
}
.sortedByDescending { it.lastModified }
@@ -12,6 +12,7 @@ import androidx.activity.OnBackPressedDispatcher
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -110,11 +111,20 @@ fun shareCrash(context: Context, filename: String) {
@Composable
fun CrashCard(crashDump: CrashDump, crashViewModel: CrashViewModel, modifier: Modifier = Modifier) {
val isReadable = crashDump.filename.endsWith(".txt")
val context = LocalContext.current
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier
.fillMaxWidth()
.padding(vertical = 1.dp, horizontal = 8.dp)
.height(64.dp)
.then(modifier)
.clickable(isReadable) {
val launchIntent = Intent(context, TextViewActivity::class.java).run {
putExtra(TextViewActivity.EXTRA_LOG_VIEW_FILENAME, crashDump.fullPath)
}
context.startActivity(launchIntent)
}
.background(MaterialTheme.colorScheme.surfaceContainerLow)
.padding(vertical = 8.dp, horizontal = 8.dp)
) {
@@ -117,8 +117,8 @@ fun GeodeLogCard(geodeLog: GeodeLog, geodeLogsViewModel: GeodeLogsViewModel, mod
.height(64.dp)
.then(modifier)
.clickable {
val launchIntent = Intent(context, GeodeLogViewActivity::class.java).run {
putExtra(GeodeLogViewActivity.EXTRA_LOG_VIEW_FILENAME, geodeLog.filename)
val launchIntent = Intent(context, TextViewActivity::class.java).run {
putExtra(TextViewActivity.EXTRA_LOG_VIEW_FILENAME, geodeLog.fullPath)
}
context.startActivity(launchIntent)
}
@@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.selection.SelectionContainer
@@ -40,18 +39,19 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.geode.launcher.R
import com.geode.launcher.log.GeodeLogsViewModel
import com.geode.launcher.ui.theme.GeodeLauncherTheme
import com.geode.launcher.ui.theme.LocalTheme
import com.geode.launcher.ui.theme.Theme
import com.geode.launcher.ui.theme.Typography
import com.geode.launcher.ui.theme.robotoMonoFamily
import com.geode.launcher.utils.PreferenceUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
class GeodeLogViewActivity : ComponentActivity() {
class TextViewActivity : ComponentActivity() {
companion object {
const val EXTRA_LOG_VIEW_FILENAME = "EXTRA_LOG_FILENAME"
}
@@ -95,14 +95,23 @@ class GeodeLogViewActivity : ComponentActivity() {
fun GeodeLogView(
onBackPressedDispatcher: OnBackPressedDispatcher?,
filename: String,
geodeLogsViewModel: GeodeLogsViewModel = viewModel(factory = GeodeLogsViewModel.Factory)
) {
var loadingFile by remember { mutableStateOf(true) }
var description by remember { mutableStateOf(emptyList<String>()) }
val toRead = File(filename)
LaunchedEffect(filename) {
loadingFile = true
description = geodeLogsViewModel.getFileText(filename)
withContext(Dispatchers.IO) {
if (!toRead.isFile) {
description = listOf("File does not exist!")
} else {
description = toRead.readLines()
}
}
loadingFile = false
}
@@ -123,7 +132,7 @@ fun GeodeLogView(
},
title = {
Text(
filename,
toRead.name,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
@@ -73,7 +73,7 @@ object LaunchUtils {
return File(getBaseDirectory(context), "save")
}
const val CRASH_INDICATOR_NAME = "lastSessionDidCrash"
val CRASH_INDICATOR_NAMES = setOf("lastSessionDidCrash", "last-pid", "last-crashed")
fun getCrashDirectory(context: Context): File {
val base = getBaseDirectory(context)
@@ -93,7 +93,7 @@ object LaunchUtils {
val children = crashDirectory.listFiles {
// ignore indicator files (including old file)
_, name -> name != CRASH_INDICATOR_NAME && name != "last-pid"
_, name -> !CRASH_INDICATOR_NAMES.contains(name)
}
return children?.maxByOrNull { it.lastModified() }
@@ -101,9 +101,9 @@ object LaunchUtils {
fun lastSessionCrashed(context: Context): Boolean {
val base = getCrashDirectory(context)
val crashIndicatorFile = File(base, CRASH_INDICATOR_NAME)
return crashIndicatorFile.exists()
return CRASH_INDICATOR_NAMES.any {
File(base, it).exists()
}
}
enum class LauncherError : Serializable {