Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### New Features

* **Thermal status row** – Optional thermal-status indicator for the compact overlay, opt-in via `OverlayMode.FullMetrics(showThermal = true)`. Combines `PowerManager.getCurrentThermalStatus()` with `getThermalHeadroom()` per [Google's ADPF guidance](https://developer.android.com/games/optimize/adpf/thermal#device-limitations-of-the-thermal-api) so devices with an incomplete thermal HAL still surface a useful signal. Requires Android 11 (API 30) or above; row stays hidden on older devices. Resolves [#246](https://github.com/Manabu-GT/DebugOverlay-Android/issues/246).
* **Configurable Logcat buffer size** – New `Config.maxLogcatEntries` controls how many entries the built-in Logcat tab retains (default 300). Also bounds `logcat -T N` / `-t N` so it caps OS replay on panel open and on bug-report snapshots. Reassignable at runtime via `DebugOverlay.configure { maxLogcatEntries = … }`.

## Version 2.5.0 *(2026-05-12)*

Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ DebugOverlay.configure {

The row shows the current thermal-throttling level with a color-coded dot. Labels are abbreviated to fit the compact panel — `None` / `Light` / `Mod` / `Sev` / `Crit` / `Emer` / `Shut` — mapping to `PowerManager.THERMAL_STATUS_NONE` / `_LIGHT` / `_MODERATE` / `_SEVERE` / `_CRITICAL` / `_EMERGENCY` / `_SHUTDOWN` respectively. Requires Android 11 (API 30) or above with a working thermal HAL — the row stays hidden on older devices and on API 30+ devices whose HAL doesn't expose `getThermalHeadroom` data. If the HAL later starts reporting, the row appears on the next poll.

### Logcat buffer size

The built-in Logcat tab keeps the last 300 entries by default. Override via `maxLogcatEntries`:

```kotlin
DebugOverlay.configure {
maxLogcatEntries = 1000
}
```

The value also bounds the `logcat -T N` / `-t N` calls, so it caps how many lines the OS replays when the panel opens and when a bug report snapshot is captured.

### Network request tracking

```kotlin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import kotlin.time.Duration.Companion.milliseconds
internal class LogcatDataSource(
scope: CoroutineScope,
private val parser: LogcatEntryParser = LogcatEntryParser(),
initialMaxEntries: Int,
@IntRange(from = 1) initialMaxEntries: Int,
) : LogSource,
Clearable,
Closeable {
Expand Down Expand Up @@ -91,9 +91,15 @@ internal class LogcatDataSource(
try {
/**
* NOTE: The -T flag with a number fetches the last N lines from this app and continue to listens
* for new logs (-t option fetches once and exists immediately).
* for new logs (-t option fetches once and exits immediately).
*/
val process = Runtime.getRuntime().exec("logcat -v threadtime,printable,epoch -T $maxEntries").also {
val process = ProcessBuilder(
"logcat",
"-v",
"threadtime,printable,epoch",
"-T",
maxEntries.toString()
).start().also {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (pre-existing, surfaced by the refactor): ProcessBuilder (like Runtime.exec) leaves stderr as a separate pipe that nothing consumes. With logcat this is harmless in practice — stderr is essentially silent — but if the OS pipe buffer ever filled the producer would deadlock. Now that the refactor uses ProcessBuilder, it's a one-liner to bulletproof it: …).redirectErrorStream(true).start(). Same for captureLogcatOnce() at line 182. Optional — feel free to defer.

synchronized(processLock) {
currentProcess = it
}
Expand Down Expand Up @@ -167,8 +173,13 @@ internal class LogcatDataSource(
private suspend fun captureLogcatOnce(): List<LogEntry> = withContext(Dispatchers.IO) {
buildList {
// -t N = fetch N recent lines and EXIT (vs -T which streams continuously)
val process = Runtime.getRuntime()
.exec("logcat -v threadtime,printable,epoch -t $maxEntries")
val process = ProcessBuilder(
"logcat",
"-v",
"threadtime,printable,epoch",
"-t",
maxEntries.toString()
).start()

try {
InputStreamReader(process.inputStream).useLines { lines ->
Expand Down
Loading