mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
feat: the session report lists the panel refresh modes, thermal state and hint-session support (#990)
This commit is contained in:
1 parent
9c9486400b
commit
522e755b37
2 files changed
+76
No files matched your search
@@ -2,10 +2,15 @@ package com.droiddeck.launcher.core
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.os.PerformanceHintManager
|
||||
import android.os.PowerManager
|
||||
import android.os.StatFs
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.Display
|
||||
import com.droiddeck.launcher.gpu.LinuxVulkanDriver
|
||||
import com.droiddeck.launcher.gpu.LinuxVulkanDriverManager
|
||||
import com.droiddeck.launcher.gpu.TurnipDriver
|
||||
@@ -54,6 +59,29 @@ object DeviceReport {
|
||||
else -> "REASON_$reason"
|
||||
}
|
||||
|
||||
internal fun thermalStatusName(status: Int): String = when (status) {
|
||||
0 -> "NONE"
|
||||
1 -> "LIGHT"
|
||||
2 -> "MODERATE"
|
||||
3 -> "SEVERE"
|
||||
4 -> "CRITICAL"
|
||||
5 -> "EMERGENCY"
|
||||
6 -> "SHUTDOWN"
|
||||
else -> "STATUS_$status"
|
||||
}
|
||||
|
||||
internal fun gameModeName(mode: Int): String = when (mode) {
|
||||
0 -> "UNSUPPORTED"
|
||||
1 -> "STANDARD"
|
||||
2 -> "PERFORMANCE"
|
||||
3 -> "BATTERY"
|
||||
4 -> "CUSTOM"
|
||||
else -> "MODE_$mode"
|
||||
}
|
||||
|
||||
internal fun refreshModesSummary(rates: List<Float>): String =
|
||||
rates.map { Math.round(it) }.distinct().sortedDescending().joinToString(", ") { "$it Hz" }
|
||||
|
||||
internal fun exitSummary(processName: String?, reason: Int, status: Int, description: String?): String =
|
||||
buildString {
|
||||
append(processName ?: "?").append(" ").append(exitReasonName(reason)).append(" status=").append(status)
|
||||
@@ -124,6 +152,19 @@ object DeviceReport {
|
||||
k("RAM total", FileUtils.sizeToString(mi.totalMem))
|
||||
k("RAM available", FileUtils.sizeToString(mi.availMem))
|
||||
}
|
||||
runCatching {
|
||||
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) k("Thermal status", thermalStatusName(pm.currentThermalStatus))
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
k("Thermal headroom (10 s)", pm.getThermalHeadroom(10).let { if (it.isNaN()) "not reported" else String.format(Locale.US, "%.2f", it) })
|
||||
}
|
||||
k("Power saver", pm.isPowerSaveMode)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val rate = runCatching { context.getSystemService(PerformanceHintManager::class.java)?.preferredUpdateRateNanos }.getOrNull()
|
||||
k("ADPF hint sessions", if (rate == null || rate <= 0) "not supported" else "supported (preferred update ${rate / 1000} us)")
|
||||
k("Game Mode", runCatching { context.getSystemService(android.app.GameManager::class.java)?.gameMode }.getOrNull()?.let { gameModeName(it) })
|
||||
}
|
||||
runCatching {
|
||||
val fs = StatFs(context.filesDir.path)
|
||||
k("App storage free", FileUtils.sizeToString(fs.availableBlocksLong * fs.blockSizeLong))
|
||||
@@ -141,6 +182,13 @@ object DeviceReport {
|
||||
h("Display")
|
||||
k("Session output", SessionState.outputSize?.let { "${it.first}x${it.second}" })
|
||||
k("Session refresh", String.format(Locale.US, "%.2f Hz", SessionState.refreshHz))
|
||||
runCatching {
|
||||
val display = context.getSystemService(DisplayManager::class.java).getDisplay(Display.DEFAULT_DISPLAY)
|
||||
k("Panel refresh now", String.format(Locale.US, "%.2f Hz", display.refreshRate))
|
||||
k("Panel refresh modes", refreshModesSummary(display.supportedModes.map { it.refreshRate }))
|
||||
}
|
||||
k("peak_refresh_rate", runCatching { Settings.System.getString(context.contentResolver, "peak_refresh_rate") }.getOrNull() ?: "not set")
|
||||
k("refresh_rate_mode", runCatching { Settings.Secure.getString(context.contentResolver, "refresh_rate_mode") }.getOrNull() ?: "not set")
|
||||
val panelSize = com.droiddeck.launcher.session.SessionDisplay.panelSize(context)
|
||||
for ((label, mode) in listOf("Resolution (Steam)" to SessionService.MODE_STEAM, "Resolution (Desktop)" to SessionService.MODE_DESKTOP)) {
|
||||
val choice = SessionPrefs.resolutionChoice(context, mode, panelSize)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.droiddeck.launcher.core
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class DeviceReportPerfTest {
|
||||
@Test fun thermalStatusesHaveTheirPlatformNames() {
|
||||
assertEquals("NONE", DeviceReport.thermalStatusName(0))
|
||||
assertEquals("MODERATE", DeviceReport.thermalStatusName(2))
|
||||
assertEquals("CRITICAL", DeviceReport.thermalStatusName(4))
|
||||
assertEquals("SHUTDOWN", DeviceReport.thermalStatusName(6))
|
||||
assertEquals("STATUS_9", DeviceReport.thermalStatusName(9))
|
||||
}
|
||||
|
||||
@Test fun gameModesHaveTheirPlatformNames() {
|
||||
assertEquals("UNSUPPORTED", DeviceReport.gameModeName(0))
|
||||
assertEquals("STANDARD", DeviceReport.gameModeName(1))
|
||||
assertEquals("PERFORMANCE", DeviceReport.gameModeName(2))
|
||||
assertEquals("BATTERY", DeviceReport.gameModeName(3))
|
||||
assertEquals("MODE_7", DeviceReport.gameModeName(7))
|
||||
}
|
||||
|
||||
@Test fun refreshModesAreRoundedDeduplicatedAndListedFastestFirst() {
|
||||
assertEquals("120 Hz, 60 Hz", DeviceReport.refreshModesSummary(listOf(60.0f, 120.00001f, 60.00001f)))
|
||||
assertEquals("60 Hz", DeviceReport.refreshModesSummary(listOf(59.94f)))
|
||||
assertEquals("", DeviceReport.refreshModesSummary(emptyList()))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user