____ _ _______ __
/ __ \ | /| / / __/ |/ /
/ /_/ / |/ |/ / _// /
\____/|__/|__/___/_||_/
owenclave / app/src/main/java/io/nekohasekai/sagernet/ui/compose/screens/LogcatScreen.kt
package io.nekohasekai.sagernet.ui.compose.screens
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.nekohasekai.sagernet.ui.compose.components.OwenclaveTopAppBar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LogcatScreen(
onMenuClick: () -> Unit,
) {
var logText by remember { mutableStateOf("") }
LaunchedEffect(Unit) {
try {
val process = Runtime.getRuntime().exec(arrayOf("logcat", "-d", "-t", "500"))
logText = process.inputStream.bufferedReader().readText()
} catch (_: Exception) {
logText = "Failed to read logs"
}
}
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
containerColor = MaterialTheme.colorScheme.surfaceContainer,
topBar = {
OwenclaveTopAppBar(
title = "Logcat",
navigationIcon = Icons.Filled.Menu,
onNavigationClick = onMenuClick,
scrollBehavior = scrollBehavior,
actions = {
IconButton(onClick = { /* send logcat */ }) {
Icon(Icons.Filled.Send, contentDescription = "Send")
}
IconButton(onClick = { /* clear logcat */ }) {
Icon(Icons.Filled.Delete, contentDescription = "Clear")
}
},
)
},
) { paddingValues ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.verticalScroll(rememberScrollState())
.padding(8.dp)
) {
Text(
text = logText,
style = MaterialTheme.typography.bodySmall.copy(
fontFamily = FontFamily.Monospace,
fontSize = 10.sp,
),
color = MaterialTheme.colorScheme.onSurface,
)
}
}
}