mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 16:32:39 +00:00
add option to filter by log level
This commit is contained in:
6 files changed
+143
-22
No files matched your search
@@ -104,16 +104,20 @@ fun getLogColor(priority: LogPriority): Color {
|
|||||||
// i just copied these from my ide tbh
|
// i just copied these from my ide tbh
|
||||||
return if (isDark) {
|
return if (isDark) {
|
||||||
when (priority) {
|
when (priority) {
|
||||||
LogPriority.ERROR -> Color(0xffdf5151)
|
LogPriority.ERROR -> Color(0xff_df_51_51)
|
||||||
LogPriority.WARN -> Color(0xffbcb500)
|
LogPriority.WARN -> Color(0xff_bc_b5_00)
|
||||||
LogPriority.FATAL -> Color(0xffb8b6fc)
|
LogPriority.FATAL -> Color(0xff_b8_b6_fc)
|
||||||
|
LogPriority.DEBUG -> Color(0xff_aa_aa_aa)
|
||||||
|
LogPriority.VERBOSE -> Color(0xff_77_77_77)
|
||||||
else -> Color.Unspecified
|
else -> Color.Unspecified
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
when (priority) {
|
when (priority) {
|
||||||
LogPriority.ERROR -> Color(0xffdf5151)
|
LogPriority.ERROR -> Color(0xff_df_51_51)
|
||||||
LogPriority.WARN -> Color(0xffeab700)
|
LogPriority.WARN -> Color(0xff_ea_b7_00)
|
||||||
LogPriority.FATAL -> Color(0xffa142f4)
|
LogPriority.FATAL -> Color(0xff_a1_42_f4)
|
||||||
|
LogPriority.DEBUG -> Color(0xff_77_77_77)
|
||||||
|
LogPriority.VERBOSE -> Color(0xff_aa_aa_aa)
|
||||||
else -> Color.Unspecified
|
else -> Color.Unspecified
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,6 +142,25 @@ fun copyLogText(context: Context, logMessage: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SelectLogLevelDialog(
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onSelect: (LogPriority) -> Unit,
|
||||||
|
initialValue: LogPriority
|
||||||
|
) {
|
||||||
|
SelectDialog(
|
||||||
|
title = stringResource(R.string.application_logs_level_dialog_name),
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
onSelect = { onSelect(it) },
|
||||||
|
initialValue = initialValue,
|
||||||
|
toLabel = {
|
||||||
|
// i'm lazy
|
||||||
|
it.name.lowercase().replaceFirstChar { c -> c.uppercaseChar() }
|
||||||
|
},
|
||||||
|
optionsCount = LogPriority.FATAL downTo LogPriority.VERBOSE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LogCard(logLine: LogLine, modifier: Modifier = Modifier) {
|
fun LogCard(logLine: LogLine, modifier: Modifier = Modifier) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -205,6 +228,18 @@ fun ApplicationLogsScreen(
|
|||||||
listState.scrollToItem(logLines.size)
|
listState.scrollToItem(logLines.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showLogLevelSelect by remember { mutableStateOf(false) }
|
||||||
|
if (showLogLevelSelect) {
|
||||||
|
SelectLogLevelDialog(
|
||||||
|
onDismissRequest = { showLogLevelSelect = false },
|
||||||
|
onSelect = {
|
||||||
|
logViewModel.logLevel = it
|
||||||
|
showLogLevelSelect = false
|
||||||
|
},
|
||||||
|
initialValue = logViewModel.logLevel
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
topBar = {
|
topBar = {
|
||||||
@@ -238,7 +273,7 @@ fun ApplicationLogsScreen(
|
|||||||
contentDescription = stringResource(R.string.application_logs_share)
|
contentDescription = stringResource(R.string.application_logs_share)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(onClick = { showMoreOptions = !showMoreOptions },) {
|
IconButton(onClick = { showMoreOptions = !showMoreOptions }) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Filled.MoreVert,
|
Icons.Filled.MoreVert,
|
||||||
contentDescription = stringResource(R.string.application_logs_more)
|
contentDescription = stringResource(R.string.application_logs_more)
|
||||||
@@ -252,7 +287,7 @@ fun ApplicationLogsScreen(
|
|||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
painterResource(R.drawable.icon_filter_list),
|
painterResource(R.drawable.icon_bug_report),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -272,6 +307,21 @@ fun ApplicationLogsScreen(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DropdownMenuItem(
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
painterResource(R.drawable.icon_filter_list),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
Text(stringResource(R.string.application_logs_level))
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
showLogLevelSelect = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -105,7 +104,7 @@ fun SettingsSelectCard(
|
|||||||
},
|
},
|
||||||
initialValue = preferenceValue,
|
initialValue = preferenceValue,
|
||||||
toLabel = toLabel,
|
toLabel = toLabel,
|
||||||
optionsCount = maxVal
|
optionsCount = 0..maxVal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,15 +189,15 @@ fun StringDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SelectDialog(
|
fun <T> SelectDialog(
|
||||||
title: String,
|
title: String,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onSelect: (Int) -> Unit,
|
onSelect: (T) -> Unit,
|
||||||
initialValue: Int,
|
initialValue: T,
|
||||||
toLabel: @Composable (Int) -> String,
|
toLabel: @Composable (T) -> String,
|
||||||
optionsCount: Int,
|
optionsCount: Iterable<T>,
|
||||||
) {
|
) {
|
||||||
var selectedValue by remember { mutableIntStateOf(initialValue) }
|
var selectedValue by remember { mutableStateOf(initialValue) }
|
||||||
|
|
||||||
Dialog(onDismissRequest = onDismissRequest) {
|
Dialog(onDismissRequest = onDismissRequest) {
|
||||||
Card(
|
Card(
|
||||||
@@ -218,7 +217,7 @@ fun SelectDialog(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// do not give the row or column padding!! it messes up the selection effect
|
// do not give the row or column padding!! it messes up the selection effect
|
||||||
(0..optionsCount).forEach { id ->
|
optionsCount.forEach { id ->
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -29,9 +29,50 @@ data class ProcessInformation(val processId: Int, val threadId: Int, val process
|
|||||||
enum class LogPriority {
|
enum class LogPriority {
|
||||||
UNKNOWN, DEFAULT, VERBOSE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT;
|
UNKNOWN, DEFAULT, VERBOSE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT;
|
||||||
|
|
||||||
|
class LogPriorityIterator(
|
||||||
|
start: LogPriority,
|
||||||
|
private val end: LogPriority,
|
||||||
|
private val step: Int
|
||||||
|
) : Iterator<LogPriority> {
|
||||||
|
private var hasNext: Boolean = if (step > 0) start <= end else start >= end
|
||||||
|
private var next = if (hasNext) start else end
|
||||||
|
|
||||||
|
override fun hasNext() = hasNext
|
||||||
|
|
||||||
|
override fun next(): LogPriority {
|
||||||
|
val current = next
|
||||||
|
if (current == end) {
|
||||||
|
if (!hasNext) {
|
||||||
|
throw NoSuchElementException()
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNext = false
|
||||||
|
} else {
|
||||||
|
next = LogPriority.fromInt(next.toInt() + step)
|
||||||
|
}
|
||||||
|
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogPriorityProgression(
|
||||||
|
override val start: LogPriority,
|
||||||
|
override val endInclusive: LogPriority,
|
||||||
|
private val step: Int = 1
|
||||||
|
) : Iterable<LogPriority>, ClosedRange<LogPriority> {
|
||||||
|
override fun iterator(): Iterator<LogPriority> {
|
||||||
|
return LogPriorityIterator(start, endInclusive, step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
infix fun downTo(to: LogPriority) = LogPriorityProgression(this, to, -1)
|
||||||
|
|
||||||
|
operator fun rangeTo(to: LogPriority) = LogPriorityProgression(this, to)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromByte(byte: Byte): LogPriority {
|
fun fromByte(byte: Byte): LogPriority = fromInt(byte.toInt())
|
||||||
return when (byte.toInt()) {
|
|
||||||
|
fun fromInt(int: Int) = when (int) {
|
||||||
0x1 -> DEFAULT
|
0x1 -> DEFAULT
|
||||||
0x2 -> VERBOSE
|
0x2 -> VERBOSE
|
||||||
0x3 -> DEBUG
|
0x3 -> DEBUG
|
||||||
@@ -41,10 +82,21 @@ enum class LogPriority {
|
|||||||
0x7 -> FATAL
|
0x7 -> FATAL
|
||||||
0x8 -> SILENT
|
0x8 -> SILENT
|
||||||
else -> UNKNOWN
|
else -> UNKNOWN
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toInt() = when (this) {
|
||||||
|
DEFAULT -> 0x1
|
||||||
|
VERBOSE -> 0x2
|
||||||
|
DEBUG -> 0x3
|
||||||
|
INFO -> 0x4
|
||||||
|
WARN -> 0x5
|
||||||
|
ERROR -> 0x6
|
||||||
|
FATAL -> 0x7
|
||||||
|
SILENT -> 0x8
|
||||||
|
else -> 0x0
|
||||||
|
}
|
||||||
|
|
||||||
fun toChar(): Char {
|
fun toChar(): Char {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
VERBOSE -> 'V'
|
VERBOSE -> 'V'
|
||||||
|
|||||||
@@ -37,6 +37,15 @@ class LogViewModel: ViewModel() {
|
|||||||
var filterCrashes = false
|
var filterCrashes = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
// skip debug/verbose lines by default
|
||||||
|
var logLevel = LogPriority.INFO
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
|
||||||
|
_lineState.clear()
|
||||||
|
loadLogs()
|
||||||
|
}
|
||||||
|
|
||||||
fun toggleCrashBuffer() {
|
fun toggleCrashBuffer() {
|
||||||
filterCrashes = !filterCrashes
|
filterCrashes = !filterCrashes
|
||||||
|
|
||||||
@@ -70,8 +79,7 @@ class LogViewModel: ViewModel() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
val line = LogLine.fromBufferedSource(logSource)
|
val line = LogLine.fromBufferedSource(logSource)
|
||||||
|
|
||||||
// skip debug/verbose lines
|
if (line.priority >= logLevel) {
|
||||||
if (line.priority >= LogPriority.INFO) {
|
|
||||||
logLines += line
|
logLines += line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M480,760Q546,760 593,713Q640,666 640,600L640,440Q640,374 593,327Q546,280 480,280Q414,280 367,327Q320,374 320,440L320,600Q320,666 367,713Q414,760 480,760ZM400,640L560,640L560,560L400,560L400,640ZM400,480L560,480L560,400L400,400L400,480ZM480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520ZM480,840Q415,840 359.5,808Q304,776 272,720L160,720L160,640L244,640Q241,620 240.5,600Q240,580 240,560L160,560L160,480L240,480Q240,460 240.5,440Q241,420 244,400L160,400L160,320L272,320Q286,297 303.5,277Q321,257 344,242L280,176L336,120L422,206Q450,197 479,197Q508,197 536,206L624,120L680,176L614,242Q637,257 655.5,276.5Q674,296 688,320L800,320L800,400L716,400Q719,420 719.5,440Q720,460 720,480L800,480L800,560L720,560Q720,580 719.5,600Q719,620 716,640L800,640L800,720L688,720Q656,776 600.5,808Q545,840 480,840Z"/>
|
||||||
|
</vector>
|
||||||
@@ -104,6 +104,8 @@
|
|||||||
<string name="application_log_copy_label">Log Message</string>
|
<string name="application_log_copy_label">Log Message</string>
|
||||||
<string name="application_logs_more">More</string>
|
<string name="application_logs_more">More</string>
|
||||||
<string name="application_logs_export">Save To</string>
|
<string name="application_logs_export">Save To</string>
|
||||||
|
<string name="application_logs_level">Set Log Level</string>
|
||||||
|
<string name="application_logs_level_dialog_name">Set minimum log level</string>
|
||||||
<string name="application_logs_export_completed">Log export complete.</string>
|
<string name="application_logs_export_completed">Log export complete.</string>
|
||||||
<string name="application_logs_default_filename" translatable="false">launcher_logcat.txt</string>
|
<string name="application_logs_default_filename" translatable="false">launcher_logcat.txt</string>
|
||||||
<string name="application_logs_crash_only">Show Crash Buffer</string>
|
<string name="application_logs_crash_only">Show Crash Buffer</string>
|
||||||
|
|||||||
Reference in new issue
Block a user