app: tell the user before the run when Shizuku is installed but not started
Distinguishes not-installed (say nothing — don't nag users who don't use Shizuku) from installed-but-stopped (amber banner: start it to include shell-tier tests), plus running-unauthorised and ready. Detection is listener-based since pingBinder() only becomes truthful once ShizukuProvider delivers the binder; a launch-time poll would show a false "not running". Installed-vs-not needs the <queries> entry on Android 11+. Verified on-device: with shizuku_server stopped, the banner shows before pressing Run; the title also now clears the status bar/cutout after the safeDrawingPadding fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
217818f7b3
commit
d7dda40e4e
@@ -115,6 +115,22 @@ private fun EcholotScreen(
|
||||
Text("Echolot", fontSize = 26.sp, fontWeight = FontWeight.SemiBold)
|
||||
Text("measure, don't guess", color = MaterialTheme.colorScheme.onSurfaceVariant, fontSize = 13.sp)
|
||||
|
||||
// Shell-tier readiness, before the run. Nothing is shown when Shizuku isn't installed —
|
||||
// only users who actually use it get reminded that it must be running.
|
||||
state.shizukuNotice?.let { notice ->
|
||||
Card(
|
||||
Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = if (state.shizukuReady) Color(0xFF14301F) else Color(0xFF3A2E12),
|
||||
),
|
||||
) {
|
||||
Text(
|
||||
notice, Modifier.padding(10.dp), fontSize = 12.sp,
|
||||
color = if (state.shizukuReady) Color(0xFF9CCFA8) else Color(0xFFFFD08A),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Button(onClick = onRun, enabled = !state.running) {
|
||||
Text(if (state.running) "Running…" else "Run measurement")
|
||||
|
||||
@@ -20,6 +20,7 @@ import app.echo_lot.probe.NetworkInventory
|
||||
import app.echo_lot.probe.Probe
|
||||
import app.echo_lot.probe.ProbeIds
|
||||
import app.echo_lot.probe.RouterIdentityProbe
|
||||
import app.echo_lot.shizuku.ShizukuAvailability
|
||||
import app.echo_lot.shizuku.ShizukuProbe
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -37,6 +38,9 @@ data class UiState(
|
||||
val stepsDone: Int = 0,
|
||||
val stepsTotal: Int = 0,
|
||||
val etaSeconds: Int = 0,
|
||||
/** Shell-tier readiness, shown before a run; null message = say nothing (Shizuku not installed). */
|
||||
val shizukuNotice: String? = null,
|
||||
val shizukuReady: Boolean = false,
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -51,6 +55,24 @@ class RunViewModel(app: Application) : AndroidViewModel(app) {
|
||||
private set
|
||||
|
||||
private var runJob: kotlinx.coroutines.Job? = null
|
||||
private val stopShizukuObserver: () -> Unit
|
||||
|
||||
init {
|
||||
// Report shell-tier readiness up front. The binder arrives asynchronously, so this is a
|
||||
// listener, not a one-shot poll — otherwise a running Shizuku would look "not running"
|
||||
// for the first moment after launch.
|
||||
stopShizukuObserver = ShizukuAvailability.observe(app) { st ->
|
||||
state = state.copy(
|
||||
shizukuNotice = ShizukuAvailability.describe(st),
|
||||
shizukuReady = st == ShizukuAvailability.State.READY,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
stopShizukuObserver()
|
||||
super.onCleared()
|
||||
}
|
||||
// Results collected so far. A cancelled run must still be able to show what it measured.
|
||||
private val collected = mutableListOf<Test>()
|
||||
private var runIds: RunIds = RunIds()
|
||||
|
||||
Reference in New Issue
Block a user