UI: drop Magisk prompt — ResourceMonitor stops probing su
ResourceMonitor.init ran `su -c id` at every ChatActivity launch to see if root was available, then used root to read /sys/class/kgsl/... and /sys/bus/platform/devices/soc:qcom,msm-cdsp-rm/... for GPU/NPU usage %. That probe was the only thing still triggering the Magisk auth dialog on each app start after the no-root LLM migration. Remove the root probe and the execRoot helper. GPU/NPU reads now return -1 (UI already renders "—" for negative values). The non-root /sys/class/kgsl/kgsl-3d0/gpubusy path is kept as a best-effort — it's world-readable on some devices, silently fails otherwise. CPU and RAM readouts are unaffected (never needed root). Dead-code `su -c ...` calls remain in Qwen3TtsEngine (hexStartRunner, hexStartCpRunner, hexStopRunner, etc.) and WhisperNpuSttEngine, but all are gated behind fallback paths that don't execute under the current PTE-only config (talkerPteModule != null && cpPteModule != null short- circuits before any su call). Left in place to avoid churning the TTS Hexagon fallback; can be purged in a later cleanup pass if needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
10fd10fd90
commit
0632db1ee0
|
|
@ -18,17 +18,12 @@ class ResourceMonitor(private val context: Context) {
|
||||||
private var prevIdle = 0L
|
private var prevIdle = 0L
|
||||||
private var prevGpuBusy = 0L
|
private var prevGpuBusy = 0L
|
||||||
private var prevGpuTotal = 0L
|
private var prevGpuTotal = 0L
|
||||||
private var hasRoot = false
|
|
||||||
|
|
||||||
init {
|
// No-root deployment (2026-04-14): the previous `su -c id` probe used to
|
||||||
// Test root access once
|
// enable GPU/NPU sysfs reads via root, but it also triggered a Magisk
|
||||||
hasRoot = try {
|
// prompt on every ChatActivity launch. The whole pipeline now runs in
|
||||||
val p = Runtime.getRuntime().exec(arrayOf("su", "-c", "id"))
|
// the app process so root is never needed — GPU/NPU usage is reported
|
||||||
val result = p.inputStream.bufferedReader().readText()
|
// as -1 (UI shows "—") and the dashboard shows CPU + RAM only.
|
||||||
p.waitFor()
|
|
||||||
result.contains("uid=0")
|
|
||||||
} catch (_: Exception) { false }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun snapshot(): ResourceSnapshot {
|
fun snapshot(): ResourceSnapshot {
|
||||||
return ResourceSnapshot(
|
return ResourceSnapshot(
|
||||||
|
|
@ -67,7 +62,9 @@ class ResourceMonitor(private val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readGpu(): Float {
|
private fun readGpu(): Float {
|
||||||
// Try direct read first (works on some devices)
|
// Non-root path: some devices expose /sys/class/kgsl/kgsl-3d0/gpubusy
|
||||||
|
// as world-readable. If it's locked down (most SELinux configs do),
|
||||||
|
// just return -1 — no root fallback, no Magisk prompt.
|
||||||
try {
|
try {
|
||||||
val content = File("/sys/class/kgsl/kgsl-3d0/gpubusy").readText().trim()
|
val content = File("/sys/class/kgsl/kgsl-3d0/gpubusy").readText().trim()
|
||||||
val parts = content.split("\\s+".toRegex())
|
val parts = content.split("\\s+".toRegex())
|
||||||
|
|
@ -81,38 +78,14 @@ class ResourceMonitor(private val context: Context) {
|
||||||
if (dt > 0) return (db * 100f / dt).coerceIn(0f, 100f)
|
if (dt > 0) return (db * 100f / dt).coerceIn(0f, 100f)
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {}
|
} catch (_: Exception) {}
|
||||||
|
|
||||||
// Try with root
|
|
||||||
if (hasRoot) {
|
|
||||||
try {
|
|
||||||
val content = execRoot("cat /sys/class/kgsl/kgsl-3d0/gpu_busy_percentage").trim()
|
|
||||||
val pct = content.replace("%", "").trim().toFloatOrNull()
|
|
||||||
if (pct != null) return pct.coerceIn(0f, 100f)
|
|
||||||
} catch (_: Exception) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1f
|
return -1f
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readNpu(): Float {
|
private fun readNpu(): Float {
|
||||||
// NPU doesn't have a standard busy metric
|
// NPU usage reporting required root sysfs reads (cdsp_rm/cpu_vote,
|
||||||
// Use CDSP (compute DSP) load as proxy if available
|
// /proc/fastrpc) that always triggered a Magisk prompt. Removed with
|
||||||
if (hasRoot) {
|
// the no-root migration — no equivalent public API exists, so the
|
||||||
try {
|
// UI just shows "—" for NPU load.
|
||||||
// Check if CDSP is active by reading vote count
|
|
||||||
val vote = execRoot("cat /sys/bus/platform/devices/soc:qcom,msm-cdsp-rm/cdsp_rm/cpu_vote 2>/dev/null").trim()
|
|
||||||
if (vote.isNotEmpty()) {
|
|
||||||
val v = vote.toIntOrNull() ?: 0
|
|
||||||
return if (v > 0) 100f else 0f
|
|
||||||
}
|
|
||||||
} catch (_: Exception) {}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Alternative: check fastrpc activity
|
|
||||||
val stat = execRoot("cat /proc/fastrpc 2>/dev/null || echo none").trim()
|
|
||||||
if (stat != "none" && stat.isNotEmpty()) return 50f
|
|
||||||
} catch (_: Exception) {}
|
|
||||||
}
|
|
||||||
return -1f
|
return -1f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,12 +107,4 @@ class ResourceMonitor(private val context: Context) {
|
||||||
} catch (_: Exception) { return 0 }
|
} catch (_: Exception) { return 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun execRoot(cmd: String): String {
|
|
||||||
return try {
|
|
||||||
val p = Runtime.getRuntime().exec(arrayOf("su", "-c", cmd))
|
|
||||||
val result = p.inputStream.bufferedReader().readText()
|
|
||||||
p.waitFor()
|
|
||||||
result
|
|
||||||
} catch (_: Exception) { "" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue